comparison sat_frontends/jp/cmd_message.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 0ae25883e223
children fee60f17ebac
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
35 super(Send, self).__init__(host, "send", help=_("send a message to a contact")) 35 super(Send, self).__init__(host, "send", help=_("send a message to a contact"))
36 self.need_loop=True 36 self.need_loop=True
37 37
38 def add_parser_options(self): 38 def add_parser_options(self):
39 self.parser.add_argument( 39 self.parser.add_argument(
40 "-l", "--lang", type=str, default="", help=_(u"language of the message") 40 "-l", "--lang", type=str, default="", help=_("language of the message")
41 ) 41 )
42 self.parser.add_argument( 42 self.parser.add_argument(
43 "-s", 43 "-s",
44 "--separate", 44 "--separate",
45 action="store_true", 45 action="store_true",
46 help=_( 46 help=_(
47 u"separate xmpp messages: send one message per line instead of one " 47 "separate xmpp messages: send one message per line instead of one "
48 u"message alone." 48 "message alone."
49 ), 49 ),
50 ) 50 )
51 self.parser.add_argument( 51 self.parser.add_argument(
52 "-n", 52 "-n",
53 "--new-line", 53 "--new-line",
54 action="store_true", 54 action="store_true",
55 help=_( 55 help=_(
56 u"add a new line at the beginning of the input (usefull for ascii art ;))" 56 "add a new line at the beginning of the input (usefull for ascii art ;))"
57 ), 57 ),
58 ) 58 )
59 self.parser.add_argument( 59 self.parser.add_argument(
60 "-S", 60 "-S",
61 "--subject", 61 "--subject",
62 type=base.unicode_decoder, 62 help=_("subject of the message"),
63 help=_(u"subject of the message"), 63 )
64 ) 64 self.parser.add_argument(
65 self.parser.add_argument( 65 "-L", "--subject_lang", type=str, default="", help=_("language of subject")
66 "-L", "--subject_lang", type=str, default="", help=_(u"language of subject")
67 ) 66 )
68 self.parser.add_argument( 67 self.parser.add_argument(
69 "-t", 68 "-t",
70 "--type", 69 "--type",
71 choices=C.MESS_TYPE_STANDARD + (C.MESS_TYPE_AUTO,), 70 choices=C.MESS_TYPE_STANDARD + (C.MESS_TYPE_AUTO,),
72 default=C.MESS_TYPE_AUTO, 71 default=C.MESS_TYPE_AUTO,
73 help=_("type of the message"), 72 help=_("type of the message"),
74 ) 73 )
75 self.parser.add_argument("-e", "--encrypt", metavar="ALGORITHM", 74 self.parser.add_argument("-e", "--encrypt", metavar="ALGORITHM",
76 help=_(u"encrypt message using given algorithm")) 75 help=_("encrypt message using given algorithm"))
77 self.parser.add_argument( 76 self.parser.add_argument(
78 "--encrypt-noreplace", 77 "--encrypt-noreplace",
79 action="store_true", 78 action="store_true",
80 help=_(u"don't replace encryption algorithm if an other one is already used")) 79 help=_("don't replace encryption algorithm if an other one is already used"))
81 syntax = self.parser.add_mutually_exclusive_group() 80 syntax = self.parser.add_mutually_exclusive_group()
82 syntax.add_argument("-x", "--xhtml", action="store_true", help=_(u"XHTML body")) 81 syntax.add_argument("-x", "--xhtml", action="store_true", help=_("XHTML body"))
83 syntax.add_argument("-r", "--rich", action="store_true", help=_(u"rich body")) 82 syntax.add_argument("-r", "--rich", action="store_true", help=_("rich body"))
84 self.parser.add_argument( 83 self.parser.add_argument(
85 "jid", type=base.unicode_decoder, help=_(u"the destination jid") 84 "jid", help=_("the destination jid")
86 ) 85 )
87 86
88 def multi_send_cb(self): 87 def multi_send_cb(self):
89 self.sent += 1 88 self.sent += 1
90 if self.sent == self.to_send: 89 if self.sent == self.to_send:
91 self.host.quit(self.errcode) 90 self.host.quit(self.errcode)
92 91
93 def multi_send_eb(self, failure_, msg): 92 def multi_send_eb(self, failure_, msg):
94 self.disp(_(u"Can't send message [{msg}]: {reason}").format( 93 self.disp(_("Can't send message [{msg}]: {reason}").format(
95 msg=msg, reason=failure_)) 94 msg=msg, reason=failure_))
96 self.errcode = C.EXIT_BRIDGE_ERRBACK 95 self.errcode = C.EXIT_BRIDGE_ERRBACK
97 self.multi_send_cb() 96 self.multi_send_cb()
98 97
99 def sendStdin(self, dest_jid): 98 def sendStdin(self, dest_jid):
110 subject = {} 109 subject = {}
111 else: 110 else:
112 subject = {self.args.subject_lang: self.args.subject} 111 subject = {self.args.subject_lang: self.args.subject}
113 112
114 if self.args.xhtml or self.args.rich: 113 if self.args.xhtml or self.args.rich:
115 key = u"xhtml" if self.args.xhtml else u"rich" 114 key = "xhtml" if self.args.xhtml else "rich"
116 if self.args.lang: 115 if self.args.lang:
117 key = u"{}_{}".format(key, self.args.lang) 116 key = "{}_{}".format(key, self.args.lang)
118 extra[key] = clean_ustr(u"".join(stdin_lines)) 117 extra[key] = clean_ustr("".join(stdin_lines))
119 stdin_lines = [] 118 stdin_lines = []
120 119
121 if self.args.separate: # we send stdin in several messages 120 if self.args.separate: # we send stdin in several messages
122 self.to_send = 0 121 self.to_send = 0
123 self.sent = 0 122 self.sent = 0
148 errback=partial(self.multi_send_eb, msg=line), 147 errback=partial(self.multi_send_eb, msg=line),
149 ) 148 )
150 149
151 else: 150 else:
152 msg = ( 151 msg = (
153 {self.args.lang: header + clean_ustr(u"".join(stdin_lines))} 152 {self.args.lang: header + clean_ustr("".join(stdin_lines))}
154 if not (self.args.xhtml or self.args.rich) 153 if not (self.args.xhtml or self.args.rich)
155 else {} 154 else {}
156 ) 155 )
157 self.host.bridge.messageSend( 156 self.host.bridge.messageSend(
158 dest_jid, 157 dest_jid,
161 self.args.type, 160 self.args.type,
162 extra, 161 extra,
163 profile_key=self.host.profile, 162 profile_key=self.host.profile,
164 callback=self.host.quit, 163 callback=self.host.quit,
165 errback=partial(self.errback, 164 errback=partial(self.errback,
166 msg=_(u"Can't send message: {}"))) 165 msg=_("Can't send message: {}")))
167 166
168 def encryptionNamespaceGetCb(self, namespace, jid_): 167 def encryptionNamespaceGetCb(self, namespace, jid_):
169 self.host.bridge.messageEncryptionStart( 168 self.host.bridge.messageEncryptionStart(
170 jid_, namespace, not self.args.encrypt_noreplace, 169 jid_, namespace, not self.args.encrypt_noreplace,
171 self.profile, 170 self.profile,
172 callback=lambda: self.sendStdin(jid_), 171 callback=lambda: self.sendStdin(jid_),
173 errback=partial(self.errback, 172 errback=partial(self.errback,
174 msg=_(u"Can't start encryption session: {}"), 173 msg=_("Can't start encryption session: {}"),
175 exit_code=C.EXIT_BRIDGE_ERRBACK, 174 exit_code=C.EXIT_BRIDGE_ERRBACK,
176 )) 175 ))
177 176
178 177
179 def start(self): 178 def start(self):
180 if self.args.xhtml and self.args.separate: 179 if self.args.xhtml and self.args.separate:
181 self.disp( 180 self.disp(
182 u"argument -s/--separate is not compatible yet with argument -x/--xhtml", 181 "argument -s/--separate is not compatible yet with argument -x/--xhtml",
183 error=True, 182 error=True,
184 ) 183 )
185 self.host.quit(2) 184 self.host.quit(2)
186 185
187 jids = self.host.check_jids([self.args.jid]) 186 jids = self.host.check_jids([self.args.jid])
192 191
193 if self.args.encrypt is not None: 192 if self.args.encrypt is not None:
194 self.host.bridge.encryptionNamespaceGet(self.args.encrypt, 193 self.host.bridge.encryptionNamespaceGet(self.args.encrypt,
195 callback=partial(self.encryptionNamespaceGetCb, jid_=jid_), 194 callback=partial(self.encryptionNamespaceGetCb, jid_=jid_),
196 errback=partial(self.errback, 195 errback=partial(self.errback,
197 msg=_(u"Can't get encryption namespace: {}"), 196 msg=_("Can't get encryption namespace: {}"),
198 exit_code=C.EXIT_BRIDGE_ERRBACK, 197 exit_code=C.EXIT_BRIDGE_ERRBACK,
199 )) 198 ))
200 else: 199 else:
201 self.sendStdin(jid_) 200 self.sendStdin(jid_)
202 201
203 202
204 class MAM(base.CommandBase): 203 class MAM(base.CommandBase):
205 204
206 def __init__(self, host): 205 def __init__(self, host):
207 super(MAM, self).__init__( 206 super(MAM, self).__init__(
208 host, "mam", use_output=C.OUTPUT_MESS, use_verbose=True, help=_(u"query archives using MAM")) 207 host, "mam", use_output=C.OUTPUT_MESS, use_verbose=True, help=_("query archives using MAM"))
209 self.need_loop=True 208 self.need_loop=True
210 209
211 def add_parser_options(self): 210 def add_parser_options(self):
212 self.parser.add_argument( 211 self.parser.add_argument(
213 "-s", "--service", type=base.unicode_decoder, default=u"", 212 "-s", "--service", default="",
214 help=_(u"jid of the service (default: profile's server")) 213 help=_("jid of the service (default: profile's server"))
215 self.parser.add_argument( 214 self.parser.add_argument(
216 "-S", "--start", dest="mam_start", type=base.date_decoder, 215 "-S", "--start", dest="mam_start", type=base.date_decoder,
217 help=_( 216 help=_(
218 u"start fetching archive from this date (default: from the beginning)")) 217 "start fetching archive from this date (default: from the beginning)"))
219 self.parser.add_argument( 218 self.parser.add_argument(
220 "-E", "--end", dest="mam_end", type=base.date_decoder, 219 "-E", "--end", dest="mam_end", type=base.date_decoder,
221 help=_(u"end fetching archive after this date (default: no limit)")) 220 help=_("end fetching archive after this date (default: no limit)"))
222 self.parser.add_argument( 221 self.parser.add_argument(
223 "-W", "--with", dest="mam_with", type=base.unicode_decoder, 222 "-W", "--with", dest="mam_with",
224 help=_(u"retrieve only archives with this jid")) 223 help=_("retrieve only archives with this jid"))
225 self.parser.add_argument( 224 self.parser.add_argument(
226 "-m", "--max", dest="rsm_max", type=int, default=20, 225 "-m", "--max", dest="rsm_max", type=int, default=20,
227 help=_(u"maximum number of items to retrieve, using RSM (default: 20))")) 226 help=_("maximum number of items to retrieve, using RSM (default: 20))"))
228 rsm_page_group = self.parser.add_mutually_exclusive_group() 227 rsm_page_group = self.parser.add_mutually_exclusive_group()
229 rsm_page_group.add_argument( 228 rsm_page_group.add_argument(
230 "-a", "--after", dest="rsm_after", type=base.unicode_decoder, 229 "-a", "--after", dest="rsm_after",
231 help=_(u"find page after this item"), metavar='ITEM_ID') 230 help=_("find page after this item"), metavar='ITEM_ID')
232 rsm_page_group.add_argument( 231 rsm_page_group.add_argument(
233 "-b", "--before", dest="rsm_before", type=base.unicode_decoder, 232 "-b", "--before", dest="rsm_before",
234 help=_(u"find page before this item"), metavar='ITEM_ID') 233 help=_("find page before this item"), metavar='ITEM_ID')
235 rsm_page_group.add_argument( 234 rsm_page_group.add_argument(
236 "--index", dest="rsm_index", type=int, 235 "--index", dest="rsm_index", type=int,
237 help=_(u"index of the page to retrieve")) 236 help=_("index of the page to retrieve"))
238 237
239 def _sessionInfosGetCb(self, session_info, data, metadata): 238 def _sessionInfosGetCb(self, session_info, data, metadata):
240 self.host.own_jid = jid.JID(session_info[u"jid"]) 239 self.host.own_jid = jid.JID(session_info["jid"])
241 self.output(data) 240 self.output(data)
242 # FIXME: metadata are not displayed correctly and don't play nice with output 241 # FIXME: metadata are not displayed correctly and don't play nice with output
243 # they should be added to output data somehow 242 # they should be added to output data somehow
244 if self.verbosity: 243 if self.verbosity:
245 for value in (u"rsm_first", u"rsm_last", u"rsm_index", u"rsm_count", 244 for value in ("rsm_first", "rsm_last", "rsm_index", "rsm_count",
246 u"mam_complete", u"mam_stable"): 245 "mam_complete", "mam_stable"):
247 if value in metadata: 246 if value in metadata:
248 label = value.split(u"_")[1] 247 label = value.split("_")[1]
249 self.disp(A.color( 248 self.disp(A.color(
250 C.A_HEADER, label, u': ' , A.RESET, metadata[value])) 249 C.A_HEADER, label, ': ' , A.RESET, metadata[value]))
251 250
252 self.host.quit() 251 self.host.quit()
253 252
254 def _MAMGetCb(self, result): 253 def _MAMGetCb(self, result):
255 data, metadata, profile = result 254 data, metadata, profile = result
258 errback=self.errback) 257 errback=self.errback)
259 258
260 def start(self): 259 def start(self):
261 extra = {} 260 extra = {}
262 if self.args.mam_start is not None: 261 if self.args.mam_start is not None:
263 extra[u"mam_start"] = float(self.args.mam_start) 262 extra["mam_start"] = float(self.args.mam_start)
264 if self.args.mam_end is not None: 263 if self.args.mam_end is not None:
265 extra[u"mam_end"] = float(self.args.mam_end) 264 extra["mam_end"] = float(self.args.mam_end)
266 if self.args.mam_with is not None: 265 if self.args.mam_with is not None:
267 extra[u"mam_with"] = self.args.mam_with 266 extra["mam_with"] = self.args.mam_with
268 for suff in ('max', 'after', 'before', 'index'): 267 for suff in ('max', 'after', 'before', 'index'):
269 key = u'rsm_' + suff 268 key = 'rsm_' + suff
270 value = getattr(self.args,key) 269 value = getattr(self.args,key)
271 if value is not None: 270 if value is not None:
272 extra[key] = unicode(value) 271 extra[key] = str(value)
273 self.host.bridge.MAMGet( 272 self.host.bridge.MAMGet(
274 self.args.service, data_format.serialise(extra), self.profile, 273 self.args.service, data_format.serialise(extra), self.profile,
275 callback=self._MAMGetCb, errback=self.errback) 274 callback=self._MAMGetCb, errback=self.errback)
276 275
277 276