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
This commit is contained in:
parent
d21a6a660f
commit
fbfe96c505
1 changed files with 6336 additions and 6398 deletions
|
|
@ -40,12 +40,12 @@ import time
|
|||
|
||||
try:
|
||||
# FIXME: to be removed when an acceptable solution is here
|
||||
unicode("") # XXX: unicode doesn't exist in pyjamas
|
||||
str("") # XXX: unicode doesn't exist in pyjamas
|
||||
except (
|
||||
TypeError,
|
||||
AttributeError,
|
||||
): # Error raised is not the same depending on pyjsbuild options
|
||||
unicode = str
|
||||
str = str
|
||||
|
||||
|
||||
class ProfileManager(object):
|
||||
|
|
@ -139,7 +139,7 @@ class ProfileManager(object):
|
|||
)
|
||||
|
||||
def _plug_profile_getFeaturesEb(self, failure):
|
||||
log.error(u"Couldn't get features: {}".format(failure))
|
||||
log.error("Couldn't get features: {}".format(failure))
|
||||
self._plug_profile_getFeaturesCb({})
|
||||
|
||||
def _plug_profile_getFeaturesCb(self, features):
|
||||
|
|
@ -154,14 +154,14 @@ class ProfileManager(object):
|
|||
self._plug_profile_gotCachedValues({})
|
||||
|
||||
def _plug_profile_failedCachedValues(self, failure):
|
||||
log.error(u"Couldn't get cached values: {}".format(failure))
|
||||
log.error("Couldn't get cached values: {}".format(failure))
|
||||
self._plug_profile_gotCachedValues({})
|
||||
|
||||
def _plug_profile_gotCachedValues(self, cached_values):
|
||||
contact_list = self.host.contact_lists[self.profile]
|
||||
# add the contact list and its listener
|
||||
for entity_s, data in cached_values.iteritems():
|
||||
for key, value in data.iteritems():
|
||||
for entity_s, data in cached_values.items():
|
||||
for key, value in data.items():
|
||||
self.host.entityDataUpdatedHandler(entity_s, key, value, self.profile)
|
||||
|
||||
if not self.connected:
|
||||
|
|
@ -203,7 +203,7 @@ class ProfileManager(object):
|
|||
|
||||
for contact in presences:
|
||||
for res in presences[contact]:
|
||||
jabber_id = (u"%s/%s" % (jid.JID(contact).bare, res)) if res else contact
|
||||
jabber_id = ("%s/%s" % (jid.JID(contact).bare, res)) if res else contact
|
||||
show = presences[contact][res][0]
|
||||
priority = presences[contact][res][1]
|
||||
statuses = presences[contact][res][2]
|
||||
|
|
@ -216,7 +216,7 @@ class ProfileManager(object):
|
|||
self.profile,
|
||||
callback=lambda data, contact=contact: gotEntityData(data, contact),
|
||||
errback=lambda failure, contact=contact: log.debug(
|
||||
u"No cache data for {}".format(contact)
|
||||
"No cache data for {}".format(contact)
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ class ProfilesManager(object):
|
|||
return profile in self._profiles
|
||||
|
||||
def __iter__(self):
|
||||
return self._profiles.iterkeys()
|
||||
return iter(self._profiles.keys())
|
||||
|
||||
def __getitem__(self, profile):
|
||||
return self._profiles[profile]
|
||||
|
|
@ -246,11 +246,11 @@ class ProfilesManager(object):
|
|||
def __len__(self):
|
||||
return len(self._profiles)
|
||||
|
||||
def iteritems(self):
|
||||
return self._profiles.iteritems()
|
||||
def items(self):
|
||||
return self._profiles.items()
|
||||
|
||||
def itervalues(self):
|
||||
return self._profiles.itervalues()
|
||||
def values(self):
|
||||
return self._profiles.values()
|
||||
|
||||
def plug(self, profile):
|
||||
if profile in self._profiles:
|
||||
|
|
@ -271,7 +271,7 @@ class ProfilesManager(object):
|
|||
del self._profiles[profile]
|
||||
|
||||
def chooseOneProfile(self):
|
||||
return self._profiles.keys()[0]
|
||||
return list(self._profiles.keys())[0]
|
||||
|
||||
|
||||
class QuickApp(object):
|
||||
|
|
@ -350,13 +350,13 @@ class QuickApp(object):
|
|||
self.ns_map = ns_map
|
||||
|
||||
def _namespacesGetEb(self, failure_):
|
||||
log.error(_(u"Can't get namespaces map: {msg}").format(msg=failure_))
|
||||
log.error(_("Can't get namespaces map: {msg}").format(msg=failure_))
|
||||
|
||||
def _encryptionPluginsGetCb(self, plugins):
|
||||
self.encryption_plugins = plugins
|
||||
|
||||
def _encryptionPluginsGetEb(self, failure_):
|
||||
log.warning(_(u"Can't retrieve encryption plugins: {msg}").format(msg=failure_))
|
||||
log.warning(_("Can't retrieve encryption plugins: {msg}").format(msg=failure_))
|
||||
|
||||
def onBridgeConnected(self):
|
||||
self.bridge.namespacesGet(
|
||||
|
|
@ -402,13 +402,13 @@ class QuickApp(object):
|
|||
|
||||
def _bridgeEb(self, failure):
|
||||
if isinstance(failure, exceptions.BridgeExceptionNoService):
|
||||
print(_(u"Can't connect to SàT backend, are you sure it's launched ?"))
|
||||
print((_("Can't connect to SàT backend, are you sure it's launched ?")))
|
||||
sys.exit(1)
|
||||
elif isinstance(failure, exceptions.BridgeInitError):
|
||||
print(_(u"Can't init bridge"))
|
||||
print((_("Can't init bridge")))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print(_(u"Error while initialising bridge: {}".format(failure)))
|
||||
print((_("Error while initialising bridge: {}".format(failure))))
|
||||
|
||||
@property
|
||||
def current_profile(self):
|
||||
|
|
@ -459,10 +459,10 @@ class QuickApp(object):
|
|||
or if connection has been lost and a reconnection is needed
|
||||
"""
|
||||
if state:
|
||||
log.debug(u"we are synchronised with server")
|
||||
log.debug("we are synchronised with server")
|
||||
if self.AUTO_RESYNC:
|
||||
# we are resynchronising all widgets
|
||||
log.debug(u"doing a full widgets resynchronisation")
|
||||
log.debug("doing a full widgets resynchronisation")
|
||||
for w in self.widgets:
|
||||
try:
|
||||
resync = w.resync
|
||||
|
|
@ -474,7 +474,7 @@ class QuickApp(object):
|
|||
|
||||
self._sync = state
|
||||
else:
|
||||
log.debug(u"we have lost synchronisation with server")
|
||||
log.debug("we have lost synchronisation with server")
|
||||
self._sync = state
|
||||
# we've lost synchronisation, all widgets must be notified
|
||||
# note: this is always called independently of AUTO_RESYNC
|
||||
|
|
@ -496,7 +496,7 @@ class QuickApp(object):
|
|||
@param with_profile (boolean): True if the signal concerns a specific profile,
|
||||
in that case the profile name has to be passed by the caller
|
||||
"""
|
||||
log.debug(u"registering signal {name}".format(name=function_name))
|
||||
log.debug("registering signal {name}".format(name=function_name))
|
||||
if handler is None:
|
||||
handler = getattr(self, "{}{}".format(function_name, "Handler"))
|
||||
if not with_profile:
|
||||
|
|
@ -582,7 +582,7 @@ class QuickApp(object):
|
|||
pass
|
||||
else:
|
||||
profile = kwargs.get("profile")
|
||||
for listener, profiles_filter in listeners.iteritems():
|
||||
for listener, profiles_filter in listeners.items():
|
||||
if profile is None or not profiles_filter or profile in profiles_filter:
|
||||
listener(*args, **kwargs)
|
||||
|
||||
|
|
@ -617,7 +617,7 @@ class QuickApp(object):
|
|||
cached_signals = self.signals_cache.pop(profile, [])
|
||||
for function_name, handler, args, kwargs in cached_signals:
|
||||
log.debug(
|
||||
u"Calling cached signal [%s] with args %s and kwargs %s"
|
||||
"Calling cached signal [%s] with args %s and kwargs %s"
|
||||
% (function_name, args, kwargs)
|
||||
)
|
||||
handler(*args, **kwargs)
|
||||
|
|
@ -632,7 +632,7 @@ class QuickApp(object):
|
|||
if not errback:
|
||||
|
||||
def errback(failure):
|
||||
log.error(_(u"Can't connect profile [%s]") % failure)
|
||||
log.error(_("Can't connect profile [%s]") % failure)
|
||||
try:
|
||||
module = failure.module
|
||||
except AttributeError:
|
||||
|
|
@ -790,8 +790,8 @@ class QuickApp(object):
|
|||
widget.onMessageState(uid, status, profile)
|
||||
|
||||
def messageSend(self, to_jid, message, subject=None, mess_type="auto", extra=None, callback=None, errback=None, profile_key=C.PROF_KEY_NONE):
|
||||
if not subject and not extra and (not message or message == {u'': u''}):
|
||||
log.debug(u"Not sending empty message")
|
||||
if not subject and not extra and (not message or message == {'': ''}):
|
||||
log.debug("Not sending empty message")
|
||||
return
|
||||
|
||||
if subject is None:
|
||||
|
|
@ -812,7 +812,7 @@ class QuickApp(object):
|
|||
return
|
||||
|
||||
self.bridge.messageSend(
|
||||
unicode(to_jid),
|
||||
str(to_jid),
|
||||
message,
|
||||
subject,
|
||||
mess_type,
|
||||
|
|
@ -857,8 +857,8 @@ class QuickApp(object):
|
|||
def mucRoomJoinedHandler(self, room_jid_s, occupants, user_nick, subject, profile):
|
||||
"""Called when a MUC room is joined"""
|
||||
log.debug(
|
||||
u"Room [{room_jid}] joined by {profile}, users presents:{users}".format(
|
||||
room_jid=room_jid_s, profile=profile, users=occupants.keys()
|
||||
"Room [{room_jid}] joined by {profile}, users presents:{users}".format(
|
||||
room_jid=room_jid_s, profile=profile, users=list(occupants.keys())
|
||||
)
|
||||
)
|
||||
room_jid = jid.JID(room_jid_s)
|
||||
|
|
@ -876,7 +876,7 @@ class QuickApp(object):
|
|||
def mucRoomLeftHandler(self, room_jid_s, profile):
|
||||
"""Called when a MUC room is left"""
|
||||
log.debug(
|
||||
u"Room [%(room_jid)s] left by %(profile)s"
|
||||
"Room [%(room_jid)s] left by %(profile)s"
|
||||
% {"room_jid": room_jid_s, "profile": profile}
|
||||
)
|
||||
room_jid = jid.JID(room_jid_s)
|
||||
|
|
@ -893,7 +893,7 @@ class QuickApp(object):
|
|||
)
|
||||
chat_widget.changeUserNick(old_nick, new_nick)
|
||||
log.debug(
|
||||
u"user [%(old_nick)s] is now known as [%(new_nick)s] in room [%(room_jid)s]"
|
||||
"user [%(old_nick)s] is now known as [%(new_nick)s] in room [%(room_jid)s]"
|
||||
% {"old_nick": old_nick, "new_nick": new_nick, "room_jid": room_jid}
|
||||
)
|
||||
|
||||
|
|
@ -905,7 +905,7 @@ class QuickApp(object):
|
|||
)
|
||||
chat_widget.setSubject(subject)
|
||||
log.debug(
|
||||
u"new subject for room [%(room_jid)s]: %(subject)s"
|
||||
"new subject for room [%(room_jid)s]: %(subject)s"
|
||||
% {"room_jid": room_jid, "subject": subject}
|
||||
)
|
||||
|
||||
|
|
@ -974,7 +974,7 @@ class QuickApp(object):
|
|||
main_notif_dict = self.profiles[profile].notifications
|
||||
|
||||
if entity is C.ENTITY_ALL:
|
||||
selected_notifs = main_notif_dict.itervalues()
|
||||
selected_notifs = iter(main_notif_dict.values())
|
||||
exact_jid = False
|
||||
else:
|
||||
if entity is None:
|
||||
|
|
@ -989,7 +989,7 @@ class QuickApp(object):
|
|||
for notifs_from_select in selected_notifs:
|
||||
|
||||
if type_ is None:
|
||||
type_notifs = notifs_from_select.itervalues()
|
||||
type_notifs = iter(notifs_from_select.values())
|
||||
else:
|
||||
type_notifs = (notifs_from_select.get(type_, []),)
|
||||
|
||||
|
|
@ -1080,10 +1080,10 @@ class QuickApp(object):
|
|||
callbacks.append((callback, errback))
|
||||
|
||||
def progressStartedHandler(self, pid, metadata, profile):
|
||||
log.info(u"Progress {} started".format(pid))
|
||||
log.info("Progress {} started".format(pid))
|
||||
|
||||
def progressFinishedHandler(self, pid, metadata, profile):
|
||||
log.info(u"Progress {} finished".format(pid))
|
||||
log.info("Progress {} finished".format(pid))
|
||||
try:
|
||||
callbacks = self._progress_ids.pop(pid)
|
||||
except KeyError:
|
||||
|
|
@ -1095,7 +1095,7 @@ class QuickApp(object):
|
|||
self.callListeners("progressFinished", pid, metadata, profile=profile)
|
||||
|
||||
def progressErrorHandler(self, pid, err_msg, profile):
|
||||
log.warning(u"Progress {pid} error: {err_msg}".format(pid=pid, err_msg=err_msg))
|
||||
log.warning("Progress {pid} error: {err_msg}".format(pid=pid, err_msg=err_msg))
|
||||
try:
|
||||
callbacks = self._progress_ids.pop(pid)
|
||||
except KeyError:
|
||||
|
|
@ -1109,7 +1109,7 @@ class QuickApp(object):
|
|||
def _subscribe_cb(self, answer, data):
|
||||
entity, profile = data
|
||||
type_ = "subscribed" if answer else "unsubscribed"
|
||||
self.bridge.subscription(type_, unicode(entity.bare), profile_key=profile)
|
||||
self.bridge.subscription(type_, str(entity.bare), profile_key=profile)
|
||||
|
||||
def subscribeHandler(self, type, raw_jid, profile):
|
||||
"""Called when a subsciption management signal is received"""
|
||||
|
|
@ -1118,18 +1118,18 @@ class QuickApp(object):
|
|||
# this is a subscription confirmation, we just have to inform user
|
||||
# TODO: call self.getEntityMBlog to add the new contact blogs
|
||||
self.showDialog(
|
||||
_(u"The contact {contact} has accepted your subscription").format(
|
||||
_("The contact {contact} has accepted your subscription").format(
|
||||
contact=entity.bare
|
||||
),
|
||||
_(u"Subscription confirmation"),
|
||||
_("Subscription confirmation"),
|
||||
)
|
||||
elif type == "unsubscribed":
|
||||
# this is a subscription refusal, we just have to inform user
|
||||
self.showDialog(
|
||||
_(u"The contact {contact} has refused your subscription").format(
|
||||
_("The contact {contact} has refused your subscription").format(
|
||||
contact=entity.bare
|
||||
),
|
||||
_(u"Subscription refusal"),
|
||||
_("Subscription refusal"),
|
||||
"error",
|
||||
)
|
||||
elif type == "subscribe":
|
||||
|
|
@ -1137,8 +1137,8 @@ class QuickApp(object):
|
|||
# TODO: use sat.stdui.ui_contact_list to display the groups selector
|
||||
self.showDialog(
|
||||
_(
|
||||
u"The contact {contact} wants to subscribe to your presence"
|
||||
u".\nDo you accept ?"
|
||||
"The contact {contact} wants to subscribe to your presence"
|
||||
".\nDo you accept ?"
|
||||
).format(contact=entity.bare),
|
||||
_("Subscription confirmation"),
|
||||
"yes/no",
|
||||
|
|
@ -1147,11 +1147,11 @@ class QuickApp(object):
|
|||
)
|
||||
|
||||
def _debugHandler(self, action, parameters, profile):
|
||||
if action == u"widgets_dump":
|
||||
if action == "widgets_dump":
|
||||
from pprint import pformat
|
||||
log.info(u"Widgets dump:\n{data}".format(data=pformat(self.widgets._widgets)))
|
||||
log.info("Widgets dump:\n{data}".format(data=pformat(self.widgets._widgets)))
|
||||
else:
|
||||
log.warning(u"Unknown debug action: {action}".format(action=action))
|
||||
log.warning("Unknown debug action: {action}".format(action=action))
|
||||
|
||||
|
||||
def showDialog(self, message, title, type="info", answer_cb=None, answer_data=None):
|
||||
|
|
@ -1178,11 +1178,11 @@ class QuickApp(object):
|
|||
pass # FIXME
|
||||
|
||||
def dialogFailure(self, failure):
|
||||
log.warning(u"Failure: {}".format(failure))
|
||||
log.warning("Failure: {}".format(failure))
|
||||
|
||||
def progressIdHandler(self, progress_id, profile):
|
||||
"""Callback used when an action result in a progress id"""
|
||||
log.info(u"Progress ID received: {}".format(progress_id))
|
||||
log.info("Progress ID received: {}".format(progress_id))
|
||||
|
||||
def isHidden(self):
|
||||
"""Tells if the frontend window is hidden.
|
||||
|
|
@ -1193,11 +1193,11 @@ class QuickApp(object):
|
|||
|
||||
def paramUpdateHandler(self, name, value, namespace, profile):
|
||||
log.debug(
|
||||
_(u"param update: [%(namespace)s] %(name)s = %(value)s")
|
||||
_("param update: [%(namespace)s] %(name)s = %(value)s")
|
||||
% {"namespace": namespace, "name": name, "value": value}
|
||||
)
|
||||
if (namespace, name) == ("Connection", "JabberID"):
|
||||
log.debug(_(u"Changing JID to %s") % value)
|
||||
log.debug(_("Changing JID to %s") % value)
|
||||
self.profiles[profile].whoami = jid.JID(value)
|
||||
elif (namespace, name) == ("General", C.SHOW_OFFLINE_CONTACTS):
|
||||
self.contact_lists[profile].showOfflineContacts(C.bool(value))
|
||||
|
|
@ -1264,13 +1264,13 @@ class QuickApp(object):
|
|||
|
||||
# we ignore metadata
|
||||
action_data = {
|
||||
k: v for k, v in action_data.iteritems() if not k.startswith("meta_")
|
||||
k: v for k, v in action_data.items() if not k.startswith("meta_")
|
||||
}
|
||||
|
||||
if action_data:
|
||||
raise exceptions.DataError(
|
||||
u"Not all keys in action_data are managed ({keys})".format(
|
||||
keys=", ".join(action_data.keys())
|
||||
"Not all keys in action_data are managed ({keys})".format(
|
||||
keys=", ".join(list(action_data.keys()))
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -1348,10 +1348,10 @@ class QuickApp(object):
|
|||
|
||||
def _avatarGetEb(self, failure_, entity, contact_list):
|
||||
# FIXME: bridge needs a proper error handling
|
||||
if "NotFound" in unicode(failure_):
|
||||
log.info(u"No avatar found for {entity}".format(entity=entity))
|
||||
if "NotFound" in str(failure_):
|
||||
log.info("No avatar found for {entity}".format(entity=entity))
|
||||
else:
|
||||
log.warning(u"Can't get avatar: {}".format(failure_))
|
||||
log.warning("Can't get avatar: {}".format(failure_))
|
||||
contact_list.setCache(entity, "avatar", self.getDefaultAvatar(entity))
|
||||
|
||||
def getAvatar(
|
||||
|
|
@ -1383,7 +1383,7 @@ class QuickApp(object):
|
|||
avatar = None
|
||||
if avatar is None:
|
||||
self.bridge.avatarGet(
|
||||
unicode(entity),
|
||||
str(entity),
|
||||
cache_only,
|
||||
hash_only,
|
||||
profile=profile,
|
||||
|
|
@ -1413,7 +1413,7 @@ class QuickApp(object):
|
|||
def onExit(self):
|
||||
"""Must be called when the frontend is terminating"""
|
||||
to_unplug = []
|
||||
for profile, profile_manager in self.profiles.iteritems():
|
||||
for profile, profile_manager in self.profiles.items():
|
||||
if profile_manager.connected and profile_manager.autodisconnect:
|
||||
# The user wants autodisconnection
|
||||
self.disconnect(profile)
|
||||
|
|
|
|||
Loading…
Reference in a new issue