Logo Search packages:      
Sourcecode: magicicada version File versions  Download package

cmd_pof.py

# DISCLAIMER: this is a proof of concept, we need tests for this!
# Author: Facundo Batista

# this always first
from twisted.internet import glib2reactor
glib2reactor.install()

import functools
import re
import time

import dbus
from dbus.mainloop.glib import DBusGMainLoop
from twisted.internet import reactor

from ubuntuone.syncdaemon import tools

# main connected stuff
loop = DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus(mainloop=loop)
sync_daemon_tool = tools.SyncDaemonTool(bus)

DATE_FMT = "%Y-%m-%d"
TIME_FMT = "%H:%M:%S"

RE_OP_LISTDIR = re.compile("ListDir\(share_id=(.*?), node_id=(.*?), .*")
RE_OP_UNLINK = re.compile("Unlink\(share_id=(.*?), node_id=(.*?), .*")
RE_OP_MAKEFILE = re.compile(
                "MakeFile\(share_id=(.*?), parent_id=(.*?), name=(.*?), .*")

class DBusHandler(object):
    def __init__(self):
        # status changed
        bus.add_signal_receiver(self.on_status_changed,
                            dbus_interface='com.ubuntuone.SyncDaemon.Status',
                            signal_name='StatusChanged')
        # content queue changed
        bus.add_signal_receiver(self.on_CQ_changed,
                            dbus_interface='com.ubuntuone.SyncDaemon.Status',
                            signal_name='ContentQueueChanged')

        # upload or download
        for s in ('DownloadStarted', 'DownloadFinished',
                  'UploadStarted', 'UploadFinished'):
            bus.add_signal_receiver(functools.partial(self.on_updown_activ, s),
                                    signal_name=s)

        # get the first one
        d = sync_daemon_tool.get_status()
        d.addCallback(self.on_status_changed)

        self._date = None
        self._last_CQ_data = None
        self._last_MQ_data = None
        self._state = None
        self._mqcaller = None

    def on_updown_activ(self, signal, *data):
        """Upload or download activity."""
        path = data[0]
        if signal in ('UploadStarted', 'DownloadStarted'):
            self._show("{0}: {1}".format(signal, path))
        else:
            self._show("{0}: {1}".format(signal, path))

    def on_CQ_changed(self, data):
        """Content Queue changed, update it."""
        def show_cq(data):
            """Show the CONTENT queue."""
            if data == self._last_CQ_data:
                return

            # it changed!
            self._last_CQ_data = data
            self._show("Content Queue:")
            if data:
                for d in data:
                    print "           ", self._format_CQ_data(d)
            else:
                print "           (empty)"

        d = sync_daemon_tool.waiting_content()
        d.addCallback(show_cq)

    def _show(self, message):
        date = time.strftime(DATE_FMT)
        if date !=  self._date:
            self._date = date
            print "-- {0} --".format(self._date)

        now = time.strftime(TIME_FMT)
        print "{0}  {1}".format(now, message)

    def _format_MQ_data(self, data):
        """Format the meta queue information."""
        if data.startswith("ListDir"):
            m = RE_OP_LISTDIR.match(data)
            if not m:
                m = "Got a ListDir, but failed to match: %r" % (data,)
                raise ValueError(m)
            share_id, node_id = m.groups()
            name = self._find_out_path(share_id, node_id)
            return "ListDir: {0}  ({1}:{2})".format(name, share_id, node_id)

        if data.startswith("Unlink"):
            m = RE_OP_UNLINK.match(data)
            if not m:
                m = "Got an Unlink, but failed to match: %r" % (data,)
                raise ValueError(m)
            share_id, node_id = m.groups()
            name = self._find_out_path(share_id, node_id)
            return "Unlink: {0}  ({1}:{2})".format(name, share_id, node_id)

        if data.startswith("MakeFile"):
            m = RE_OP_MAKEFILE.match(data)
            if not m:
                m = "Got a Makefile, but failed to match: %r" % (data,)
                raise ValueError(m)
            share_id, parent_id, name = m.groups()
            parent = self._find_out_path(share_id, parent_id)
            return "MakeFile: {0}  (in {1})".format(name, parent)

        # these operations are very simple
        if data in ('GetPublicFiles', 'AccountInquiry', 'FreeSpaceInquiry',
                    'ListVolumes', 'ListShares'):
            return data

        return "Op? {0}".format(data)

    def _format_CQ_data(self, data):
        """Format the content queue information."""
        return "{operation}: {path}  ({share}:{node})".format(**data)

    def _find_out_path(self, share_id, node_id):
        """Curse the destiny!"""
        return "?"

    def on_status_changed(self, state):
        """Show the state nicely."""
        self._state = state
        if state["is_error"]:
            print "State: Error!"
            return

        # normal
        self._show("State: {name}   Q: {queues}   C: {connection}".format(
                                                                    **state))
        self._check_MQ()

    def _check_MQ(self):
        """Check MQ if we should."""
        # check if we have something to show in MQ!
        if self._state['name'] != 'QUEUE_MANAGER' or self._state['queues'] \
                            not in ('WORKING_ON_METADATA', 'WORKING_ON_BOTH'):
            return

        # we have a previous call later running?
        if self._mqcaller is not None and self._mqcaller.active():
            self._mqcaller.cancel()

        def show_mq(data):
            """Show the META queue."""
            if data == self._last_MQ_data:
                return

            # it changed!
            self._last_MQ_data = data
            self._show("Meta Queue:")
            if data:
                for d in data:
                    print "           ", self._format_MQ_data(d)
            else:
                print "           (empty)"

        d = sync_daemon_tool.waiting_metadata()
        d.addCallback(show_mq)

        self._mqcaller = reactor.callLater(1, self._check_MQ)

def main():
    print "Check if it's running..."
    if not tools.is_running():
        print "ERROR: SD is not running!"
        reactor.stop()

    sh = DBusHandler()

if __name__ == "__main__":
    reactor.callWhenRunning(main)
    reactor.run()

Generated by  Doxygen 1.6.0   Back to index