| #!/usr/bin/python |
| |
| from __future__ import absolute_import, print_function, unicode_literals |
| |
| from optparse import OptionParser |
| import os |
| from pprint import pformat |
| import sys |
| import dbus |
| import dbus.mainloop.glib |
| try: |
| from gi.repository import GObject |
| except ImportError: |
| import gobject as GObject |
| |
| BUS_NAME='org.bluez.obex' |
| PATH = '/org/bluez/obex' |
| CLIENT_INTERFACE = 'org.bluez.obex.Client1' |
| SESSION_INTERFACE = 'org.bluez.obex.Session1' |
| MESSAGE_ACCESS_INTERFACE = 'org.bluez.obex.MessageAccess1' |
| MESSAGE_INTERFACE = 'org.bluez.obex.Message1' |
| TRANSFER_INTERFACE = 'org.bluez.obex.Transfer1' |
| |
| def unwrap(x): |
| """Hack to unwrap D-Bus values, so that they're easier to read when |
| printed. Taken from d-feet """ |
| |
| if isinstance(x, list): |
| return map(unwrap, x) |
| |
| if isinstance(x, tuple): |
| return tuple(map(unwrap, x)) |
| |
| if isinstance(x, dict): |
| return dict([(unwrap(k), unwrap(v)) for k, v in x.iteritems()]) |
| |
| for t in [unicode, str, long, int, float, bool]: |
| if isinstance(x, t): |
| return t(x) |
| |
| return x |
| |
| def parse_options(): |
| parser.add_option("-d", "--device", dest="device", |
| help="Device to connect", metavar="DEVICE") |
| parser.add_option("-c", "--chdir", dest="new_dir", |
| help="Change current directory to DIR", metavar="DIR") |
| parser.add_option("-l", "--lsdir", action="store_true", dest="ls_dir", |
| help="List folders in current directory") |
| parser.add_option("-v", "--verbose", action="store_true", dest="verbose") |
| parser.add_option("-L", "--lsmsg", action="store", dest="ls_msg", |
| help="List messages in supplied CWD subdir") |
| parser.add_option("-g", "--get", action="store", dest="get_msg", |
| help="Get message contents") |
| parser.add_option("-p", "--push", action="store", dest="push_msg", |
| help="Push message") |
| parser.add_option("--get-properties", action="store", dest="get_msg_properties", |
| help="Get message properties") |
| parser.add_option("--mark-read", action="store", dest="mark_msg_read", |
| help="Marks the messages as read") |
| parser.add_option("--mark-unread", action="store", dest="mark_msg_unread", |
| help="Marks the messages as unread") |
| parser.add_option("--mark-deleted", action="store", dest="mark_msg_deleted", |
| help="Deletes the message from the folder") |
| parser.add_option("--mark-undeleted", action="store", dest="mark_msg_undeleted", |
| help="Undeletes the message") |
| parser.add_option("-u", "--update-inbox", action="store_true", dest="update_inbox", |
| help="Checks for new mails") |
| |
| return parser.parse_args() |
| |
| def set_folder(session, new_dir): |
| session.SetFolder(new_dir) |
| |
| class MapClient: |
| def __init__(self, session_path, verbose=False): |
| self.progress = 0 |
| self.transfer_path = None |
| self.props = dict() |
| self.verbose = verbose |
| self.path = session_path |
| bus = dbus.SessionBus() |
| obj = bus.get_object(BUS_NAME, session_path) |
| self.session = dbus.Interface(obj, SESSION_INTERFACE) |
| self.map = dbus.Interface(obj, MESSAGE_ACCESS_INTERFACE) |
| bus.add_signal_receiver(self.properties_changed, |
| dbus_interface="org.freedesktop.DBus.Properties", |
| signal_name="PropertiesChanged", |
| path_keyword="path") |
| |
| def create_transfer_reply(self, path, properties): |
| self.transfer_path = path |
| self.props[path] = properties |
| if self.verbose: |
| print("Transfer created: %s (file %s)" % (path, |
| properties["Filename"])) |
| |
| def generic_reply(self): |
| if self.verbose: |
| print("Operation succeeded") |
| |
| def error(self, err): |
| print(err) |
| mainloop.quit() |
| |
| def transfer_complete(self, path): |
| if self.verbose: |
| print("Transfer finished") |
| properties = self.props.get(path) |
| if properties == None: |
| return |
| f = open(properties["Filename"], "r") |
| os.remove(properties["Filename"]) |
| print(f.readlines()) |
| |
| def transfer_error(self, path): |
| print("Transfer %s error" % path) |
| mainloop.quit() |
| |
| def properties_changed(self, interface, properties, invalidated, path): |
| req = self.props.get(path) |
| if req == None: |
| return |
| |
| if properties['Status'] == 'complete': |
| self.transfer_complete(path) |
| return |
| |
| if properties['Status'] == 'error': |
| self.transfer_error(path) |
| return |
| |
| def set_folder(self, new_dir): |
| self.map.SetFolder(new_dir) |
| |
| def list_folders(self): |
| for i in self.map.ListFolders(dict()): |
| print("%s/" % (i["Name"])) |
| |
| def list_messages(self, folder): |
| ret = self.map.ListMessages(folder, dict()) |
| print(pformat(unwrap(ret))) |
| |
| def get_message(self, handle): |
| self.map.ListMessages("", dict()) |
| path = self.path + "/message" + handle |
| obj = bus.get_object(BUS_NAME, path) |
| msg = dbus.Interface(obj, MESSAGE_INTERFACE) |
| msg.Get("", True, reply_handler=self.create_transfer_reply, |
| error_handler=self.error) |
| |
| def push_message(self, filename): |
| self.map.PushMessage(filename, "telecom/msg/outbox", dict(), |
| reply_handler=self.create_transfer_reply, |
| error_handler=self.error) |
| |
| def get_message_properties(self, handle): |
| self.map.ListMessages("", dict()) |
| path = self.path + "/message" + handle |
| obj = bus.get_object(BUS_NAME, path) |
| msg = dbus.Interface(obj, "org.freedesktop.DBus.Properties") |
| ret = msg.GetAll(MESSAGE_INTERFACE) |
| print(pformat(unwrap(ret))) |
| |
| def set_message_property(self, handle, prop, flag): |
| self.map.ListMessages("", dict()) |
| path = self.path + "/message" + handle |
| obj = bus.get_object(BUS_NAME, path) |
| msg = dbus.Interface(obj, MESSAGE_INTERFACE) |
| msg.SetProperty (prop, flag); |
| |
| def update_inbox(self): |
| self.map.UpdateInbox() |
| |
| |
| if __name__ == '__main__': |
| |
| dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |
| |
| parser = OptionParser() |
| |
| (options, args) = parse_options() |
| |
| if not options.device: |
| parser.print_help() |
| exit(0) |
| |
| bus = dbus.SessionBus() |
| mainloop = GObject.MainLoop() |
| |
| client = dbus.Interface(bus.get_object(BUS_NAME, PATH), |
| CLIENT_INTERFACE) |
| |
| print("Creating Session") |
| path = client.CreateSession(options.device, { "Target": "map" }) |
| |
| map_client = MapClient(path, options.verbose) |
| |
| if options.new_dir: |
| map_client.set_folder(options.new_dir) |
| |
| if options.ls_dir: |
| map_client.list_folders() |
| |
| if options.ls_msg is not None: |
| map_client.list_messages(options.ls_msg) |
| |
| if options.get_msg is not None: |
| map_client.get_message(options.get_msg) |
| |
| if options.push_msg is not None: |
| map_client.push_message(options.push_msg) |
| |
| if options.get_msg_properties is not None: |
| map_client.get_message_properties(options.get_msg_properties) |
| |
| if options.mark_msg_read is not None: |
| map_client.set_message_property(options.mark_msg_read, "Read", True) |
| |
| if options.mark_msg_unread is not None: |
| map_client.set_message_property(options.mark_msg_unread, "Read", False) |
| |
| if options.mark_msg_deleted is not None: |
| map_client.set_message_property(options.mark_msg_deleted, "Deleted", True) |
| |
| if options.mark_msg_undeleted is not None: |
| map_client.set_message_property(options.mark_msg_undeleted, "Deleted", False) |
| |
| if options.update_inbox: |
| map_client.update_inbox() |
| |
| mainloop.run() |