comparison sat/plugins/plugin_misc_merge_requests.py @ 2622:8fb99ed47db4

core: lines limit
author Goffi <goffi@goffi.org>
date Wed, 27 Jun 2018 07:50:35 +0200
parents 700327fa9281
children 003b8b4b56a7
comparison
equal deleted inserted replaced
2621:2f75830a8228 2622:8fb99ed47db4
82 in_sign='ssssa{sas}ssa{ss}s', out_sign='s', 82 in_sign='ssssa{sas}ssa{ss}s', out_sign='s',
83 method=self._set, 83 method=self._set,
84 async=True) 84 async=True)
85 host.bridge.addMethod("mergeRequestsSchemaGet", ".plugin", 85 host.bridge.addMethod("mergeRequestsSchemaGet", ".plugin",
86 in_sign='sss', out_sign='s', 86 in_sign='sss', out_sign='s',
87 method=utils.partial(self._s._getUISchema, default_node=NS_MERGE_REQUESTS), 87 method=utils.partial(self._s._getUISchema,
88 default_node=NS_MERGE_REQUESTS),
88 async=True) 89 async=True)
89 host.bridge.addMethod("mergeRequestParseData", ".plugin", 90 host.bridge.addMethod("mergeRequestParseData", ".plugin",
90 in_sign='ss', out_sign='aa{ss}', 91 in_sign='ss', out_sign='aa{ss}',
91 method=self._parseData, 92 method=self._parseData,
92 async=True) 93 async=True)
102 @param name(unicode): name of the handler 103 @param name(unicode): name of the handler
103 @param handler(object): instance of the handler. 104 @param handler(object): instance of the handler.
104 It must have the following methods, which may all return a Deferred: 105 It must have the following methods, which may all return a Deferred:
105 - check(repository): True if repository can be handled 106 - check(repository): True if repository can be handled
106 - export(repository): return export data, i.e. the patches 107 - export(repository): return export data, i.e. the patches
107 - parse(export_data): parse report data and return a list of dict (1 per patch) with: 108 - parse(export_data): parse report data and return a list of dict
109 (1 per patch) with:
108 - title: title of the commit message (first line) 110 - title: title of the commit message (first line)
109 - body: body of the commit message 111 - body: body of the commit message
110 @aram data_types(list[unicode]): data types that his handler can generate or parse 112 @aram data_types(list[unicode]): data types that his handler can generate or parse
111 """ 113 """
112 if name in self._handlers: 114 if name in self._handlers:
113 raise exceptions.ConflictError(_(u"a handler with name {name} already exists!").format( 115 raise exceptions.ConflictError(_(u"a handler with name {name} already "
114 name = name)) 116 u"exists!").format(name = name))
115 self._handlers[name] = MergeRequestHandler(name, 117 self._handlers[name] = MergeRequestHandler(name,
116 handler, 118 handler,
117 data_types, 119 data_types,
118 short_desc, 120 short_desc,
119 priority) 121 priority)
121 self._handlers_list.sort(key=lambda name: self._handlers[name].priority) 123 self._handlers_list.sort(key=lambda name: self._handlers[name].priority)
122 if isinstance(data_types, basestring): 124 if isinstance(data_types, basestring):
123 data_types = [data_types] 125 data_types = [data_types]
124 for data_type in data_types: 126 for data_type in data_types:
125 if data_type in self._type_handlers: 127 if data_type in self._type_handlers:
126 log.warning(_(u'merge requests of type {type} are already handled by {old_handler}, ' 128 log.warning(_(u'merge requests of type {type} are already handled by '
127 u'ignoring {new_handler}').format( 129 u'{old_handler}, ignoring {new_handler}').format(
128 type = data_type, 130 type = data_type,
129 old_handler = self._type_handlers[data_type].name, 131 old_handler = self._type_handlers[data_type].name,
130 new_handler = name)) 132 new_handler = name))
131 continue 133 continue
132 self._type_handlers[data_type] = self._handlers[name] 134 self._type_handlers[data_type] = self._handlers[name]
133 135
134 def _get(self, service='', node='', max_items=10, item_ids=None, sub_id=None, extra_dict=None, profile_key=C.PROF_KEY_NONE): 136 def _get(self, service='', node='', max_items=10, item_ids=None, sub_id=None,
137 extra_dict=None, profile_key=C.PROF_KEY_NONE):
135 if extra_dict and 'parse' in extra_dict: 138 if extra_dict and 'parse' in extra_dict:
136 extra_dict['parse'] = C.bool(extra_dict['parse']) 139 extra_dict['parse'] = C.bool(extra_dict['parse'])
137 client, service, node, max_items, extra, sub_id = self._s.prepareBridgeGet(service, node, max_items, sub_id, extra_dict, profile_key) 140 client, service, node, max_items, extra, sub_id = self._s.prepareBridgeGet(
138 d = self.get(client, service, node or None, max_items, item_ids, sub_id or None, extra.rsm_request, extra.extra) 141 service, node, max_items, sub_id, extra_dict, profile_key)
142 d = self.get(client, service, node or None, max_items, item_ids, sub_id or None,
143 extra.rsm_request, extra.extra)
139 d.addCallback(lambda (tickets, metadata, parsed_patches): ( 144 d.addCallback(lambda (tickets, metadata, parsed_patches): (
140 self._p.serItemsData((tickets, metadata)) + 145 self._p.serItemsData((tickets, metadata)) +
141 ([[{key: unicode(value) for key, value in p.iteritems()} 146 ([[{key: unicode(value) for key, value in p.iteritems()}
142 for p in patches] for patches in parsed_patches],))) 147 for p in patches] for patches in parsed_patches],)))
143 return d 148 return d
144 149
145 @defer.inlineCallbacks 150 @defer.inlineCallbacks
146 def get(self, client, service=None, node=None, max_items=None, item_ids=None, sub_id=None, rsm_request=None, extra=None): 151 def get(self, client, service=None, node=None, max_items=None, item_ids=None,
152 sub_id=None, rsm_request=None, extra=None):
147 """Retrieve merge requests and convert them to XMLUI 153 """Retrieve merge requests and convert them to XMLUI
148 154
149 @param extra(XEP-0060.parse, None): can have following keys: 155 @param extra(XEP-0060.parse, None): can have following keys:
150 - update(bool): if True, will return list of parsed request data 156 - update(bool): if True, will return list of parsed request data
151 other params are the same as for [TICKETS._get] 157 other params are the same as for [TICKETS._get]
182 request_data = ticket.named_widgets[FIELD_DATA].value 188 request_data = ticket.named_widgets[FIELD_DATA].value
183 parsed_data = yield self.parseData(request_type, request_data) 189 parsed_data = yield self.parseData(request_type, request_data)
184 parsed_patches.append(parsed_data) 190 parsed_patches.append(parsed_data)
185 defer.returnValue((tickets_xmlui, metadata, parsed_patches)) 191 defer.returnValue((tickets_xmlui, metadata, parsed_patches))
186 192
187 def _set(self, service, node, repository, method, values, schema=None, item_id=None, extra=None, profile_key=C.PROF_KEY_NONE): 193 def _set(self, service, node, repository, method, values, schema=None, item_id=None,
188 client, service, node, schema, item_id, extra = self._s.prepareBridgeSet(service, node, schema, item_id, extra, profile_key) 194 extra=None, profile_key=C.PROF_KEY_NONE):
189 d = self.set(client, service, node, repository, method, values, schema, item_id, extra, deserialise=True) 195 client, service, node, schema, item_id, extra = self._s.prepareBridgeSet(
196 service, node, schema, item_id, extra, profile_key)
197 d = self.set(client, service, node, repository, method, values, schema, item_id,
198 extra, deserialise=True)
190 d.addCallback(lambda ret: ret or u'') 199 d.addCallback(lambda ret: ret or u'')
191 return d 200 return d
192 201
193 @defer.inlineCallbacks 202 @defer.inlineCallbacks
194 def set(self, client, service, node, repository, method=u'auto', values=None, schema=None, item_id=None, extra=None, deserialise=False): 203 def set(self, client, service, node, repository, method=u'auto', values=None,
204 schema=None, item_id=None, extra=None, deserialise=False):
195 """Publish a tickets 205 """Publish a tickets
196 206
197 @param service(None, jid.JID): Pubsub service to use 207 @param service(None, jid.JID): Pubsub service to use
198 @param node(unicode, None): Pubsub node to use 208 @param node(unicode, None): Pubsub node to use
199 None to use default tickets node 209 None to use default tickets node
200 @param repository(unicode): path to the repository where the code stands 210 @param repository(unicode): path to the repository where the code stands
201 @param method(unicode): name of one of the registered handler, or "auto" to try autodetection. 211 @param method(unicode): name of one of the registered handler,
212 or "auto" to try autodetection.
202 other arguments are same as for [TICKETS.set] 213 other arguments are same as for [TICKETS.set]
203 @return (unicode): id of the created item 214 @return (unicode): id of the created item
204 """ 215 """
205 if not node: 216 if not node:
206 node = NS_MERGE_REQUESTS 217 node = NS_MERGE_REQUESTS
211 # in case of update, we may re-user former patches data 222 # in case of update, we may re-user former patches data
212 # so repository is not mandatory 223 # so repository is not mandatory
213 raise exceptions.DataError(_(u"repository must be specified")) 224 raise exceptions.DataError(_(u"repository must be specified"))
214 225
215 if FIELD_DATA in values: 226 if FIELD_DATA in values:
216 raise exceptions.DataError(_(u"{field} is set by backend, you must not set it in frontend").format( 227 raise exceptions.DataError(_(u"{field} is set by backend, you must not set "
217 field = FIELD_DATA)) 228 u"it in frontend").format(field = FIELD_DATA))
218 229
219 if repository: 230 if repository:
220 if method == u'auto': 231 if method == u'auto':
221 for name in self._handlers_list: 232 for name in self._handlers_list:
222 handler = self._handlers[name].handler 233 handler = self._handlers[name].handler
223 can_handle = yield handler.check(repository) 234 can_handle = yield handler.check(repository)
224 if can_handle: 235 if can_handle:
225 log.info(_(u"{name} handler will be used").format(name=name)) 236 log.info(_(u"{name} handler will be used").format(name=name))
226 break 237 break
227 else: 238 else:
228 log.warning(_(u"repository {path} can't be handled by any installed handler").format( 239 log.warning(_(u"repository {path} can't be handled by any installed "
240 u"handler").format(
229 path = repository)) 241 path = repository))
230 raise exceptions.NotFound(_(u"no handler for this repository has been found")) 242 raise exceptions.NotFound(_(u"no handler for this repository has "
243 u"been found"))
231 else: 244 else:
232 try: 245 try:
233 handler = self._handlers[name].handler 246 handler = self._handlers[name].handler
234 except KeyError: 247 except KeyError:
235 raise exceptions.NotFound(_(u"No handler of this name found")) 248 raise exceptions.NotFound(_(u"No handler of this name found"))
236 249
237 data = yield handler.export(repository) 250 data = yield handler.export(repository)
238 if not data.strip(): 251 if not data.strip():
239 raise exceptions.DataError(_(u'export data is empty, do you have any change to send?')) 252 raise exceptions.DataError(_(u'export data is empty, do you have any '
253 u'change to send?'))
240 254
241 if not values.get(u'title') or not values.get(u'body'): 255 if not values.get(u'title') or not values.get(u'body'):
242 patches = yield handler.parse(data, values.get(FIELD_DATA_TYPE)) 256 patches = yield handler.parse(data, values.get(FIELD_DATA_TYPE))
243 commits_msg = patches[-1][self.META_COMMIT_MSG] 257 commits_msg = patches[-1][self.META_COMMIT_MSG]
244 msg_lines = commits_msg.splitlines() 258 msg_lines = commits_msg.splitlines()
247 if not values.get(u'body'): 261 if not values.get(u'body'):
248 values[u'body'] = u'\n'.join(msg_lines[1:]) 262 values[u'body'] = u'\n'.join(msg_lines[1:])
249 263
250 values[FIELD_DATA] = data 264 values[FIELD_DATA] = data
251 265
252 item_id = yield self._t.set(client, service, node, values, schema, item_id, extra, deserialise, form_ns=NS_MERGE_REQUESTS) 266 item_id = yield self._t.set(client, service, node, values, schema, item_id, extra,
267 deserialise, form_ns=NS_MERGE_REQUESTS)
253 defer.returnValue(item_id) 268 defer.returnValue(item_id)
254 269
255 def _parseData(self, data_type, data): 270 def _parseData(self, data_type, data):
256 d = self.parseData(data_type, data) 271 d = self.parseData(data_type, data)
257 d.addCallback(lambda parsed_patches: 272 d.addCallback(lambda parsed_patches:
268 @raise NotFound: no handler can parse this data_type 283 @raise NotFound: no handler can parse this data_type
269 """ 284 """
270 try: 285 try:
271 handler = self._type_handlers[data_type] 286 handler = self._type_handlers[data_type]
272 except KeyError: 287 except KeyError:
273 raise exceptions.NotFound(_(u'No handler can handle data type "{type}"').format(type=data_type)) 288 raise exceptions.NotFound(_(u'No handler can handle data type "{type}"')
289 .format(type=data_type))
274 return defer.maybeDeferred(handler.handler.parse, data, data_type) 290 return defer.maybeDeferred(handler.handler.parse, data, data_type)
275 291
276 def _import(self, repository, item_id, service=None, node=None, extra=None, profile_key=C.PROF_KEY_NONE): 292 def _import(self, repository, item_id, service=None, node=None, extra=None,
293 profile_key=C.PROF_KEY_NONE):
277 client = self.host.getClient(profile_key) 294 client = self.host.getClient(profile_key)
278 service = jid.JID(service) if service else None 295 service = jid.JID(service) if service else None
279 d = self.import_request(client, repository, item_id, service, node or None, extra=extra or None) 296 d = self.import_request(client, repository, item_id, service, node or None,
297 extra=extra or None)
280 return d 298 return d
281 299
282 @defer.inlineCallbacks 300 @defer.inlineCallbacks
283 def import_request(self, client, repository, item, service=None, node=None, extra=None): 301 def import_request(self, client, repository, item, service=None, node=None,
302 extra=None):
284 """Import a merge request in specified directory 303 """Import a merge request in specified directory
285 304
286 @param repository(unicode): path to the repository where the code stands 305 @param repository(unicode): path to the repository where the code stands
287 """ 306 """
288 if not node: 307 if not node:
298 data = ticket_xmlui.named_widgets[FIELD_DATA].value 317 data = ticket_xmlui.named_widgets[FIELD_DATA].value
299 data_type = ticket_xmlui.named_widgets[FIELD_DATA_TYPE].value 318 data_type = ticket_xmlui.named_widgets[FIELD_DATA_TYPE].value
300 try: 319 try:
301 handler = self._type_handlers[data_type] 320 handler = self._type_handlers[data_type]
302 except KeyError: 321 except KeyError:
303 raise exceptions.NotFound(_(u'No handler found to import {data_type}').format(data_type=data_type)) 322 raise exceptions.NotFound(_(u'No handler found to import {data_type}')
323 .format(data_type=data_type))
304 log.info(_(u"Importing patch [{item_id}] using {name} handler").format( 324 log.info(_(u"Importing patch [{item_id}] using {name} handler").format(
305 item_id = item, 325 item_id = item,
306 name = handler.name)) 326 name = handler.name))
307 yield handler.handler.import_(repository, data, data_type, item, service, node, extra) 327 yield handler.handler.import_(repository, data, data_type, item, service, node,
328 extra)