Mercurial > libervia-backend
comparison sat/plugins/plugin_tickets_import_bugzilla.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 3e4e78de9cca |
children | 003b8b4b56a7 |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | 19 |
20 from sat.core.i18n import _, D_ | 20 from sat.core.i18n import _, D_ |
21 from sat.core.constants import Const as C | 21 from sat.core.constants import Const as C |
22 from sat.core.log import getLogger | 22 from sat.core.log import getLogger |
23 | |
23 log = getLogger(__name__) | 24 log = getLogger(__name__) |
24 from sat.core import exceptions | 25 from sat.core import exceptions |
26 | |
25 # from twisted.internet import threads | 27 # from twisted.internet import threads |
26 from twisted.internet import defer | 28 from twisted.internet import defer |
27 import os.path | 29 import os.path |
28 from lxml import etree | 30 from lxml import etree |
29 from sat.tools.common import date_utils | 31 from sat.tools.common import date_utils |
34 C.PI_IMPORT_NAME: "IMPORT_BUGZILLA", | 36 C.PI_IMPORT_NAME: "IMPORT_BUGZILLA", |
35 C.PI_TYPE: C.PLUG_TYPE_BLOG, | 37 C.PI_TYPE: C.PLUG_TYPE_BLOG, |
36 C.PI_DEPENDENCIES: ["TICKETS_IMPORT"], | 38 C.PI_DEPENDENCIES: ["TICKETS_IMPORT"], |
37 C.PI_MAIN: "BugzillaImport", | 39 C.PI_MAIN: "BugzillaImport", |
38 C.PI_HANDLER: "no", | 40 C.PI_HANDLER: "no", |
39 C.PI_DESCRIPTION: _("""Tickets importer for Bugzilla""") | 41 C.PI_DESCRIPTION: _("""Tickets importer for Bugzilla"""), |
40 } | 42 } |
41 | 43 |
42 SHORT_DESC = D_(u"import tickets from Bugzilla xml export file") | 44 SHORT_DESC = D_(u"import tickets from Bugzilla xml export file") |
43 | 45 |
44 LONG_DESC = D_(u"""This importer handle Bugzilla xml export file. | 46 LONG_DESC = D_( |
47 u"""This importer handle Bugzilla xml export file. | |
45 | 48 |
46 To use it, you'll need to export tickets using XML. | 49 To use it, you'll need to export tickets using XML. |
47 Tickets will be uploaded with the same ID as for Bugzilla, any existing ticket with this ID will be replaced. | 50 Tickets will be uploaded with the same ID as for Bugzilla, any existing ticket with this ID will be replaced. |
48 | 51 |
49 location: you must use the absolute path to your .xml file | 52 location: you must use the absolute path to your .xml file |
50 """) | 53 """ |
54 ) | |
51 | 55 |
52 STATUS_MAP = { | 56 STATUS_MAP = { |
53 'NEW': 'queued', | 57 "NEW": "queued", |
54 'ASSIGNED': 'started', | 58 "ASSIGNED": "started", |
55 'RESOLVED': 'review', | 59 "RESOLVED": "review", |
56 'CLOSED': 'closed', | 60 "CLOSED": "closed", |
57 'REOPENED': 'started' # we loose data here because there is no need on basic workflow to have a reopened status | 61 "REOPENED": "started", # we loose data here because there is no need on basic workflow to have a reopened status |
58 } | 62 } |
59 | 63 |
60 | 64 |
61 class BugzillaParser(object): | 65 class BugzillaParser(object): |
62 # TODO: add a way to reassign values | 66 # TODO: add a way to reassign values |
63 | 67 |
64 def parse(self, file_path): | 68 def parse(self, file_path): |
65 tickets = [] | 69 tickets = [] |
66 root = etree.parse(file_path) | 70 root = etree.parse(file_path) |
67 | 71 |
68 for bug in root.xpath('bug'): | 72 for bug in root.xpath("bug"): |
69 ticket = {} | 73 ticket = {} |
70 ticket['id'] = bug.findtext('bug_id') | 74 ticket["id"] = bug.findtext("bug_id") |
71 ticket['created'] = date_utils.date_parse(bug.findtext('creation_ts')) | 75 ticket["created"] = date_utils.date_parse(bug.findtext("creation_ts")) |
72 ticket['updated'] = date_utils.date_parse(bug.findtext('delta_ts')) | 76 ticket["updated"] = date_utils.date_parse(bug.findtext("delta_ts")) |
73 ticket['title'] = bug.findtext('short_desc') | 77 ticket["title"] = bug.findtext("short_desc") |
74 reporter_elt = bug.find('reporter') | 78 reporter_elt = bug.find("reporter") |
75 ticket['author'] = reporter_elt.get('name') | 79 ticket["author"] = reporter_elt.get("name") |
76 if ticket['author'] is None: | 80 if ticket["author"] is None: |
77 if '@' in reporter_elt.text: | 81 if "@" in reporter_elt.text: |
78 ticket['author'] = reporter_elt.text[:reporter_elt.text.find('@')].title() | 82 ticket["author"] = reporter_elt.text[ |
83 : reporter_elt.text.find("@") | |
84 ].title() | |
79 else: | 85 else: |
80 ticket['author'] = u'no name' | 86 ticket["author"] = u"no name" |
81 ticket['author_email'] = reporter_elt.text | 87 ticket["author_email"] = reporter_elt.text |
82 assigned_to_elt = bug.find('assigned_to') | 88 assigned_to_elt = bug.find("assigned_to") |
83 ticket['assigned_to_name'] = assigned_to_elt.get('name') | 89 ticket["assigned_to_name"] = assigned_to_elt.get("name") |
84 ticket['assigned_to_email'] = assigned_to_elt.text | 90 ticket["assigned_to_email"] = assigned_to_elt.text |
85 ticket['cc_emails'] = [e.text for e in bug.findall('cc')] | 91 ticket["cc_emails"] = [e.text for e in bug.findall("cc")] |
86 ticket['priority'] = bug.findtext('priority').lower().strip() | 92 ticket["priority"] = bug.findtext("priority").lower().strip() |
87 ticket['severity'] = bug.findtext('bug_severity').lower().strip() | 93 ticket["severity"] = bug.findtext("bug_severity").lower().strip() |
88 ticket['product'] = bug.findtext('product') | 94 ticket["product"] = bug.findtext("product") |
89 ticket['component'] = bug.findtext('component') | 95 ticket["component"] = bug.findtext("component") |
90 ticket['version'] = bug.findtext('version') | 96 ticket["version"] = bug.findtext("version") |
91 ticket['platform'] = bug.findtext('rep_platform') | 97 ticket["platform"] = bug.findtext("rep_platform") |
92 ticket['os'] = bug.findtext('op_sys') | 98 ticket["os"] = bug.findtext("op_sys") |
93 ticket['status'] = STATUS_MAP.get(bug.findtext('bug_status'), 'queued') | 99 ticket["status"] = STATUS_MAP.get(bug.findtext("bug_status"), "queued") |
94 ticket['milestone'] = bug.findtext('target_milestone') | 100 ticket["milestone"] = bug.findtext("target_milestone") |
95 | |
96 | 101 |
97 body = None | 102 body = None |
98 comments = [] | 103 comments = [] |
99 for longdesc in bug.findall('long_desc'): | 104 for longdesc in bug.findall("long_desc"): |
100 if body is None: | 105 if body is None: |
101 body = longdesc.findtext('thetext') | 106 body = longdesc.findtext("thetext") |
102 else: | 107 else: |
103 who = longdesc.find('who') | 108 who = longdesc.find("who") |
104 comment = {'id': longdesc.findtext('commentid'), | 109 comment = { |
105 'author_email': who.text, | 110 "id": longdesc.findtext("commentid"), |
106 'published': date_utils.date_parse(longdesc.findtext('bug_when')), | 111 "author_email": who.text, |
107 'author': who.get('name', who.text), | 112 "published": date_utils.date_parse(longdesc.findtext("bug_when")), |
108 'content': longdesc.findtext('thetext')} | 113 "author": who.get("name", who.text), |
114 "content": longdesc.findtext("thetext"), | |
115 } | |
109 comments.append(comment) | 116 comments.append(comment) |
110 | 117 |
111 ticket['body'] = body | 118 ticket["body"] = body |
112 ticket['comments'] = comments | 119 ticket["comments"] = comments |
113 tickets.append(ticket) | 120 tickets.append(ticket) |
114 | 121 |
115 tickets.sort(key = lambda t: int(t['id'])) | 122 tickets.sort(key=lambda t: int(t["id"])) |
116 return (tickets, len(tickets)) | 123 return (tickets, len(tickets)) |
117 | 124 |
118 | 125 |
119 class BugzillaImport(object): | 126 class BugzillaImport(object): |
120 | |
121 def __init__(self, host): | 127 def __init__(self, host): |
122 log.info(_(u"Bugilla Import plugin initialization")) | 128 log.info(_(u"Bugilla Import plugin initialization")) |
123 self.host = host | 129 self.host = host |
124 host.plugins['TICKETS_IMPORT'].register('bugzilla', self.Import, SHORT_DESC, LONG_DESC) | 130 host.plugins["TICKETS_IMPORT"].register( |
131 "bugzilla", self.Import, SHORT_DESC, LONG_DESC | |
132 ) | |
125 | 133 |
126 def Import(self, client, location, options=None): | 134 def Import(self, client, location, options=None): |
127 if not os.path.isabs(location): | 135 if not os.path.isabs(location): |
128 raise exceptions.DataError(u"An absolute path to XML data need to be given as location") | 136 raise exceptions.DataError( |
137 u"An absolute path to XML data need to be given as location" | |
138 ) | |
129 bugzilla_parser = BugzillaParser() | 139 bugzilla_parser = BugzillaParser() |
130 # d = threads.deferToThread(bugzilla_parser.parse, location) | 140 # d = threads.deferToThread(bugzilla_parser.parse, location) |
131 d = defer.maybeDeferred(bugzilla_parser.parse, location) | 141 d = defer.maybeDeferred(bugzilla_parser.parse, location) |
132 return d | 142 return d |