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