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