def _create_attachment(self, req, ticket, upload, description): if hasattr(upload, 'filename'): attachment = Attachment(self.env, 'ticket', ticket.id) if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) max_size = self.env.config.get('attachment', 'max_size') if max_size >= 0 and size > max_size: raise TracError(_('Maximum attachment size: %(num)s bytes', num=max_size), _('Upload failed')) filename = unicodedata.normalize('NFC', unicode(upload.filename, 'utf-8')) filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError(_('No file uploaded')) attachment.description = description if 'author' in req.args: attachment.author = get_reporter_id(req, 'author') attachment.ipnr = req.remote_addr attachment.insert(filename, upload.file, size)
def _do_uploadPicture(self, req, userProfile, teamRosterData, req_arg_picture = 'tr_userProfile_picture' ): upload = req.args.get(req_arg_picture, None) if upload == None or not hasattr(upload, 'filename') or not upload.filename: return userProfile.picture_href if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) # seek to end of file size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) filename = upload.filename filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError(_('No file uploaded')) page = WikiPage(self.env, self.teamRoster_wikiPage) if not page.exists: page.text="= Team Roster Pictures =" page.save( 'trac', 'Page created by tracteamroster component', req.remote_addr) attachment = Attachment(self.env, 'wiki', self.teamRoster_wikiPage) attachment.author = get_reporter_id(req, 'author') attachment.ipnr = req.remote_addr attachment.insert('_'.join([userProfile.id, filename]), upload.file, size) return req.href('/'.join(['raw-attachment', 'wiki',self.teamRoster_wikiPage,attachment.filename]))
def addWikiPage(self, page, attachments): '''Add a wiki page as a list of dictionaries''' db = self._env.get_db_cnx() cursor = db.cursor() pageCountRes = cursor.execute( 'select count(*) as count from wiki where name = %s', (page[0]['name'], )) pageCount = pageCountRes.fetchone()[0] assert pageCount == 0, 'Page %s found in %s' % (page[0]['name'], self.name) insertWikiQuery = 'insert into wiki (name, version, time, author, ipnr, text, comment, readonly) values (%s, %s, %s, %s, %s, %s, %s, %s)' for pV in page: insertValues = (pV['name'], pV['version'], pV['time'], pV['author'], pV['ipnr'], pV['text'], pV['comment'], pV['readonly']) insertRes = cursor.execute(insertWikiQuery, insertValues) for a in attachments: pageAttach = Attachment(self._env, 'wiki', pV['name']) pageAttach.description = a['description'] pageAttach.author = a['author'] pageAttach.ipnr = a['ipnr'] pageAttach.insert(a['filename'], a['fileobj'], a['size'], t=a['time']) db.commit()
def _create_attachment(self, req, tid, upload, description): attachment = Attachment(self.env, "ticket", tid) if hasattr(upload.file, "fileno"): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) max_size = self.env.config.get("attachment", "max_size") if 0 <= max_size < size: raise TracError(_("Maximum attachment size: %(num)s bytes", num=max_size), _("Upload failed")) filename = _normalized_filename(upload.filename) if not filename: raise TracError(_("No file uploaded")) attachment.description = description attachment.author = get_reporter_id(req, "author") attachment.ipnr = req.remote_addr attachment.insert(filename, upload.file, size)
def putAttachmentEx(self, req, pagename, filename, description, data, replace=True): """ Attach a file to a Wiki page. Returns the (possibly transformed) filename of the attachment. Use this method if you don't care about WikiRPC compatibility. """ if not WikiPage(self.env, pagename).exists: raise ResourceNotFound, 'Wiki page "%s" does not exist' % pagename if replace: try: attachment = Attachment(self.env, 'wiki', pagename, filename) req.perm(attachment.resource).require('ATTACHMENT_DELETE') attachment.delete() except TracError: pass attachment = Attachment(self.env, 'wiki', pagename) req.perm(attachment.resource).require('ATTACHMENT_CREATE') attachment.author = req.authname attachment.description = description attachment.insert(filename, StringIO(data.data), len(data.data)) return attachment.filename
def addTicket(self, ticket, source): '''Add a ticket from a dict''' db = self._env.get_db_cnx() cursor = db.cursor() idCountRes = cursor.execute('select count(*) as count from ticket where id = %s', (ticket['id'],)) idCount = idCountRes.fetchone()[0] assert idCount == 0, 'Ticket %s found in %s' % (ticket['id'], self.name) insertMainTicketQuery = 'insert into ticket (id, type, time, changetime, component, severity, priority, owner, \ reporter, cc, version, milestone, status, resolution, summary, description, keywords) \ values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' insertMainTicketValues = (ticket['id'], ticket['type'], ticket['time'], ticket['changetime'], ticket['component'], \ ticket['severity'], ticket['priority'], ticket['owner'], ticket['reporter'], ticket['cc'], ticket['version'], \ ticket['milestone'], ticket['status'], ticket['resolution'], ticket['summary'], ticket['description'], ticket['keywords']) insertMainTicketRes = cursor.execute(insertMainTicketQuery, insertMainTicketValues) #so we know where the ticket came from insertTicketSourceQuery = 'insert into ticket_custom (ticket, name, value) values (%s, %s, %s)' insertTicketSourceValues = (ticket['id'], 'project', source) insertTicketSourceRes = cursor.execute(insertTicketSourceQuery, insertTicketSourceValues) insertTicketChangeQuery = 'insert into ticket_change (ticket, time, author, field, oldvalue, newvalue) values (%s, %s, %s, %s, %s, %s)' for ticket_change in ticket['ticket_change']: insertTicketChangeValues = (ticket['id'], ticket_change['time'], ticket_change['author'], ticket_change['field'], ticket_change['oldvalue'], ticket_change['newvalue']) insertTicketChangeRes = cursor.execute(insertTicketChangeQuery, insertTicketChangeValues) for a in ticket['attachment']: ticketAttach = Attachment(self._env, 'ticket', ticket['id']) ticketAttach.description = a['description'] ticketAttach.author = a['author'] ticketAttach.ipnr = a['ipnr'] ticketAttach.insert(a['filename'], a['fileobj'], a['size'], t=a['time']) db.commit()
def _process_attachment(self, req, config, build): resource_id = req.args['member'] == 'config' \ and build.config or build.resource.id upload = req.args['file'] if not upload.file: send_error(req, message="Attachment not received.") self.log.debug('Received attachment %s for attaching to build:%s', upload.filename, resource_id) # Determine size of file upload.file.seek(0, 2) # to the end size = upload.file.tell() upload.file.seek(0) # beginning again # Delete attachment if it already exists try: old_attach = Attachment(self.env, 'build', parent_id=resource_id, filename=upload.filename) old_attach.delete() except ResourceNotFound: pass # Save new attachment attachment = Attachment(self.env, 'build', parent_id=resource_id) attachment.description = req.args.get('description', '') attachment.author = req.authname attachment.insert(upload.filename, upload.file, size) self._send_response(req, 201, 'Attachment created', headers={ 'Content-Type': 'text/plain', 'Content-Length': str(len('Attachment created'))})
def _create_attachment(self, req, ticket, upload, description): if hasattr(upload, 'filename'): attachment = Attachment(self.env, 'ticket', ticket.id) if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) max_size = self.env.config.get('attachment', 'max_size') if max_size >= 0 and size > max_size: raise TracError( _('Maximum attachment size: %(num)s bytes', num=max_size), _('Upload failed')) filename = unicodedata.normalize('NFC', unicode(upload.filename, 'utf-8')) filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError(_('No file uploaded')) attachment.description = description if 'author' in req.args: attachment.author = get_reporter_id(req, 'author') attachment.ipnr = req.remote_addr attachment.insert(filename, upload.file, size)
def addAttachment(self, ticket_id, filename, datafile, filesize, author, description, upload_time): # copied from bugzilla2trac attachment = Attachment(self.env, 'ticket', ticket_id) attachment.author = author attachment.description = description attachment.insert(filename, datafile, filesize, upload_time) del attachment
def addAttachment(self, author, a): if a["filename"] != "": description = a["description"] id = a["bug_id"] filename = a["filename"] filedata = StringIO.StringIO(a["thedata"]) filesize = len(filedata.getvalue()) time = a["creation_ts"] print " ->inserting attachment '%s' for ticket %s -- %s" % (filename, id, description) attachment = Attachment(self.env, "ticket", id) attachment.author = author attachment.description = description attachment.insert(filename, filedata, filesize, datetime2epoch(time)) del attachment
def addAttachment(self, author, a): description = a['description'].encode('utf-8') id = a['bug_id'] filename = a['filename'].encode('utf-8') filedata = StringIO.StringIO(a['thedata'].tostring()) filesize = len(filedata.getvalue()) time = a['creation_ts'] print " ->inserting attachment '%s' for ticket %s -- %s" % \ (filename, id, description) attachment = Attachment(self.env, 'ticket', id) attachment.author = author attachment.description = description attachment.insert(filename, filedata, filesize, time.strftime('%s')) del attachment
def addAttachment(self, author, a): if a['filename'] != '': description = a['description'] id = a['bug_id'] filename = a['filename'] filedata = StringIO.StringIO(a['thedata']) filesize = len(filedata.getvalue()) time = a['creation_ts'] print " ->inserting attachment '%s' for ticket %s -- %s" % \ (filename, id, description) attachment = Attachment(self.env, 'ticket', id) attachment.author = author attachment.description = description attachment.insert(filename, filedata, filesize, datetime2epoch(time)) del attachment
def attach(self, ticket, image): attachment = Attachment(self.env, 'ticket', ticket.id) attachment.author = ticket['reporter'] attachment.description = ticket['summary'] image.file.seek(0,2) # seek to end of file size = image.file.tell() filename = image.filename image.file.seek(0) attachment.insert(filename, image.file, size) # XXX shouldn't this only be called for, like, the # first image or whenever you really want to set the default? from imagetrac.default_image import DefaultTicketImage if self.env.is_component_enabled(DefaultTicketImage): DefaultTicketImage(self.env).set_default(ticket.id, filename)
def attach(self, ticket, image): attachment = Attachment(self.env, 'ticket', ticket.id) attachment.author = ticket['reporter'] attachment.description = ticket['summary'] image.file.seek(0, 2) # seek to end of file size = image.file.tell() filename = image.filename image.file.seek(0) attachment.insert(filename, image.file, size) # XXX shouldn't this only be called for, like, the # first image or whenever you really want to set the default? from imagetrac.default_image import DefaultTicketImage if self.env.is_component_enabled(DefaultTicketImage): DefaultTicketImage(self.env).set_default(ticket.id, filename)
def putAttachment(self, req, ticket, filename, description, data, replace=True): """ Add an attachment, optionally (and defaulting to) overwriting an existing one. Returns filename.""" if not model.Ticket(self.env, ticket).exists: raise TracError, 'Ticket "%s" does not exist' % ticket if replace: try: attachment = Attachment(self.env, 'ticket', ticket, filename) attachment.delete() except TracError: pass attachment = Attachment(self.env, 'ticket', ticket) attachment.author = req.authname or 'anonymous' attachment.description = description attachment.insert(filename, StringIO(data.data), len(data.data)) return attachment.filename
def addAttachment(self, author, a): if a['filename'] != '': description = a['description'] id = a['bug_id'] filename = a['filename'] filedata = io.BytesIO(a['thedata']) filesize = len(filedata.getvalue()) time = a['creation_ts'] print(" ->inserting attachment '%s' for ticket %s -- %s" % (filename, id, description)) attachment = Attachment(self.env, 'ticket', id) attachment.author = author attachment.description = description attachment.insert(filename, filedata, filesize, datetime2epoch(time)) del attachment
def addTicket(self, ticket, source): '''Add a ticket from a dict''' db = self._env.get_db_cnx() cursor = db.cursor() idCountRes = cursor.execute( 'select count(*) as count from ticket where id = %s', (ticket['id'], )) idCount = idCountRes.fetchone()[0] assert idCount == 0, 'Ticket %s found in %s' % (ticket['id'], self.name) insertMainTicketQuery = 'insert into ticket (id, type, time, changetime, component, severity, priority, owner, \ reporter, cc, version, milestone, status, resolution, summary, description, keywords) \ values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' insertMainTicketValues = (ticket['id'], ticket['type'], ticket['time'], ticket['changetime'], ticket['component'], \ ticket['severity'], ticket['priority'], ticket['owner'], ticket['reporter'], ticket['cc'], ticket['version'], \ ticket['milestone'], ticket['status'], ticket['resolution'], ticket['summary'], ticket['description'], ticket['keywords']) insertMainTicketRes = cursor.execute(insertMainTicketQuery, insertMainTicketValues) #so we know where the ticket came from insertTicketSourceQuery = 'insert into ticket_custom (ticket, name, value) values (%s, %s, %s)' insertTicketSourceValues = (ticket['id'], 'project', source) insertTicketSourceRes = cursor.execute(insertTicketSourceQuery, insertTicketSourceValues) insertTicketChangeQuery = 'insert into ticket_change (ticket, time, author, field, oldvalue, newvalue) values (%s, %s, %s, %s, %s, %s)' for ticket_change in ticket['ticket_change']: insertTicketChangeValues = (ticket['id'], ticket_change['time'], ticket_change['author'], ticket_change['field'], ticket_change['oldvalue'], ticket_change['newvalue']) insertTicketChangeRes = cursor.execute(insertTicketChangeQuery, insertTicketChangeValues) for a in ticket['attachment']: ticketAttach = Attachment(self._env, 'ticket', ticket['id']) ticketAttach.description = a['description'] ticketAttach.author = a['author'] ticketAttach.ipnr = a['ipnr'] ticketAttach.insert(a['filename'], a['fileobj'], a['size'], t=a['time']) db.commit()
def putAttachmentEx(self, req, pagename, filename, description, data, replace=True): """ Attach a file to a Wiki page. Returns the (possibly transformed) filename of the attachment. Use this method if you don't care about WikiRPC compatibility. """ if not WikiPage(self.env, pagename).exists: raise TracError, 'Wiki page "%s" does not exist' % pagename if replace: try: attachment = Attachment(self.env, 'wiki', pagename, filename) attachment.delete() except TracError: pass attachment = Attachment(self.env, 'wiki', pagename) attachment.author = req.authname or 'anonymous' attachment.description = description attachment.insert(filename, StringIO(data.data), len(data.data)) return attachment.filename
def putAttachment(self, req, ticket, filename, description, data, replace=True): """ Add an attachment, optionally (and defaulting to) overwriting an existing one. Returns filename.""" if not model.Ticket(self.env, ticket).exists: raise ResourceNotFound('Ticket "%s" does not exist' % ticket) if replace: try: attachment = Attachment(self.env, 'ticket', ticket, filename) req.perm(attachment.resource).require('ATTACHMENT_DELETE') attachment.delete() except TracError: pass attachment = Attachment(self.env, 'ticket', ticket) req.perm(attachment.resource).require('ATTACHMENT_CREATE') attachment.author = req.authname attachment.description = description attachment.insert(filename, StringIO(data.data), len(data.data)) return attachment.filename
def addWikiPage(self, page, attachments): '''Add a wiki page as a list of dictionaries''' db = self._env.get_db_cnx() cursor = db.cursor() pageCountRes = cursor.execute('select count(*) as count from wiki where name = %s', (page[0]['name'],)) pageCount = pageCountRes.fetchone()[0] assert pageCount == 0, 'Page %s found in %s' % (page[0]['name'], self.name) insertWikiQuery = 'insert into wiki (name, version, time, author, ipnr, text, comment, readonly) values (%s, %s, %s, %s, %s, %s, %s, %s)' for pV in page: insertValues = (pV['name'], pV['version'], pV['time'], pV['author'], pV['ipnr'], pV['text'], pV['comment'], pV['readonly']) insertRes = cursor.execute(insertWikiQuery, insertValues) for a in attachments: pageAttach = Attachment(self._env, 'wiki', pV['name']) pageAttach.description = a['description'] pageAttach.author = a['author'] pageAttach.ipnr = a['ipnr'] pageAttach.insert(a['filename'], a['fileobj'], a['size'], t=a['time']) db.commit()
def get_uploaded_file_href(self, req, user, field, req_field): """Returns uploaded file's url @param req: trac.web.req @param user: tracusermanager.api.User @param field: str @param req_field: str @return: str """ # validate request field upload = req.args.get(req_field, None) if upload == None or not hasattr(upload, 'filename') or not upload.filename: return user[field] if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) # seek to end of file size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) filename = upload.filename filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError(_('No file uploaded')) page = WikiPage(self.env, self.attachments_wikiPage) if not page.exists: page.text="= UserManager's Attachments =" page.save( 'trac', 'Page created by tracusermanager.profile component', req.remote_addr) attachment = Attachment(self.env, 'wiki', self.attachments_wikiPage) attachment.author = get_reporter_id(req, 'author') attachment.ipnr = req.remote_addr attachment.description = (_("%s\'s Avatar") % (user.username)) attachment.insert('_'.join([user.username, filename]), upload.file, size) return req.href('/'.join(['raw-attachment', 'wiki',self.attachments_wikiPage, attachment.filename]))
def putAttachmentEx(self, req, pagename, filename, description, data, replace=True): """ Attach a file to a Wiki page. Returns the (possibly transformed) filename of the attachment. Use this method if you don't care about WikiRPC compatibility. """ if not WikiPage(self.env, pagename).exists: raise ResourceNotFound, 'Wiki page "%s" does not exist' % pagename if replace: try: attachment = Attachment(self.env, "wiki", pagename, filename) req.perm(attachment.resource).require("ATTACHMENT_DELETE") attachment.delete() except TracError: pass attachment = Attachment(self.env, "wiki", pagename) req.perm(attachment.resource).require("ATTACHMENT_CREATE") attachment.author = req.authname attachment.description = description attachment.insert(filename, StringIO(data.data), len(data.data)) return attachment.filename
def create_sizes(self, ticket, attachment): """create the sizes for a ticket image""" filename = attachment.filename # add the specified sizes as attachments sizes = self.sizes() for name, size in sizes.items(): # crop the image image = Image.open(attachment.path) i = crop_resize(image, size) buffer = StringIO() i.save(buffer, image.format) buffer.seek(0,2) # seek to end of file filesize = buffer.tell() buffer.seek(0) a = Attachment(self.env, 'ticket', ticket.id) a.author = ticket['reporter'] a.description = ticket['summary'] f = ('.%sx%s.' % (size[0] or '', size[1] or '')).join(filename.rsplit('.', 1)) # XXX assumes the file has an extension a.insert(f, buffer, filesize)
def test_attachment(self): attachment = Attachment(self.env, 'ticket', 42) attachment.description = 'Summary line' attachment.author = 'Santa' attachment.ipnr = 'northpole.example.com' attachment.insert('foo.txt', StringIO('Lorem ipsum dolor sit amet'), 0) so = self._get_so() self.assertEquals('%s:attachment:ticket:42:foo.txt' % self.basename, so.doc_id) self.assertEquals('attachment', so.realm) self.assertEquals('foo.txt', so.id) self.assertEquals('ticket', so.parent_realm) self.assertEquals(42, so.parent_id) self.assertTrue('foo.txt' in so.title) self.assertEquals('Santa', so.author) self.assertEquals(attachment.date, so.created) self.assertEquals(attachment.date, so.changed) self.assertTrue('Santa' in so.involved) #self.assertTrue('Lorem ipsum' in so.oneline) # TODO self.assertTrue('Lorem ipsum' in so.body.read()) self.assertTrue('Summary line' in so.comments)
def addAttachment(self, author, a): if a['filename'] != '': description = a['description'].strip() id = a['bug_id'] filename = a['filename'].strip() filedata = StringIO(a['thedata']) filesize = len(filedata.getvalue()) time = a['creation_ts'] #print "author: " + author print "id: %d" % id print "filename: " + filename #print "filesize: %d" % filesize #print "description: " + description #print " ->inserting attachment '%s' for ticket %s -- %s" % \ # (filename, id, description) attachment = Attachment(self.env, 'ticket', id) attachment.author = author attachment.description = description attachment.insert(filename, filedata, filesize, datetime2epoch(time))
def _process_attachment(self, req, config, build): resource_id = req.args['member'] == 'config' \ and build.config or build.resource.id upload = req.args['file'] if not upload.file: send_error(req, message="Attachment not received.") self.log.debug('Received attachment %s for attaching to build:%s', upload.filename, resource_id) # Determine size of file upload.file.seek(0, 2) # to the end size = upload.file.tell() upload.file.seek(0) # beginning again # Delete attachment if it already exists try: old_attach = Attachment(self.env, 'build', parent_id=resource_id, filename=upload.filename) old_attach.delete() except ResourceNotFound: pass # Save new attachment attachment = Attachment(self.env, 'build', parent_id=resource_id) attachment.description = req.args.get('description', '') attachment.author = req.authname attachment.insert(upload.filename, upload.file, size) self._send_response(req, 201, 'Attachment created', headers={ 'Content-Type': 'text/plain', 'Content-Length': str(len('Attachment created')) })
def add_attachments(env, ticket, attachments): """add attachments to the ticket""" ctr = 1 for msg in attachments: attachment = Attachment(env, 'ticket', ticket.id) attachment.author = ticket['reporter'] attachment.description = ticket['summary'] payload = msg.get_payload() if msg.get('Content-Transfer-Encoding') == 'base64': payload = base64.b64decode(payload) size = len(payload) filename = msg.get_filename() or message.get('Subject') if not filename: filename = 'attachment-%d' % ctr extensions = KNOWN_MIME_TYPES.get(message.get_content_type()) if extensions: filename += '.%s' % extensions[0] ctr += 1 buffer = StringIO() print >> buffer, payload buffer.seek(0) attachment.insert(filename, buffer, size) os.chmod(attachment._get_path(), 0666)
def create_sizes(self, ticket, attachment): """create the sizes for a ticket image""" filename = attachment.filename # add the specified sizes as attachments sizes = self.sizes() for name, size in sizes.items(): # crop the image image = Image.open(attachment.path) i = crop_resize(image, size) buffer = StringIO() i.save(buffer, image.format) buffer.seek(0, 2) # seek to end of file filesize = buffer.tell() buffer.seek(0) a = Attachment(self.env, 'ticket', ticket.id) a.author = ticket['reporter'] a.description = ticket['summary'] f = ('.%sx%s.' % (size[0] or '', size[1] or '')).join( filename.rsplit('.', 1)) # XXX assumes the file has an extension a.insert(f, buffer, filesize)
def expand_macro(self, formatter, name, content, args=None): parent = formatter.resource this_page = Attachment(self.env, parent.realm, parent.id) path = this_page.path path = path[len(os.path.join(self.env.path, 'attachments/')):] path = os.path.join(self.env.path, _inbox, path) path = os.path.realpath(path) # follow symbolic link if needed if not os.path.exists(path) and not os.path.isdir(path): return newfiles = os.listdir(path) for attachment in Attachment.select(self.env, parent.realm, parent.id): if attachment.filename in newfiles: newfiles.remove(attachment.filename) # avoid overwrite if len(newfiles) == 0: return for filename in newfiles: fullpath = os.path.join(path, filename) if not os.path.isfile(fullpath): continue # skip it stat = os.stat(fullpath) this_page = Attachment(self.env, parent.realm, parent.id) this_page.author = __package__ # attacher name this_page.insert(filename, file(fullpath), stat.st_size) self.log.debug('ATTACHED NEW FILE: %s' % filename)
# Collect attachments from the request body for attach_elem in elem.children(Recipe.ATTACH): attach_elem = list(attach_elem.children('file'))[0] # One file only filename = attach_elem.attr.get('filename') resource_id = attach_elem.attr.get('resource') == 'config' \ and build.config or build.resource.id try: # Delete attachment if it already exists old_attach = Attachment(self.env, 'build', parent_id=resource_id, filename=filename) old_attach.delete() except ResourceNotFound: pass attachment = Attachment(self.env, 'build', parent_id=resource_id) attachment.description = attach_elem.attr.get('description') attachment.author = req.authname fileobj = StringIO(attach_elem.gettext().decode('base64')) attachment.insert(filename, fileobj, fileobj.len, db=db) # If this was the last step in the recipe we mark the build as # completed if last_step: self.log.info('Slave %s completed build %d ("%s" as of [%s])', build.slave, build.id, build.config, build.rev) build.stopped = step.stopped # Determine overall outcome of the build by checking the outcome # of the individual steps against the "onerror" specification of # each step in the recipe for num, recipe_step in enumerate(recipe): step = BuildStep.fetch(self.env, build.id, recipe_step.id)
attach_elem = list( attach_elem.children('file'))[0] # One file only filename = attach_elem.attr.get('filename') resource_id = attach_elem.attr.get('resource') == 'config' \ and build.config or build.resource.id try: # Delete attachment if it already exists old_attach = Attachment(self.env, 'build', parent_id=resource_id, filename=filename) old_attach.delete() except ResourceNotFound: pass attachment = Attachment(self.env, 'build', parent_id=resource_id) attachment.description = attach_elem.attr.get('description') attachment.author = req.authname fileobj = StringIO(attach_elem.gettext().decode('base64')) attachment.insert(filename, fileobj, fileobj.len, db=db) # If this was the last step in the recipe we mark the build as # completed if last_step: self.log.info('Slave %s completed build %d ("%s" as of [%s])', build.slave, build.id, build.config, build.rev) build.stopped = step.stopped # Determine overall outcome of the build by checking the outcome # of the individual steps against the "onerror" specification of # each step in the recipe for num, recipe_step in enumerate(recipe): step = BuildStep.fetch(self.env, build.id, recipe_step.id)
def insert_raw_email(self, bytes): msg = email.message_from_string(bytes) raw = MailinglistRawMessage(self.env, mailinglist=self, bytes=bytes) raw.insert() msg_id = msg['message-id'] if msg_id: msg_id = msg_id.strip() references = msg['references'] if references: references = references.strip() in_reply_to = msg['in-reply-to'] if msg['date']: date = parse_rfc2822_date(msg['date']) else: date = datetime.now(utc) subject = decode_header(msg['Subject']) # Fetch or create a category for the message if in_reply_to: conv, new = self.get_conv(msg, in_reply_to, subject, date) elif references: conv, new = self.get_conv(msg, references, subject, date) elif 'thread-index' in msg: conv, new = self.get_conv_ms(msg, subject, date) else: conv = MailinglistConversation(self.env, mailinglist=self, date=date, subject=subject) conv.insert() new = True self.env.log.debug("Using conversation %s (new: %s)", conv, new) # Extract the text/plain body body = '' for part in msg.walk(): if part.get_content_type() == 'text/plain': missing = object() attachment = part.get_param('attachment', missing, 'content-disposition') if not attachment is missing: continue txt = part.get_payload(decode=True) charset = part.get_param('charset', 'ascii') # Make sure the charset is supported and fallback to 'ascii' # if not try: codecs.lookup(charset) except LookupError: charset = 'ascii' body += txt.decode(charset, 'replace') rn, fe = email.Utils.parseaddr(msg['from']) from_name = decode_header(rn) from_email = decode_header(fe) if not from_name: from_name = from_email db = self.env.get_read_db() cursor = db.cursor() cursor.execute('SELECT sid ' 'FROM session_attribute ' 'WHERE value = %s ' 'AND name = \'email\' AND authenticated = 1 LIMIT 1', (from_email,)) row = cursor.fetchone() if row is not None: trac_username = row[0] else: trac_username = from_email to = decode_header(msg['to']) cc = decode_header(msg['cc']) m = MailinglistMessage(self.env, conversation=conv, subject=subject, body=body, msg_id=msg_id, date=date, raw=raw, to_header=to, cc_header=cc, from_name=from_name, from_email=from_email) m.insert() if new: conv.first = m for part in msg.walk(): if part.is_multipart(): continue if part.get_content_type == 'text/plain': continue filename = part.get_filename() missing = object() if not filename or filename is missing: continue mime_type = part.get_content_type() description = decode_header(part.get('content-description','')) attachment = Attachment(self.env, m.resource.realm, m.resource.id) attachmentbytes = part.get_payload(decode=True) attachment.author = trac_username attachment.insert(filename, StringIO(attachmentbytes), len(attachmentbytes), t=date) return m
def _parse_multipart(self, author, msg): body = '' # delete all attachement at message-id Attachment.delete_all(self.env, 'mailarchive', self.id, self.db) for part in msg.walk(): content_type = part.get_content_type() self.log.debug('Content-Type:' + content_type) file_counter = 1 if content_type == 'multipart/mixed': pass elif content_type == 'text/html' and self._is_file(part) == False: if body != '': body += "\n------------------------------\n\n" body = part.get_payload(decode=True) charset = part.get_content_charset() self.log.debug('charset:' + str(charset)) # Todo:need try if charset != None: body = self._to_unicode(body, charset) elif content_type == 'text/plain' and self._is_file(part) == False: #body = part.get_payload(decode=True) if body != '': body += "\n------------------------------\n\n" current_body = part.get_payload(decode=True) charset = part.get_content_charset() self.log.debug('charset:' + str(charset)) # Todo:need try if charset != None: #body = self._to_unicode(body, charset) body += self._to_unicode(current_body, charset) else: body += current_body elif part.get_payload(decode=True) == None: pass # file attachment else: self.log.debug(part.get_content_type()) # get filename # Applications should really sanitize the given filename so that an # email message can't be used to overwrite important files filename = self._get_filename(part) if not filename: import mimetypes ext = mimetypes.guess_extension(part.get_content_type()) if not ext: # Use a generic bag-of-bits extension ext = '.bin' filename = 'part-%03d%s' % (file_counter, ext) file_counter += 1 self.log.debug("filename:" + filename.encode(OUTPUT_ENCODING)) # make attachment tmp = os.tmpfile() tempsize = len(part.get_payload(decode=True)) tmp.write(part.get_payload(decode=True)) tmp.flush() tmp.seek(0,0) attachment = Attachment(self.env, 'mailarchive', self.id) attachment.description = '' # req.args.get('description', '') attachment.author = author #req.args.get('author', '') attachment.ipnr = '127.0.0.1' try: attachment.insert(filename, tmp, tempsize, None, self.db) except Exception, e: try: ext = filename.split('.')[-1] if ext == filename: ext = '.bin' else: ext = '.' + ext filename = 'part-%03d%s' % (file_counter, ext) file_counter += 1 attachment.description += ', Original FileName: %s' % filename attachment.insert(filename, tmp, tempsize, None, self.db) self.log.warn('As name is too long, the attached file is renamed : ' + filename) except Exception, e: self.log.error('Exception at attach file of Message-ID:' + self.messageid) traceback.print_exc(e) tmp.close()
def _insert_attachment(self, author): parent_resource = Resource('parent_realm', 'parent_id') att = Attachment(self.env, 'parent_realm', 'parent_id') att.author = author att.insert('file.txt', io.BytesIO(), 1) return Resource('attachment', 'file.txt', parent=parent_resource)