|
|
|
@ -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,45 +95,67 @@ 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 convert(self, path, dbus_path=None): |
|
|
|
|
def delete_mms(self, dbus_path): |
|
|
|
|
""" |
|
|
|
|
Convert a provided mms file to a mail stored in a mbox. |
|
|
|
|
|
|
|
|
|
:param path: the mms filesystem path |
|
|
|
|
:type path: str |
|
|
|
|
Ask mmsd to delete the mms. |
|
|
|
|
|
|
|
|
|
:param dbus_path: the mms dbus path |
|
|
|
|
:type dbus_path: str |
|
|
|
|
""" |
|
|
|
|
# Check if the provided file present |
|
|
|
|
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 |
|
|
|
|
# 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 |
|
|
|
|
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 |
|
|
|
|
return False |
|
|
|
|
status.read_file(open(f"{path}.status")) |
|
|
|
|
|
|
|
|
|
# Allow only incoming MMS for the time beeing |
|
|
|
|
if (status['info']['state'] == 'downloaded' or |
|
|
|
|
if not (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) |
|
|
|
|
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. |
|
|
|
|
|
|
|
|
|
:param path: the mms filesystem path |
|
|
|
|
:type path: str |
|
|
|
|
|
|
|
|
|
:param dbus_path: the mms dbus path |
|
|
|
|
:type dbus_path: str |
|
|
|
|
""" |
|
|
|
|
# Check if the provided file present |
|
|
|
|
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]}" |
|
|
|
|
|
|
|
|
|
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: |
|
|
|
|