Ticket #3439: admin-provider.diff

File admin-provider.diff, 4.2 kB (added by progrium@gmail.com, 4 months ago)
  • trac/admin/api.py

    old new  
    3333        where `template` is the name of the template to use and `data` is the 
    3434        data to be passed to the template. 
    3535        """ 
     36         
     37class IAdminConsoleProvider(Interface): 
     38    """ 
     39    Extension point interface for components to provide an administrative 
     40    interface from within trac-admin. 
     41    """ 
     42 
     43    def get_console_commands(self, tracadm): 
     44        """ 
     45        Return an iterable of (name, help, callable, completer) tuples. 
     46 
     47        tracadm is a TracAdmin instance. 
     48 
     49        completer can be null. help is in the same format that trac-admin 
     50        uses. 
     51        """ 
     52     
     53class AdminCommands(Component): 
     54    """ 
     55    Component end-point for IAdminConsoleProvider extensions 
     56    """ 
     57    admin_providers = ExtensionPoint(IAdminConsoleProvider) 
     58 
     59    def import_providers(self, tracadm): 
     60        for provider in self.admin_providers: 
     61            for command in provider.get_console_commands(tracadm): 
     62                name, help, callback, completer = command 
     63                if hasattr(tracadm.__class__, 'do_' + name): 
     64                    raise Exception("Can't use IAdminConsoleProvider %s, console command '%s' already exists" % (provider.__class__.__name__, name)) 
     65                setattr(tracadm.__class__, 'do_' + name, callback) 
     66                setattr(tracadm.__class__, '_help_' + name, help) 
     67                if completer: 
     68                    setattr(tracadm.__class__, 'complete_' + name, completer) 
  • trac/admin/console.py

    old new  
    2828 
    2929from trac import __version__ as VERSION 
    3030from trac import perm, util, db_default 
    31 from trac.core import TracError 
     31from trac.core import * 
     32from trac.loader import load_components 
    3233from trac.env import Environment 
    3334from trac.perm import PermissionSystem 
    3435from trac.ticket.model import * 
     
    4142from trac.wiki import WikiPage 
    4243from trac.wiki.api import WikiSystem 
    4344from trac.wiki.macros import WikiMacroBase 
     45from trac.admin import AdminCommands, IAdminConsoleProvider 
    4446 
    4547TRAC_VERSION = pkg_resources.get_distribution('Trac').version 
    4648 
     49 
    4750def copytree(src, dst, symlinks=False, skip=[]): 
    4851    """Recursively copy a directory tree using copy2() (from shutil.copytree.) 
    4952 
     
    8487    _date_format = '%Y-%m-%d' 
    8588    _datetime_format = '%Y-%m-%d %H:%M:%S' 
    8689    _date_format_hint = 'YYYY-MM-DD' 
     90    _admin_commands = None 
    8791 
    8892    def __init__(self, envdir=None): 
    8993        cmd.Cmd.__init__(self) 
     
    129133        self.prompt = "Trac [%s]> " % self.envname 
    130134        if env is not None: 
    131135            self.__env = env 
     136        else: 
     137            self.env_open() 
    132138 
    133139    def env_check(self): 
    134140        try: 
     
    141147        try: 
    142148            if not self.__env: 
    143149                self.__env = Environment(self.envname) 
     150                AdminCommands(self.__env).import_providers(self) 
    144151            return self.__env 
    145152        except Exception, e: 
    146153            print 'Failed to open environment.', e 
     
    254261    _help_help = [('help', 'Show documentation')] 
    255262 
    256263    def all_docs(cls): 
    257         return (cls._help_help + cls._help_initenv + cls._help_hotcopy + 
    258                 cls._help_resync + cls._help_upgrade + cls._help_deploy + 
    259                 cls._help_permission + cls._help_wiki + 
    260                 cls._help_ticket + cls._help_ticket_type +  
    261                 cls._help_priority + cls._help_severity + 
    262                 cls._help_component + cls._help_version + 
    263                 cls._help_milestone + cls._help_resolution) 
     264        # Extract documentation from all _help_* members 
     265        docs = [] 
     266        doc_strings = [doc for doc in dir(cls) if doc.startswith('_help_') and doc[6:] not in ('EOF', 'exit', 'quit')] 
     267        for doc in doc_strings: 
     268            docs.extend(getattr(cls, doc)) 
     269        docs.sort(lambda a, b: cmp(a[0], b[0])) 
     270        return docs 
    264271    all_docs = classmethod(all_docs) 
    265272 
    266273    def do_help(self, line=None):