def __init__(self, attach_pb, project_name): """Get IssueAttachmentContent PB and make its fields available as attrs. Args: attach_pb: Attachment part of IssueComment protocol buffer. project_name: string Name of the current project. """ super(AttachmentView, self).__init__(attach_pb) self.filesizestr = template_helpers.BytesKbOrMb(attach_pb.filesize) self.downloadurl = 'attachment?aid=%s' % attach_pb.attachment_id self.url = None self.thumbnail_url = None self.video_url = None if IsViewableImage(attach_pb.mimetype, attach_pb.filesize): self.url = self.downloadurl + '&inline=1' self.thumbnail_url = self.url + '&thumb=1' elif IsViewableVideo(attach_pb.mimetype, attach_pb.filesize): self.url = self.downloadurl + '&inline=1' self.video_url = self.url elif IsViewableText(attach_pb.mimetype, attach_pb.filesize): self.url = tracker_helpers.FormatRelativeIssueURL( project_name, urls.ISSUE_ATTACHMENT_TEXT, aid=attach_pb.attachment_id) self.iconurl = '/images/paperclip.png'
def testBytesKbOrMb(self): self.assertEqual('1023 bytes', template_helpers.BytesKbOrMb(1023)) self.assertEqual('1.0 KB', template_helpers.BytesKbOrMb(1024)) self.assertEqual('1023 KB', template_helpers.BytesKbOrMb(1024 * 1023)) self.assertEqual('1.0 MB', template_helpers.BytesKbOrMb(1024 * 1024)) self.assertEqual('98.0 MB', template_helpers.BytesKbOrMb(98 * 1024 * 1024)) self.assertEqual('99 MB', template_helpers.BytesKbOrMb(99 * 1024 * 1024))
def _BuildComponentQuota(self, used_bytes, quota_bytes, field_name): """Return an object to easily display quota info in EZT.""" if quota_bytes: used_percent = 100 * used_bytes // quota_bytes else: used_percent = 0 quota_mb = quota_bytes // 1024 // 1024 return template_helpers.EZTItem( used=template_helpers.BytesKbOrMb(used_bytes), quota_mb=quota_mb, used_percent=used_percent, avail_percent=100 - used_percent, field_name=field_name)
def __init__(self, attach_pb, project_name): """Get IssueAttachmentContent PB and make its fields available as attrs. Args: attach_pb: Attachment part of IssueComment protocol buffer. project_name: string Name of the current project. """ super(AttachmentView, self).__init__(attach_pb) self.filesizestr = template_helpers.BytesKbOrMb(attach_pb.filesize) self.downloadurl = attachment_helpers.GetDownloadURL( attach_pb.attachment_id) self.url = attachment_helpers.GetViewURL(attach_pb, self.downloadurl, project_name) self.thumbnail_url = attachment_helpers.GetThumbnailURL( attach_pb, self.downloadurl) self.video_url = attachment_helpers.GetVideoURL( attach_pb, self.downloadurl) self.iconurl = '/images/paperclip.png'
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page. Args: mr: commonly used info parsed from the request. Returns: Dict of values used by EZT for rendering the page. """ with mr.profiler.Phase('getting config'): config = self.services.config.GetProjectConfig( mr.cnxn, mr.project_id) # In addition to checking perms, we adjust some default field values for # project members. is_member = framework_bizobj.UserIsInProject(mr.project, mr.auth.effective_ids) page_perms = self.MakePagePerms( mr, None, permissions.CREATE_ISSUE, permissions.SET_STAR, permissions.EDIT_ISSUE, permissions.EDIT_ISSUE_SUMMARY, permissions.EDIT_ISSUE_STATUS, permissions.EDIT_ISSUE_OWNER, permissions.EDIT_ISSUE_CC) with work_env.WorkEnv(mr, self.services) as we: userprefs = we.GetUserPrefs(mr.auth.user_id) code_font = any( pref for pref in userprefs.prefs if pref.name == 'code_font' and pref.value == 'true') template = self._GetTemplate(mr.cnxn, config, mr.template_name, is_member) if template.summary: initial_summary = template.summary initial_summary_must_be_edited = template.summary_must_be_edited else: initial_summary = PLACEHOLDER_SUMMARY initial_summary_must_be_edited = True if template.status: initial_status = template.status elif is_member: initial_status = 'Accepted' else: initial_status = 'New' # not offering meta, only used in hidden field. component_paths = [] for component_id in template.component_ids: component_paths.append( tracker_bizobj.FindComponentDefByID(component_id, config).path) initial_components = ', '.join(component_paths) if template.owner_id: initial_owner = framework_views.MakeUserView( mr.cnxn, self.services.user, template.owner_id) elif template.owner_defaults_to_member and page_perms.EditIssue: initial_owner = mr.auth.user_view else: initial_owner = None if initial_owner: initial_owner_name = initial_owner.email owner_avail_state = initial_owner.avail_state owner_avail_message_short = initial_owner.avail_message_short else: initial_owner_name = '' owner_avail_state = None owner_avail_message_short = None # Check whether to allow attachments from the entry page allow_attachments = tracker_helpers.IsUnderSoftAttachmentQuota( mr.project) config_view = tracker_views.ConfigView(mr, self.services, config, template) # If the user followed a link that specified the template name, make sure # that it is also in the menu as the current choice. # TODO(jeffcarp): Unit test this. config_view.template_view.can_view = ezt.boolean(True) # TODO(jeffcarp): Unit test this. offer_templates = len(config_view.template_names) > 1 restrict_to_known = config.restrict_to_known enum_field_name_set = { fd.field_name.lower() for fd in config.field_defs if fd.field_type is tracker_pb2.FieldTypes.ENUM_TYPE and not fd.is_deleted } # TODO(jrobbins): restrictions link_or_template_labels = mr.GetListParam('labels', template.labels) labels = [ lab for lab in link_or_template_labels if not tracker_bizobj.LabelIsMaskedByField(lab, enum_field_name_set) ] # Corp-mode users automatically add R-V-G. with work_env.WorkEnv(mr, self.services) as we: userprefs = we.GetUserPrefs(mr.auth.user_id) corp_mode = any( up.name == 'restrict_new_issues' and up.value == 'true' for up in userprefs.prefs) if corp_mode: if not any(lab.lower().startswith('restrict-view-') for lab in labels): labels.append(CORP_RESTRICTION_LABEL) field_user_views = tracker_views.MakeFieldUserViews( mr.cnxn, template, self.services.user) approval_ids = [av.approval_id for av in template.approval_values] field_views = tracker_views.MakeAllFieldValueViews( config, link_or_template_labels, [], template.field_values, field_user_views, parent_approval_ids=approval_ids, phases=template.phases) # TODO(jojwang): monorail:6305, remove this hack when Edit perms for field # values are implemented. field_views = [ view for view in field_views if view.field_name.lower() not in RESTRICTED_FLT_FIELDS ] # TODO(jrobbins): remove "or []" after next release. (prechecked_approvals, required_approval_ids, phases) = issue_tmpl_helpers.GatherApprovalsPageData( template.approval_values or [], template.phases, config) approvals = [ view for view in field_views if view.field_id in approval_ids ] page_data = { 'issue_tab_mode': 'issueEntry', 'initial_summary': initial_summary, 'template_summary': initial_summary, 'clear_summary_on_click': ezt.boolean(initial_summary_must_be_edited and 'initial_summary' not in mr.form_overrides), 'must_edit_summary': ezt.boolean(initial_summary_must_be_edited), 'initial_description': template.content, 'template_name': template.name, 'component_required': ezt.boolean(template.component_required), 'initial_status': initial_status, 'initial_owner': initial_owner_name, 'owner_avail_state': owner_avail_state, 'owner_avail_message_short': owner_avail_message_short, 'initial_components': initial_components, 'initial_cc': '', 'initial_blocked_on': '', 'initial_blocking': '', 'initial_hotlists': '', 'labels': labels, 'fields': field_views, 'any_errors': ezt.boolean(mr.errors.AnyErrors()), 'page_perms': page_perms, 'allow_attachments': ezt.boolean(allow_attachments), 'max_attach_size': template_helpers.BytesKbOrMb( framework_constants.MAX_POST_BODY_SIZE), 'offer_templates': ezt.boolean(offer_templates), 'config': config_view, 'restrict_to_known': ezt.boolean(restrict_to_known), 'is_member': ezt.boolean(is_member), 'code_font': ezt.boolean(code_font), # The following are necessary for displaying phases that come with # this template. These are read-only. 'allow_edit': ezt.boolean(False), 'initial_phases': phases, 'approvals': approvals, 'prechecked_approvals': prechecked_approvals, 'required_approval_ids': required_approval_ids, # See monorail:4692 and the use of PHASES_WITH_MILESTONES # in elements/flt/mr-launch-overview/mr-phase.js 'issue_phase_names': list({ phase.name.lower() for phase in phases if phase.name in PHASES_WITH_MILESTONES }), } return page_data
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page. Args: mr: commonly used info parsed from the request. Returns: Dict of values used by EZT for rendering the page. """ with self.profiler.Phase('getting config'): config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) # In addition to checking perms, we adjust some default field values for # project members. is_member = framework_bizobj.UserIsInProject( mr.project, mr.auth.effective_ids) page_perms = self.MakePagePerms( mr, None, permissions.CREATE_ISSUE, permissions.SET_STAR, permissions.EDIT_ISSUE, permissions.EDIT_ISSUE_SUMMARY, permissions.EDIT_ISSUE_STATUS, permissions.EDIT_ISSUE_OWNER, permissions.EDIT_ISSUE_CC) wkp = _SelectTemplate(mr.template_name, config, is_member) if wkp.summary: initial_summary = wkp.summary initial_summary_must_be_edited = wkp.summary_must_be_edited else: initial_summary = PLACEHOLDER_SUMMARY initial_summary_must_be_edited = True if wkp.status: initial_status = wkp.status elif is_member: initial_status = 'Accepted' else: initial_status = 'New' # not offering meta, only used in hidden field. component_paths = [] for component_id in wkp.component_ids: component_paths.append( tracker_bizobj.FindComponentDefByID(component_id, config).path) initial_components = ', '.join(component_paths) if wkp.owner_id: initial_owner = framework_views.MakeUserView( mr.cnxn, self.services.user, wkp.owner_id) elif wkp.owner_defaults_to_member and page_perms.EditIssue: initial_owner = mr.auth.user_view else: initial_owner = None if initial_owner: initial_owner_name = initial_owner.email owner_avail_state = initial_owner.avail_state owner_avail_message_short = initial_owner.avail_message_short else: initial_owner_name = '' owner_avail_state = None owner_avail_message_short = None # Check whether to allow attachments from the entry page allow_attachments = tracker_helpers.IsUnderSoftAttachmentQuota(mr.project) config_view = tracker_views.ConfigView(mr, self.services, config) # If the user followed a link that specified the template name, make sure # that it is also in the menu as the current choice. for template_view in config_view.templates: if template_view.name == mr.template_name: template_view.can_view = ezt.boolean(True) offer_templates = len(list( tmpl for tmpl in config_view.templates if tmpl.can_view)) > 1 restrict_to_known = config.restrict_to_known field_name_set = {fd.field_name.lower() for fd in config.field_defs if not fd.is_deleted} # TODO(jrobbins): restrictions link_or_template_labels = mr.GetListParam('labels', wkp.labels) labels = [lab for lab in link_or_template_labels if not tracker_bizobj.LabelIsMaskedByField(lab, field_name_set)] field_user_views = tracker_views.MakeFieldUserViews( mr.cnxn, wkp, self.services.user) field_views = [ tracker_views.MakeFieldValueView( fd, config, link_or_template_labels, [], wkp.field_values, field_user_views) # TODO(jrobbins): field-level view restrictions, display options for fd in config.field_defs if not fd.is_deleted] page_data = { 'issue_tab_mode': 'issueEntry', 'initial_summary': initial_summary, 'template_summary': initial_summary, 'clear_summary_on_click': ezt.boolean( initial_summary_must_be_edited and 'initial_summary' not in mr.form_overrides), 'must_edit_summary': ezt.boolean(initial_summary_must_be_edited), 'initial_description': wkp.content, 'template_name': wkp.name, 'component_required': ezt.boolean(wkp.component_required), 'initial_status': initial_status, 'initial_owner': initial_owner_name, 'owner_avail_state': owner_avail_state, 'owner_avail_message_short': owner_avail_message_short, 'initial_components': initial_components, 'initial_cc': '', 'initial_blocked_on': '', 'initial_blocking': '', 'labels': labels, 'fields': field_views, 'any_errors': ezt.boolean(mr.errors.AnyErrors()), 'page_perms': page_perms, 'allow_attachments': ezt.boolean(allow_attachments), 'max_attach_size': template_helpers.BytesKbOrMb( framework_constants.MAX_POST_BODY_SIZE), 'offer_templates': ezt.boolean(offer_templates), 'config': config_view, 'restrict_to_known': ezt.boolean(restrict_to_known), } return page_data
def GatherPageData(self, mr): """Parse the attachment ID from the request and serve its content. Args: mr: commonly used info parsed from the request. Returns: Dict of values used by EZT for rendering almost the page. """ with mr.profiler.Phase('get issue, comment, and attachment'): try: attachment, issue = tracker_helpers.GetAttachmentIfAllowed( mr, self.services) except exceptions.NoSuchIssueException: webapp2.abort(404, 'issue not found') except exceptions.NoSuchAttachmentException: webapp2.abort(404, 'attachment not found') except exceptions.NoSuchCommentException: webapp2.abort(404, 'comment not found') content = [] 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() filesize = len(content) # This servlet only displays safe textual attachments. The user should # not have been given a link to this servlet for any other kind. if not attachment_helpers.IsViewableText(attachment.mimetype, filesize): self.abort(400, 'not a text file') u_text, is_binary, too_large = filecontent.DecodeFileContents(content) lines = prettify.PrepareSourceLinesForHighlighting( u_text.encode('utf8')) config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) granted_perms = tracker_bizobj.GetGrantedPerms(issue, mr.auth.effective_ids, config) page_perms = self.MakePagePerms(mr, issue, permissions.DELETE_ISSUE, permissions.CREATE_ISSUE, granted_perms=granted_perms) page_data = { 'issue_tab_mode': 'issueDetail', 'local_id': issue.local_id, 'filename': attachment.filename, 'filesize': template_helpers.BytesKbOrMb(filesize), 'file_lines': lines, 'is_binary': ezt.boolean(is_binary), 'too_large': ezt.boolean(too_large), 'code_reviews': None, 'page_perms': page_perms, } if is_binary or too_large: page_data['should_prettify'] = ezt.boolean(False) else: page_data.update( prettify.BuildPrettifyData(len(lines), attachment.filename)) return page_data