diff options
author | Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> | 2011-10-19 13:22:42 +0100 |
---|---|---|
committer | Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> | 2011-10-19 13:22:42 +0100 |
commit | 7423834758dda2093a6e8e675ab4078c5f87ffcd (patch) | |
tree | 0a1ecc7aa3767daec030024da9011c79ef865e1f /pykolab | |
parent | 7f981d42521913a3f7a715cd043cbf7fba5009b0 (diff) | |
download | pykolab-7423834758dda2093a6e8e675ab4078c5f87ffcd.tar.gz |
Restructure the command-line interface so that it can be extended easier, and particular commands can be shipped in seperate packages
Diffstat (limited to 'pykolab')
-rw-r--r-- | pykolab/cli/__init__.py | 622 | ||||
-rw-r--r-- | pykolab/cli/cmd_create_mailbox.py | 43 | ||||
-rw-r--r-- | pykolab/cli/cmd_delete_mailbox.py | 53 | ||||
-rw-r--r-- | pykolab/cli/cmd_export_mailbox.py | 125 | ||||
-rw-r--r-- | pykolab/cli/cmd_list_deleted_mailboxes.py | 44 | ||||
-rw-r--r-- | pykolab/cli/cmd_list_domains.py | 54 | ||||
-rw-r--r-- | pykolab/cli/cmd_list_mailboxes.py | 63 | ||||
-rw-r--r-- | pykolab/cli/cmd_sync.py | 60 | ||||
-rw-r--r-- | pykolab/cli/cmd_undelete_mailbox.py | 48 | ||||
-rw-r--r-- | pykolab/cli/commands.py | 192 | ||||
-rw-r--r-- | pykolab/cli/telemetry/__init__.py | 0 | ||||
-rw-r--r-- | pykolab/cli/telemetry/cmd_examine_command_issue.py | 126 | ||||
-rw-r--r-- | pykolab/cli/telemetry/cmd_examine_session.py | 144 | ||||
-rw-r--r-- | pykolab/cli/telemetry/cmd_expire_sessions.py | 39 | ||||
-rw-r--r-- | pykolab/cli/telemetry/cmd_list_sessions.py | 66 |
15 files changed, 1067 insertions, 612 deletions
diff --git a/pykolab/cli/__init__.py b/pykolab/cli/__init__.py index 65c60c8..98075c9 100644 --- a/pykolab/cli/__init__.py +++ b/pykolab/cli/__init__.py @@ -43,621 +43,19 @@ imap = pykolab.imap class Cli(object): def __init__(self): - domain_group = conf.add_cli_parser_option_group(_("CLI Options")) + import commands + commands.__init__() - domain_group.add_option( '--review', - dest = "review", - action = "store_true", - default = False, - help = _("Review LDIF before committed")) + to_execute = [] - conf.finalize_conf() + arg_num = 1 + for arg in sys.argv[1:]: + arg_num += 1 + if not arg.startswith('-') and len(sys.argv) > arg_num: + if commands.commands.has_key(sys.argv[arg_num].replace('-','_')): + to_execute.append(sys.argv[arg_num].replace('-','_')) - try: - action = conf.cli_args.pop(0) - except IndexError, e: - self.no_command() - - action_function = action.replace('-','_') - action_components = action.split('-') - - if hasattr(self, "action_%s" %(action)): - exec("self.action_%s()" %(action)) - elif hasattr(self, "action_%s" %(action_function)): - log.info(_("TODO: self.check_%s()") %(action_function)) - exec("self.action_%s()" %(action_function)) - else: - try: - action_domain = action_components.pop() - action_action = action_components.pop() - exec("from pykolab.cli import action_%s" %(action_domain)) - if hasattr("action_%s" %(action_domain), "%s" %(action_action)): - exec( - "result = action_%s.%s(%r)" %( - action_domain, - action_action, - conf.cli_args - ) - ) - - except IndexError, e: - self.no_command() - except ImportError, e: - pass - - self.print_usage() - - def no_command(self): - print >> sys.stderr, _("No command given, see --help for details") - sys.exit(1) - - ## - ## Alias (shorthand) commands - ## - - def action_cm(self): - """ - Alias for action_create_mailbox - """ - - self.action_create_mailbox() - - def action_dm(self): - """ - Alias for action_delete_mailbox - """ - - self.action_delete_mailbox() - - def action_lm(self): - """ - Alias for action_list_mailbox - """ - - self.action_list_mailbox() - - ## - ## Actual commands - ## - - def action_add_domain(self): - log.info( - _("TODO: Figure out where the domain should actually be added.") - ) - - domainname = conf.cli_args.pop(0) - - log.info(_("Adding domain %s") %(domainname)) - - # The dn of our new entry/object - log.info(_("TODO: Make the format for a new domain configurable.")) - dn = "associateddomain=%s,cn=kolab,cn=config" %(domainname) - - # A dict to help build the "body" of the object - log.info(_("TODO: Make what a domain looks like configurable.")) - attrs = {} - attrs['objectclass'] = [ - 'top', - 'domainrelatedobject', - 'organization', - 'inetdomain' - ] - attrs['associatedDomain'] = ['%s' %(domainname)] - domainname_components = domainname.split('.') - attrs['inetDomainBaseDN'] = [ - 'dc=%s,dc=%s' %( - domainname_components[0], - domainname_components[1] - ) - ] - - # TODO: Prompt for organization name/description. For now, use domain - # name. - attrs['o'] = ['%s' %(domainname)] - - go_ahead = True - - if conf.cli_keywords.review: - ldif_writer = ldif.LDIFWriter(sys.stdout) - ldif_writer.unparse(dn,attrs) - if not utils.ask_confirmation( - _("Please ACK or NACK the above LDIF:"), - default="y", - all_inclusive_no=True - ): - - go_ahead = False - - if go_ahead: - # Convert our dict to nice syntax for the add-function using - # modlist-module - _ldif = addModlist(attrs) - - # TODO: Use auth - # Now build an ldap connection and execute the motherf. - ldap_con = ldap.initialize(conf.get('ldap', 'uri')) - ldap_con.bind_s( - conf.get('ldap', 'bind_dn'), - conf.get('ldap', 'bind_pw') - ) - - # The try/except should actually be in check_add_domain - try: - # Do the actual synchronous add-operation to the ldapserver - ldap_con.add_s(dn,_ldif) - except ldap.ALREADY_EXISTS, e: - log.error(_("Domain %s already exists.") %(domainname)) - - # Its nice to the server to disconnect and free resources when done - ldap_con.unbind_s() - - def action_add_group(self): - print >> sys.stderr, _("Not yet implemented.") - sys.exit(1) - - def action_add_user(self): - print >> sys.stderr, _("Not yet implemented.") - sys.exit(1) - - def action_create_mailbox(self): - mailbox = conf.cli_args.pop(0) - - imap.connect() - imap.cm(mailbox) - - def action_delete_domain(self): - domainname = conf.cli_args.pop(0) - - log.info(_("Deleting domain %s") %(domainname)) - - dn = "associateddomain=%s,cn=kolab,cn=config" %(domainname) - - # TODO: Use auth - ldap_con = ldap.initialize(conf.get('ldap', 'uri')) - ldap_con.bind_s( - conf.get('ldap', 'bind_dn'), - conf.get('ldap', 'bind_pw') - ) - - # The try/except should actually be in check_del_domain() - try: - # Do the actual synchronous add-operation to the ldapserver - ldap_con.delete_s(dn) - except ldap.NO_SUCH_OBJECT, e: - log.error(_("No domain %s exists.") %(domainname)) - - # Its nice to the server to disconnect and free resources when done - ldap_con.unbind_s() - - def action_delete_group(self): - print >> sys.stderr, _("Not yet implemented.") - sys.exit(1) - - def action_delete_mailbox(self): - """ - Delete mailbox - """ - - target_folder = None - - try: - delete_folder = conf.cli_args.pop(0) - except IndexError, e: - print >> sys.stderr, _("No mailbox specified") - sys.exit(1) - - imap.connect() - imap.dm(delete_folder) - - def action_delete_user(self): - print >> sys.stderr, _("Not yet implemented.") - sys.exit(1) - - def action_export_mailbox(self): - import os - import subprocess - - user = conf.cli_args.pop(0) - - # TODO: /etc/imapd.conf is not the definitive location for the - # imapd.conf configuration file. - partition_proc = subprocess.Popen( - ['grep', '^partition', '/etc/imapd.conf'], - stdout=subprocess.PIPE - ) - - partitions = [ - x.split(':')[1].strip() - for x in partition_proc.communicate()[0].split('\n') - if len(x.split(':')) > 1 - ] - - # TODO: ctl_mboxlist is not necessarily in this location. - ctl_mboxlist_args = [ '/usr/lib/cyrus-imapd/ctl_mboxlist', '-d' ] - ctl_mboxlist = subprocess.Popen( - ctl_mboxlist_args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - - mboxlist_proc = subprocess.Popen( - ['grep', '-E', '\s*%s\s*.*i.*p.*' %(user)], - stdin=ctl_mboxlist.stdout, - stdout=subprocess.PIPE - ) - - ctl_mboxlist.stdout.close() - - # TODO: Handle errors from ctl_mboxlist process (stderr) - mboxlist_output = mboxlist_proc.communicate()[0] - - zipper_args = [ 'zip', '-r', '%s.zip' %(user) ] - directories = [] - - for mbox_internal in mboxlist_output.split('\n'): - if len(mbox_internal.split('\t')[0].split('!')) > 1: - domain = mbox_internal.split('\t')[0].split('!')[0] - mailbox = '/'.join( - mbox_internal.split( - '\t' - )[0].split( - '!' - )[1].split( - '.' - )[1:] - ) - - for partition in partitions: - mbox_dir = '%s/domain/%s/%s/%s/user/%s/' %( - partition, - domain[0], - domain, - user[0], - mailbox - ) - - if os.path.isdir(mbox_dir): - directories.append(mbox_dir) - - else: - log.debug( - _('%s is not a directory') %(mbox_dir), - level=5 - ) - - if not len(directories) == 0: - zipper_output = subprocess.Popen( - zipper_args + directories, - stdout=subprocess.PIPE - ).communicate()[0] - - print >> sys.stderr, _("ZIP file at %s.zip") %(user) - else: - print >> sys.stderr, _("No directories found for user %s") %(user) - sys.exit(1) - - def action_list_deleted(self): - """ - List deleted mailboxes - """ - imap.connect() - folders = imap.lm("DELETED/*") - print "Deleted folders:" - for folder in folders: - print folder - - def action_list_domains(self): - auth.connect() - - # Create the authentication object. - # TODO: Binds with superuser credentials! - domains = auth.list_domains() - - # TODO: Take a hint in --quiet, and otherwise print out a nice table - # with headers and such. - for domain,domain_aliases in domains: - if len(domain_aliases) > 0: - print _("Primary domain: %s - Secondary domain(s): %s") %( - domain, - ', '.join(domain_aliases) - ) - else: - print _("Primary domain: %s") %(domain) - - def action_list_mailbox(self): - """ - List mailboxes - """ - try: - searches = [ conf.cli_args.pop(0) ] - except IndexError, e: - #searches = [ 'DELETED/*', 'shared/*', 'user/*' ] - searches = [ '' ] - - imap.connect() - - folders = [] - - for search in searches: - folders.extend(imap.lm(search)) - - for folder in folders: - print folder - - def action_sync(self): - log.debug(_("Listing domains..."), level=5) - start_time = time.time() - domains = auth.list_domains() - end_time = time.time() - log.debug( - _("Found %d domains in %d seconds") %( - len(domains), - (end_time-start_time) - ), - level=8 - ) - - all_folders = [] - - for primary_domain,secondary_domains in domains: - log.debug(_("Running for domain %s") %(primary_domain), level=8) - auth.connect(primary_domain) - start_time = time.time() - auth.synchronize(primary_domain, secondary_domains) - end_time = time.time() - - log.info(_("Synchronizing users for %s took %d seconds") - %(primary_domain, (end_time-start_time)) - ) - - def action_telemetry_examine_command_issue_id(self): - from pykolab import telemetry - - db = telemetry.init_db() - - try: - wanted = conf.cli_args.pop(0) - except: - log.error(_("Unspecified command issue identifier")) - sys.exit(1) - - command_issue = db.query( - telemetry.TelemetryCommandIssue - ).filter_by( - id=wanted - ).first() - - if command_issue == None: - log.error(_("Invalid command issue identifier")) - sys.exit(1) - - session = db.query( - telemetry.TelemetrySession - ).filter_by( - id=command_issue.session_id - ).first() - - if session == None: - log.error(_("Invalid session identifier")) - sys.exit(1) - - user = db.query( - telemetry.TelemetryUser - ).filter_by( - id=session.user_id - ).first() - - server = db.query( - telemetry.TelemetryServer - ).filter_by( - id=session.server_id - ).first() - - print _("Session by %s on server %s") %(user.sasl_username,server.fqdn) - - command_issues = db.query( - telemetry.TelemetryCommandIssue - ).filter_by( - session_id=session.id - ) - - for _command_issue in command_issues: - command = db.query( - telemetry.TelemetryCommand - ).filter_by( - id=_command_issue.command_id - ).first() - - command_arg = db.query( - telemetry.TelemetryCommandArg - ).filter_by( - id=_command_issue.command_arg_id - ).first() - - if command_issue.id == _command_issue.id: - print "=========" - - print "Client(%d): %s %s %s" %( - _command_issue.id, - _command_issue.command_tag, - command.command, - command_arg.command_arg - ) - - server_responses = db.query( - telemetry.TelemetryServerResponse - ).filter_by( - command_issue_id=_command_issue.id - ) - - for server_response in server_responses: - server_response_lines = server_response.response.split('\n'); - - for server_response_line in server_response_lines: - print "Server(%d): %s" %( - server_response.id, - server_response_line - ) - - if command_issue.id == _command_issue.id: - print "=========" - - def action_telemetry_examine_session(self, session_id=None): - from pykolab import telemetry - - db = telemetry.init_db() - - wanted = False - - if session_id == None: - try: - wanted = conf.cli_args.pop(0) - except: - log.error(_("Unspecified session identifier")) - sys.exit(1) - - if not wanted: - wanted = session_id - - session_wanted = None - - try: - _wanted = (int)(wanted) - session_wanted = _wanted - except: - user_wanted = wanted - - if not session_wanted == None: - session = db.query( - telemetry.TelemetrySession - ).filter_by( - id=session_wanted - ).first() - - if session == None: - log.error(_("Invalid session identifier")) - sys.exit(1) - - user = db.query( - telemetry.TelemetryUser - ).filter_by( - id=session.user_id - ).first() - - server = db.query( - telemetry.TelemetryServer - ).filter_by( - id=session.server_id - ).first() - - else: - user = db.query( - telemetry.TelemetryUser - ).filter_by( - sasl_username=user_wanted - ).first() - - sessions = db.query( - telemetry.TelemetrySession - ).filter_by( - user_id=user.id - ).order_by( - telemetry.telemetry_session_table.c.start - ) - - for session in sessions: - self.action_telemetry_examine_session(session_id=session.id) - - return - - print _("Session by %s on server %s") %(user.sasl_username,server.fqdn) - - command_issues = db.query( - telemetry.TelemetryCommandIssue - ).filter_by( - session_id=session.id - ) - - for command_issue in command_issues: - command = db.query( - telemetry.TelemetryCommand - ).filter_by( - id=command_issue.command_id - ).first() - - command_arg = db.query( - telemetry.TelemetryCommandArg - ).filter_by( - id=command_issue.command_arg_id - ).first() - - print "Client(%d): %s %s %s" %( - command_issue.id, - command_issue.command_tag, - command.command, - command_arg.command_arg - ) - - server_responses = db.query( - telemetry.TelemetryServerResponse - ).filter_by( - command_issue_id=command_issue.id - ) - - for server_response in server_responses: - server_response_lines = server_response.response.split('\n'); - for server_response_line in server_response_lines: - print "Server(%d): %s" %( - server_response.id, - server_response_line - ) - - def action_telemetry_expire_sessions(self): - from pykolab import telemetry - telemetry.expire_sessions() - - def action_telemetry_list_sessions(self): - from pykolab import telemetry - - db = telemetry.init_db() - - sessions = db.query( - telemetry.TelemetrySession - ).order_by( - telemetry.telemetry_session_table.c.start - ) - - for session in sessions: - user = db.query( - telemetry.TelemetryUser - ).filter_by( - id=session.user_id - ).first() - - print _("Session for user %s started at %s with ID %s") %( - user.sasl_username, - session.start, - session.id - ) - - def action_undelete_mailbox(self): - """ - Undelete mailbox - """ - - target_folder = None - - undelete_folder = conf.cli_args.pop(0) - if len(conf.cli_args) > 0: - target_folder = conf.cli_args.pop(0) - - imap.connect() - imap.undelete(undelete_folder, target_folder) + commands.execute('_'.join(to_execute)) def run(self): pass - - def print_usage(self): - print >> sys.stderr, _("Actions") + ":" - print >> sys.stderr, "add-domain <domainname>" - print >> sys.stderr, "list-domains" diff --git a/pykolab/cli/cmd_create_mailbox.py b/pykolab/cli/cmd_create_mailbox.py new file mode 100644 index 0000000..5e0fb80 --- /dev/null +++ b/pykolab/cli/cmd_create_mailbox.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('create_mailbox', execute, description=description(), aliases='cm') + +def description(): + return """Create a mailbox or sub-folder of an existing mailbox.""" + +def execute(*args, **kw): + mailbox = conf.cli_args.pop(0) + + imap.connect() + imap.cm(mailbox) + diff --git a/pykolab/cli/cmd_delete_mailbox.py b/pykolab/cli/cmd_delete_mailbox.py new file mode 100644 index 0000000..e1bd11f --- /dev/null +++ b/pykolab/cli/cmd_delete_mailbox.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('delete_mailbox', execute, description=description(), aliases=['dm']) + +def description(): + return """Delete a mailbox or sub-folder. Note that the mailbox or folder is removed recursively.""" + +def execute(*args, **kw): + """ + Delete mailbox + """ + + try: + delete_folder = conf.cli_args.pop(0) + except IndexError, e: + print >> sys.stderr, _("No mailbox specified") + sys.exit(1) + + imap.connect() + delete_folders = imap.lm(delete_folder) + for delete_folder in delete_folders: + imap.delete_mailfolder(delete_folder) + diff --git a/pykolab/cli/cmd_export_mailbox.py b/pykolab/cli/cmd_export_mailbox.py new file mode 100644 index 0000000..eaca347 --- /dev/null +++ b/pykolab/cli/cmd_export_mailbox.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('export_mailbox', execute) + +def cli_options(): + my_option_group = conf.add_cli_parser_option_group(_("CLI Options")) + my_option_group.add_option( '--all', + dest = "all", + action = "store_true", + default = False, + help = _("All folders this user has access to")) + +def execute(*args, **kw): + import os + import subprocess + + user = conf.cli_args.pop(0) + + # TODO: /etc/imapd.conf is not the definitive location for the + # imapd.conf configuration file. + partition_proc = subprocess.Popen( + ['grep', '^partition', '/etc/imapd.conf'], + stdout=subprocess.PIPE + ) + + partitions = [ + x.split(':')[1].strip() + for x in partition_proc.communicate()[0].split('\n') + if len(x.split(':')) > 1 + ] + + # TODO: ctl_mboxlist is not necessarily in this location. + ctl_mboxlist_args = [ '/usr/lib/cyrus-imapd/ctl_mboxlist', '-d' ] + ctl_mboxlist = subprocess.Popen( + ctl_mboxlist_args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + + mboxlist_proc = subprocess.Popen( + ['grep', '-E', '\s*%s\s*.*i.*p.*' %(user)], + stdin=ctl_mboxlist.stdout, + stdout=subprocess.PIPE + ) + + ctl_mboxlist.stdout.close() + + # TODO: Handle errors from ctl_mboxlist process (stderr) + mboxlist_output = mboxlist_proc.communicate()[0] + + zipper_args = [ 'zip', '-r', '%s.zip' %(user) ] + directories = [] + + for mbox_internal in mboxlist_output.split('\n'): + if len(mbox_internal.split('\t')[0].split('!')) > 1: + domain = mbox_internal.split('\t')[0].split('!')[0] + mailbox = '/'.join( + mbox_internal.split( + '\t' + )[0].split( + '!' + )[1].split( + '.' + )[1:] + ) + + for partition in partitions: + mbox_dir = '%s/domain/%s/%s/%s/user/%s/' %( + partition, + domain[0], + domain, + user[0], + mailbox + ) + + if os.path.isdir(mbox_dir): + directories.append(mbox_dir) + + else: + log.debug( + _('%s is not a directory') %(mbox_dir), + level=5 + ) + + if not len(directories) == 0: + zipper_output = subprocess.Popen( + zipper_args + directories, + stdout=subprocess.PIPE + ).communicate()[0] + + print >> sys.stderr, _("ZIP file at %s.zip") %(user) + else: + print >> sys.stderr, _("No directories found for user %s") %(user) + sys.exit(1) + diff --git a/pykolab/cli/cmd_list_deleted_mailboxes.py b/pykolab/cli/cmd_list_deleted_mailboxes.py new file mode 100644 index 0000000..3ca6991 --- /dev/null +++ b/pykolab/cli/cmd_list_deleted_mailboxes.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('list_deleted_mailboxes', execute) + +def execute(*args, **kw): + """ + List deleted mailboxes + """ + imap.connect() + folders = imap.lm("DELETED/*") + print "Deleted folders:" + for folder in folders: + print folder + diff --git a/pykolab/cli/cmd_list_domains.py b/pykolab/cli/cmd_list_domains.py new file mode 100644 index 0000000..7018445 --- /dev/null +++ b/pykolab/cli/cmd_list_domains.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('list_domains', execute, description="List Kolab domains.") + +def execute(*args, **kw): + auth.connect() + + # Create the authentication object. + # TODO: Binds with superuser credentials! + domains = auth.list_domains() + + print "%-39s %-40s" %("Primary Domain Name Space","Secondary Domain Name Space(s)") + + # TODO: Take a hint in --quiet, and otherwise print out a nice table + # with headers and such. + for domain,domain_aliases in domains: + if len(domain_aliases) > 0: + print _("%-39s %-40s") %( + domain, + ', '.join(domain_aliases) + ) + else: + print _("%-39s") %(domain) + diff --git a/pykolab/cli/cmd_list_mailboxes.py b/pykolab/cli/cmd_list_mailboxes.py new file mode 100644 index 0000000..f6f6e10 --- /dev/null +++ b/pykolab/cli/cmd_list_mailboxes.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('list_mailboxes', execute, description="List mailboxes.\n" + \ + "%-28s" %('') + \ + "Use wildcards '*' and '%' for more control.\n") + +def cli_options(): + my_option_group = conf.add_cli_parser_option_group(_("CLI Options")) + my_option_group.add_option( '--raw', + dest = "raw", + action = "store_true", + default = False, + help = _("Display raw UTF-7 folder names")) + +def execute(*args, **kw): + """ + List mailboxes + """ + try: + searches = [ conf.cli_args.pop(1) ] + except IndexError, e: + #searches = [ 'DELETED/*', 'shared/*', 'user/*' ] + searches = [ '' ] + + imap.connect() + + folders = [] + + for search in searches: + folders.extend(imap.lm(search)) + + for folder in folders: + print folder diff --git a/pykolab/cli/cmd_sync.py b/pykolab/cli/cmd_sync.py new file mode 100644 index 0000000..ebb9cf3 --- /dev/null +++ b/pykolab/cli/cmd_sync.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('sync', execute, description="Synchronize Kolab Users with IMAP.") + +def execute(*args, **kw): + log.debug(_("Listing domains..."), level=5) + start_time = time.time() + domains = auth.list_domains() + end_time = time.time() + log.debug( + _("Found %d domains in %d seconds") %( + len(domains), + (end_time-start_time) + ), + level=8 + ) + + all_folders = [] + + for primary_domain,secondary_domains in domains: + log.debug(_("Running for domain %s") %(primary_domain), level=8) + auth.connect(primary_domain) + start_time = time.time() + auth.synchronize(primary_domain, secondary_domains) + end_time = time.time() + + log.info(_("Synchronizing users for %s took %d seconds") + %(primary_domain, (end_time-start_time)) + ) + diff --git a/pykolab/cli/cmd_undelete_mailbox.py b/pykolab/cli/cmd_undelete_mailbox.py new file mode 100644 index 0000000..e4dec3a --- /dev/null +++ b/pykolab/cli/cmd_undelete_mailbox.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import commands + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +def __init__(): + commands.register('undelete_mailbox', execute, description="Recover mailboxes previously deleted.") + +def execute(*args, **kw): + """ + Undelete mailbox + """ + + target_folder = None + + undelete_folder = conf.cli_args.pop(0) + if len(conf.cli_args) > 0: + target_folder = conf.cli_args.pop(0) + + imap.connect() + imap.undelete_mailfolder(undelete_folder, target_folder) + diff --git a/pykolab/cli/commands.py b/pykolab/cli/commands.py new file mode 100644 index 0000000..2173ce0 --- /dev/null +++ b/pykolab/cli/commands.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import os +import sys + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +commands = {} +command_groups = {} + +def __init__(): + # We only want the base path + commands_base_path = os.path.dirname(__file__) + + for commands_path, dirnames, filenames in os.walk(commands_base_path): + if not commands_path == commands_base_path: + continue + + for filename in filenames: + if filename.startswith('cmd_') and filename.endswith('.py'): + module_name = filename.replace('.py','') + cmd_name = module_name.replace('cmd_', '') + #print "exec(\"from %s import __init__ as %s_register\"" %(module_name,cmd_name) + exec("from %s import __init__ as %s_register" %(module_name,cmd_name)) + exec("%s_register()" %(cmd_name)) + + for dirname in dirnames: + register_group(commands_path, dirname) + + register('help', list_commands) + + register('list_users', not_yet_implemented, description="Not yet implemented") + register('add_user', not_yet_implemented, description="Not yet implemented") + register('delete_user', not_yet_implemented, description="Not yet implemented") + + register('list_groups', not_yet_implemented, description="Not yet implemented") + register('add_group', not_yet_implemented, description="Not yet implemented") + register('delete_group', not_yet_implemented, description="Not yet implemented") + + register('add_domain', not_yet_implemented, description="Not yet implemented") + register('delete_domain', not_yet_implemented, description="Not yet implemented") + +def list_commands(*args, **kw): + """ + List commands + """ + + __commands = {} + + for command in commands.keys(): + if isinstance(command, tuple): + command_group, command = command + __commands[command_group] = { + command: commands[(command_group,command)] + } + else: + __commands[command] = commands[command] + + _commands = __commands.keys() + _commands.sort() + + for _command in _commands: + if __commands[_command].has_key('function'): + # This is a top-level command + if not __commands[_command]['description'] == None: + print "%-25s - %s" %(_command.replace('_','-'),__commands[_command]['description']) + else: + print "%-25s" %(_command.replace('_','-')) + + for _command in _commands: + if not __commands[_command].has_key('function'): + # This is a nested command + print "\n" + _("Command Group: %s") %(_command) + "\n" + ___commands = __commands[_command].keys() + ___commands.sort() + for __command in ___commands: + if not __commands[_command][__command]['description'] == None: + print "%-4s%-21s - %s" %('',__command.replace('_','-'),__commands[_command][__command]['description']) + else: + print "%-4s%-21s" %('',__command.replace('_','-')) + +def execute(cmd_name, *args, **kw): + if not commands.has_key(cmd_name): + log.error(_("No such command.")) + sys.exit(1) + + if not commands[cmd_name].has_key('function') and \ + not commands[cmd_name].has_key('group'): + log.error(_("No such command.")) + sys.exit(1) + + if commands[cmd_name].has_key('group'): + group = commands[cmd_name]['group'] + command_name = commands[cmd_name]['cmd_name'] + try: + exec("from %s.cmd_%s import cli_options as %s_%s_cli_options" %(group,command_name,group,command_name)) + exec("%s_%s_cli_options()" %(group,command_name)) + except ImportError, e: + pass + + else: + try: + exec("from cmd_%s import cli_options as %s_cli_options" %(cmd_name,cmd_name)) + exec("%s_cli_options()" %(cmd_name)) + except ImportError, e: + pass + + conf.finalize_conf() + _cmd_name = conf.cli_args.pop(0) + commands[cmd_name]['function'](conf.cli_args, kw) + +def register_group(dirname, module): + commands_base_path = os.path.join(os.path.dirname(__file__), module) + + commands[module] = {} + + for commands_path, dirnames, filenames in os.walk(commands_base_path): + if not commands_path == commands_base_path: + continue + + for filename in filenames: + if filename.startswith('cmd_') and filename.endswith('.py'): + module_name = filename.replace('.py','') + cmd_name = module_name.replace('cmd_', '') + #print "exec(\"from %s.%s import __init__ as %s_%s_register\"" %(module,module_name,module,cmd_name) + exec("from %s.%s import __init__ as %s_%s_register" %(module,module_name,module,cmd_name)) + exec("%s_%s_register()" %(module,cmd_name)) + +def register(cmd_name, func, group=None, description=None, aliases=[]): + if not group == None: + command = "%s_%s" %(group,cmd_name) + else: + command = cmd_name + + if isinstance(aliases, basestring): + aliases = [aliases] + + if commands.has_key(command): + log.fatal(_("Command '%s' already registered") %(command)) + sys.exit(1) + + if callable(func): + if group == None: + commands[cmd_name] = { + 'function': func, + 'description': description + } + else: + commands[group][cmd_name] = { + 'function': func, + 'description': description + } + + commands[command] = commands[group][cmd_name] + commands[command]['group'] = group + commands[command]['cmd_name'] = cmd_name + + for alias in aliases: + commands[alias] = { + 'function': func, + 'description': _("Alias for %s") %(cmd_name) + } + +## +## Commands not yet implemented +## + +def not_yet_implemented(*args, **kw): + print _("Not yet implemented") + sys.exit(1)
\ No newline at end of file diff --git a/pykolab/cli/telemetry/__init__.py b/pykolab/cli/telemetry/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pykolab/cli/telemetry/__init__.py diff --git a/pykolab/cli/telemetry/cmd_examine_command_issue.py b/pykolab/cli/telemetry/cmd_examine_command_issue.py new file mode 100644 index 0000000..cceb5fe --- /dev/null +++ b/pykolab/cli/telemetry/cmd_examine_command_issue.py @@ -0,0 +1,126 @@ + +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +from pykolab import telemetry +from pykolab.cli import commands + +def __init__(): + commands.register('examine_command_issue', execute, group='telemetry', description="Examine a particular telemetry command issue.") + +def execute(*args, **kw): + db = telemetry.init_db() + + try: + wanted = conf.cli_args.pop(0) + except: + log.error(_("Unspecified command issue identifier")) + sys.exit(1) + + command_issue = db.query( + telemetry.TelemetryCommandIssue + ).filter_by( + id=wanted + ).first() + + if command_issue == None: + log.error(_("Invalid command issue identifier")) + sys.exit(1) + + session = db.query( + telemetry.TelemetrySession + ).filter_by( + id=command_issue.session_id + ).first() + + if session == None: + log.error(_("Invalid session identifier")) + sys.exit(1) + + user = db.query( + telemetry.TelemetryUser + ).filter_by( + id=session.user_id + ).first() + + server = db.query( + telemetry.TelemetryServer + ).filter_by( + id=session.server_id + ).first() + + print _("Session by %s on server %s") %(user.sasl_username,server.fqdn) + + command_issues = db.query( + telemetry.TelemetryCommandIssue + ).filter_by( + session_id=session.id + ) + + for _command_issue in command_issues: + command = db.query( + telemetry.TelemetryCommand + ).filter_by( + id=_command_issue.command_id + ).first() + + command_arg = db.query( + telemetry.TelemetryCommandArg + ).filter_by( + id=_command_issue.command_arg_id + ).first() + + if command_issue.id == _command_issue.id: + print "=========" + + print "Client(%d): %s %s %s" %( + _command_issue.id, + _command_issue.command_tag, + command.command, + command_arg.command_arg + ) + + server_responses = db.query( + telemetry.TelemetryServerResponse + ).filter_by( + command_issue_id=_command_issue.id + ) + + for server_response in server_responses: + server_response_lines = server_response.response.split('\n'); + + for server_response_line in server_response_lines: + print "Server(%d): %s" %( + server_response.id, + server_response_line + ) + + if command_issue.id == _command_issue.id: + print "=========" + diff --git a/pykolab/cli/telemetry/cmd_examine_session.py b/pykolab/cli/telemetry/cmd_examine_session.py new file mode 100644 index 0000000..f36c0a9 --- /dev/null +++ b/pykolab/cli/telemetry/cmd_examine_session.py @@ -0,0 +1,144 @@ + +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +from pykolab import telemetry +from pykolab.cli import commands + +def __init__(): + commands.register('examine_session', execute, group='telemetry', description="Examine a Telemetry session.") + +def execute(*args, **kw): + db = telemetry.init_db() + + wanted = False + + if session_id == None: + try: + wanted = conf.cli_args.pop(0) + except: + log.error(_("Unspecified session identifier")) + sys.exit(1) + + if not wanted: + wanted = session_id + + session_wanted = None + + try: + _wanted = (int)(wanted) + session_wanted = _wanted + except: + user_wanted = wanted + + if not session_wanted == None: + session = db.query( + telemetry.TelemetrySession + ).filter_by( + id=session_wanted + ).first() + + if session == None: + log.error(_("Invalid session identifier")) + sys.exit(1) + + user = db.query( + telemetry.TelemetryUser + ).filter_by( + id=session.user_id + ).first() + + server = db.query( + telemetry.TelemetryServer + ).filter_by( + id=session.server_id + ).first() + + else: + user = db.query( + telemetry.TelemetryUser + ).filter_by( + sasl_username=user_wanted + ).first() + + sessions = db.query( + telemetry.TelemetrySession + ).filter_by( + user_id=user.id + ).order_by( + telemetry.telemetry_session_table.c.start + ) + + for session in sessions: + self.action_telemetry_examine_session(session_id=session.id) + + return + + print _("Session by %s on server %s") %(user.sasl_username,server.fqdn) + + command_issues = db.query( + telemetry.TelemetryCommandIssue + ).filter_by( + session_id=session.id + ) + + for command_issue in command_issues: + command = db.query( + telemetry.TelemetryCommand + ).filter_by( + id=command_issue.command_id + ).first() + + command_arg = db.query( + telemetry.TelemetryCommandArg + ).filter_by( + id=command_issue.command_arg_id + ).first() + + print "Client(%d): %s %s %s" %( + command_issue.id, + command_issue.command_tag, + command.command, + command_arg.command_arg + ) + + server_responses = db.query( + telemetry.TelemetryServerResponse + ).filter_by( + command_issue_id=command_issue.id + ) + + for server_response in server_responses: + server_response_lines = server_response.response.split('\n'); + for server_response_line in server_response_lines: + print "Server(%d): %s" %( + server_response.id, + server_response_line + ) + diff --git a/pykolab/cli/telemetry/cmd_expire_sessions.py b/pykolab/cli/telemetry/cmd_expire_sessions.py new file mode 100644 index 0000000..2da1d3f --- /dev/null +++ b/pykolab/cli/telemetry/cmd_expire_sessions.py @@ -0,0 +1,39 @@ + +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +from pykolab import telemetry +from pykolab.cli import commands + +def __init__(): + commands.register('expire_sessions', execute, group='telemetry', description="Expire Telemetry sessions.") + +def execute(*args, **kw): + telemetry.expire_sessions() + diff --git a/pykolab/cli/telemetry/cmd_list_sessions.py b/pykolab/cli/telemetry/cmd_list_sessions.py new file mode 100644 index 0000000..d2c5293 --- /dev/null +++ b/pykolab/cli/telemetry/cmd_list_sessions.py @@ -0,0 +1,66 @@ + +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 3 or, at your option, any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import pykolab + +from pykolab.translate import _ + +log = pykolab.getLogger('pykolab.cli') +conf = pykolab.getConf() + +auth = pykolab.auth +imap = pykolab.imap + +from pykolab import telemetry +from pykolab.cli import commands + +def __init__(): + commands.register('list_sessions', execute, group='telemetry', description="List IMAP sessions using Telemetry.") + +def cli_options(): + my_option_group = conf.add_cli_parser_option_group(_("List Options")) + my_option_group.add_option( '--since', + dest = "since", + action = "store", + default = 0, + help = _("Display sessions since ...")) + +def execute(*args, **kw): + db = telemetry.init_db() + + sessions = db.query( + telemetry.TelemetrySession + ).order_by( + telemetry.telemetry_session_table.c.start + ) + + for session in sessions: + user = db.query( + telemetry.TelemetryUser + ).filter_by( + id=session.user_id + ).first() + + print _("Session for user %s started at %s with ID %s") %( + user.sasl_username, + session.start, + session.id + ) + |