Source code for tic.development.admin.api

# -*- coding: utf-8 -*-
# 
# Copyright (C)2006-2009 Edgewall Software
#

import os.path
import sys
import traceback

from tic.core import *

console_date_format = '%Y-%m-%d'
console_datetime_format = '%Y-%m-%d %H:%M:%S'
console_date_format_hint = 'YYYY-MM-DD'

def _(str):
    """
    hack tell we implement multilanguage
    """
    return str

[docs]class AdminCommandError(TicError): """Exception raised when an admin command cannot be executed.""" def __init__(self, msg, show_usage=False, cmd=None): TicError.__init__(self, msg) self.show_usage = show_usage self.cmd = cmd
[docs]class IAdminCommandProvider(Interface): """Extension point interface for adding commands to the console administration interface. """
[docs] def get_admin_commands(self): """Return a list of available admin commands. The items returned by this function must be tuples of the form `(command, args, help, complete, execute)`, where `command` contains the space-separated command and sub-command names, `args` is a string describing the command arguments and `help` is the help text. The first paragraph of the help text is taken as a short help, shown in the list of commands. `complete` is called to auto-complete the command arguments, with the current list of arguments as its only argument. It should return a list of relevant values for the last argument in the list. `execute` is called to execute the command, with the command arguments passed as positional arguments. """
[docs]class AdminCommandManager(Component): """tic command manager.""" providers = ExtensionPoint(IAdminCommandProvider)
[docs] def get_command_help(self, args=[]): """Return help information for a set of commands.""" commands = [] for provider in self.providers: for cmd in provider.get_admin_commands() or []: parts = cmd[0].split() if parts[:len(args)] == args: commands.append(cmd[:3]) commands.sort() return commands
[docs] def complete_command(self, args, cmd_only=False): """Perform auto-completion on the given arguments.""" comp = [] for provider in self.providers: for cmd in provider.get_admin_commands() or []: parts = cmd[0].split() plen = min(len(parts), len(args) - 1) if args[:plen] != parts[:plen]: # Prefix doesn't match continue elif len(args) <= len(parts): # Command name comp.append(parts[len(args) - 1]) elif not cmd_only: # Arguments if cmd[3] is None: return [] return cmd[3](args[len(parts):]) or [] return comp
[docs] def execute_command(self, *args): """Execute a command given by a list of arguments.""" args = list(args) for provider in self.providers: for cmd in provider.get_admin_commands() or []: parts = cmd[0].split() if args[:len(parts)] == parts: f = cmd[4] fargs = args[len(parts):] try: return f(*fargs) except AdminCommandError, e: e.cmd = ' '.join(parts) raise except TypeError, e: tb = traceback.extract_tb(sys.exc_info()[2]) if len(tb) == 1: raise AdminCommandError(_("Invalid arguments"), show_usage=True, cmd=' '.join(parts)) raise raise AdminCommandError(_("Command not found"), show_usage=True)
[docs]class PrefixList(list): """A list of prefixes for command argument auto-completion."""
[docs] def complete(self, text): return list(set(a for a in self if a.startswith(text)))
[docs]class PathList(list): """A list of paths for command argument auto-completion."""
[docs] def complete(self, text): """Return the items in the list matching text.""" matches = list(set(a for a in self if a.startswith(text))) if len(matches) == 1 and not os.path.isdir(matches[0]): matches[0] += ' ' return matches
[docs]def get_dir_list(path, dirs_only=False): """Return a list of paths to filesystem entries in the same directory as the given path.""" dname = os.path.dirname(path) d = os.path.join(os.getcwd(), dname) result = PathList() try: dlist = os.listdir(d) except OSError: return result for entry in dlist: path = os.path.join(dname, entry) try: if os.path.isdir(path): result.append(os.path.join(path, '')) elif not dirs_only: result.append(path) except OSError: pass return result