Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: appengine/monorail/tracker/issueattachment.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """Issue Tracker code to serve out issue attachments.
7
8 Summary of page classes:
9 AttachmentPage: Serve the content of an attachment w/ the appropriate
10 MIME type.
11 IssueAttachmentDeletion: Form handler for deleting attachments.
12 """
13
14 import base64
15 import logging
16 import os
17 import re
18 import urllib
19
20 import webapp2
21
22 from google.appengine.api import app_identity
23 from google.appengine.api import images
24
25 from framework import framework_helpers
26 from framework import gcs_helpers
27 from framework import permissions
28 from framework import servlet
29 from framework import urls
30 from services import issue_svc
31 from tracker import tracker_helpers
32 from tracker import tracker_views
33
34
35 # This will likely appear blank or as a broken image icon in the browser.
36 NO_PREVIEW_ICON = ''
37 NO_PREVIEW_MIME_TYPE = 'image/png'
38
39 FILE_RE = re.compile('^[-_.a-zA-Z0-9 #+()]+$')
40
41
42 class AttachmentPage(servlet.Servlet):
43 """AttachmentPage serves issue attachments."""
44
45 def GatherPageData(self, mr):
46 """Parse the attachment ID from the request and serve its content.
47
48 Args:
49 mr: commonly used info parsed from the request.
50
51 Returns: dict of values used by EZT for rendering the page.
52 """
53 try:
54 attachment, _issue = tracker_helpers.GetAttachmentIfAllowed(
55 mr, self.services)
56 except issue_svc.NoSuchIssueException:
57 webapp2.abort(404, 'issue not found')
58 except issue_svc.NoSuchAttachmentException:
59 webapp2.abort(404, 'attachment not found')
60 except issue_svc.NoSuchCommentException:
61 webapp2.abort(404, 'comment not found')
62
63 if not attachment.gcs_object_id:
64 webapp2.abort(404, 'attachment data not found')
65
66 bucket_name = app_identity.get_default_gcs_bucket_name()
67 object_path = '/' + bucket_name + attachment.gcs_object_id
68
69 if mr.thumb:
70 url = gcs_helpers.SignUrl(object_path + '-thumbnail')
71 self.redirect(url, abort=True)
72
73 # By default GCS will return images and attachments displayable inline.
74 url = gcs_helpers.SignUrl(object_path)
75 if not mr.inline:
76 filename = attachment.filename
77 if not FILE_RE.match(filename):
78 print "bad file name: %s" % attachment.attachment_id
79 filename = 'attachment-%d.dat' % attachment.attachment_id
80
81 url = url + '&' + urllib.urlencode(
82 {'response-content-disposition':
83 ('attachment; filename=%s' % filename)})
84
85 self.redirect(url, abort=True)
86
87
88 class IssueAttachmentDeletion(servlet.Servlet):
89 """Form handler that allows user to hard-delete attachments."""
90
91 def ProcessFormData(self, mr, post_data):
92 """Process the form that soft-deletes an issue attachment.
93
94 Args:
95 mr: commonly used info parsed from the request.
96 post_data: HTML form data from the request.
97
98 Returns:
99 String URL to redirect the user to after processing.
100 """
101 local_id = int(post_data['id'])
102 sequence_num = int(post_data['sequence_num'])
103 attachment_id = int(post_data['aid'])
104 delete = 'delete' in post_data
105
106 issue = self.services.issue.GetIssueByLocalID(
107 mr.cnxn, mr.project_id, local_id)
108
109 all_comments = self.services.issue.GetCommentsForIssue(
110 mr.cnxn, issue.issue_id)
111 logging.info('comments on %s are: %s', local_id, all_comments)
112 comment = all_comments[sequence_num]
113
114 if not permissions.CanDelete(
115 mr.auth.user_id, mr.auth.effective_ids, mr.perms,
116 comment.deleted_by, comment.user_id, mr.project,
117 permissions.GetRestrictions(issue)):
118 raise permissions.PermissionException(
119 'Cannot un/delete attachment')
120
121 self.services.issue.SoftDeleteAttachment(
122 mr.cnxn, mr.project_id, local_id, sequence_num,
123 attachment_id, self.services.user, delete=delete)
124
125 return framework_helpers.FormatAbsoluteURL(
126 mr, urls.ISSUE_DETAIL, id=local_id)
OLDNEW
« no previous file with comments | « appengine/monorail/tracker/issueadvsearch.py ('k') | appengine/monorail/tracker/issueattachmenttext.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698