comparison sat/plugins/plugin_misc_merge_requests.py @ 3309:71761e9fb984

plugins tickets, merge-requests: `ticketsGet` and `mergeRequestsGet` serialisation: those methods now return data serialised with `data_format.serialise`
author Goffi <goffi@goffi.org>
date Thu, 16 Jul 2020 09:07:26 +0200
parents 559a625a236b
children bb0225aaf4e6
comparison
equal deleted inserted replaced
3308:384283adcce1 3309:71761e9fb984
15 # GNU Affero General Public License for more details. 15 # GNU Affero General Public License for more details.
16 16
17 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
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 collections import namedtuple
21 from twisted.internet import defer
22 from twisted.words.protocols.jabber import jid
20 from sat.core.i18n import _ 23 from sat.core.i18n import _
21 from sat.core.constants import Const as C 24 from sat.core.constants import Const as C
22 from sat.core import exceptions 25 from sat.core import exceptions
23 from twisted.internet import defer 26 from sat.tools.common import data_format
24 from twisted.words.protocols.jabber import jid
25 from collections import namedtuple
26 from sat.core.log import getLogger 27 from sat.core.log import getLogger
28
27 29
28 log = getLogger(__name__) 30 log = getLogger(__name__)
29 31
30 NS_MERGE_REQUESTS = 'org.salut-a-toi.merge_requests:0' 32 NS_MERGE_REQUESTS = 'org.salut-a-toi.merge_requests:0'
31 33
72 self._t = self.host.plugins["TICKETS"] 74 self._t = self.host.plugins["TICKETS"]
73 self._handlers = {} 75 self._handlers = {}
74 self._handlers_list = [] # handlers sorted by priority 76 self._handlers_list = [] # handlers sorted by priority
75 self._type_handlers = {} # data type => handler map 77 self._type_handlers = {} # data type => handler map
76 host.bridge.addMethod("mergeRequestsGet", ".plugin", 78 host.bridge.addMethod("mergeRequestsGet", ".plugin",
77 in_sign='ssiassa{ss}s', out_sign='(asa{ss}aaa{ss})', 79 in_sign='ssiassa{ss}s', out_sign='s',
78 method=self._get, 80 method=self._get,
79 async_=True 81 async_=True
80 ) 82 )
81 host.bridge.addMethod("mergeRequestSet", ".plugin", 83 host.bridge.addMethod("mergeRequestSet", ".plugin",
82 in_sign='ssssa{sas}ssss', out_sign='s', 84 in_sign='ssssa{sas}ssss', out_sign='s',
134 old_handler = self._type_handlers[data_type].name, 136 old_handler = self._type_handlers[data_type].name,
135 new_handler = name)) 137 new_handler = name))
136 continue 138 continue
137 self._type_handlers[data_type] = self._handlers[name] 139 self._type_handlers[data_type] = self._handlers[name]
138 140
141 def serialise(self, get_data):
142 tickets_xmlui, metadata, items_patches = get_data
143 tickets_xmlui_s, metadata = self._p.transItemsData((tickets_xmlui, metadata))
144 return data_format.serialise({
145 "items": tickets_xmlui_s,
146 "metadata": metadata,
147 "items_patches": items_patches,
148 })
149
139 def _get(self, service='', node='', max_items=10, item_ids=None, sub_id=None, 150 def _get(self, service='', node='', max_items=10, item_ids=None, sub_id=None,
140 extra_dict=None, profile_key=C.PROF_KEY_NONE): 151 extra_dict=None, profile_key=C.PROF_KEY_NONE):
141 if extra_dict and 'parse' in extra_dict: 152 if extra_dict and 'parse' in extra_dict:
142 extra_dict['parse'] = C.bool(extra_dict['parse']) 153 extra_dict['parse'] = C.bool(extra_dict['parse'])
143 client, service, node, max_items, extra, sub_id = self._s.prepareBridgeGet( 154 client, service, node, max_items, extra, sub_id = self._s.prepareBridgeGet(
144 service, node, max_items, sub_id, extra_dict, profile_key) 155 service, node, max_items, sub_id, extra_dict, profile_key)
145 d = self.get(client, service, node or None, max_items, item_ids, sub_id or None, 156 d = self.get(client, service, node or None, max_items, item_ids, sub_id or None,
146 extra.rsm_request, extra.extra) 157 extra.rsm_request, extra.extra)
147 d.addCallback(lambda tickets_metadata_parsed_patches: ( 158 d.addCallback(self.serialise)
148 self._p.transItemsData((tickets_metadata_parsed_patches[0], tickets_metadata_parsed_patches[1])) +
149 ([[{key: str(value) for key, value in p.items()}
150 for p in patches] for patches in tickets_metadata_parsed_patches[2]],)))
151 return d 159 return d
152 160
153 @defer.inlineCallbacks 161 @defer.inlineCallbacks
154 def get(self, client, service=None, node=None, max_items=None, item_ids=None, 162 def get(self, client, service=None, node=None, max_items=None, item_ids=None,
155 sub_id=None, rsm_request=None, extra=None): 163 sub_id=None, rsm_request=None, extra=None):
195 203
196 def _set(self, service, node, repository, method, values, schema=None, item_id=None, 204 def _set(self, service, node, repository, method, values, schema=None, item_id=None,
197 extra="", profile_key=C.PROF_KEY_NONE): 205 extra="", profile_key=C.PROF_KEY_NONE):
198 client, service, node, schema, item_id, extra = self._s.prepareBridgeSet( 206 client, service, node, schema, item_id, extra = self._s.prepareBridgeSet(
199 service, node, schema, item_id, extra, profile_key) 207 service, node, schema, item_id, extra, profile_key)
200 d = self.set(client, service, node, repository, method, values, schema, 208 d = defer.ensureDeferred(
201 item_id or None, extra, deserialise=True) 209 self.set(
210 client, service, node, repository, method, values, schema,
211 item_id or None, extra, deserialise=True
212 )
213 )
202 d.addCallback(lambda ret: ret or '') 214 d.addCallback(lambda ret: ret or '')
203 return d 215 return d
204 216
205 @defer.inlineCallbacks 217 async def set(self, client, service, node, repository, method='auto', values=None,
206 def set(self, client, service, node, repository, method='auto', values=None,
207 schema=None, item_id=None, extra=None, deserialise=False): 218 schema=None, item_id=None, extra=None, deserialise=False):
208 """Publish a tickets 219 """Publish a tickets
209 220
210 @param service(None, jid.JID): Pubsub service to use 221 @param service(None, jid.JID): Pubsub service to use
211 @param node(unicode, None): Pubsub node to use 222 @param node(unicode, None): Pubsub node to use
232 243
233 if repository: 244 if repository:
234 if method == 'auto': 245 if method == 'auto':
235 for name in self._handlers_list: 246 for name in self._handlers_list:
236 handler = self._handlers[name].handler 247 handler = self._handlers[name].handler
237 can_handle = yield handler.check(repository) 248 can_handle = await handler.check(repository)
238 if can_handle: 249 if can_handle:
239 log.info(_("{name} handler will be used").format(name=name)) 250 log.info(_("{name} handler will be used").format(name=name))
240 break 251 break
241 else: 252 else:
242 log.warning(_("repository {path} can't be handled by any installed " 253 log.warning(_("repository {path} can't be handled by any installed "
248 try: 259 try:
249 handler = self._handlers[name].handler 260 handler = self._handlers[name].handler
250 except KeyError: 261 except KeyError:
251 raise exceptions.NotFound(_("No handler of this name found")) 262 raise exceptions.NotFound(_("No handler of this name found"))
252 263
253 data = yield handler.export(repository) 264 data = await handler.export(repository)
254 if not data.strip(): 265 if not data.strip():
255 raise exceptions.DataError(_('export data is empty, do you have any ' 266 raise exceptions.DataError(_('export data is empty, do you have any '
256 'change to send?')) 267 'change to send?'))
257 268
258 if not values.get('title') or not values.get('body'): 269 if not values.get('title') or not values.get('body'):
259 patches = yield handler.parse(data, values.get(FIELD_DATA_TYPE)) 270 patches = await handler.parse(data, values.get(FIELD_DATA_TYPE))
260 commits_msg = patches[-1][self.META_COMMIT_MSG] 271 commits_msg = patches[-1][self.META_COMMIT_MSG]
261 msg_lines = commits_msg.splitlines() 272 msg_lines = commits_msg.splitlines()
262 if not values.get('title'): 273 if not values.get('title'):
263 values['title'] = msg_lines[0] 274 values['title'] = msg_lines[0]
264 if not values.get('body'): 275 if not values.get('body'):
265 ts = self.host.plugins['TEXT_SYNTAXES'] 276 ts = self.host.plugins['TEXT_SYNTAXES']
266 xhtml = yield ts.convert( 277 xhtml = await ts.convert(
267 '\n'.join(msg_lines[1:]), 278 '\n'.join(msg_lines[1:]),
268 syntax_from = ts.SYNTAX_TEXT, 279 syntax_from = ts.SYNTAX_TEXT,
269 syntax_to = ts.SYNTAX_XHTML, 280 syntax_to = ts.SYNTAX_XHTML,
270 profile = client.profile) 281 profile = client.profile)
271 values['body'] = '<div xmlns="{ns}">{xhtml}</div>'.format( 282 values['body'] = '<div xmlns="{ns}">{xhtml}</div>'.format(
272 ns=C.NS_XHTML, xhtml=xhtml) 283 ns=C.NS_XHTML, xhtml=xhtml)
273 284
274 values[FIELD_DATA] = data 285 values[FIELD_DATA] = data
275 286
276 item_id = yield self._t.set(client, service, node, values, schema, item_id, extra, 287 item_id = await self._t.set(client, service, node, values, schema, item_id, extra,
277 deserialise, form_ns=NS_MERGE_REQUESTS) 288 deserialise, form_ns=NS_MERGE_REQUESTS)
278 defer.returnValue(item_id) 289 return item_id
279 290
280 def _parseData(self, data_type, data): 291 def _parseData(self, data_type, data):
281 d = self.parseData(data_type, data) 292 d = self.parseData(data_type, data)
282 d.addCallback(lambda parsed_patches: 293 d.addCallback(lambda parsed_patches:
283 {key: str(value) for key, value in parsed_patches.items()}) 294 {key: str(value) for key, value in parsed_patches.items()})