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:
Goffi 2019-08-13 19:08:41 +02:00
commit fbfe96c505

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SAT plugin for adding D-Bus to Ad-Hoc Commands
@ -30,8 +30,8 @@ try:
from lxml import etree
except ImportError:
etree = None
log.warning(u"Missing module lxml, please download/install it from http://lxml.de/ ."
u"Auto D-Bus discovery will be disabled")
log.warning("Missing module lxml, please download/install it from http://lxml.de/ ."
"Auto D-Bus discovery will be disabled")
from collections import OrderedDict
import os.path
import uuid
@ -40,8 +40,8 @@ try:
from dbus.mainloop.glib import DBusGMainLoop
except ImportError:
dbus = None
log.warning(u"Missing module dbus, please download/install it"
u"auto D-Bus discovery will be disabled")
log.warning("Missing module dbus, please download/install it"
"auto D-Bus discovery will be disabled")
else:
DBusGMainLoop(set_as_default=True)
@ -50,18 +50,18 @@ NS_MEDIA_PLAYER = "org.salutatoi.mediaplayer"
FD_NAME = "org.freedesktop.DBus"
FD_PATH = "/org/freedekstop/DBus"
INTROSPECT_IFACE = "org.freedesktop.DBus.Introspectable"
MPRIS_PREFIX = u"org.mpris.MediaPlayer2"
CMD_GO_BACK = u"GoBack"
CMD_GO_FWD = u"GoFW"
MPRIS_PREFIX = "org.mpris.MediaPlayer2"
CMD_GO_BACK = "GoBack"
CMD_GO_FWD = "GoFW"
SEEK_OFFSET = 5 * 1000 * 1000
MPRIS_COMMANDS = [u"org.mpris.MediaPlayer2.Player." + cmd for cmd in (
u"Previous", CMD_GO_BACK, u"PlayPause", CMD_GO_FWD, u"Next")]
MPRIS_PATH = u"/org/mpris/MediaPlayer2"
MPRIS_COMMANDS = ["org.mpris.MediaPlayer2.Player." + cmd for cmd in (
"Previous", CMD_GO_BACK, "PlayPause", CMD_GO_FWD, "Next")]
MPRIS_PATH = "/org/mpris/MediaPlayer2"
MPRIS_PROPERTIES = OrderedDict((
(u"org.mpris.MediaPlayer2", (
("org.mpris.MediaPlayer2", (
"Identity",
)),
(u"org.mpris.MediaPlayer2.Player", (
("org.mpris.MediaPlayer2.Player", (
"Metadata",
"PlaybackStatus",
"Volume",
@ -69,7 +69,7 @@ MPRIS_PROPERTIES = OrderedDict((
))
MPRIS_METADATA_KEY = "Metadata"
MPRIS_METADATA_MAP = OrderedDict((
("xesam:title", u"Title"),
("xesam:title", "Title"),
))
INTROSPECT_METHOD = "Introspect"
@ -88,7 +88,7 @@ PLUGIN_INFO = {
C.PI_DEPENDENCIES: ["XEP-0050"],
C.PI_MAIN: "AdHocDBus",
C.PI_HANDLER: "no",
C.PI_DESCRIPTION: _(u"""Add D-Bus management to Ad-Hoc commands"""),
C.PI_DESCRIPTION: _("""Add D-Bus management to Ad-Hoc commands"""),
}
@ -104,7 +104,7 @@ class AdHocDBus(object):
in_sign="sasasasasasass",
out_sign="(sa(sss))",
method=self._adHocDBusAddAuto,
async=True,
async_=True,
)
host.bridge.addMethod(
"adHocRemotesGet",
@ -112,10 +112,10 @@ class AdHocDBus(object):
in_sign="s",
out_sign="a(sss)",
method=self._adHocRemotesGet,
async=True,
async_=True,
)
self._c = host.plugins["XEP-0050"]
host.registerNamespace(u"mediaplayer", NS_MEDIA_PLAYER)
host.registerNamespace("mediaplayer", NS_MEDIA_PLAYER)
if dbus is not None:
self.session_bus = dbus.SessionBus()
self.fd_object = self.session_bus.get_object(
@ -124,7 +124,7 @@ class AdHocDBus(object):
def profileConnected(self, client):
if dbus is not None:
self._c.addAdHocCommand(
client, self.localMediaCb, D_(u"Media Players"),
client, self.localMediaCb, D_("Media Players"),
node=NS_MEDIA_PLAYER,
timeout=60*60*6 # 6 hours timeout, to avoid breaking remote
# in the middle of a movie
@ -151,7 +151,7 @@ class AdHocDBus(object):
def _DBusGetProperty(self, proxy, interface, name):
return self._DBusAsyncCall(
proxy, u"Get", interface, name, interface=u"org.freedesktop.DBus.Properties")
proxy, "Get", interface, name, interface="org.freedesktop.DBus.Properties")
def _DBusListNames(self):
@ -271,7 +271,7 @@ class AdHocDBus(object):
elif len(actions) == 2:
# we should have the answer here
try:
x_elt = command_elt.elements(data_form.NS_X_DATA, "x").next()
x_elt = next(command_elt.elements(data_form.NS_X_DATA, "x"))
answer_form = data_form.Form.fromElement(x_elt)
command = answer_form["command"]
except (KeyError, StopIteration):
@ -295,11 +295,11 @@ class AdHocDBus(object):
return DBusCallback(
client, None, session_data, self._c.ACTION.EXECUTE, node
)
form = data_form.Form("form", title=_(u"Updated"))
form.addField(data_form.Field("fixed", u"Command sent"))
form = data_form.Form("form", title=_("Updated"))
form.addField(data_form.Field("fixed", "Command sent"))
status = self._c.STATUS.COMPLETED
payload = None
note = (self._c.NOTE.INFO, _(u"Command sent"))
note = (self._c.NOTE.INFO, _("Command sent"))
else:
raise self._c.AdHocError(self._c.ERROR.INTERNAL)
@ -363,18 +363,18 @@ class AdHocDBus(object):
opt.label or opt.value))
except Exception as e:
log.warning(_(
u"Can't retrieve remote controllers on {device_jid}: "
u"{reason}".format(device_jid=device_jid, reason=e)))
"Can't retrieve remote controllers on {device_jid}: "
"{reason}".format(device_jid=device_jid, reason=e)))
break
defer.returnValue(remotes)
def doMPRISCommand(self, proxy, command):
iface, command = command.rsplit(u".", 1)
iface, command = command.rsplit(".", 1)
if command == CMD_GO_BACK:
command = u'Seek'
command = 'Seek'
args = [-SEEK_OFFSET]
elif command == CMD_GO_FWD:
command = u'Seek'
command = 'Seek'
args = [SEEK_OFFSET]
else:
args = []
@ -382,17 +382,17 @@ class AdHocDBus(object):
def addMPRISMetadata(self, form, metadata):
"""Serialise MRPIS Metadata according to MPRIS_METADATA_MAP"""
for mpris_key, name in MPRIS_METADATA_MAP.iteritems():
for mpris_key, name in MPRIS_METADATA_MAP.items():
if mpris_key in metadata:
value = unicode(metadata[mpris_key])
form.addField(data_form.Field(fieldType=u"fixed",
value = str(metadata[mpris_key])
form.addField(data_form.Field(fieldType="fixed",
var=name,
value=value))
@defer.inlineCallbacks
def localMediaCb(self, client, command_elt, session_data, action, node):
try:
x_elt = command_elt.elements(data_form.NS_X_DATA, "x").next()
x_elt = next(command_elt.elements(data_form.NS_X_DATA, "x"))
command_form = data_form.Form.fromElement(x_elt)
except StopIteration:
command_form = None
@ -402,16 +402,16 @@ class AdHocDBus(object):
bus_names = yield self._DBusListNames()
bus_names = [b for b in bus_names if b.startswith(MPRIS_PREFIX)]
if len(bus_names) == 0:
note = (self._c.NOTE.INFO, D_(u"No media player found."))
note = (self._c.NOTE.INFO, D_("No media player found."))
defer.returnValue((None, self._c.STATUS.COMPLETED, None, note))
options = []
status = self._c.STATUS.EXECUTING
form = data_form.Form("form", title=D_(u"Media Player Selection"),
form = data_form.Form("form", title=D_("Media Player Selection"),
formNamespace=NS_MEDIA_PLAYER)
for bus in bus_names:
player_name = bus[len(MPRIS_PREFIX)+1:]
if not player_name:
log.warning(_(u"Ignoring MPRIS bus without suffix"))
log.warning(_("Ignoring MPRIS bus without suffix"))
continue
options.append(data_form.Option(bus, player_name))
field = data_form.Field(
@ -423,53 +423,53 @@ class AdHocDBus(object):
else:
# player request
try:
bus_name = command_form[u"media_player"]
bus_name = command_form["media_player"]
except KeyError:
raise ValueError(_(u"missing media_player value"))
raise ValueError(_("missing media_player value"))
if not bus_name.startswith(MPRIS_PREFIX):
log.warning(_(u"Media player ad-hoc command trying to use non MPRIS bus. "
u"Hack attempt? Refused bus: {bus_name}").format(
log.warning(_("Media player ad-hoc command trying to use non MPRIS bus. "
"Hack attempt? Refused bus: {bus_name}").format(
bus_name=bus_name))
note = (self._c.NOTE.ERROR, D_(u"Invalid player name."))
note = (self._c.NOTE.ERROR, D_("Invalid player name."))
defer.returnValue((None, self._c.STATUS.COMPLETED, None, note))
try:
proxy = self.session_bus.get_object(bus_name, MPRIS_PATH)
except dbus.exceptions.DBusException as e:
log.warning(_(u"Can't get D-Bus proxy: {reason}").format(reason=e))
note = (self._c.NOTE.ERROR, D_(u"Media player is not available anymore"))
log.warning(_("Can't get D-Bus proxy: {reason}").format(reason=e))
note = (self._c.NOTE.ERROR, D_("Media player is not available anymore"))
defer.returnValue((None, self._c.STATUS.COMPLETED, None, note))
try:
command = command_form[u"command"]
command = command_form["command"]
except KeyError:
pass
else:
yield self.doMPRISCommand(proxy, command)
# we construct the remote control form
form = data_form.Form("form", title=D_(u"Media Player Selection"))
form.addField(data_form.Field(fieldType=u"hidden",
var=u"media_player",
form = data_form.Form("form", title=D_("Media Player Selection"))
form.addField(data_form.Field(fieldType="hidden",
var="media_player",
value=bus_name))
for iface, properties_names in MPRIS_PROPERTIES.iteritems():
for iface, properties_names in MPRIS_PROPERTIES.items():
for name in properties_names:
try:
value = yield self._DBusGetProperty(proxy, iface, name)
except Exception as e:
log.warning(_(u"Can't retrieve attribute {name}: {reason}")
log.warning(_("Can't retrieve attribute {name}: {reason}")
.format(name=name, reason=e))
continue
if name == MPRIS_METADATA_KEY:
self.addMPRISMetadata(form, value)
else:
form.addField(data_form.Field(fieldType=u"fixed",
form.addField(data_form.Field(fieldType="fixed",
var=name,
value=unicode(value)))
value=str(value)))
commands = [data_form.Option(c, c.rsplit(u".", 1)[1]) for c in MPRIS_COMMANDS]
form.addField(data_form.Field(fieldType=u"list-single",
var=u"command",
commands = [data_form.Option(c, c.rsplit(".", 1)[1]) for c in MPRIS_COMMANDS]
form.addField(data_form.Field(fieldType="list-single",
var="command",
options=commands,
required=True))