Merge branch 'main' into avm99963-monorail
Merged commit cd4b3b336f1f14afa02990fdc2eec5d9467a827e
GitOrigin-RevId: e67bbf185d5538e1472bb42e0abb2a141f88bac1
diff --git a/tracker/componentcreate.py b/tracker/componentcreate.py
index 9cb713c..9974879 100644
--- a/tracker/componentcreate.py
+++ b/tracker/componentcreate.py
@@ -11,6 +11,7 @@
import logging
import time
+from framework import flaskservlet
from framework import framework_helpers
from framework import framework_views
from framework import jsonfeed
@@ -28,7 +29,7 @@
class ComponentCreate(servlet.Servlet):
"""Servlet allowing project owners to create a component."""
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PROCESS
_PAGE_TEMPLATE = 'tracker/component-create-page.ezt'
def AssertBasePermission(self, mr):
@@ -136,6 +137,12 @@
return framework_helpers.FormatAbsoluteURL(
mr, urls.ADMIN_COMPONENTS, saved=1, ts=int(time.time()))
+ # def GetComponentCreatePage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostComponentCreatePage(self, **kwargs):
+ # return self.handler(**kwargs)
+
def LeafNameErrorMessage(parent_path, leaf_name, config):
"""Return an error message for the given component name, or None."""
diff --git a/tracker/fieldcreate.py b/tracker/fieldcreate.py
index ead72ad..b1f2316 100644
--- a/tracker/fieldcreate.py
+++ b/tracker/fieldcreate.py
@@ -15,6 +15,7 @@
import ezt
from framework import exceptions
+from framework import flaskservlet
from framework import framework_helpers
from framework import jsonfeed
from framework import permissions
@@ -30,7 +31,7 @@
class FieldCreate(servlet.Servlet):
"""Servlet allowing project owners to create a custom field."""
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PROCESS
_PAGE_TEMPLATE = 'tracker/field-create-page.ezt'
def AssertBasePermission(self, mr):
@@ -198,6 +199,12 @@
return framework_helpers.FormatAbsoluteURL(
mr, urls.ADMIN_LABELS, saved=1, ts=int(time.time()))
+ # def GetFieldCreate(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostFieldCreate(self, **kwargs):
+ # return self.handler(**kwargs)
+
def FieldNameErrorMessage(field_name, config):
"""Return an error message for the given field name, or None."""
diff --git a/tracker/fielddetail.py b/tracker/fielddetail.py
index 3e7ebb3..76cf378 100644
--- a/tracker/fielddetail.py
+++ b/tracker/fielddetail.py
@@ -15,6 +15,7 @@
import ezt
from framework import exceptions
+from framework import flaskservlet
from framework import framework_helpers
from framework import framework_views
from framework import permissions
@@ -30,7 +31,7 @@
class FieldDetail(servlet.Servlet):
"""Servlet allowing project owners to view and edit a custom field."""
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PROCESS
_PAGE_TEMPLATE = 'tracker/field-detail-page.ezt'
def _GetFieldDef(self, mr):
@@ -247,3 +248,9 @@
return framework_helpers.FormatAbsoluteURL(
mr, urls.FIELD_DETAIL, field=field_def.field_name,
saved=1, ts=int(time.time()))
+
+ # def GetFieldDetail(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostFieldDetail(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/fltconversion.py b/tracker/fltconversion.py
index c26ab62..e42b432 100644
--- a/tracker/fltconversion.py
+++ b/tracker/fltconversion.py
@@ -134,6 +134,7 @@
'phase_map, approvals_to_labels, labels_re')
+# TODO: change to FlaskInternalTask when convert to flask
class FLTConvertTask(jsonfeed.InternalTask):
"""FLTConvert converts current Type=Launch issues into Type=FLT-Launch."""
@@ -530,6 +531,12 @@
return tracker_bizobj.MakeFieldValue(
field_id, None, None, user_id, None, None, False)
+ # def GetFLTConvertTask(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostFLTConvertTask(self, **kwargs):
+ # return self.handler(**kwargs)
+
def ConvertMLabels(
labels, phases, m_target_id, m_approved_id, labels_re, phase_map):
diff --git a/tracker/issueadmin.py b/tracker/issueadmin.py
index 5c34f72..10fbdc8 100644
--- a/tracker/issueadmin.py
+++ b/tracker/issueadmin.py
@@ -24,6 +24,7 @@
from features import filterrules_views
from features import savedqueries_helpers
from framework import authdata
+from framework import flaskservlet
from framework import framework_bizobj
from framework import framework_constants
from framework import framework_helpers
@@ -43,7 +44,7 @@
class IssueAdminBase(servlet.Servlet):
"""Base class for servlets allowing project owners to configure tracker."""
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PROCESS
_PROCESS_SUBTAB = None # specified in subclasses
def GatherPageData(self, mr):
@@ -90,7 +91,7 @@
"""Servlet allowing project owners to configure well-known statuses."""
_PAGE_TEMPLATE = 'tracker/admin-statuses-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_STATUSES
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_STATUSES
def ProcessSubtabForm(self, post_data, mr):
"""Process the status definition section of the admin page.
@@ -141,12 +142,18 @@
return urls.ADMIN_STATUSES
+ # def GetAdminStatusesPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostAdminStatusesPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
class AdminLabels(IssueAdminBase):
"""Servlet allowing project owners to labels and fields."""
_PAGE_TEMPLATE = 'tracker/admin-labels-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_LABELS
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_LABELS
def GatherPageData(self, mr):
"""Build up a dictionary of data values to use when rendering the page.
@@ -224,12 +231,18 @@
return urls.ADMIN_LABELS
+ # def GetAdminLabelsPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostAdminLabelsPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
class AdminTemplates(IssueAdminBase):
"""Servlet allowing project owners to configure templates."""
_PAGE_TEMPLATE = 'tracker/admin-templates-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_TEMPLATES
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_TEMPLATES
def GatherPageData(self, mr):
"""Build up a dictionary of data values to use when rendering the page.
@@ -288,12 +301,18 @@
return (GetSelectedTemplateID('default_template_for_developers'),
GetSelectedTemplateID('default_template_for_users'))
+ # def GetAdminTemplatesPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostAdminTemplatesPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
class AdminComponents(IssueAdminBase):
"""Servlet allowing project owners to view the list of components."""
_PAGE_TEMPLATE = 'tracker/admin-components-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_COMPONENTS
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_COMPONENTS
def GatherPageData(self, mr):
"""Build up a dictionary of data values to use when rendering the page.
@@ -398,12 +417,18 @@
failed_templ=','.join(templates_errors),
deleted=','.join(deleted_components))
+ # def GetAdminComponentsPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostAdminComponentsPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
class AdminViews(IssueAdminBase):
"""Servlet for project owners to set default columns, axes, and sorting."""
_PAGE_TEMPLATE = 'tracker/admin-views-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_VIEWS
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_VIEWS
def GatherPageData(self, mr):
"""Build up a dictionary of data values to use when rendering the page.
@@ -463,6 +488,12 @@
return urls.ADMIN_VIEWS
+ # def GetAdminViewsPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostAdminViewsPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
def _ParseListPreferences(post_data):
"""Parse the part of a project admin form about artifact list preferences."""
@@ -509,7 +540,7 @@
"""Servlet allowing project owners to configure filter rules."""
_PAGE_TEMPLATE = 'tracker/admin-rules-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_RULES
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_RULES
def AssertBasePermission(self, mr):
"""Check whether the user has any permission to visit this page.
@@ -585,3 +616,9 @@
mr.cnxn, self.services, mr.project, config)
return urls.ADMIN_RULES
+
+ # def GetAdminRulesPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostAdminRulesPage(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issueadvsearch.py b/tracker/issueadvsearch.py
index d824098..f702763 100644
--- a/tracker/issueadvsearch.py
+++ b/tracker/issueadvsearch.py
@@ -17,6 +17,7 @@
import re
from features import savedqueries_helpers
+from framework import flaskservlet
from framework import framework_helpers
from framework import permissions
from framework import servlet
@@ -31,7 +32,7 @@
"""IssueAdvancedSearch shows a form to enter an advanced search."""
_PAGE_TEMPLATE = 'tracker/issue-advsearch-page.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
# This form *only* redirects to a GET request, and permissions are checked
# in that handler.
@@ -121,3 +122,9 @@
values = VALUE_RE.findall(user_input)
search_term = '%s%s' % (operator, ','.join(values))
search_query.append(search_term)
+
+ # def GetIssueAdvSearchPage(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostIssueAdvSearchPage(self, **kwargs):
+ # return self.handler(**kwargs)
\ No newline at end of file
diff --git a/tracker/issueattachment.py b/tracker/issueattachment.py
index d6fa978..26982d0 100644
--- a/tracker/issueattachment.py
+++ b/tracker/issueattachment.py
@@ -18,14 +18,13 @@
import logging
import os
import re
-import urllib
-
-import webapp2
+from six.moves import urllib
from google.appengine.api import app_identity
from google.appengine.api import images
from framework import exceptions
+from framework import flaskservlet
from framework import framework_constants
from framework import framework_helpers
from framework import gcs_helpers
@@ -54,20 +53,20 @@
Returns: dict of values used by EZT for rendering the page.
"""
if mr.signed_aid != attachment_helpers.SignAttachmentID(mr.aid):
- webapp2.abort(400, 'Please reload the issue page')
+ self.abort(400, 'Please reload the issue page')
try:
attachment, _issue = tracker_helpers.GetAttachmentIfAllowed(
mr, self.services)
except exceptions.NoSuchIssueException:
- webapp2.abort(404, 'issue not found')
+ self.abort(404, 'issue not found')
except exceptions.NoSuchAttachmentException:
- webapp2.abort(404, 'attachment not found')
+ self.abort(404, 'attachment not found')
except exceptions.NoSuchCommentException:
- webapp2.abort(404, 'comment not found')
+ self.abort(404, 'comment not found')
if not attachment.gcs_object_id:
- webapp2.abort(404, 'attachment data not found')
+ self.abort(404, 'attachment data not found')
bucket_name = app_identity.get_default_gcs_bucket_name()
@@ -91,3 +90,6 @@
url = gcs_helpers.SignUrl(bucket_name, gcs_object_id)
self.redirect(url, abort=True)
+
+ # def GetAttachmentPage(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issueattachmenttext.py b/tracker/issueattachmenttext.py
index d3daaf9..40db170 100644
--- a/tracker/issueattachmenttext.py
+++ b/tracker/issueattachmenttext.py
@@ -14,15 +14,13 @@
import logging
-import webapp2
-
-from google.appengine.api import app_identity
-
-from third_party import cloudstorage
import ezt
+from google.appengine.api import app_identity
+from google.cloud import storage
from features import prettify
from framework import exceptions
+from framework import flaskservlet
from framework import filecontent
from framework import permissions
from framework import servlet
@@ -36,7 +34,7 @@
"""AttachmentText displays textual attachments much like source browsing."""
_PAGE_TEMPLATE = 'tracker/issue-attachment-text.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
def GatherPageData(self, mr):
"""Parse the attachment ID from the request and serve its content.
@@ -52,19 +50,27 @@
attachment, issue = tracker_helpers.GetAttachmentIfAllowed(
mr, self.services)
except exceptions.NoSuchIssueException:
- webapp2.abort(404, 'issue not found')
+ self.abort(404, 'issue not found')
except exceptions.NoSuchAttachmentException:
- webapp2.abort(404, 'attachment not found')
+ self.abort(404, 'attachment not found')
except exceptions.NoSuchCommentException:
- webapp2.abort(404, 'comment not found')
+ self.abort(404, 'comment not found')
- content = []
+ content = b''
if attachment.gcs_object_id:
bucket_name = app_identity.get_default_gcs_bucket_name()
full_path = '/' + bucket_name + attachment.gcs_object_id
logging.info("reading gcs: %s" % full_path)
- with cloudstorage.open(full_path, 'r') as f:
- content = f.read()
+
+ # Strip leading slash from object ID for backwards compatibility.
+ blob_name = attachment.gcs_object_id
+ if blob_name.startswith('/'):
+ blob_name = blob_name[1:]
+
+ client = storage.Client()
+ bucket = client.get_bucket(bucket_name)
+ blob = bucket.get_blob(blob_name)
+ content = blob.download_as_bytes()
filesize = len(content)
@@ -101,3 +107,6 @@
len(lines), attachment.filename))
return page_data
+
+ # def GetAttachmentText(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issuebulkedit.py b/tracker/issuebulkedit.py
index c1f5229..3ea4d3f 100644
--- a/tracker/issuebulkedit.py
+++ b/tracker/issuebulkedit.py
@@ -14,7 +14,7 @@
from __future__ import absolute_import
import collections
-import httplib
+from six.moves import http_client
import itertools
import logging
import time
@@ -24,6 +24,7 @@
from features import filterrules_helpers
from features import send_notifications
from framework import exceptions
+from framework import flaskservlet
from framework import framework_constants
from framework import framework_views
from framework import permissions
@@ -41,7 +42,7 @@
"""IssueBulkEdit lists multiple issues and allows an edit to all of them."""
_PAGE_TEMPLATE = 'tracker/issue-bulk-edit-page.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
_SECONDS_OVERHEAD = 4
_SECONDS_PER_UPDATE = 0.12
_SLOWNESS_THRESHOLD = 10
@@ -170,31 +171,41 @@
"""
if not mr.local_id_list:
logging.info('missing issue local IDs, probably tampered')
- self.response.status = httplib.BAD_REQUEST
+ #TODO: switch when convert /p to flask
+ # self.response.status_code = http_client.BAD_REQUEST
+ self.response.status = http_client.BAD_REQUEST
return
# Check that the user is logged in; anon users cannot update issues.
if not mr.auth.user_id:
logging.info('user was not logged in, cannot update issue')
- self.response.status = httplib.BAD_REQUEST # xxx should raise except
+ #TODO: switch when convert /p to flask
+ # self.response.status_code = http_client.BAD_REQUEST
+ self.response.status = http_client.BAD_REQUEST
return
# Check that the user has permission to add a comment, and to enter
# metadata if they are trying to do that.
if not self.CheckPerm(mr, permissions.ADD_ISSUE_COMMENT):
logging.info('user has no permission to add issue comment')
- self.response.status = httplib.BAD_REQUEST
+ #TODO: switch when convert /p to flask
+ # self.response.status_code = http_client.BAD_REQUEST
+ self.response.status = http_client.BAD_REQUEST
return
if not self.CheckPerm(mr, permissions.EDIT_ISSUE):
logging.info('user has no permission to edit issue metadata')
- self.response.status = httplib.BAD_REQUEST
+ #TODO: switch when convert /p to flask
+ # self.response.status_code = http_client.BAD_REQUEST
+ self.response.status = http_client.BAD_REQUEST
return
move_to = post_data.get('move_to', '').lower()
if move_to and not self.CheckPerm(mr, permissions.DELETE_ISSUE):
logging.info('user has no permission to move issue')
- self.response.status = httplib.BAD_REQUEST
+ #TODO: switch when convert /p to flask
+ # self.response.status_code = http_client.BAD_REQUEST
+ self.response.status = http_client.BAD_REQUEST
return
config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
@@ -471,3 +482,9 @@
# TODO(jrobbins): implement bulk=N param for a better confirmation alert.
return tracker_helpers.FormatIssueListURL(
mr, config, saved=len(mr.local_id_list), ts=int(time.time()))
+
+ # def GetIssueBulkEdit(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostIssueBulkEdit(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issuedetailezt.py b/tracker/issuedetailezt.py
index 9460669..3a10443 100644
--- a/tracker/issuedetailezt.py
+++ b/tracker/issuedetailezt.py
@@ -14,7 +14,6 @@
from __future__ import division
from __future__ import absolute_import
-import httplib
import json
import logging
import time
@@ -28,6 +27,7 @@
from features import hotlist_helpers
from features import hotlist_views
from framework import exceptions
+from framework import flaskservlet
from framework import framework_bizobj
from framework import framework_constants
from framework import framework_helpers
@@ -159,14 +159,23 @@
class FlipperNext(FlipperRedirectBase):
next_handler = True
+ # def GetFlipperNextRedirectPage(self, **kwargs):
+ # self.next_handler = True
+ # return self.handler(**kwargs)
+
class FlipperPrev(FlipperRedirectBase):
next_handler = False
+ # def GetFlipperPrevRedirectPage(self, **kwargs):
+ # self.next_handler = False
+ # return self.handler(**kwargs)
+
class FlipperList(servlet.Servlet):
# pylint: disable=arguments-differ
# pylint: disable=unused-argument
+ # TODO: (monorail:6511)change to get(self) when convert to flask
def get(self, project_name=None, viewed_username=None, hotlist_id=None):
with work_env.WorkEnv(self.mr, self.services) as we:
hotlist_id = self.mr.GetIntParam('hotlist_id')
@@ -190,7 +199,11 @@
hotlist, self.services)
self.redirect(url)
+ # def GetFlipperList(self, **kwargs):
+ # return self.handler(**kwargs)
+
+# TODO: (monorail:6511) change to flaskJsonFeed when convert to flask
class FlipperIndex(jsonfeed.JsonFeed):
"""Return a JSON object of an issue's index in search.
@@ -261,6 +274,12 @@
'total_count': total_count,
}
+ # def GetFlipperIndex(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostFlipperIndex(self, **kwargs):
+ # return self.handler(**kwargs)
+
def _ShouldShowFlipper(mr, services):
"""Return True if we should show the flipper."""
diff --git a/tracker/issueentry.py b/tracker/issueentry.py
index 77de114..2ae59d8 100644
--- a/tracker/issueentry.py
+++ b/tracker/issueentry.py
@@ -18,6 +18,7 @@
from features import hotlist_helpers
from features import send_notifications
from framework import exceptions
+from framework import flaskservlet
from framework import framework_bizobj
from framework import framework_constants
from framework import framework_helpers
@@ -45,7 +46,7 @@
"""IssueEntry shows a page with a simple form to enter a new issue."""
_PAGE_TEMPLATE = 'tracker/issue-entry-page.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
# The issue filing wizard is a separate app that posted back to Monorail's
# issue entry page. To make this possible for the wizard, we need to allow
@@ -511,6 +512,12 @@
return template
+ # def GetIssueEntry(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostIssueEntry(self, **kwargs):
+ # return self.handler(**kwargs)
+
def _AttachDefaultApprovers(config, approval_values):
approval_defs_by_id = {ad.approval_id: ad for ad in config.approval_defs}
diff --git a/tracker/issueentryafterlogin.py b/tracker/issueentryafterlogin.py
index d25a7c1..3008d54 100644
--- a/tracker/issueentryafterlogin.py
+++ b/tracker/issueentryafterlogin.py
@@ -11,6 +11,7 @@
import logging
+from framework import flaskservlet
from framework import servlet
from framework import servlet_helpers
@@ -25,8 +26,9 @@
if not mr.auth.user_id:
self.abort(400, 'Only signed-in users should reach this URL.')
- with mr.profiler.Phase('getting config'):
- config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
- entry_page_url = servlet_helpers.ComputeIssueEntryURL(mr, config)
+ entry_page_url = servlet_helpers.ComputeIssueEntryURL(mr)
logging.info('Redirecting to %r', entry_page_url)
self.redirect(entry_page_url, abort=True)
+
+ # def GetIssueEntryAfterLogin(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issueexport.py b/tracker/issueexport.py
index a457a17..91620c4 100644
--- a/tracker/issueexport.py
+++ b/tracker/issueexport.py
@@ -16,6 +16,7 @@
from businesslogic import work_env
from features import savedqueries_helpers
+from framework import flaskservlet
from framework import permissions
from framework import jsonfeed
from framework import servlet
@@ -26,7 +27,7 @@
"""IssueExportControls let's an admin choose how to export issues."""
_PAGE_TEMPLATE = 'tracker/issue-export-page.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
def AssertBasePermission(self, mr):
"""Make sure that the logged in user has permission to view this page."""
@@ -69,7 +70,11 @@
'saved_queries': saved_query_views,
}
+ # def GetIssueExport(self, **kwargs):
+ # return self.handler(**kwargs)
+
+# TODO: convert to FLaskJsonFeed while conver to flask
class IssueExportJSON(jsonfeed.JsonFeed):
"""IssueExport shows a range of issues in JSON format."""
@@ -277,3 +282,9 @@
if merge.project_id == mr.project.project_id:
issue_json['merged_into'] = merge.local_id
return issue_json
+
+ # def GetIssueExportJSON(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostIssueExportJSON(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issueimport.py b/tracker/issueimport.py
index 1e0289b..bd54db9 100644
--- a/tracker/issueimport.py
+++ b/tracker/issueimport.py
@@ -17,6 +17,7 @@
import ezt
from features import filterrules_helpers
+from framework import flaskservlet
from framework import framework_helpers
from framework import jsonfeed
from framework import permissions
@@ -35,7 +36,7 @@
"""IssueImport loads a file of issues in JSON format."""
_PAGE_TEMPLATE = 'tracker/issue-import-page.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
def AssertBasePermission(self, mr):
"""Make sure that the logged in user has permission to view this page."""
@@ -304,6 +305,12 @@
self.services.issue.SetUsedLocalID(cnxn, project_id)
event_log.append('Finished import')
+ # def GetIssueImport(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostIssueImport(self, **kwargs):
+ # return self.handler(**kwargs)
+
class JSONImportError(Exception):
"""Exception to raise if imported JSON is invalid."""
diff --git a/tracker/issueoriginal.py b/tracker/issueoriginal.py
index 55a494f..cbab3b1 100644
--- a/tracker/issueoriginal.py
+++ b/tracker/issueoriginal.py
@@ -17,6 +17,7 @@
import ezt
from businesslogic import work_env
+from framework import flaskservlet
from framework import filecontent
from framework import permissions
from framework import servlet
@@ -96,3 +97,6 @@
self.abort(404, 'comment not found')
return issue, comment
+
+ # def GetIssueOriginal(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issuereindex.py b/tracker/issuereindex.py
index de5d2f0..71acfe8 100644
--- a/tracker/issuereindex.py
+++ b/tracker/issuereindex.py
@@ -9,9 +9,10 @@
from __future__ import absolute_import
import logging
-import urllib
+from six.moves import urllib
import settings
+from framework import flaskservlet
from framework import permissions
from framework import servlet
from framework import urls
@@ -22,7 +23,7 @@
"""IssueReindex shows a form to request that issues be indexed."""
_PAGE_TEMPLATE = 'tracker/issue-reindex-page.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
def AssertBasePermission(self, mr):
"""Check whether the user has any permission to visit this page.
@@ -83,5 +84,11 @@
'num': num,
'auto_submit': bool(auto_submit),
}
- return '/p/%s%s?%s' % (mr.project_name, urls.ISSUE_REINDEX,
- urllib.urlencode(query_map))
+ return '/p/%s%s?%s' % (
+ mr.project_name, urls.ISSUE_REINDEX, urllib.parse.urlencode(query_map))
+
+ # def GetIssueReindex(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostIssueReindex(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/issuetips.py b/tracker/issuetips.py
index eb75265..f85bcd6 100644
--- a/tracker/issuetips.py
+++ b/tracker/issuetips.py
@@ -10,6 +10,7 @@
import logging
+from framework import flaskservlet
from framework import servlet
from framework import permissions
@@ -18,7 +19,7 @@
"""IssueSearchTips on-line help on how to use issue search."""
_PAGE_TEMPLATE = 'tracker/issue-search-tips.ezt'
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
def GatherPageData(self, mr):
"""Build up a dictionary of data values to use when rendering the page."""
@@ -27,3 +28,6 @@
'issue_tab_mode': 'issueSearchTips',
'page_perms': self.MakePagePerms(mr, None, permissions.CREATE_ISSUE),
}
+
+ # def GetIssueSearchTips(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/spam.py b/tracker/spam.py
deleted file mode 100644
index a30fc3e..0000000
--- a/tracker/spam.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
-
-"""Classes that implement spam flagging features.
-"""
-from __future__ import print_function
-from __future__ import division
-from __future__ import absolute_import
-
-import httplib
-import logging
-
-from framework import framework_helpers
-from framework import paginate
-from framework import permissions
-from framework import urls
-from framework import servlet
-from framework import template_helpers
-from framework import xsrf
-from tracker import spam_helpers
-from tracker import tracker_bizobj
-
-
-class ModerationQueue(servlet.Servlet):
- _PAGE_TEMPLATE = 'tracker/spam-moderation-queue.ezt'
-
- def GatherPageData(self, mr):
- if not self.CheckPerm(mr, permissions.MODERATE_SPAM):
- raise permissions.PermissionException()
-
- page_perms = self.MakePagePerms(
- mr, None, permissions.MODERATE_SPAM,
- permissions.EDIT_ISSUE, permissions.CREATE_ISSUE,
- permissions.SET_STAR)
-
- # TODO(seanmccullough): Figure out how to get the IssueFlagQueue either
- # integrated into this page data, or on its own subtab of spam moderation.
- # Also figure out the same for Comments.
- issue_items, total_count = self.services.spam.GetIssueClassifierQueue(
- mr.cnxn, self.services.issue, mr.project.project_id, mr.start, mr.num)
-
- issue_queue = spam_helpers.DecorateIssueClassifierQueue(mr.cnxn,
- self.services.issue, self.services.spam, self.services.user,
- issue_items)
-
- url_params = [(name, mr.GetParam(name)) for name in
- framework_helpers.RECOGNIZED_PARAMS]
- p = paginate.ArtifactPagination(
- [], mr.num, mr.GetPositiveIntParam('start'),
- mr.project_name, urls.SPAM_MODERATION_QUEUE, total_count=total_count,
- url_params=url_params)
-
- return {
- 'issue_queue': issue_queue,
- 'projectname': mr.project.project_name,
- 'pagination': p,
- 'page_perms': page_perms,
- }
diff --git a/tracker/spam_helpers.py b/tracker/spam_helpers.py
deleted file mode 100644
index 2bf2c90..0000000
--- a/tracker/spam_helpers.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
-
-"""Set of helpers for constructing spam-related pages.
-"""
-from __future__ import print_function
-from __future__ import division
-from __future__ import absolute_import
-from framework import template_helpers
-import ezt
-
-from datetime import datetime
-
-def DecorateIssueClassifierQueue(
- cnxn, issue_service, spam_service, user_service, moderation_items):
- issue_ids = [item.issue_id for item in moderation_items]
- issues = issue_service.GetIssues(cnxn, issue_ids)
- issue_map = {}
- for issue in issues:
- issue_map[issue.issue_id] = issue
-
- flag_counts = spam_service.LookupIssueFlagCounts(cnxn, issue_ids)
-
- reporter_ids = [issue.reporter_id for issue in issues]
- reporters = user_service.GetUsersByIDs(cnxn, reporter_ids)
- comments = issue_service.GetCommentsForIssues(cnxn, issue_ids)
-
- items = []
- for item in moderation_items:
- issue=issue_map[item.issue_id]
- first_comment = comments.get(item.issue_id, ["[Empty]"])[0]
-
- items.append(template_helpers.EZTItem(
- issue=issue,
- summary=template_helpers.FitUnsafeText(issue.summary, 80),
- comment_text=template_helpers.FitUnsafeText(first_comment.content, 80),
- reporter=reporters[issue.reporter_id],
- flag_count=flag_counts.get(issue.issue_id, 0),
- is_spam=ezt.boolean(item.is_spam),
- verdict_time=item.verdict_time,
- classifier_confidence=item.classifier_confidence,
- reason=item.reason,
- ))
-
- return items
diff --git a/tracker/template_helpers.py b/tracker/template_helpers.py
index c567b4a..1f15bcc 100644
--- a/tracker/template_helpers.py
+++ b/tracker/template_helpers.py
@@ -47,6 +47,8 @@
content = framework_helpers.WordWrapSuperLongLines(content, max_cols=75)
status = post_data.get('status', '')
owner_str = post_data.get('owner', '')
+ # TODO(crbug.com/monorail/10936): switch when convert /p to flask
+ # labels = post_data.getlist('label')
labels = post_data.getall('label')
field_val_strs = collections.defaultdict(list)
for fd in config.field_defs:
diff --git a/tracker/templatecreate.py b/tracker/templatecreate.py
index e10a25b..139c4f5 100644
--- a/tracker/templatecreate.py
+++ b/tracker/templatecreate.py
@@ -15,6 +15,7 @@
import ezt
from framework import authdata
+from framework import flaskservlet
from framework import framework_bizobj
from framework import framework_helpers
from framework import servlet
@@ -32,9 +33,9 @@
class TemplateCreate(servlet.Servlet):
"""Servlet allowing project owners to create an issue template."""
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PROCESS
_PAGE_TEMPLATE = 'tracker/template-detail-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_TEMPLATES
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_TEMPLATES
def AssertBasePermission(self, mr):
"""Check whether the user has any permission to visit this page.
@@ -191,3 +192,9 @@
return framework_helpers.FormatAbsoluteURL(
mr, urls.ADMIN_TEMPLATES, saved=1, ts=int(time.time()))
+
+ # def GetTemplateCreate(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostTemplateCreate(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/templatedetail.py b/tracker/templatedetail.py
index cd48a80..a3386b4 100644
--- a/tracker/templatedetail.py
+++ b/tracker/templatedetail.py
@@ -15,6 +15,7 @@
import ezt
from framework import authdata
+from framework import flaskservlet
from framework import framework_bizobj
from framework import framework_helpers
from framework import framework_views
@@ -33,9 +34,9 @@
class TemplateDetail(servlet.Servlet):
"""Servlet allowing project owners to edit/delete an issue template"""
- _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
+ _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PROCESS
_PAGE_TEMPLATE = 'tracker/template-detail-page.ezt'
- _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_TEMPLATES
+ _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_TEMPLATES
def AssertBasePermission(self, mr):
"""Check whether the user has any permission to visit this page.
@@ -243,3 +244,9 @@
return framework_helpers.FormatAbsoluteURL(
mr, urls.TEMPLATE_DETAIL, template=template.name,
saved=1, ts=int(time.time()))
+
+ # def GetTemplateDetail(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def PostTemplateDetail(self, **kwargs):
+ # return self.handler(**kwargs)
diff --git a/tracker/test/issueattachment_test.py b/tracker/test/issueattachment_test.py
index 8c65014..9fccba5 100644
--- a/tracker/test/issueattachment_test.py
+++ b/tracker/test/issueattachment_test.py
@@ -10,7 +10,6 @@
import unittest
-from google.appengine.api import images
from google.appengine.ext import testbed
import mox
@@ -18,16 +17,12 @@
from framework import gcs_helpers
from framework import permissions
-from framework import servlet
from proto import tracker_pb2
from services import service_manager
from testing import fake
from testing import testing_helpers
from tracker import attachment_helpers
from tracker import issueattachment
-from tracker import tracker_helpers
-
-from third_party import cloudstorage
class IssueattachmentTest(unittest.TestCase):
@@ -41,9 +36,6 @@
self.testbed.init_urlfetch_stub()
self.attachment_data = ""
- self._old_gcs_open = cloudstorage.open
- cloudstorage.open = fake.gcs_open
-
services = service_manager.Services(
project=fake.ProjectService(),
config=fake.ConfigService(),
@@ -74,7 +66,6 @@
self.mox.UnsetStubs()
self.mox.ResetAll()
self.testbed.deactivate()
- cloudstorage.open = self._old_gcs_open
attachment_helpers.SignAttachmentID = self.orig_sign_attachment_id
def testGatherPageData_NotFound(self):
diff --git a/tracker/test/issueattachmenttext_test.py b/tracker/test/issueattachmenttext_test.py
index 187aa42..f7dda8d 100644
--- a/tracker/test/issueattachmenttext_test.py
+++ b/tracker/test/issueattachmenttext_test.py
@@ -8,18 +8,15 @@
from __future__ import division
from __future__ import absolute_import
-import logging
+import mock
import unittest
-from mock import patch
-from google.appengine.ext import testbed
-
-from third_party import cloudstorage
import ezt
+from google.appengine.ext import testbed
+from google.cloud import storage
import webapp2
-from framework import filecontent
from framework import permissions
from proto import tracker_pb2
from services import service_manager
@@ -85,12 +82,18 @@
services.issue.TestAddAttachment(
self.attach1, self.comment1.id, self.issue.issue_id)
# TODO(jrobbins): add tests for binary content
- self._old_gcs_open = cloudstorage.open
- cloudstorage.open = fake.gcs_open
+
+ self.client = mock.MagicMock()
+ self.bucket = mock.MagicMock()
+ self.blob = mock.MagicMock()
+ self.client.get_bucket = mock.MagicMock(return_value=self.bucket)
+ self.bucket.get_blob = mock.MagicMock(return_value=self.blob)
+ self.blob.download_as_bytes = mock.MagicMock()
+ mock.patch.object(storage, 'Client', return_value=self.client).start()
def tearDown(self):
self.testbed.deactivate()
- cloudstorage.open = self._old_gcs_open
+ mock.patch.stopall()
def testGatherPageData_CommentDeleted(self):
"""If the attachment's comment was deleted, give a 403."""
@@ -155,6 +158,9 @@
self.assertEqual(404, cm.exception.code)
def testGatherPageData_Normal(self):
+ self.blob.download_as_bytes = mock.MagicMock(
+ return_value='/app_default_bucket/pid/attachments/abcdefg')
+
_request, mr = testing_helpers.GetRequestObjects(
project=self.project,
path='/p/proj/issues/attachmentText?id=1&aid=1234',
@@ -175,7 +181,7 @@
self.assertEqual(None, page_data['code_reviews'])
- @patch('framework.filecontent.DecodeFileContents')
+ @mock.patch('framework.filecontent.DecodeFileContents')
def testGatherPageData_HugeFile(self, mock_DecodeFileContents):
_request, mr = testing_helpers.GetRequestObjects(
project=self.project,
diff --git a/tracker/tracker_helpers.py b/tracker/tracker_helpers.py
index c9f9e5a..cd9acfa 100644
--- a/tracker/tracker_helpers.py
+++ b/tracker/tracker_helpers.py
@@ -17,7 +17,7 @@
import logging
import re
import time
-import urllib
+from six.moves import urllib
from google.appengine.api import app_identity
@@ -151,8 +151,10 @@
comment = post_data.get('comment', '')
is_description = bool(post_data.get('description', ''))
status = post_data.get('status', '')
- template_name = urllib.unquote_plus(post_data.get('template_name', ''))
+ template_name = urllib.parse.unquote_plus(post_data.get('template_name', ''))
component_str = post_data.get('components', '')
+ # TODO: switch when convert /p to flask
+ # label_strs = post_data.getlist('label')
label_strs = post_data.getall('label')
if is_description:
@@ -257,6 +259,8 @@
phase_field_val_strs_remove = collections.defaultdict(dict)
for key in post_data.keys():
if key.startswith(_CUSTOM_FIELD_NAME_PREFIX):
+ # TODO: switch when convert /p to flask
+ # val_strs = [v for v in post_data.getlist(key) if v]
val_strs = [v for v in post_data.getall(key) if v]
if val_strs:
try:
@@ -327,6 +331,8 @@
Returns:
a list of attachment ids for kept attachments
"""
+ # TODO: switch when convert /p to flask
+ # kept_attachments = post_data.getlist('keep-attachment')
kept_attachments = post_data.getall('keep-attachment')
return [int(aid) for aid in kept_attachments]
@@ -616,8 +622,10 @@
url = urls.ISSUE_LIST
kwargs['projects'] = ','.join(sorted(project_names))
- param_strings = ['%s=%s' % (k, urllib.quote((u'%s' % v).encode('utf-8')))
- for k, v in kwargs.items()]
+ param_strings = [
+ '%s=%s' % (k, urllib.parse.quote((u'%s' % v).encode('utf-8')))
+ for k, v in kwargs.items()
+ ]
if param_strings:
url += '?' + '&'.join(sorted(param_strings))
if absolute:
diff --git a/tracker/tracker_views.py b/tracker/tracker_views.py
index 0c54555..c2687db 100644
--- a/tracker/tracker_views.py
+++ b/tracker/tracker_views.py
@@ -12,7 +12,7 @@
import logging
import re
import time
-import urllib
+from six.moves import urllib
from google.appengine.api import app_identity
import ezt
@@ -252,9 +252,12 @@
self.thumbnail_url = gcs_helpers.SignUrl(bucket_name,
gcs_object + '-thumbnail')
self.viewurl = (
- gcs_helpers.SignUrl(bucket_name, gcs_object) + '&' + urllib.urlencode(
- {'response-content-displacement':
- ('attachment; filename=%s' % self.filename)}))
+ gcs_helpers.SignUrl(bucket_name, gcs_object) + '&' +
+ urllib.parse.urlencode(
+ {
+ 'response-content-displacement':
+ ('attachment; filename=%s' % self.filename)
+ }))
class AttachmentView(template_helpers.PBProxy):
diff --git a/tracker/webcomponentspage.py b/tracker/webcomponentspage.py
index 4e2ad0d..eadd983 100644
--- a/tracker/webcomponentspage.py
+++ b/tracker/webcomponentspage.py
@@ -16,6 +16,7 @@
import logging
import settings
+from framework import flaskservlet
from framework import servlet
from framework import framework_helpers
from framework import permissions
@@ -60,6 +61,18 @@
'old_ui_url': old_ui_url,
}
+ # def GetWebComponentsIssueDetail(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def GetWebComponentsIssueList(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def GetWebComponentsIssueWizard(self, **kwargs):
+ # return self.handler(**kwargs)
+
+ # def GetWebComponentsIssueNewEntry(self, **kwargs):
+ # return self.handler(**kwargs)
+
class ProjectListPage(WebComponentsPage):