comparison src/plugins/plugin_misc_merge_requests.py @ 2471:544c4d2fec45

plugins schema, merge_requests, tickets*: factorisation Dode common in plugins using schema have been factorised in pubsub schema plugin, and filters users in tickets handling have been renamed in a more generic way and put there too. "reporter*" fields in tickets have been renamed to "author*" as it is a more generic term which can be used elsewhere. The use of new utils.partial function make easy the creation of simple plugins using schema.
author Goffi <goffi@goffi.org>
date Fri, 12 Jan 2018 15:58:54 +0100
parents 637ac234424f
children 3f0a3a0ed290
comparison
equal deleted inserted replaced
2470:8084066ac95b 2471:544c4d2fec45
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 _ 20 from sat.core.i18n import _
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core import exceptions 22 from sat.core import exceptions
23 from twisted.words.protocols.jabber import jid
24 from twisted.internet import defer 23 from twisted.internet import defer
25 from wokkel import generic
26 from collections import namedtuple 24 from collections import namedtuple
25 from sat.tools import utils
27 from sat.core.log import getLogger 26 from sat.core.log import getLogger
28 log = getLogger(__name__) 27 log = getLogger(__name__)
29 28
30 NS_MERGE_REQUESTS = 'org.salut-a-toi.merge_requests:0' 29 NS_MERGE_REQUESTS = 'org.salut-a-toi.merge_requests:0'
31 30
32 PLUGIN_INFO = { 31 PLUGIN_INFO = {
33 C.PI_NAME: _("Merge requests management"), 32 C.PI_NAME: _("Merge requests management"),
34 C.PI_IMPORT_NAME: "MERGE_REQUESTS", 33 C.PI_IMPORT_NAME: "MERGE_REQUESTS",
35 C.PI_TYPE: "EXP", 34 C.PI_TYPE: "EXP",
36 C.PI_PROTOCOLS: [], 35 C.PI_PROTOCOLS: [],
37 C.PI_DEPENDENCIES: ["XEP-0060", "PUBSUB_SCHEMA", "TICKETS"], 36 C.PI_DEPENDENCIES: ["XEP-0060", "PUBSUB_SCHEMA"],
38 C.PI_MAIN: "MergeRequests", 37 C.PI_MAIN: "MergeRequests",
39 C.PI_HANDLER: "no", 38 C.PI_HANDLER: "no",
40 C.PI_DESCRIPTION: _("""Merge requests management plugin""") 39 C.PI_DESCRIPTION: _("""Merge requests management plugin""")
41 } 40 }
42 41
67 log.info(_(u"Merge requests plugin initialization")) 66 log.info(_(u"Merge requests plugin initialization"))
68 self.host = host 67 self.host = host
69 host.registerNamespace('merge_requests', NS_MERGE_REQUESTS) 68 host.registerNamespace('merge_requests', NS_MERGE_REQUESTS)
70 self._p = self.host.plugins["XEP-0060"] 69 self._p = self.host.plugins["XEP-0060"]
71 self._s = self.host.plugins["PUBSUB_SCHEMA"] 70 self._s = self.host.plugins["PUBSUB_SCHEMA"]
72 self._t = self.host.plugins["TICKETS"]
73 self._handlers = {} 71 self._handlers = {}
74 self._handlers_list = [] # handlers sorted by priority 72 self._handlers_list = [] # handlers sorted by priority
75 self._type_handlers = {} # data type => handler map 73 self._type_handlers = {} # data type => handler map
76 host.bridge.addMethod("mergeRequestsGet", ".plugin", 74 host.bridge.addMethod("mergeRequestsGet", ".plugin",
77 in_sign='ssiassa{ss}s', out_sign='(asa{ss}aaa{ss})', 75 in_sign='ssiassa{ss}s', out_sign='(asa{ss}aaa{ss})',
82 in_sign='ssssa{sas}ssa{ss}s', out_sign='s', 80 in_sign='ssssa{sas}ssa{ss}s', out_sign='s',
83 method=self._set, 81 method=self._set,
84 async=True) 82 async=True)
85 host.bridge.addMethod("mergeRequestsSchemaGet", ".plugin", 83 host.bridge.addMethod("mergeRequestsSchemaGet", ".plugin",
86 in_sign='sss', out_sign='s', 84 in_sign='sss', out_sign='s',
87 method=self._getSchema, 85 method=utils.partial(self._s._getUISchema, default_node=NS_MERGE_REQUESTS),
88 async=True) 86 async=True)
89 host.bridge.addMethod("mergeRequestParseData", ".plugin", 87 host.bridge.addMethod("mergeRequestParseData", ".plugin",
90 in_sign='ss', out_sign='aa{ss}', 88 in_sign='ss', out_sign='aa{ss}',
91 method=self._parseData, 89 method=self._parseData,
92 async=True) 90 async=True)
125 new_handler = name)) 123 new_handler = name))
126 continue 124 continue
127 self._type_handlers[data_type] = self._handlers[name] 125 self._type_handlers[data_type] = self._handlers[name]
128 126
129 def _get(self, service='', node='', max_items=10, item_ids=None, sub_id=None, extra_dict=None, profile_key=C.PROF_KEY_NONE): 127 def _get(self, service='', node='', max_items=10, item_ids=None, sub_id=None, extra_dict=None, profile_key=C.PROF_KEY_NONE):
130 client = self.host.getClient(profile_key)
131 service = jid.JID(service) if service else None
132 max_items = None if max_items == C.NO_LIMIT else max_items
133 if extra_dict and 'parse' in extra_dict: 128 if extra_dict and 'parse' in extra_dict:
134 extra_dict['parse'] = C.bool(extra_dict['parse']) 129 extra_dict['parse'] = C.bool(extra_dict['parse'])
135 extra = self._p.parseExtra(extra_dict) 130 client, service, node, max_items, extra, sub_id = self._s.prepareBridgeGet(service, node, max_items, sub_id, extra_dict, profile_key)
136 d = self.get(client, service, node or None, max_items, item_ids, sub_id or None, extra.rsm_request, extra.extra) 131 d = self.get(client, service, node or None, max_items, item_ids, sub_id or None, extra.rsm_request, extra.extra)
137 d.addCallback(lambda (tickets, metadata, parsed_patches): ( 132 d.addCallback(lambda (tickets, metadata, parsed_patches): (
138 self._p.serItemsData((tickets, metadata)) + 133 self._p.serItemsData((tickets, metadata)) +
139 ([[{key: unicode(value) for key, value in p.iteritems()} 134 ([[{key: unicode(value) for key, value in p.iteritems()}
140 for p in patches] for patches in parsed_patches],))) 135 for p in patches] for patches in parsed_patches],)))
151 - XMLUI of the tickets, like [TICKETS._get] 146 - XMLUI of the tickets, like [TICKETS._get]
152 - list of parsed request data (if extra['parse'] is set, else empty list) 147 - list of parsed request data (if extra['parse'] is set, else empty list)
153 """ 148 """
154 if not node: 149 if not node:
155 node = NS_MERGE_REQUESTS 150 node = NS_MERGE_REQUESTS
156 tickets_xmlui, metadata = yield self._t.get(client, service, node, max_items, item_ids, sub_id, rsm_request, extra, form_ns=NS_MERGE_REQUESTS) 151 tickets_xmlui, metadata = yield self._s.getDataFormItems(
152 client,
153 service,
154 node,
155 max_items=max_items,
156 item_ids=item_ids,
157 sub_id=sub_id,
158 rsm_request=rsm_request,
159 extra=extra,
160 form_ns=NS_MERGE_REQUESTS)
157 parsed_patches = [] 161 parsed_patches = []
158 if extra.get('parse', False): 162 if extra.get('parse', False):
159 for ticket in tickets_xmlui: 163 for ticket in tickets_xmlui:
160 request_type = ticket.named_widgets[FIELD_DATA_TYPE].value 164 request_type = ticket.named_widgets[FIELD_DATA_TYPE].value
161 request_data = ticket.named_widgets[FIELD_DATA].value 165 request_data = ticket.named_widgets[FIELD_DATA].value
162 parsed_data = yield self.parseData(request_type, request_data) 166 parsed_data = yield self.parseData(request_type, request_data)
163 parsed_patches.append(parsed_data) 167 parsed_patches.append(parsed_data)
164 defer.returnValue((tickets_xmlui, metadata, parsed_patches)) 168 defer.returnValue((tickets_xmlui, metadata, parsed_patches))
165 169
166 def _set(self, service, node, repository, method, values, schema=None, item_id=None, extra=None, profile_key=C.PROF_KEY_NONE): 170 def _set(self, service, node, repository, method, values, schema=None, item_id=None, extra=None, profile_key=C.PROF_KEY_NONE):
167 client = self.host.getClient(profile_key) 171 client, service, schema, extra = self._s.prepareBridgeSet(service, node, schema, extra)
168 service = None if not service else jid.JID(service)
169 if extra and 'update' in extra:
170 extra['update'] = C.bool(extra['update'])
171 if schema:
172 schema = generic.parseXml(schema.encode('utf-8'))
173 else:
174 schema = None
175 d = self.set(client, service, node or None, repository, method, values, schema, item_id or None, extra, deserialise=True) 172 d = self.set(client, service, node or None, repository, method, values, schema, item_id or None, extra, deserialise=True)
176 d.addCallback(lambda ret: ret or u'') 173 d.addCallback(lambda ret: ret or u'')
177 return d 174 return d
178 175
179 @defer.inlineCallbacks 176 @defer.inlineCallbacks
186 @param repository(unicode): path to the repository where the code stands 183 @param repository(unicode): path to the repository where the code stands
187 @param method(unicode): name of one of the registered handler, or "auto" to try autodetection. 184 @param method(unicode): name of one of the registered handler, or "auto" to try autodetection.
188 other arguments are same as for [TICKETS.set] 185 other arguments are same as for [TICKETS.set]
189 @return (unicode): id of the created item 186 @return (unicode): id of the created item
190 """ 187 """
191 if not node:
192 node = NS_MERGE_REQUESTS
193
194 if values is None: 188 if values is None:
195 values = {} 189 values = {}
196 190
197 if FIELD_DATA in values: 191 if FIELD_DATA in values:
198 raise exceptions.DataError(_(u"{field} is set by backend, you must not set it in frontend").format( 192 raise exceptions.DataError(_(u"{field} is set by backend, you must not set it in frontend").format(
228 if not values.get(u'body'): 222 if not values.get(u'body'):
229 values[u'body'] = u'\n'.join(msg_lines[1:]) 223 values[u'body'] = u'\n'.join(msg_lines[1:])
230 224
231 values[FIELD_DATA] = data 225 values[FIELD_DATA] = data
232 226
233 item_id = yield self._t.set(client, service, node, values, schema, item_id, extra, deserialise, form_ns=NS_MERGE_REQUESTS) 227 item_id = yield self._t.set(client, service, node, values, schema, item_id, extra, deserialise, default_node=NS_MERGE_REQUESTS, form_ns=NS_MERGE_REQUESTS)
234 defer.returnValue(item_id) 228 defer.returnValue(item_id)
235
236 def _getSchema(self, service, node, profile_key=C.PROF_KEY_NONE):
237 if not node:
238 node = NS_MERGE_REQUESTS
239 return self._s._getUISchema(service, node, profile_key)
240 229
241 def _parseData(self, data_type, data): 230 def _parseData(self, data_type, data):
242 d = self.parseData(data_type, data) 231 d = self.parseData(data_type, data)
243 d.addCallback(lambda parsed_patches: 232 d.addCallback(lambda parsed_patches:
244 {key: unicode(value) for key, value in parsed_patches.iteritems()}) 233 {key: unicode(value) for key, value in parsed_patches.iteritems()})