def _migrate_attachments(self, attachments, to_product=None, copy=False): for type, id, filename in attachments: old_path = Attachment._get_path(self.env.path, type, id, filename) new_path = self.env.path if to_product: new_path = os.path.join(new_path, 'products', to_product) new_path = Attachment._get_path(new_path, type, id, filename) dirname = os.path.dirname(new_path) if not os.path.exists(old_path): self.log.warning( "Missing attachment files for %s:%s/%s", type, id, filename) continue if os.path.exists(new_path): # TODO: Do we want to overwrite? continue try: if not os.path.exists(dirname): os.makedirs(dirname) if copy: if hasattr(os, 'link'): # TODO: It this safe? os.link(old_path, new_path) else: shutil.copy(old_path, new_path) else: os.rename(old_path, new_path) except OSError as err: self.log.warning( "Could not move attachment %s from %s %s to" "product @ (%s)", filename, type, id, str(err) )
def move_attachment_file(env, parent_realm, parent_id, filename): old_path = os.path.join(env.path, 'attachments', parent_realm, unicode_quote(parent_id)) if filename: old_path = os.path.join(old_path, unicode_quote(filename)) old_path = os.path.normpath(old_path) if os.path.isfile(old_path): new_path = Attachment._get_path(env.path, parent_realm, parent_id, filename) try: os.renames(old_path, new_path) except OSError: printerr(_("Unable to move attachment from:\n\n" " %(old_path)s\n\nto:\n\n %(new_path)s\n", old_path=old_path, new_path=new_path)) raise else: env.log.warning("Can't find file for 'attachment:%s:%s:%s', ignoring", filename, parent_realm, parent_id)
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 get_issues(self): cursor = self.db_cnx.cursor() cursor.execute( "SELECT id, type, time, changetime, component, severity, priority, owner, reporter," "cc, version, status, resolution, summary, description, keywords FROM ticket" ) trac_issues = list([]) for row in cursor: issue = TracIssue(row[0]) issue.time = self.to_unix_time(row[2]) issue.changetime = self.to_unix_time(row[3]) issue.reporter = self._get_user_login(row[8]) if row[9] is not None: cc = row[9].split(",") for c in cc: if len(c) > 0: cc_name = self._get_user_login(c.strip()) if cc_name is not None: issue.cc.add(cc_name) issue.summary = row[13] issue.description = row[14] issue.custom_fields["Type"] = row[1] issue.custom_fields["Component"] = row[4] issue.custom_fields["Severity"] = row[5] issue.custom_fields["Priority"] = row[6] issue.custom_fields["Owner"] = self._get_user_login(row[7]) issue.custom_fields["Version"] = row[10] issue.custom_fields["Status"] = row[11] issue.custom_fields["Resolution"] = row[12] if row[15] is not None: keywords = row[15].rsplit(",") for kw in keywords: if len(kw) > 0: issue.keywords.add(kw.strip()) #getting custom fields from ticket_custom table custom_field_cursor = self.db_cnx.cursor() custom_field_cursor.execute( "SELECT name, value FROM ticket_custom WHERE ticket=%s", (str(row[0]), )) for cf in custom_field_cursor: issue.custom_fields[cf[0].capitalize()] = cf[1] # getting attachments from attachment table attachment_cursor = self.db_cnx.cursor() attachment_cursor.execute( "SELECT filename, size, time, description, author FROM attachment WHERE " "type = %s AND id = %s", ("ticket", str(issue.id))) #path = self.env_path + "/attachments/ticket/" + str(issue.id) + "/" for elem in attachment_cursor: #at = TracAttachment(path + elem[0]) at = TracAttachment( Attachment._get_path(self.env.path, 'ticket', str(issue.id), elem[0])) at.name = elem[0] at.size = elem[1] at.time = self.to_unix_time(elem[2]) at.description = elem[3] at.author_name = elem[4] issue.attachment.add(at) trac_issues.append(issue) #getting comments change_cursor = self.db_cnx.cursor() change_cursor.execute( "SELECT time, author, newvalue, oldvalue FROM ticket_change WHERE ticket = %s AND field = %s ORDER BY time DESC", ( str(row[0]), "comment", )) for elem in change_cursor: if (elem[2] is None) or (not len(elem[2].lstrip())): continue comment = TracComment(self.to_unix_time(elem[0])) comment.author = str(elem[1]) comment.content = unicode(elem[2]) comment.id = elem[3] issue.comments.add(comment) return trac_issues
def get_issues(self): cursor = self.db_cnx.cursor() cursor.execute("SELECT id, type, time, changetime, component, severity, priority, owner, reporter," "cc, version, status, resolution, summary, description, keywords FROM ticket") trac_issues = list([]) for row in cursor: issue = TracIssue(row[0]) issue.time = to_unix_time(row[2]) issue.changetime = to_unix_time(row[3]) issue.reporter = self._get_user_login(row[8]) if row[9] is not None: cc = row[9].split(",") for c in cc: if len(c) > 0: cc_name = self._get_user_login(c.strip()) if cc_name is not None: issue.cc.add(cc_name) issue.summary = row[13] issue.description = row[14] issue.custom_fields["Type"] = row[1] issue.custom_fields["Component"] = row[4] issue.custom_fields["Severity"] = row[5] issue.custom_fields["Priority"] = row[6] issue.custom_fields["Owner"] = self._get_user_login(row[7]) issue.custom_fields["Version"] = row[10] issue.custom_fields["Status"] = row[11] issue.custom_fields["Resolution"] = row[12] if row[15] is not None: keywords = row[15].rsplit(",") for kw in keywords: if len(kw) > 0: issue.keywords.add(kw.strip()) #getting custom fields from ticket_custom table custom_field_cursor = self.db_cnx.cursor() custom_field_cursor.execute("SELECT name, value FROM ticket_custom WHERE ticket=%s", (str(row[0]),)) for cf in custom_field_cursor: issue.custom_fields[cf[0].capitalize()] = cf[1] # getting attachments from attachment table attachment_cursor = self.db_cnx.cursor() attachment_cursor.execute("SELECT filename, size, time, description, author FROM attachment WHERE " "type = %s AND id = %s", ("ticket", str(issue.id))) #path = self.env_path + "/attachments/ticket/" + str(issue.id) + "/" for elem in attachment_cursor: #at = TracAttachment(path + elem[0]) at = TracAttachment(Attachment._get_path(self.env.path, 'ticket', str(issue.id), elem[0])) at.name = elem[0] at.size = elem[1] at.time = to_unix_time(elem[2]) at.description = elem[3] at.author_name = elem[4] issue.attachment.add(at) trac_issues.append(issue) #getting comments change_cursor = self.db_cnx.cursor() change_cursor.execute("SELECT time, author, newvalue, oldvalue FROM ticket_change WHERE ticket = %s AND field = %s ORDER BY time DESC", (str(row[0]), "comment",)) for elem in change_cursor: if (elem[2] is None) or (not len(elem[2].lstrip())): continue comment = TracComment(to_unix_time(elem[0])) comment.author = str(elem[1]) comment.content = unicode(elem[2]) comment.id = elem[3] issue.comments.add(comment) #getting workitems for ttp in self._timetracking_plugins: issue.workitems.update(set(ttp[row[0]])) return trac_issues