From 209317ba21d277d3f4375ee4728f1ee43d3a3f7c Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 5 May 2021 16:25:46 +0200 Subject: [PATCH] [feat] Use more mmsd dbus API - Mark MMS as read on conversion - Allow deleting MMS after conversion --- README.md | 10 ++++-- mms2mail | 100 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index b58b873..7e32662 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Convert MMSd MMS file to mbox. ## installation -### dependancy +### dependency - python3 - python3-watchdog (pip install watchdog) @@ -43,11 +43,15 @@ attach_mms = false ; whether to attach the full mms binary file ## usage -mms2mail [-h] [-d [{dbus,filesystem}] | -f FILES [FILES ...]] +``` +mms2mail [-h] [-d [{dbus,filesystem}] | -f FILES [FILES ...]] [--delete] [--force-read] optional arguments: -h, --help show this help message and exit -d [{dbus,filesystem}], --daemon [{dbus,filesystem}] Use dbus signal from mmsd by default but can also watch mmsd storage folder (useful for mmsd < 1.0) -f FILES [FILES ...], --file FILES [FILES ...] - parse specified mms files + Parse specified mms files and quit + --delete Ask mmsd to delete the converted MMS + --force-read Force conversion even if MMS is marked as read +``` \ No newline at end of file diff --git a/mms2mail b/mms2mail index c7d82ea..77e0329 100755 --- a/mms2mail +++ b/mms2mail @@ -49,10 +49,22 @@ class MMS2Mail: Mail support is provided by marrow.mailer """ - def __init__(self): - """Return class instance.""" + def __init__(self, delete=False, force_read=False): + """ + Return class instance. + + :param delete: delete MMS after conversion + :type delete: bool + + :param force_read: force converting an already read MMS (batch mode) + :type force_read: bool + """ + self.delete = delete + self.force_read = force_read self.config = configparser.ConfigParser() self.config.read(f"{Path.home()}/.mms/modemmanager/mms2mail.ini") + self.attach_mms = self.config.getboolean('mail', 'attach_mms', + fallback=False) self.domain = self.config.get('mail', 'domain', fallback=socket.getfqdn()) self.user = self.config.get('mail', 'user', fallback=getpass.getuser()) @@ -75,7 +87,7 @@ class MMS2Mail: def mark_mms_read(self, dbus_path): """ - Ask MMSd to mark the mms as read. + Ask mmsd to mark the mms as read. :param dbus_path: the mms dbus path :type dbus_path: str @@ -83,8 +95,50 @@ class MMS2Mail: message = dbus.Interface(self.bus.get_object('org.ofono.mms', dbus_path), 'org.ofono.mms.Message') + print(f"Marking MMS as read {dbus_path}", file=sys.stderr) message.MarkRead() + def delete_mms(self, dbus_path): + """ + Ask mmsd to delete the mms. + + :param dbus_path: the mms dbus path + :type dbus_path: str + """ + message = dbus.Interface(self.bus.get_object('org.ofono.mms', + dbus_path), + 'org.ofono.mms.Message') + print(f"Deleting MMS {dbus_path}", file=sys.stderr) + message.Delete() + + def check_mms(self, path): + """ + Check wether the provided file would be converted. + + :param path: the mms filesystem path + :type path: str + :rtype bool + """ + # Check for mmsd data file + if not Path(f"{path}").is_file(): + print("MMS file not found : aborting", file=sys.stderr) + return False + # Check for mmsd status file + status = configparser.ConfigParser() + if not Path(f"{path}.status").is_file(): + print("MMS status file not found : aborting", file=sys.stderr) + return False + status.read_file(open(f"{path}.status")) + # Allow only incoming MMS for the time beeing + if not (status['info']['state'] == 'downloaded' or + status['info']['state'] == 'received'): + print("Outgoing MMS : aborting", file=sys.stderr) + return False + if not (self.force_read or not status.getboolean('info', 'read')): + print("Already converted MMS : aborting", file=sys.stderr) + return False + return True + def convert(self, path, dbus_path=None): """ Convert a provided mms file to a mail stored in a mbox. @@ -96,32 +150,12 @@ class MMS2Mail: :type dbus_path: str """ # Check if the provided file present - if not Path(f"{path}").is_file(): - print("MMS file not found : aborting", file=sys.stderr) + if not self.check_mms(path): + print("MMS file not convertible.", file=sys.stderr) return # Generate its dbus path, for future operation (mark as read, delete) if not dbus_path: dbus_path = f"/org/ofono/mms/modemmanager/{path.split('/')[-1]}" - if Path(f"{path}.mail").is_file() and args.watcher: - print(f"Already converted MMS : doing nothing ({path})", - file=sys.stderr) - return - # Check for mmsd status file - status = configparser.ConfigParser() - if not Path(f"{path}.status").is_file(): - print("MMS status file not found : aborting", file=sys.stderr) - return - status.read_file(open(f"{path}.status")) - - # Allow only incoming MMS for the time beeing - if (status['info']['state'] == 'downloaded' or - status['info']['state'] == 'received'): - print(f"New incoming MMS : converting to Mail ({path})", - file=sys.stderr) - else: - print(f"New outgoing MMS : doing nothing ({path})", - file=sys.stderr) - return mms = MMSMessage.from_file(path) @@ -161,11 +195,14 @@ class MMS2Mail: if not message.plain: message.plain = " " # Add MMS binary file, for debugging purpose or reparsing in the future - if self.config.getboolean('mail', 'attach_mms', fallback=False): + if self.attach_mms: message.attach(path, None, None, None, False, "mms.bin") # Creating an empty file stating the mms as been converted - Path(f"{path}.mail").touch() + self.mark_mms_read(dbus_path) + + if self.delete: + self.delete_mms(dbus_path) # Write the mail self.mailer.send(message) @@ -267,10 +304,15 @@ if __name__ == '__main__': nargs="?", default="dbus", choices=['dbus', 'filesystem'], dest='watcher') mode.add_argument("-f", "--file", nargs='+', - help="parse specified mms files", dest='files') + help="Parse specified mms files and quit", dest='files') + parser.add_argument('--delete', action='store_true', dest='delete', + help="Ask mmsd to delete the converted MMS") + parser.add_argument('--force-read', action='store_true', + dest='force_read', help="Force conversion even if MMS \ + is marked as read") args = parser.parse_args() - m = MMS2Mail() + m = MMS2Mail(args.delete, args.force_read) if args.files: for mms_file in args.files: