Mercurial > libervia-backend
comparison sat/plugins/plugin_misc_text_commands.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 26edcf3a30eb |
children | d715d912afac |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
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 | 23 from twisted.words.protocols.jabber import jid |
24 from twisted.internet import defer | 24 from twisted.internet import defer |
25 from sat.core.log import getLogger | 25 from sat.core.log import getLogger |
26 | |
26 log = getLogger(__name__) | 27 log = getLogger(__name__) |
27 from twisted.python import failure | 28 from twisted.python import failure |
28 from collections import OrderedDict | 29 from collections import OrderedDict |
29 | 30 |
30 PLUGIN_INFO = { | 31 PLUGIN_INFO = { |
33 C.PI_TYPE: "Misc", | 34 C.PI_TYPE: "Misc", |
34 C.PI_PROTOCOLS: ["XEP-0245"], | 35 C.PI_PROTOCOLS: ["XEP-0245"], |
35 C.PI_DEPENDENCIES: [], | 36 C.PI_DEPENDENCIES: [], |
36 C.PI_MAIN: "TextCommands", | 37 C.PI_MAIN: "TextCommands", |
37 C.PI_HANDLER: "no", | 38 C.PI_HANDLER: "no", |
38 C.PI_DESCRIPTION: _("""IRC like text commands""") | 39 C.PI_DESCRIPTION: _("""IRC like text commands"""), |
39 } | 40 } |
40 | 41 |
41 | 42 |
42 class InvalidCommandSyntax(Exception): | 43 class InvalidCommandSyntax(Exception): |
43 """Throwed while parsing @command in docstring if syntax is invalid""" | 44 """Throwed while parsing @command in docstring if syntax is invalid""" |
45 | |
44 pass | 46 pass |
45 | 47 |
46 | 48 |
47 CMD_KEY = "@command" | 49 CMD_KEY = "@command" |
48 CMD_TYPES = ('group', 'one2one', 'all') | 50 CMD_TYPES = ("group", "one2one", "all") |
49 FEEDBACK_INFO_TYPE = "TEXT_CMD" | 51 FEEDBACK_INFO_TYPE = "TEXT_CMD" |
50 | 52 |
51 | 53 |
52 class TextCommands(object): | 54 class TextCommands(object): |
53 #FIXME: doc strings for commands have to be translatable | 55 # FIXME: doc strings for commands have to be translatable |
54 # plugins need a dynamic translation system (translation | 56 # plugins need a dynamic translation system (translation |
55 # should be downloadable independently) | 57 # should be downloadable independently) |
56 | 58 |
57 HELP_SUGGESTION = _("Type '/help' to get a list of the available commands. If you didn't want to use a command, please start your message with '//' to escape the slash.") | 59 HELP_SUGGESTION = _( |
60 "Type '/help' to get a list of the available commands. If you didn't want to use a command, please start your message with '//' to escape the slash." | |
61 ) | |
58 | 62 |
59 def __init__(self, host): | 63 def __init__(self, host): |
60 log.info(_("Text commands initialization")) | 64 log.info(_("Text commands initialization")) |
61 self.host = host | 65 self.host = host |
62 # this is internal command, so we set high priority | 66 # this is internal command, so we set high priority |
76 - "doc_short_help" (default: ""): the untranslated short documentation | 80 - "doc_short_help" (default: ""): the untranslated short documentation |
77 - "type" (default "all"): the command type as specified in documentation | 81 - "type" (default "all"): the command type as specified in documentation |
78 - "args" (default: ""): the arguments available, using syntax specified in documentation. | 82 - "args" (default: ""): the arguments available, using syntax specified in documentation. |
79 - "doc_arg_[name]": the doc of [name] argument | 83 - "doc_arg_[name]": the doc of [name] argument |
80 """ | 84 """ |
81 data = OrderedDict([('doc_short_help', ""), | 85 data = OrderedDict([("doc_short_help", ""), ("type", "all"), ("args", "")]) |
82 ('type', 'all'), | |
83 ('args', '')]) | |
84 docstring = cmd.__doc__ | 86 docstring = cmd.__doc__ |
85 if docstring is None: | 87 if docstring is None: |
86 log.warning(u"Not docstring found for command {}".format(cmd_name)) | 88 log.warning(u"Not docstring found for command {}".format(cmd_name)) |
87 docstring = "" | 89 docstring = "" |
88 | 90 |
89 doc_data = docstring.split("\n") | 91 doc_data = docstring.split("\n") |
90 data["doc_short_help"] = doc_data[0] | 92 data["doc_short_help"] = doc_data[0] |
91 | 93 |
92 try: | 94 try: |
93 cmd_indent = 0 # >0 when @command is found are we are parsing it | 95 cmd_indent = 0 # >0 when @command is found are we are parsing it |
94 | 96 |
95 for line in doc_data: | 97 for line in doc_data: |
96 stripped = line.strip() | 98 stripped = line.strip() |
97 if cmd_indent and line[cmd_indent:cmd_indent+5] == " -": | 99 if cmd_indent and line[cmd_indent : cmd_indent + 5] == " -": |
98 colon_idx = line.find(":") | 100 colon_idx = line.find(":") |
99 if colon_idx == -1: | 101 if colon_idx == -1: |
100 raise InvalidCommandSyntax("No colon found in argument description") | 102 raise InvalidCommandSyntax( |
101 arg_name = line[cmd_indent+6:colon_idx].strip() | 103 "No colon found in argument description" |
104 ) | |
105 arg_name = line[cmd_indent + 6 : colon_idx].strip() | |
102 if not arg_name: | 106 if not arg_name: |
103 raise InvalidCommandSyntax("No name found in argument description") | 107 raise InvalidCommandSyntax( |
104 arg_help = line[colon_idx+1:].strip() | 108 "No name found in argument description" |
109 ) | |
110 arg_help = line[colon_idx + 1 :].strip() | |
105 data["doc_arg_{}".format(arg_name)] = arg_help | 111 data["doc_arg_{}".format(arg_name)] = arg_help |
106 elif cmd_indent: | 112 elif cmd_indent: |
107 # we are parsing command and indent level is not good, it's finished | 113 # we are parsing command and indent level is not good, it's finished |
108 break | 114 break |
109 elif stripped.startswith(CMD_KEY): | 115 elif stripped.startswith(CMD_KEY): |
111 | 117 |
112 # type | 118 # type |
113 colon_idx = stripped.find(":") | 119 colon_idx = stripped.find(":") |
114 if colon_idx == -1: | 120 if colon_idx == -1: |
115 raise InvalidCommandSyntax("missing colon") | 121 raise InvalidCommandSyntax("missing colon") |
116 type_data = stripped[len(CMD_KEY):colon_idx].strip() | 122 type_data = stripped[len(CMD_KEY) : colon_idx].strip() |
117 if len(type_data) == 0: | 123 if len(type_data) == 0: |
118 type_data="(all)" | 124 type_data = "(all)" |
119 elif len(type_data) <= 2 or type_data[0] != '(' or type_data[-1] != ')': | 125 elif ( |
126 len(type_data) <= 2 or type_data[0] != "(" or type_data[-1] != ")" | |
127 ): | |
120 raise InvalidCommandSyntax("Bad type data syntax") | 128 raise InvalidCommandSyntax("Bad type data syntax") |
121 type_ = type_data[1:-1] | 129 type_ = type_data[1:-1] |
122 if type_ not in CMD_TYPES: | 130 if type_ not in CMD_TYPES: |
123 raise InvalidCommandSyntax("Unknown type {}".format(type_)) | 131 raise InvalidCommandSyntax("Unknown type {}".format(type_)) |
124 data["type"] = type_ | 132 data["type"] = type_ |
125 | 133 |
126 #args | 134 # args |
127 data["args"] = stripped[colon_idx+1:].strip() | 135 data["args"] = stripped[colon_idx + 1 :].strip() |
128 except InvalidCommandSyntax as e: | 136 except InvalidCommandSyntax as e: |
129 log.warning(u"Invalid command syntax for command {command}: {message}".format(command=cmd_name, message=e.message)) | 137 log.warning( |
138 u"Invalid command syntax for command {command}: {message}".format( | |
139 command=cmd_name, message=e.message | |
140 ) | |
141 ) | |
130 | 142 |
131 return data | 143 return data |
132 | |
133 | 144 |
134 def registerTextCommands(self, instance): | 145 def registerTextCommands(self, instance): |
135 """ Add a text command | 146 """ Add a text command |
136 | 147 |
137 @param instance: instance of a class containing text commands | 148 @param instance: instance of a class containing text commands |
138 """ | 149 """ |
139 for attr in dir(instance): | 150 for attr in dir(instance): |
140 if attr.startswith('cmd_'): | 151 if attr.startswith("cmd_"): |
141 cmd = getattr(instance, attr) | 152 cmd = getattr(instance, attr) |
142 if not callable(cmd): | 153 if not callable(cmd): |
143 log.warning(_(u"Skipping not callable [%s] attribute") % attr) | 154 log.warning(_(u"Skipping not callable [%s] attribute") % attr) |
144 continue | 155 continue |
145 cmd_name = attr[4:] | 156 cmd_name = attr[4:] |
146 if not cmd_name: | 157 if not cmd_name: |
147 log.warning(_("Skipping cmd_ method")) | 158 log.warning(_("Skipping cmd_ method")) |
148 if cmd_name in self._commands: | 159 if cmd_name in self._commands: |
149 suff=2 | 160 suff = 2 |
150 while (cmd_name + str(suff)) in self._commands: | 161 while (cmd_name + str(suff)) in self._commands: |
151 suff+=1 | 162 suff += 1 |
152 new_name = cmd_name + str(suff) | 163 new_name = cmd_name + str(suff) |
153 log.warning(_(u"Conflict for command [{old_name}], renaming it to [{new_name}]").format(old_name=cmd_name, new_name=new_name)) | 164 log.warning( |
165 _( | |
166 u"Conflict for command [{old_name}], renaming it to [{new_name}]" | |
167 ).format(old_name=cmd_name, new_name=new_name) | |
168 ) | |
154 cmd_name = new_name | 169 cmd_name = new_name |
155 self._commands[cmd_name] = cmd_data = OrderedDict({'callback':cmd}) # We use an Ordered dict to keep documenation order | 170 self._commands[cmd_name] = cmd_data = OrderedDict( |
171 {"callback": cmd} | |
172 ) # We use an Ordered dict to keep documenation order | |
156 cmd_data.update(self._parseDocString(cmd, cmd_name)) | 173 cmd_data.update(self._parseDocString(cmd, cmd_name)) |
157 log.info(_("Registered text command [%s]") % cmd_name) | 174 log.info(_("Registered text command [%s]") % cmd_name) |
158 | 175 |
159 def addWhoIsCb(self, callback, priority=0): | 176 def addWhoIsCb(self, callback, priority=0): |
160 """Add a callback which give information to the /whois command | 177 """Add a callback which give information to the /whois command |
166 @param priority: priority of the information to show (the highest priority will be displayed first) | 183 @param priority: priority of the information to show (the highest priority will be displayed first) |
167 """ | 184 """ |
168 self._whois.append((priority, callback)) | 185 self._whois.append((priority, callback)) |
169 self._whois.sort(key=lambda item: item[0], reverse=True) | 186 self._whois.sort(key=lambda item: item[0], reverse=True) |
170 | 187 |
171 def sendMessageTrigger(self, client, mess_data, pre_xml_treatments, post_xml_treatments): | 188 def sendMessageTrigger( |
189 self, client, mess_data, pre_xml_treatments, post_xml_treatments | |
190 ): | |
172 """Install SendMessage command hook """ | 191 """Install SendMessage command hook """ |
173 pre_xml_treatments.addCallback(self._sendMessageCmdHook, client) | 192 pre_xml_treatments.addCallback(self._sendMessageCmdHook, client) |
174 return True | 193 return True |
175 | 194 |
176 def _sendMessageCmdHook(self, mess_data, client): | 195 def _sendMessageCmdHook(self, mess_data, client): |
183 commands can be deferred or not | 202 commands can be deferred or not |
184 @param mess_data(dict): data comming from sendMessage trigger | 203 @param mess_data(dict): data comming from sendMessage trigger |
185 @param profile: %(doc_profile)s | 204 @param profile: %(doc_profile)s |
186 """ | 205 """ |
187 try: | 206 try: |
188 msg = mess_data["message"][''] | 207 msg = mess_data["message"][""] |
189 msg_lang = '' | 208 msg_lang = "" |
190 except KeyError: | 209 except KeyError: |
191 try: | 210 try: |
192 # we have not default message, we try to take the first found | 211 # we have not default message, we try to take the first found |
193 msg_lang, msg = mess_data["message"].iteritems().next() | 212 msg_lang, msg = mess_data["message"].iteritems().next() |
194 except StopIteration: | 213 except StopIteration: |
195 log.debug(u"No message found, skipping text commands") | 214 log.debug(u"No message found, skipping text commands") |
196 return mess_data | 215 return mess_data |
197 | 216 |
198 try: | 217 try: |
199 if msg[:2] == '//': | 218 if msg[:2] == "//": |
200 # we have a double '/', it's the escape sequence | 219 # we have a double '/', it's the escape sequence |
201 mess_data["message"][msg_lang] = msg[1:] | 220 mess_data["message"][msg_lang] = msg[1:] |
202 return mess_data | 221 return mess_data |
203 if msg[0] != '/': | 222 if msg[0] != "/": |
204 return mess_data | 223 return mess_data |
205 except IndexError: | 224 except IndexError: |
206 return mess_data | 225 return mess_data |
207 | 226 |
208 # we have a command | 227 # we have a command |
209 d = None | 228 d = None |
210 command = msg[1:].partition(' ')[0].lower() | 229 command = msg[1:].partition(" ")[0].lower() |
211 if command.isalpha(): | 230 if command.isalpha(): |
212 # looks like an actual command, we try to call the corresponding method | 231 # looks like an actual command, we try to call the corresponding method |
213 def retHandling(ret): | 232 def retHandling(ret): |
214 """ Handle command return value: | 233 """ Handle command return value: |
215 if ret is True, normally send message (possibly modified by command) | 234 if ret is True, normally send message (possibly modified by command) |
227 except AttributeError: | 246 except AttributeError: |
228 msg = u"with error {}".format(failure.value) | 247 msg = u"with error {}".format(failure.value) |
229 self.feedBack(client, u"Command failed {}".format(msg), mess_data) | 248 self.feedBack(client, u"Command failed {}".format(msg), mess_data) |
230 return False | 249 return False |
231 | 250 |
232 mess_data["unparsed"] = msg[1 + len(command):] # part not yet parsed of the message | 251 mess_data["unparsed"] = msg[ |
252 1 + len(command) : | |
253 ] # part not yet parsed of the message | |
233 try: | 254 try: |
234 cmd_data = self._commands[command] | 255 cmd_data = self._commands[command] |
235 except KeyError: | 256 except KeyError: |
236 self.feedBack(client, _("Unknown command /%s. ") % command + self.HELP_SUGGESTION, mess_data) | 257 self.feedBack( |
258 client, | |
259 _("Unknown command /%s. ") % command + self.HELP_SUGGESTION, | |
260 mess_data, | |
261 ) | |
237 log.debug("text command help message") | 262 log.debug("text command help message") |
238 raise failure.Failure(exceptions.CancelError()) | 263 raise failure.Failure(exceptions.CancelError()) |
239 else: | 264 else: |
240 if not self._contextValid(mess_data, cmd_data): | 265 if not self._contextValid(mess_data, cmd_data): |
241 # The command is not launched in the right context, we throw a message with help instructions | 266 # The command is not launched in the right context, we throw a message with help instructions |
242 context_txt = _("group discussions") if cmd_data["type"] == "group" else _("one to one discussions") | 267 context_txt = ( |
243 feedback = _("/{command} command only applies in {context}.").format(command=command, context=context_txt) | 268 _("group discussions") |
244 self.feedBack(client, u"{} {}".format(feedback, self.HELP_SUGGESTION), mess_data) | 269 if cmd_data["type"] == "group" |
270 else _("one to one discussions") | |
271 ) | |
272 feedback = _("/{command} command only applies in {context}.").format( | |
273 command=command, context=context_txt | |
274 ) | |
275 self.feedBack( | |
276 client, u"{} {}".format(feedback, self.HELP_SUGGESTION), mess_data | |
277 ) | |
245 log.debug("text command invalid message") | 278 log.debug("text command invalid message") |
246 raise failure.Failure(exceptions.CancelError()) | 279 raise failure.Failure(exceptions.CancelError()) |
247 else: | 280 else: |
248 d = defer.maybeDeferred(cmd_data["callback"], client, mess_data) | 281 d = defer.maybeDeferred(cmd_data["callback"], client, mess_data) |
249 d.addErrback(genericErrback) | 282 d.addErrback(genericErrback) |
250 d.addCallback(retHandling) | 283 d.addCallback(retHandling) |
251 | 284 |
252 return d or mess_data # if a command is detected, we should have a deferred, else we send the message normally | 285 return ( |
286 d or mess_data | |
287 ) # if a command is detected, we should have a deferred, else we send the message normally | |
253 | 288 |
254 def _contextValid(self, mess_data, cmd_data): | 289 def _contextValid(self, mess_data, cmd_data): |
255 """Tell if a command can be used in the given context | 290 """Tell if a command can be used in the given context |
256 | 291 |
257 @param mess_data(dict): message data as given in sendMessage trigger | 292 @param mess_data(dict): message data as given in sendMessage trigger |
258 @param cmd_data(dict): command data as returned by self._parseDocString | 293 @param cmd_data(dict): command data as returned by self._parseDocString |
259 @return (bool): True if command can be used in this context | 294 @return (bool): True if command can be used in this context |
260 """ | 295 """ |
261 if ((cmd_data['type'] == "group" and mess_data["type"] != "groupchat") or | 296 if (cmd_data["type"] == "group" and mess_data["type"] != "groupchat") or ( |
262 (cmd_data['type'] == 'one2one' and mess_data["type"] == "groupchat")): | 297 cmd_data["type"] == "one2one" and mess_data["type"] == "groupchat" |
298 ): | |
263 return False | 299 return False |
264 return True | 300 return True |
265 | 301 |
266 def getRoomJID(self, arg, service_jid): | 302 def getRoomJID(self, arg, service_jid): |
267 """Return a room jid with a shortcut | 303 """Return a room jid with a shortcut |
268 | 304 |
269 @param arg: argument: can be a full room jid (e.g.: sat@chat.jabberfr.org) | 305 @param arg: argument: can be a full room jid (e.g.: sat@chat.jabberfr.org) |
270 or a shortcut (e.g.: sat or sat@ for sat on current service) | 306 or a shortcut (e.g.: sat or sat@ for sat on current service) |
271 @param service_jid: jid of the current service (e.g.: chat.jabberfr.org) | 307 @param service_jid: jid of the current service (e.g.: chat.jabberfr.org) |
272 """ | 308 """ |
273 nb_arobas = arg.count('@') | 309 nb_arobas = arg.count("@") |
274 if nb_arobas == 1: | 310 if nb_arobas == 1: |
275 if arg[-1] != '@': | 311 if arg[-1] != "@": |
276 return jid.JID(arg) | 312 return jid.JID(arg) |
277 return jid.JID(arg + service_jid) | 313 return jid.JID(arg + service_jid) |
278 return jid.JID(u"%s@%s" % (arg, service_jid)) | 314 return jid.JID(u"%s@%s" % (arg, service_jid)) |
279 | 315 |
280 def feedBack(self, client, message, mess_data, info_type=FEEDBACK_INFO_TYPE): | 316 def feedBack(self, client, message, mess_data, info_type=FEEDBACK_INFO_TYPE): |
281 """Give a message back to the user""" | 317 """Give a message back to the user""" |
282 if mess_data["type"] == 'groupchat': | 318 if mess_data["type"] == "groupchat": |
283 to_ = mess_data["to"].userhostJID() | 319 to_ = mess_data["to"].userhostJID() |
284 else: | 320 else: |
285 to_ = client.jid | 321 to_ = client.jid |
286 | 322 |
287 # we need to invert send message back, so sender need to original destinee | 323 # we need to invert send message back, so sender need to original destinee |
288 mess_data["from"] = mess_data["to"] | 324 mess_data["from"] = mess_data["to"] |
289 mess_data["to"] = to_ | 325 mess_data["to"] = to_ |
290 mess_data["type"] = C.MESS_TYPE_INFO | 326 mess_data["type"] = C.MESS_TYPE_INFO |
291 mess_data["message"] = {'': message} | 327 mess_data["message"] = {"": message} |
292 mess_data["extra"]["info_type"] = info_type | 328 mess_data["extra"]["info_type"] = info_type |
293 client.messageSendToBridge(mess_data) | 329 client.messageSendToBridge(mess_data) |
294 | 330 |
295 def cmd_whois(self, client, mess_data): | 331 def cmd_whois(self, client, mess_data): |
296 """show informations on entity | 332 """show informations on entity |
301 """ | 337 """ |
302 log.debug("Catched whois command") | 338 log.debug("Catched whois command") |
303 | 339 |
304 entity = mess_data["unparsed"].strip() | 340 entity = mess_data["unparsed"].strip() |
305 | 341 |
306 if mess_data['type'] == "groupchat": | 342 if mess_data["type"] == "groupchat": |
307 room = mess_data["to"].userhostJID() | 343 room = mess_data["to"].userhostJID() |
308 try: | 344 try: |
309 if self.host.plugins["XEP-0045"].isNickInRoom(client, room, entity): | 345 if self.host.plugins["XEP-0045"].isNickInRoom(client, room, entity): |
310 entity = u"%s/%s" % (room, entity) | 346 entity = u"%s/%s" % (room, entity) |
311 except KeyError: | 347 except KeyError: |
323 return False | 359 return False |
324 | 360 |
325 if not target_jid.resource: | 361 if not target_jid.resource: |
326 target_jid.resource = self.host.memory.getMainResource(client, target_jid) | 362 target_jid.resource = self.host.memory.getMainResource(client, target_jid) |
327 | 363 |
328 whois_msg = [_(u"whois for %(jid)s") % {'jid': target_jid}] | 364 whois_msg = [_(u"whois for %(jid)s") % {"jid": target_jid}] |
329 | 365 |
330 d = defer.succeed(None) | 366 d = defer.succeed(None) |
331 for ignore, callback in self._whois: | 367 for ignore, callback in self._whois: |
332 d.addCallback(lambda ignore: callback(client, whois_msg, mess_data, target_jid)) | 368 d.addCallback( |
369 lambda ignore: callback(client, whois_msg, mess_data, target_jid) | |
370 ) | |
333 | 371 |
334 def feedBack(ignore): | 372 def feedBack(ignore): |
335 self.feedBack(client, u"\n".join(whois_msg), mess_data) | 373 self.feedBack(client, u"\n".join(whois_msg), mess_data) |
336 return False | 374 return False |
337 | 375 |
346 """ | 384 """ |
347 strings = [] | 385 strings = [] |
348 for doc_name, doc_help in cmd_data.iteritems(): | 386 for doc_name, doc_help in cmd_data.iteritems(): |
349 if doc_name.startswith("doc_arg_"): | 387 if doc_name.startswith("doc_arg_"): |
350 arg_name = doc_name[8:] | 388 arg_name = doc_name[8:] |
351 strings.append(u"- {name}: {doc_help}".format(name=arg_name, doc_help=_(doc_help))) | 389 strings.append( |
390 u"- {name}: {doc_help}".format(name=arg_name, doc_help=_(doc_help)) | |
391 ) | |
352 | 392 |
353 return strings | 393 return strings |
354 | 394 |
355 def cmd_me(self, client, mess_data): | 395 def cmd_me(self, client, mess_data): |
356 """display a message at third person | 396 """display a message at third person |
374 """ | 414 """ |
375 cmd_name = mess_data["unparsed"].strip() | 415 cmd_name = mess_data["unparsed"].strip() |
376 if cmd_name and cmd_name[0] == "/": | 416 if cmd_name and cmd_name[0] == "/": |
377 cmd_name = cmd_name[1:] | 417 cmd_name = cmd_name[1:] |
378 if cmd_name and cmd_name not in self._commands: | 418 if cmd_name and cmd_name not in self._commands: |
379 self.feedBack(client, _(u"Invalid command name [{}]\n".format(cmd_name)), mess_data) | 419 self.feedBack( |
420 client, _(u"Invalid command name [{}]\n".format(cmd_name)), mess_data | |
421 ) | |
380 cmd_name = "" | 422 cmd_name = "" |
381 if not cmd_name: | 423 if not cmd_name: |
382 # we show the global help | 424 # we show the global help |
383 longuest = max([len(command) for command in self._commands]) | 425 longuest = max([len(command) for command in self._commands]) |
384 help_cmds = [] | 426 help_cmds = [] |
385 | 427 |
386 for command in sorted(self._commands): | 428 for command in sorted(self._commands): |
387 cmd_data = self._commands[command] | 429 cmd_data = self._commands[command] |
388 if not self._contextValid(mess_data, cmd_data): | 430 if not self._contextValid(mess_data, cmd_data): |
389 continue | 431 continue |
390 spaces = (longuest - len(command)) * ' ' | 432 spaces = (longuest - len(command)) * " " |
391 help_cmds.append(" /{command}: {spaces} {short_help}".format( | 433 help_cmds.append( |
392 command=command, | 434 " /{command}: {spaces} {short_help}".format( |
393 spaces=spaces, | 435 command=command, |
394 short_help=cmd_data["doc_short_help"] | 436 spaces=spaces, |
395 )) | 437 short_help=cmd_data["doc_short_help"], |
396 | 438 ) |
397 help_mess = _(u"Text commands available:\n%s") % (u'\n'.join(help_cmds), ) | 439 ) |
440 | |
441 help_mess = _(u"Text commands available:\n%s") % (u"\n".join(help_cmds),) | |
398 else: | 442 else: |
399 # we show detailled help for a command | 443 # we show detailled help for a command |
400 cmd_data = self._commands[cmd_name] | 444 cmd_data = self._commands[cmd_name] |
401 syntax = cmd_data["args"] | 445 syntax = cmd_data["args"] |
402 help_mess = _(u"/{name}: {short_help}\n{syntax}{args_help}").format( | 446 help_mess = _(u"/{name}: {short_help}\n{syntax}{args_help}").format( |
403 name=cmd_name, | 447 name=cmd_name, |
404 short_help=cmd_data['doc_short_help'], | 448 short_help=cmd_data["doc_short_help"], |
405 syntax=_(" "*4+"syntax: {}\n").format(syntax) if syntax else "", | 449 syntax=_(" " * 4 + "syntax: {}\n").format(syntax) if syntax else "", |
406 args_help=u'\n'.join([u" "*8+"{}".format(line) for line in self._getArgsHelp(cmd_data)])) | 450 args_help=u"\n".join( |
451 [u" " * 8 + "{}".format(line) for line in self._getArgsHelp(cmd_data)] | |
452 ), | |
453 ) | |
407 | 454 |
408 self.feedBack(client, help_mess, mess_data) | 455 self.feedBack(client, help_mess, mess_data) |