[Telepathy-commits] [telepathy-pinocchio/master] add add-account and remove-account commands to pinocchio-ctl and necessary support to pinocchio itself

Travis Reitter travis.reitter at collabora.co.uk
Fri Aug 15 18:51:03 PDT 2008


---
 README                           |   24 +++++++++++++
 bin/pinocchio-ctl                |   55 +++++++++++++++++++++++++++++-
 pinocchio/common.py              |   18 +++++++++
 pinocchio/connection/__init__.py |   13 +------
 pinocchio/connection_manager.py  |   71 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 169 insertions(+), 12 deletions(-)

diff --git a/README b/README
index b91ba97..448c313 100644
--- a/README
+++ b/README
@@ -59,6 +59,30 @@ Returns the roster to its default state, reverting all changes to contacts,
 groups, contact lists, etc.
 
 
+'add-account' command
+-------------
+
+Create a new pinocchio "server-side" account (create the empty contacts file,
+etc.). Note this does not create a corresponding Mission Control account.
+
+The 'add-account' command arguments are structured as:
+
+    ACCOUNT_NAME
+
+
+'remove-account' command
+-------------
+
+Delete an existing pinocchio "server-side" account (remove the account
+directory). This command only attempts to remove accounts in
+$HOME/.telepathy-pinocchio/accounts, and not the global accounts in
+/var/lib/telepathy-pinocchio/accounts.
+
+The 'remove-account' command arguments are structured as:
+
+    ACCOUNT_NAME
+
+
 'add-contact' command
 -------------
 
diff --git a/bin/pinocchio-ctl b/bin/pinocchio-ctl
index 68dde18..47eb4d0 100755
--- a/bin/pinocchio-ctl
+++ b/bin/pinocchio-ctl
@@ -310,6 +310,8 @@ def print_help_exit(exit_status, pre_message=None):
        reset (revert the contact list to its defaults)
        add-group GROUP_1 [GROUP_2] [...]
        remove-group GROUP_1 [GROUP_2] [...]
+       add-account ACCOUNT_NAME
+       remove-account ACCOUNT_NAME
        
        add-contact USERNAME:[lists=LIST_1][+LIST_2][+...] [...]
 
@@ -836,6 +838,55 @@ def command_reset(opts, args, mainloop):
         connection.Disconnect()
     mainloop.quit()
 
+def command_add_account(opts, args, mainloop):
+    """Create a new pinocchio/dummy account.
+
+    Arguments:
+    opts -- command-line options
+    args -- currently ignored
+    mainloop -- the gobject mainloop to use for signals
+    """
+    pre_message_mangled = "'reset' command does not take any arguments"
+
+    if len(args) != 1:
+        print_help_exit(10, pre_message_mangled)
+
+    account_name = args[0]
+    bus = dbus.SessionBus()
+    manager = connection_manager_get(bus)
+
+    manager.create_account(account_name)
+
+    print "new account '%s' created" % account_name
+
+    mainloop.quit()
+
+def command_remove_account(opts, args, mainloop):
+    """Delete a local pinocchio/dummy account. Won't work for globally-installed
+    accounts.
+
+    Arguments:
+    opts -- command-line options
+    args -- currently ignored
+    mainloop -- the gobject mainloop to use for signals
+    """
+    pre_message_mangled = "'reset' command does not take any arguments"
+
+    if len(args) != 1:
+        print_help_exit(10, pre_message_mangled)
+
+    account_name = args[0]
+    bus = dbus.SessionBus()
+    manager = connection_manager_get(bus)
+
+    try:
+        manager.remove_account(account_name)
+        print "account '%s' removed" % account_name
+    except:
+        print "failed to remove account '%s'" % account_name
+
+    mainloop.quit()
+
 def signal_handlers_init(bus):
     """Set up handlers for the signals we're interested in.
     
@@ -859,7 +910,9 @@ COMMANDS = {'list': command_list,
             'add-group': command_add_group,
             'remove-group': command_remove_group,
             'set': command_set_unified,
-            'reset': command_reset}
+            'reset': command_reset,
+            'add-account': command_add_account,
+            'remove-account': command_remove_account}
 
 def validate_args(argv):
     """Ensure that the given command-line arguments are valid and return their
diff --git a/pinocchio/common.py b/pinocchio/common.py
index fe10bc8..03feb86 100644
--- a/pinocchio/common.py
+++ b/pinocchio/common.py
@@ -156,3 +156,21 @@ def xml_insert_element(xml_doc, parent_node, element_name, element_content,
         parent_node.appendChild(trailer_node)
 
     return element
+
+def save_roster(xml_doc, account_id):
+    """Write the roster XML content to the contacts file for the account.
+
+    Arguments:
+    xml_doc -- minidom Document object of the encompassing document
+    account_id -- sanitized account ID
+    """
+    filename = get_contacts_file(account_id, PREFIX_SAVED)
+
+    # make sure the parent directories exist
+    parent_dir = os.path.dirname(filename)
+    if not os.path.isdir(parent_dir):
+        os.makedirs(parent_dir)
+
+    file = open(filename, 'w')
+    file.write(xml_doc.toxml(encoding='utf-8'))
+    file.close()
diff --git a/pinocchio/connection/__init__.py b/pinocchio/connection/__init__.py
index 16b9244..d234367 100644
--- a/pinocchio/connection/__init__.py
+++ b/pinocchio/connection/__init__.py
@@ -347,15 +347,6 @@ class Connection(tp.server.Connection,
             newline_value = xml_doc.createTextNode('\n\n')
             roster_xml.appendChild(newline_value)
 
+        
         account_id = self.get_account_id()
-        filename = pin.common.get_contacts_file(account_id,
-                                                pin.common.PREFIX_SAVED)
-
-        # make sure the parent directories exist
-        parent_dir = os.path.dirname(filename)
-        if not os.path.isdir(parent_dir):
-            os.makedirs(parent_dir)
-
-        file = open(filename, 'w')
-        file.write(xml_doc.toxml(encoding='utf-8'))
-        file.close()
+        pin.common.save_roster(xml_doc, account_id)
diff --git a/pinocchio/connection_manager.py b/pinocchio/connection_manager.py
index a0344b8..71346ba 100644
--- a/pinocchio/connection_manager.py
+++ b/pinocchio/connection_manager.py
@@ -17,6 +17,11 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 # 02110-1301 USA
 
+import os.path
+import shutil
+from xml.dom import minidom
+import dbus.service
+
 import telepathy as tp
 
 import pinocchio as pin
@@ -152,8 +157,74 @@ class ConnectionManager(tp.server.ConnectionManager):
 
         return channel_result
 
+    def account_exists(self, account_name):
+        """Returns True if the account exists, False otherwise.
+
+        Arguments:
+        account_name -- raw account name (eg, foo at example.org)
+        """
+        account_id = tp.server.conn._escape_as_identifier(account_name)
+
+        filename = pin.common.get_contacts_file(
+                                            account_id,
+                                            pin.common.PREFIX_SAVED_PREFERRED)
+
+        return os.path.isfile(filename)
+
     def connections_teardown(self):
         """Tear down all managed connections."""
 
         for connection in self._connections:
             connection.Disconnect()
+
+    @dbus.service.method(tp.interfaces.CONNECTION_MANAGER,
+                         in_signature='s', out_signature='')
+    def create_account(self, account_name):
+        """Initalize a new account with an empty roster.
+
+        Arguments:
+        account_name -- raw account name (eg, foo at example.org)
+
+        Exceptions:
+        org.freedesktop.Telepathy.Error.InvalidArgument
+        """
+        # TODO: improve this validation
+        if not account_name:
+            raise tp.errors.InvalidArgument('invalid account name')
+
+        account_id = tp.server.conn._escape_as_identifier(account_name)
+
+        # only create the account if it doesn't exist
+        if not self.account_exists(account_name):
+            dom_impl = minidom.getDOMImplementation()
+            xml_doc = dom_impl.createDocument(None, 'roster', None)
+            roster_xml = xml_doc.documentElement
+
+            # add newline for human-readability
+            newline_value = xml_doc.createTextNode('\n')
+            roster_xml.appendChild(newline_value)
+
+            pin.common.save_roster(xml_doc, account_id)
+
+    @dbus.service.method(tp.interfaces.CONNECTION_MANAGER,
+                         in_signature='s', out_signature='')
+    def remove_account(self, account_name):
+        """Delete an existing account. Note that this won't delete a global
+        account.
+
+        Arguments:
+        account_name -- raw account name (eg, foo at example.org)
+
+        Exceptions:
+        org.freedesktop.Telepathy.Error.InvalidArgument
+        """
+        # TODO: improve this validation
+        if not account_name:
+            raise tp.errors.InvalidArgument('invalid account name')
+
+        account_id = tp.server.conn._escape_as_identifier(account_name)
+
+        # only remove the account if it exists
+        account_dir = pin.common.get_account_dir(pin.common.PREFIX_SAVED,
+                                                 account_id)
+        shutil.rmtree(account_dir)
-- 
1.5.6.3



More information about the Telepathy-commits mailing list