Changeset 151

Show
Ignore:
Timestamp:
05/06/08 22:23:46 (2 months ago)
Author:
rgrp
Message:

[shakespeare/cli][s]: move cli code from bin into shakespeare.cli and run/install it using paste.scripts entry point in setup.py.

  • At same time: deprecate runserver command with info about using paster serve.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/setup.py

    Revision 148 Revision 151
    1try: 1try: 
    2    from setuptools import setup, find_packages 2    from setuptools import setup, find_packages 
    3except ImportError: 3except ImportError: 
    4    from ez_setup import use_setuptools 4    from ez_setup import use_setuptools 
    5    use_setuptools() 5    use_setuptools() 
    6    from setuptools import setup, find_packages 6    from setuptools import setup, find_packages 
    7 7 
    8import sys 8import sys 
    9sys.path.insert(0, '.') 9sys.path.insert(0, '.') 
    10from shakespeare import __version__, __application_name__ 10from shakespeare import __version__, __application_name__ 
    11 11 
    12setup( 12setup( 
    13    name = __application_name__, 13    name = __application_name__, 
    14    version = __version__, 14    version = __version__, 
    15    packages=find_packages(exclude=['ez_setup']), 15    packages=find_packages(exclude=['ez_setup']), 
    16    scripts = ['bin/shakespeare-admin'],   
    17    include_package_data=True, 16    include_package_data=True, 
    18 17 
    19    install_requires=[ 18    install_requires=[ 
    20        'Pylons>=0.9.6.1', 19        'Pylons>=0.9.6.1', 
    21        'SQLObject>=0.6', 20        'SQLObject>=0.6', 
    22        'Genshi>=0.3', 21        'Genshi>=0.3', 
    23        'annotater>=0.1', 22        'annotater>=0.1', 
    24        ], 23        ], 
    25    test_suite='nose.collector', 24    test_suite='nose.collector', 
    26    package_data={'shakespeare': ['i18n/*/LC_MESSAGES/*.mo']}, 25    package_data={'shakespeare': ['i18n/*/LC_MESSAGES/*.mo']}, 
    27    #message_extractors = {'shakespeare': [ 26    #message_extractors = {'shakespeare': [ 
    28    #        ('**.py', 'python', None), 27    #        ('**.py', 'python', None), 
    29    #        ('public/**', 'ignore', None)]}, 28    #        ('public/**', 'ignore', None)]}, 
    30    entry_points=''' 29    entry_points=''' 
    31    [paste.app_factory] 30    [paste.app_factory] 
    32    main = shakespeare.config.middleware:make_app 31    main = shakespeare.config.middleware:make_app 
    33 32 
    34    [paste.app_install] 33    [paste.app_install] 
    35    main = pylons.util:PylonsInstaller 34    main = pylons.util:PylonsInstaller 
      35 
      36    [console_scripts] 
      37    shakespeare-admin=shakespeare.cli:main 
    36    ''', 38    ''', 
    37 39 
    38    # metadata for upload to PyPI 40    # metadata for upload to PyPI 
    39    author = "Rufus Pollock (Open Knowledge Foundation)", 41    author = "Rufus Pollock (Open Knowledge Foundation)", 
    40    author_email = "rufus.pollock@okfn.org", 42    author_email = "rufus.pollock@okfn.org", 
    41    description = \ 43    description = \ 
    42"A full open set of Shakespeare's works along with anciallary material, a variety of tools and a python api", 44"A full open set of Shakespeare's works along with anciallary material, a variety of tools and a python api", 
    43    long_description = \ 45    long_description = \ 
    44""" 46""" 
    45The Open Shakespeare package provides a full open set of shakespeare's works 47The Open Shakespeare package provides a full open set of shakespeare's works 
    46(often in multiple versions) along with ancillary material, a variety of tools 48(often in multiple versions) along with ancillary material, a variety of tools 
    47and a python API. 49and a python API. 
    48 50 
    49Specifically in addition to the works themselves (often in multiple versions) 51Specifically in addition to the works themselves (often in multiple versions) 
    50there is an introduction, a chronology, explanatory notes, a concordance and 52there is an introduction, a chronology, explanatory notes, a concordance and 
    51search facilities. 53search facilities. 
    52 54 
    53All material is open source/open knowledge so that anyone can use, redistribute 55All material is open source/open knowledge so that anyone can use, redistribute 
    54and reuse these materials freely. For exact details of the license under which 56and reuse these materials freely. For exact details of the license under which 
    55this package is made available please see COPYING.txt. 57this package is made available please see COPYING.txt. 
    56 58 
    57Open Shakespeare has been developed under the aegis of the Open Knowledge 59Open Shakespeare has been developed under the aegis of the Open Knowledge 
    58Foundation (http://www.okfn.org/). 60Foundation (http://www.okfn.org/). 
    59""", 61""", 
    60    license = "MIT", 62    license = "MIT", 
    61    keywords = "open shakespeare search view", 63    keywords = "open shakespeare search view", 
    62    url = "http://www.openshakespeare.org/",  64    url = "http://www.openshakespeare.org/",  
    63    download_url = "http://www.openshakespeare.org/code/", 65    download_url = "http://www.openshakespeare.org/code/", 
    64    classifiers = [ 66    classifiers = [ 
    65        'Development Status :: 4 - Beta', 67        'Development Status :: 4 - Beta', 
    66        'Environment :: Console', 68        'Environment :: Console', 
    67        'Environment :: Web Environment', 69        'Environment :: Web Environment', 
    68        'Intended Audience :: Developers', 70        'Intended Audience :: Developers', 
    69        'License :: OSI Approved :: MIT License', 71        'License :: OSI Approved :: MIT License', 
    70        'Operating System :: OS Independent', 72        'Operating System :: OS Independent', 
    71        'Programming Language :: Python', 73        'Programming Language :: Python', 
    72        'Topic :: Software Development :: Libraries :: Python Modules'], 74        'Topic :: Software Development :: Libraries :: Python Modules'], 
    73) 75) 
  • trunk/shakespeare/cli.py

    Revision 138 Revision 151
    1#!/usr/bin/env python 1#!/usr/bin/env python 
    2 2 
    3import cmd 3import cmd 
    4import os 4import os 
    5import StringIO 5import StringIO 
    6 6 
    7class ShakespeareAdmin(cmd.Cmd): 7class ShakespeareAdmin(cmd.Cmd): 
    8    """ 8    """ 
    9    TODO: self.verbose option and associated self._print 9    TODO: self.verbose option and associated self._print 
    10    """ 10    """ 
    11 11 
    12    prompt = 'The Bard > ' 12    prompt = 'The Bard > ' 
    13 13 
    14    def run_interactive(self, line=None): 14    def run_interactive(self, line=None): 
    15        """Run an interactive session. 15        """Run an interactive session. 
    16        """ 16        """ 
    17        print 'Welcome to shakespeare-admin interactive mode\n' 17        print 'Welcome to shakespeare-admin interactive mode\n' 
    18        self.do_about() 18        self.do_about() 
    19        print 'Type:  "?" or "help" for help on commands.\n' 19        print 'Type:  "?" or "help" for help on commands.\n' 
    20        while 1: 20        while 1: 
    21            try: 21            try: 
    22                self.cmdloop() 22                self.cmdloop() 
    23                break 23                break 
    24            except KeyboardInterrupt: 24            except KeyboardInterrupt: 
    25                raise 25                raise 
    26 26 
    27    def do_help(self, line=None): 27    def do_help(self, line=None): 
    28        cmd.Cmd.do_help(self, line) 28        cmd.Cmd.do_help(self, line) 
    29 29 
    30    def do_about(self, line=None): 30    def do_about(self, line=None): 
    31        import shakespeare 31        import shakespeare 
    32        version = shakespeare.__version__ 32        version = shakespeare.__version__ 
    33        about = \ 33        about = \ 
    34'''Open Shakespeare version %s. Copyright the Open Knowledge Foundation. 34'''Open Shakespeare version %s. Copyright the Open Knowledge Foundation. 
    35Open Shakespeare is open-knowledge and open-source. See COPYING for details. 35Open Shakespeare is open-knowledge and open-source. See COPYING for details. 
    36''' % version 36''' % version 
    37        print about 37        print about 
    38 38 
    39    def do_quit(self, line=None): 39    def do_quit(self, line=None): 
    40        sys.exit() 40        sys.exit() 
    41 41 
    42    def do_EOF(self, *args): 42    def do_EOF(self, *args): 
    43        print '' 43        print '' 
    44        sys.exit() 44        sys.exit() 
    45 45 
    46    # ================= 46    # ================= 
    47    # Commands 47    # Commands 
    48 48 
    49    def do_db(self, line=None): 49    def do_db(self, line=None): 
    50        actions = [ 'create', 'clean', 'rebuild' ] 50        actions = [ 'create', 'clean', 'rebuild' ] 
    51        if line is None or line not in actions: 51        if line is None or line not in actions: 
    52            self.help_db() 52            self.help_db() 
    53            return 1 53            return 1 
    54        import shakespeare.dm 54        import shakespeare.dm 
    55        shakespeare.dm.__dict__[line+'db']() 55        shakespeare.dm.__dict__[line+'db']() 
    56 56 
    57    def help_db(self, line=None): 57    def help_db(self, line=None): 
    58        usage = \ 58        usage = \ 
    59'''db <action> 59'''db <action> 
    60 60 
    61Where action is one of create, clean, rebuild.''' 61Where action is one of create, clean, rebuild.''' 
    62        print usage 62        print usage 
    63     63     
    64    def do_gutenberg(self, line=None): 64    def do_gutenberg(self, line=None): 
    65        import shakespeare.gutenberg 65        import shakespeare.gutenberg 
    66        helper = shakespeare.gutenberg.Helper(verbose=True) 66        helper = shakespeare.gutenberg.Helper(verbose=True) 
    67        if not line: 67        if not line: 
    68            helper.execute() 68            helper.execute() 
    69        elif line == 'print_index': 69        elif line == 'print_index': 
    70            import pprint 70            import pprint 
    71            pprint.pprint(helper.get_index()) 71            pprint.pprint(helper.get_index()) 
    72        else: 72        else: 
    73            msg = 'Unknown argument %s' % line 73            msg = 'Unknown argument %s' % line 
    74            raise Exception(msg) 74            raise Exception(msg) 
    75 75 
    76    def help_gutenberg(self, line=None): 76    def help_gutenberg(self, line=None): 
    77        usage = \ 77        usage = \ 
    78""" 78""" 
    79Download and process all Project Gutenberg shakespeare texts""" 79Download and process all Project Gutenberg shakespeare texts""" 
    80        print usage  80        print usage  
    81 81 
    82    def do_moby(self, line=None): 82    def do_moby(self, line=None): 
    83        import shakespeare.moby 83        import shakespeare.moby 
    84        helper = shakespeare.moby.Helper(verbose=True) 84        helper = shakespeare.moby.Helper(verbose=True) 
    85        if not line: 85        if not line: 
    86            helper.execute() 86            helper.execute() 
    87        elif line == 'print_index': 87        elif line == 'print_index': 
    88            import pprint 88            import pprint 
    89            pprint.pprint(helper.get_index()) 89            pprint.pprint(helper.get_index()) 
    90        else: 90        else: 
    91            msg = 'Unknown argument %s' % line 91            msg = 'Unknown argument %s' % line 
    92            raise Exception(msg) 92            raise Exception(msg) 
    93 93 
    94    def help_moby(self, line=None): 94    def help_moby(self, line=None): 
    95        usage = \ 95        usage = \ 
    96''' 96''' 
    97Download and process all Moby/Bosak shakespeare texts''' 97Download and process all Moby/Bosak shakespeare texts''' 
    98        print usage  98        print usage  
    99 99 
    100    def _init_index(self): 100    def _init_index(self): 
    101        import shakespeare.index 101        import shakespeare.index 
    102        self._index = shakespeare.index.all 102        self._index = shakespeare.index.all 
    103 103 
    104    def _filter_index(self, line): 104    def _filter_index(self, line): 
    105        """Filter items in index return only those whose id (url) is in line 105        """Filter items in index return only those whose id (url) is in line 
    106        If line is empty or None return all items 106        If line is empty or None return all items 
    107        """ 107        """ 
    108        if line: 108        if line: 
    109            textsToAdd = [] 109            textsToAdd = [] 
    110            textNames = line.split() 110            textNames = line.split() 
    111            for item in self._index: 111            for item in self._index: 
    112                if item.name in textNames: 112                if item.name in textNames: 
    113                    textsToAdd.append(item) 113                    textsToAdd.append(item) 
    114            return textsToAdd 114            return textsToAdd 
    115        else: 115        else: 
    116            self._init_index() 116            self._init_index() 
    117            return self._index 117            return self._index 
    118     118     
    119    def do_print_index(self, line): 119    def do_print_index(self, line): 
    120        self._init_index() 120        self._init_index() 
    121        header = \ 121        header = \ 
    122'''          +-------------------+ 122'''          +-------------------+ 
    123          | Index of Material | 123          | Index of Material | 
    124          +-------------------+ 124          +-------------------+ 
    125 125 
    126''' 126''' 
    127        print header 127        print header 
    128        for row in self._index: 128        for row in self._index: 
    129            print row.name.ljust(35), row.title 129            print row.name.ljust(35), row.title 
    130 130 
    131    def help_print_index(self, line=None): 131    def help_print_index(self, line=None): 
    132        usage = \ 132        usage = \ 
    133'''Print index of Shakespeare texts to stdout''' 133'''Print index of Shakespeare texts to stdout''' 
    134        print usage 134        print usage 
    135 135 
    136    def do_make_concordance(self, line=None): 136    def do_make_concordance(self, line=None): 
    137        self._init_index() 137        self._init_index() 
    138        print 'Making concordance (this may take some time ...):' 138        print 'Making concordance (this may take some time ...):' 
    139        from shakespeare.concordance import ConcordanceBuilder 139        from shakespeare.concordance import ConcordanceBuilder 
    140        import time 140        import time 
    141        start = end = 0 141        start = end = 0 
    142        start = time.time() 142        start = time.time() 
    143        cc = ConcordanceBuilder() 143        cc = ConcordanceBuilder() 
    144        textsToAdd = [] 144        textsToAdd = [] 
    145        if line is not None: 145        if line is not None: 
    146            textsToAdd = self._filter_index(line) 146            textsToAdd = self._filter_index(line) 
    147        else: 147        else: 
    148            def gut_non_folio(material): 148            def gut_non_folio(material): 
    149                return '_gut' in material.name and 'gut_f' not in material.name 149                return '_gut' in material.name and 'gut_f' not in material.name 
    150            textsToAdd = filter(gut_non_folio, self._index)  150            textsToAdd = filter(gut_non_folio, self._index)  
    151        for item in textsToAdd: 151        for item in textsToAdd: 
    152            print 'Adding: %s (%s)' % (item.name, item.title) 152            print 'Adding: %s (%s)' % (item.name, item.title) 
    153            cc.add_text(item.name) 153            cc.add_text(item.name) 
    154        end = time.time() 154        end = time.time() 
    155        timetaken = end - start 155        timetaken = end - start 
    156        print 'Finished. Time taken was %ss' % timetaken 156        print 'Finished. Time taken was %ss' % timetaken 
    157 157 
    158    def help_make_concordance(self, line=None): 158    def help_make_concordance(self, line=None): 
    159        usage = \ 159        usage = \ 
    160'''Create a concordance 160'''Create a concordance 
    161 161 
    162If no arguments supplied then use all non-folio gutenberg shakespeare texts. 162If no arguments supplied then use all non-folio gutenberg shakespeare texts. 
    163Otherwise arguments should be a space seperated list of work name ids 163Otherwise arguments should be a space seperated list of work name ids 
    164''' 164''' 
    165        print usage 165        print usage 
    166 166 
    167    def do_init(self, line=None): 167    def do_init(self, line=None): 
    168        self.do_gutenberg(line) 168        self.do_gutenberg(line) 
    169        self.do_moby(line) 169        self.do_moby(line) 
    170        self.do_make_concordance(line) 170        self.do_make_concordance(line) 
    171 171 
    172    def help_init(self, line=None): 172    def help_init(self, line=None): 
    173        usage = \ 173        usage = \ 
    174'''Convenience function that sets everything up by running: 174'''Convenience function that sets everything up by running: 
    175    1. gutenberg 175    1. gutenberg 
    176    2. moby 176    2. moby 
    177    3. make_concordance''' 177    3. make_concordance''' 
    178        print usage 178        print usage 
    179 179 
    180    def _runserver_wsgiref(self):   
    181        import wsgiref.simple_server   
    182        import shakespeare.wsgi   
    183        app = shakespeare.wsgi.app_factory(None)   
    184        port = 8080   
    185        httpd = wsgiref.simple_server.make_server('', port, app)   
    186        print "Serving HTTP on port %s..." % port   
    187        httpd.serve_forever()   
    188   
    189    def _runserver_paste_plain(self):   
    190        import shakespeare.wsgi   
    191        import paste.httpserver   
    192        app = shakespeare.wsgi.app_factory(None)   
    193        paste.httpserver.serve(app)   
    194   
    195    def _runserver_paste_deploy(self):   
    196        conf = shakespeare.conf()   
    197        paste_conf_file = os.path.abspath(conf.get('web', 'paste_conf_file'))   
    198        import paste.deploy   
    199        app = paste.deploy.loadapp('config:%s' % paste_conf_file)   
    200        import paste.httpserver   
    201        paste.httpserver.serve(app)   
    202   
    203    def do_runserver(self, line=None): 180    def do_runserver(self, line=None): 
    204        # default 181        self.help_runserver() 
    205        if not line or line == 'paste':   
    206            self._runserver_paste_plain()   
    207        elif line == 'wsgiref':   
    208            self._runserver_wsgiref()   
    209        else:   
    210            print 'Unknown argument: %s' % line   
    211            self.help_runserver()   
    212 182 
    213    def help_runserver(self, line=None): 183    def help_runserver(self, line=None): 
    214        usage = \ 184        usage = \ 
    215'''runserver [ paste (default) | wsgiref ]  185 '''This command has been DEPRECATED. 
    216  186  
    217Start a webserver (of optional type) to provide the user interface to the  187 Please use `paster serve` to run a server now, e.g.:: 
    218shakespeare package.  188  
    219  189     paster serve <my-config.ini> 
    220The resulting website should be availabe at http://localhost:8080  190 ''' 
    221'''  191         print usage 
    222        print usage  192  
    223  193  
    224  194 def main(): 
    225if __name__ == '__main__':  195     import optparse 
    226    import sys  196     usage = \ 
    227    adminCmd = ShakespeareAdmin()  197 '''%prog [options] <command> 
    228    if len(sys.argv) < 2:  198  
    229        adminCmd.run_interactive()  199 Run about or help for details.''' 
       200     parser = optparse.OptionParser(usage) 
       201     parser.add_option('-v', '--verbose', dest='verbose', help='Be verbose', 
       202             action='store_true', default=False)  
       203     options, args = parser.parse_args() 
       204      
       205     if len(args) == 0: 
       206         parser.print_help() 
       207         return 1 
    230    else: 208    else: 
    231        args = ' '.join(sys.argv[1:])  209         cmd = ShakespeareAdmin() 
       210         args = ' '.join(args) 
    232        args = args.replace('-','_') 211        args = args.replace('-','_') 
    233        adminCmd.onecmd(args)  212         cmd.onecmd(args) 
       213