diff --git a/README.md b/README.md index 0240682..ffa54d7 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,14 @@ By default: - python3 - python3-aiosmtpd + - python3-pydbus - python-messaging (pip install python-messaging) ### setup Install the dependency and mms2mail (on debian based distribution): ``` sudo apt-get install python3 +sudo apt-get install python3-pydbus sudo apt-get install python3-aiosmtpd pip install --user python-messaging diff --git a/mms2mail b/mms2mail index 3631315..f82d0f0 100755 --- a/mms2mail +++ b/mms2mail @@ -14,8 +14,7 @@ import mailbox import email from gi.repository import GLib -import dbus -import dbus.mainloop.glib +import pydbus import os import re @@ -115,7 +114,7 @@ class MMS2Mail: return None return status['info']['state'] - def message_added(self, name, value, member, path, interface): + def message_added(self, name, value): """Trigger conversion on MessageAdded signal.""" if value['Status'] == 'downloaded' or value['Status'] == 'received': log.debug(f"New incoming MMS found ({name.split('/')[-1]})") @@ -309,6 +308,7 @@ class Mail2MMSHandler: recipients = [] attachments = [] smil = None + for r in envelope.rcpt_tos: number = r.split('@')[0] if self.pattern.search(number): @@ -321,6 +321,7 @@ class Mail2MMSHandler: return '553 Requested action not taken: mailbox name not allowed' mail = self.parser.parsebytes(envelope.content) + subject = mail.get('subject', failobj=None) cid = 1 total_size = 0 with tempfile.TemporaryDirectory(prefix='mailtomms-') as tmp_dir: @@ -358,8 +359,11 @@ class Mail2MMSHandler: elif total_size > self.total_max_attachment_size: return '554 5.3.4 Message too big for system' try: - self.dbusmmsd.send_mms(recipients, attachments, smil) - except dbus.exceptions.DBusException as e: + self.dbusmmsd.send_mms(recipients=recipients, + attachments=attachments, + subject=subject, + smil=smil) + except Exception as e: log.error(e) return '421 mmsd service not available' return '250 OK' @@ -376,8 +380,7 @@ class DbusMMSd(): :type mms2mail: mms2mail() """ self.mms2mail = mms2mail - dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - self.bus = dbus.SessionBus() + self.bus = pydbus.SessionBus() def set_mms2mail(self, mms2mail): """ @@ -395,9 +398,7 @@ class DbusMMSd(): :param dbus_path: the mms dbus path :type dbus_path: str """ - message = dbus.proxies.Interface(self.bus.get_object('org.ofono.mms', - dbus_path), - 'org.ofono.mms.Message') + message = self.bus.get('org.ofono.mms', dbus_path) log.debug(f"Marking MMS as read {dbus_path}") message.MarkRead() @@ -408,11 +409,7 @@ class DbusMMSd(): :param dbus_path: the mms dbus path :type dbus_path: str """ - if self.disable_dbus: - return None - message = dbus.proxies.Interface(self.bus.get_object('org.ofono.mms', - dbus_path), - 'org.ofono.mms.Message') + message = self.bus.get('org.ofono.mms', dbus_path) log.debug(f"Deleting MMS {dbus_path}") message.Delete() @@ -423,13 +420,10 @@ class DbusMMSd(): :return the mmsd service :rtype dbus.Interface """ - manager = dbus.Interface(self.bus.get_object('org.ofono.mms', - '/org/ofono/mms'), - 'org.ofono.mms.Manager') + manager = self.bus.get('org.ofono.mms', '/org/ofono/mms') services = manager.GetServices() path = services[0][0] - service = dbus.Interface(self.bus.get_object('org.ofono.mms', path), - 'org.ofono.mms.Service') + service = self.bus.get('org.ofono.mms', path) return service def get_manager_config(self): @@ -442,7 +436,28 @@ class DbusMMSd(): service = self.get_service() return service.GetProperties() - def send_mms(self, recipients, attachments, smil=None): + def get_send_message_version(self): + """ + Ask mmsd its SendMessage method Signature. + + :return true if mmsd is mmsd-tng allowing Subject in mms + :rtype bool + """ + if not hasattr(self, 'mmsdtng'): + from xml.dom import minidom + mmsdtng = False + svc = self.get_service() + i = svc.Introspect() + dom = minidom.parseString(i) + for method in dom.getElementsByTagName('method'): + if method.getAttribute('name') == "SendMessage": + for arg in method.getElementsByTagName('arg'): + if arg.getAttribute('name') == 'options': + mmsdtng = True + self.mmsdtng = mmsdtng + return self.mmsdtng + + def send_mms(self, recipients, attachments, subject=None, smil=None): """ Ask mmsd to send a MMS. @@ -457,37 +472,35 @@ class DbusMMSd(): """ service = self.get_service() - mms_recipients = dbus.Array([], signature=dbus.Signature('s')) - for r in recipients: - mms_recipients.append(dbus.String(r)) - - if smil: - log.debug("Send MMS as Related") - mms_smil = dbus.String(smil) + mmsdtng = self.get_send_message_version() + if mmsdtng: + log.debug("Using mmsd-tng as backend") + option_list = {} + if subject: + log.debug(f"MMS Subject = {subject}") + option_list['Subject'] = GLib.Variant('s', subject) + if smil: + log.debug("Send MMS as Related") + option_list['smil'] = GLib.Variant('s', smil) + options = GLib.Variant('a{sv}', option_list) + path = service.SendMessage(recipients, options, + attachments) else: - log.debug("Send MMS as Mixed") - mms_smil = "" - - mms_attachments = dbus.Array([], signature=dbus.Signature('(sss)')) - for a in attachments: - log.debug("Attachment: ({})".format(a)) - mms_attachments.append(dbus.Struct((dbus.String(a[0]), - dbus.String(a[1]), - dbus.String(a[2]) - ), signature=None)) - - path = service.SendMessage(mms_recipients, mms_smil, mms_attachments) + log.debug("Using mmsd as backend") + if smil: + log.debug("Send MMS as Related") + else: + log.debug("Send MMS as Mixed") + smil = "" + path = service.SendMessage(recipients, smil, + attachments) log.debug(path) def add_signal_receiver(self): """Add a signal receiver to the current bus.""" if self.mms2mail: - self.bus.add_signal_receiver(self.mms2mail.message_added, - bus_name="org.ofono.mms", - signal_name="MessageAdded", - member_keyword="member", - path_keyword="path", - interface_keyword="interface") + service = self.get_service() + service.onMessageAdded = self.mms2mail.message_added return True else: return False