| 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
|---|
| 2 | | 2 | |
|---|
| 3 | import cmd | 3 | import cmd |
|---|
| 4 | import os | 4 | import os |
|---|
| 5 | import StringIO | 5 | import StringIO |
|---|
| 6 | | 6 | |
|---|
| 7 | class ShakespeareAdmin(cmd.Cmd): | 7 | class 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 | def __init__(self, config=None, verbose=False): | 12 | def __init__(self, config=None, verbose=False): |
|---|
| 13 | # cmd.Cmd is not a new style class | 13 | # cmd.Cmd is not a new style class |
|---|
| 14 | cmd.Cmd.__init__(self) | 14 | cmd.Cmd.__init__(self) |
|---|
| 15 | self.config = config | 15 | self.config = config |
|---|
| 16 | self.verbose = verbose | 16 | self.verbose = verbose |
|---|
| 17 | | 17 | |
|---|
| 18 | def _print(self, msg, force=False): | 18 | def _print(self, msg, force=False): |
|---|
| 19 | if self.verbose or force: | 19 | if self.verbose or force: |
|---|
| 20 | print msg | 20 | print msg |
|---|
| 21 | | 21 | |
|---|
| 22 | def _register_config(self): | 22 | def _register_config(self): |
|---|
| 23 | import sys | 23 | import sys |
|---|
| 24 | if not self.config: | 24 | if not self.config: |
|---|
| 25 | msg = 'No configuration file has been specified. See -h help for details' | 25 | msg = 'No configuration file has been specified. See -h help for details' |
|---|
| 26 | print msg | 26 | print msg |
|---|
| 27 | sys.exit(1) | 27 | sys.exit(1) |
|---|
| 28 | import shakespeare | 28 | import shakespeare |
|---|
| 29 | shakespeare.register_config(self.config) | 29 | shakespeare.register_config(self.config) |
|---|
| 30 | | 30 | |
|---|
| 31 | def do_help(self, line=None): | 31 | def do_help(self, line=None): |
|---|
| 32 | cmd.Cmd.do_help(self, line) | 32 | cmd.Cmd.do_help(self, line) |
|---|
| 33 | | 33 | |
|---|
| 34 | def do_about(self, line=None): | 34 | def do_about(self, line=None): |
|---|
| 35 | import shakespeare | 35 | import shakespeare |
|---|
| 36 | version = shakespeare.__version__ | 36 | version = shakespeare.__version__ |
|---|
| 37 | about = \ | 37 | about = \ |
|---|
| 38 | '''Open Shakespeare version %s. Copyright the Open Knowledge Foundation. | 38 | '''Open Shakespeare version %s. Copyright the Open Knowledge Foundation. |
|---|
| 39 | Open Shakespeare is open-knowledge and open-source. See COPYING for details. | 39 | Open Shakespeare is open-knowledge and open-source. See COPYING for details. |
|---|
| 40 | | 40 | |
|---|
| 41 | For more information about the package run `info`. | 41 | For more information about the package run `info`. |
|---|
| 42 | ''' % version | 42 | ''' % version |
|---|
| 43 | print about | 43 | print about |
|---|
| 44 | | 44 | |
|---|
| 45 | def do_quit(self, line=None): | 45 | def do_quit(self, line=None): |
|---|
| 46 | sys.exit() | 46 | sys.exit() |
|---|
| 47 | | 47 | |
|---|
| 48 | def do_EOF(self, *args): | 48 | def do_EOF(self, *args): |
|---|
| 49 | print '' | 49 | print '' |
|---|
| 50 | sys.exit() | 50 | sys.exit() |
|---|
| 51 | | 51 | |
|---|
| 52 | # ================= | 52 | # ================= |
|---|
| 53 | # Commands | 53 | # Commands |
|---|
| 54 | | 54 | |
|---|
| 55 | def do_db(self, line=None): | 55 | def do_db(self, line=None): |
|---|
| 56 | actions = [ 'create', 'clean', 'init' ] | 56 | actions = [ 'create', 'clean', 'init' ] |
|---|
| 57 | if line is None or line not in actions: | 57 | if line is None or line not in actions: |
|---|
| 58 | self.help_db() | 58 | self.help_db() |
|---|
| 59 | return 1 | 59 | return 1 |
|---|
| 60 | self._register_config() | 60 | self._register_config() |
|---|
| 61 | import shakespeare.model | 61 | import shakespeare.model |
|---|
| 62 | import shakespeare | 62 | import shakespeare |
|---|
| 63 | if line == 'init': | 63 | if line == 'init': |
|---|
| 64 | import pkg_resources | 64 | import pkg_resources |
|---|
| 65 | pkg = 'shksprdata' | 65 | pkg = 'shksprdata' |
|---|
| 66 | meta = pkg_resources.resource_stream(pkg, 'texts/metadata.txt') | 66 | meta = pkg_resources.resource_stream(pkg, 'texts/metadata.txt') |
|---|
| 67 | shakespeare.model.Material.load_from_metadata(meta) | 67 | shakespeare.model.Material.load_from_metadata(meta) |
|---|
| 68 | elif line == 'clean': | 68 | elif line == 'clean': |
|---|
| 69 | config = shakespeare.conf() | 69 | config = shakespeare.conf() |
|---|
| 70 | shakespeare.model.metadata.drop_all(bind=config['pylons.g'].sa_engine) | 70 | shakespeare.model.metadata.drop_all(bind=config['pylons.g'].sa_engine) |
|---|
| 71 | elif line == 'create': | 71 | elif line == 'create': |
|---|
| 72 | print 'To create db use paster: paster setup-app {config-file}' | 72 | print 'To create db use paster: paster setup-app {config-file}' |
|---|
| 73 | else: | 73 | else: |
|---|
| 74 | print self.help_db() | 74 | print self.help_db() |
|---|
| 75 | | 75 | |
|---|
| 76 | def help_db(self, line=None): | 76 | def help_db(self, line=None): |
|---|
| 77 | usage = \ | 77 | usage = \ |
|---|
| 78 | '''db { create | init } | 78 | '''db { create | init } |
|---|
| 79 | ''' | 79 | ''' |
|---|
| 80 | print usage | 80 | print usage |
|---|
| 81 | | 81 | |
|---|
| 82 | def do_gutenberg(self, line=None): | 82 | def do_gutenberg(self, line=None): |
|---|
| 83 | self._register_config() | 83 | self._register_config() |
|---|
| 84 | import shakespeare.gutenberg | 84 | import shakespeare.gutenberg |
|---|
| 85 | helper = shakespeare.gutenberg.Helper(verbose=True) | 85 | helper = shakespeare.gutenberg.Helper(verbose=True) |
|---|
| 86 | if not line: | 86 | if not line: |
|---|
| 87 | helper.execute() | 87 | helper.execute() |
|---|
| 88 | elif line == 'print_index': | 88 | elif line == 'print_index': |
|---|
| 89 | import pprint | 89 | import pprint |
|---|
| 90 | pprint.pprint(helper.get_index()) | 90 | pprint.pprint(helper.get_index()) |
|---|
| 91 | else: | 91 | else: |
|---|
| 92 | msg = 'Unknown argument %s' % line | 92 | msg = 'Unknown argument %s' % line |
|---|
| 93 | raise Exception(msg) | 93 | raise Exception(msg) |
|---|
| 94 | | 94 | |
|---|
| 95 | def help_gutenberg(self, line=None): | 95 | def help_gutenberg(self, line=None): |
|---|
| 96 | usage = \ | 96 | usage = \ |
|---|
| 97 | """ | 97 | """ |
|---|
| 98 | Download and process all Project Gutenberg shakespeare texts""" | 98 | Download and process all Project Gutenberg shakespeare texts""" |
|---|
| 99 | print usage | 99 | print usage |
|---|
| 100 | | 100 | |
|---|
| 101 | def do_moby(self, line=None): | 101 | def do_moby(self, line=None): |
|---|
| 102 | import shakespeare.moby | 102 | import shakespeare.moby |
|---|
| 103 | helper = shakespeare.moby.Helper(verbose=True) | 103 | helper = shakespeare.moby.Helper(verbose=True) |
|---|
| 104 | if not line: | 104 | if not line: |
|---|
| 105 | helper.execute() | 105 | helper.execute() |
|---|
| 106 | elif line == 'print_index': | 106 | elif line == 'print_index': |
|---|
| 107 | import pprint | 107 | import pprint |
|---|
| 108 | pprint.pprint(helper.get_index()) | 108 | pprint.pprint(helper.get_index()) |
|---|
| 109 | else: | 109 | else: |
|---|
| 110 | msg = 'Unknown argument %s' % line | 110 | msg = 'Unknown argument %s' % line |
|---|
| 111 | raise Exception(msg) | 111 | raise Exception(msg) |
|---|
| 112 | | 112 | |
|---|
| 113 | def help_moby(self, line=None): | 113 | def help_moby(self, line=None): |
|---|
| 114 | self._register_config() | 114 | self._register_config() |
|---|
| 115 | usage = \ | 115 | usage = \ |
|---|
| 116 | ''' | 116 | ''' |
|---|
| 117 | Download and process all Moby/Bosak shakespeare texts''' | 117 | Download and process all Moby/Bosak shakespeare texts''' |
|---|
| 118 | print usage | 118 | print usage |
|---|
| 119 | | 119 | |
|---|
| 120 | def _init_index(self): | 120 | def _init_index(self): |
|---|
| 121 | self._register_config() | 121 | self._register_config() |
|---|
| 122 | import shakespeare.index | 122 | import shakespeare.index |
|---|
| 123 | self._index = shakespeare.index.all | 123 | self._index = shakespeare.index.all |
|---|
| 124 | | 124 | |
|---|
| 125 | def _filter_index(self, line): | 125 | def _filter_index(self, line): |
|---|
| 126 | """Filter items in index return only those whose id (url) is in line | 126 | """Filter items in index return only those whose id (url) is in line |
|---|
| 127 | If line is empty or None return all items | 127 | If line is empty or None return all items |
|---|
| 128 | """ | 128 | """ |
|---|
| 129 | if line: | 129 | if line: |
|---|
| 130 | textsToAdd = [] | 130 | textsToAdd = [] |
|---|
| 131 | textNames = line.split() | 131 | textNames = line.split() |
|---|
| 132 | for item in self._index: | 132 | for item in self._index: |
|---|
| 133 | if item.name in textNames: | 133 | if item.name in textNames: |
|---|
| 134 | textsToAdd.append(item) | 134 | textsToAdd.append(item) |
|---|
| 135 | return textsToAdd | 135 | return textsToAdd |
|---|
| 136 | else: | 136 | else: |
|---|
| 137 | self._init_index() | 137 | self._init_index() |
|---|
| 138 | return self._index | 138 | return self._index |
|---|
| 139 | | 139 | |
|---|
| 140 | def do_index(self, line): | 140 | def do_index(self, line): |
|---|
| 141 | self._init_index() | 141 | self._init_index() |
|---|
| 142 | header = \ | 142 | header = \ |
|---|
| 143 | ''' +-------------------+ | 143 | ''' +-------------------+ |
|---|
| 144 | | Index of Material | | 144 | | Index of Material | |
|---|
| 145 | +-------------------+ | 145 | +-------------------+ |
|---|
| 146 | | 146 | |
|---|
| 147 | ''' | 147 | ''' |
|---|
| 148 | print header | 148 | print header |
|---|
| 149 | for row in self._index: | 149 | for row in self._index: |
|---|
| 150 | print row.name.ljust(35), row.title | 150 | print row.name.ljust(35), row.title |
|---|
| 151 | | 151 | |
|---|
| 152 | def help_index(self, line=None): | 152 | def help_index(self, line=None): |
|---|
| 153 | usage = \ | 153 | usage = \ |
|---|
| 154 | '''Print index of Shakespeare texts to stdout''' | 154 | '''Print index of Shakespeare texts to stdout''' |
|---|
| 155 | print usage | 155 | print usage |
|---|
| 156 | | 156 | |
|---|
| 157 | def do_runserver(self, line=None): | 157 | def do_runserver(self, line=None): |
|---|
| 158 | self.help_runserver() | 158 | self.help_runserver() |
|---|
| 159 | | 159 | |
|---|
| 160 | def help_runserver(self, line=None): | 160 | def help_runserver(self, line=None): |
|---|
| 161 | usage = \ | 161 | usage = \ |
|---|
| 162 | '''This command has been DEPRECATED. | 162 | '''This command has been DEPRECATED. |
|---|
| 163 | | 163 | |
|---|
| 164 | Please use `paster serve` to run a server now, e.g.:: | 164 | Please use `paster serve` to run a server now, e.g.:: |
|---|
| 165 | | 165 | |
|---|
| 166 | paster serve <my-config.ini> | 166 | paster serve <my-config.ini> |
|---|
| 167 | ''' | 167 | ''' |
|---|
| 168 | print usage | 168 | print usage |
|---|
| 169 | | 169 | |
|---|
| 170 | def do_info(self, line=None): | 170 | def do_info(self, line=None): |
|---|
| 171 | import shakespeare | 171 | import shakespeare |
|---|
| 172 | info = shakespeare.__doc__ | 172 | info = shakespeare.__doc__ |
|---|
| 173 | print | 173 | print |
|---|
| 174 | print ' ## Open Shakespeare ##' | 174 | print ' ## Open Shakespeare ##' |
|---|
| 175 | print info | 175 | print info |
|---|
| 176 | | 176 | |
|---|
| 177 | def help_info(self, line=None): | 177 | def help_info(self, line=None): |
|---|
| 178 | print 'Information about this package.' | 178 | print 'Information about this package.' |
|---|
| 179 | | 179 | |
|---|
| 180 | def _parse_line(self, line): | 180 | def _parse_line(self, line): |
|---|
| 181 | line = line.strip() | 181 | line = line.strip() |
|---|
| 182 | args = line.split() | 182 | args = line.split() |
|---|
| 183 | action = '' | 183 | action = '' |
|---|
| 184 | remainder = '' | 184 | remainder = '' |
|---|
| 185 | if len(args) > 0: | 185 | if len(args) > 0: |
|---|
| 186 | action = args[0] | 186 | action = args[0] |
|---|
| 187 | if len(args) > 1: | 187 | if len(args) > 1: |
|---|
| 188 | remainder = ' '.join(args[1:]) | 188 | remainder = ' '.join(args[1:]) |
|---|
| 189 | return (action, remainder) | 189 | return (action, remainder) |
|---|
| 190 | | 190 | |
|---|
| 191 | def do_search(self, line): | 191 | def do_search(self, line): |
|---|
| 192 | self._register_config() | 192 | self._register_config() |
|---|
| 193 | import shakespeare.search | 193 | import shakespeare.search |
|---|
| 194 | index = shakespeare.search.SearchIndex.default_index() | 194 | index = shakespeare.search.SearchIndex.default_index() |
|---|
| 195 | | 195 | |
|---|
| 196 | action, extra = self._parse_line(line) | 196 | action, extra = self._parse_line(line) |
|---|
| 197 | if action == 'addpath': | 197 | if action == 'addpath': |
|---|
| 198 | index.add_from_path(extra) | 198 | index.add_from_path(extra) |
|---|
| 199 | elif action == 'query': | 199 | elif action == 'query': |
|---|
| 200 | results = index.search(extra) | 200 | results = index.search(extra) |
|---|
| 201 | print index.print_matches(results) | 201 | print index.print_matches(results) |
|---|
| 202 | elif action == 'addtext': | 202 | elif action == 'addtext': |
|---|
| 203 | import shakespeare.model as model | 203 | import shakespeare.model as model |
|---|
| 204 | text = model.Material.byName(extra) | 204 | text = model.Material.byName(extra) |
|---|
| 205 | fileobj = text.get_text() | 205 | fileobj = text.get_text() |
|---|
| 216 | else: | 216 | else: |
|---|
| 217 | print 'Unrecognized action: %s' % action | 217 | print 'Unrecognized action: %s' % action |
|---|
| 218 | self.help_search() | 218 | self.help_search() |
|---|
| 219 | return 1 | 219 | return 1 |
|---|
| 220 | | 220 | |
|---|
| 221 | def help_search(self, line=None): | 221 | def help_search(self, line=None): |
|---|
| 222 | info = \ | 222 | info = \ |
|---|
| 223 | ''' | 223 | ''' |
|---|
| 224 | search addpath {path} | 224 | search addpath {path} |
|---|
| 225 | - Add contents of {path} (file itself or all text files in directory if | 225 | - Add contents of {path} (file itself or all text files in directory if |
|---|
| 226 | directory) to the search index. | 226 | directory) to the search index. |
|---|
| 227 | | 227 | |
|---|
| 228 | search addtext {name} | 228 | search addtext {name} |
|---|
| 229 | - Add db text named {name} to search index. | 229 | - Add db text named {name} to search index. |
|---|
| 230 | | 230 | |
|---|
| 231 | search query {query} | 231 | search query {query} |
|---|
| 232 | - Query search index with {query}. | 232 | - Query search index with {query}. |
|---|
| 233 | | 233 | |
|---|
| 234 | search init | 234 | search init |
|---|
| 235 | - Add all texts in DB to index. | 235 | - Add all texts in DB to index. |
|---|
| 236 | ''' | 236 | ''' |
|---|
| 237 | print info | 237 | print info |
|---|
| 238 | | 238 | |
|---|
| 239 | def do_stats(self, line): | 239 | def do_stats(self, line): |
|---|
| 240 | self._register_config() | 240 | self._register_config() |
|---|
| 241 | action, extra = self._parse_line(line) | 241 | action, extra = self._parse_line(line) |
|---|
| 242 | | 242 | |
|---|
| 243 | import shakespeare.stats | 243 | import shakespeare.stats |
|---|
| 244 | stats = shakespeare.stats.Stats() | 244 | stats = shakespeare.stats.Stats() |
|---|
| 245 | if action == 'init': | 245 | if action == 'init': |
|---|
| 246 | self._init_index() | 246 | self._init_index() |
|---|
| 247 | for text in self._index: | 247 | for text in self._index: |
|---|
| 248 | # exclude folios as many odd spellings | 248 | # exclude folios as many odd spellings |
|---|
| 249 | if text.name.endswith('_f'): | 249 | if text.name.endswith('_f'): |
|---|
| 250 | continue | 250 | continue |
|---|
| 251 | self._print('Adding: %s' % text.name) | 251 | self._print('Adding: %s' % text.name) |
|---|
| 252 | stats.statsify(text, text.get_text()) | 252 | stats.statsify(text, text.get_text()) |
|---|
| 253 | elif action == 'addtext': | 253 | elif action == 'addtext': |
|---|
| 254 | import shakespeare.model as model | 254 | import shakespeare.model as model |
|---|
| 255 | text = model.Material.byName(extra) | 255 | text = model.Material.byName(extra) |
|---|
| 256 | stats.statsify(text, text.get_text()) | 256 | stats.statsify(text, text.get_text()) |
|---|
| 257 | elif action == 'show': | 257 | elif action == 'show': |
|---|
| 258 | textstats = stats.text_stats(extra) | 258 | textstats = stats.text_stats(extra) |
|---|
| 259 | for s in textstats: | 259 | for s in textstats: |
|---|
| 260 | print s.word, s.freq | 260 | print s.word, s.freq |
|---|
| 261 | else: | 261 | else: |
|---|
| 262 | print 'Unrecognized action: %s' % action | 262 | print 'Unrecognized action: %s' % action |
|---|
| 263 | self.help_stats() | 263 | self.help_stats() |
|---|
| 264 | return 1 | 264 | return 1 |
|---|
| 265 | | 265 | |
|---|
| 266 | def help_stats(self, line=None): | 266 | def help_stats(self, line=None): |
|---|
| 267 | info = \ | 267 | info = \ |
|---|
| 268 | ''' | 268 | ''' |
|---|
| 269 | stats addtext {name} | 269 | stats addtext {name} |
|---|
| 270 | - Add db text named {name} to stats index. | 270 | - Add db text named {name} to stats index. |
|---|
| 271 | | 271 | |
|---|
| 272 | stats show {name} | 272 | stats show {name} |
|---|
| 273 | - Query stats index with {query}. | 273 | - Query stats index with {query}. |
|---|
| 274 | | 274 | |
|---|
| 275 | stats init | 275 | stats init |
|---|
| 276 | - Prepare statistics for all texts in DB. | 276 | - Prepare statistics for all texts in DB. |
|---|
| 277 | ''' | 277 | ''' |
|---|
| 278 | print info | 278 | print info |
|---|
| 279 | | 279 | |
|---|
| 280 | | 280 | |
|---|
| 281 | def main(): | 281 | def main(): |
|---|
| 282 | import optparse | 282 | import optparse |
|---|
| 283 | usage = \ | 283 | usage = \ |
|---|
| 284 | '''%prog [options] <command> | 284 | '''%prog [options] <command> |
|---|
| 285 | | 285 | |
|---|
| 286 | For list of the commands available run: | 286 | For list of the commands available run: |
|---|
| 287 | | 287 | |
|---|
| 288 | $ shakespeare-admin help | 288 | $ shakespeare-admin help |
|---|
| 289 | | 289 | |
|---|
| 290 | For more general information run the about or info commands.''' | 290 | For more general information run the about or info commands.''' |
|---|
| 291 | parser = optparse.OptionParser(usage) | 291 | parser = optparse.OptionParser(usage) |
|---|
| 292 | parser.add_option('-v', '--verbose', dest='verbose', help='Be verbose', | 292 | parser.add_option('-v', '--verbose', dest='verbose', help='Be verbose', |
|---|
| 293 | action='store_true', default=False) | 293 | action='store_true', default=False) |
|---|
| 294 | parser.add_option('-c', '--config', dest='config', | 294 | parser.add_option('-c', '--config', dest='config', |
|---|
| 295 | help='Path to config file', default=None) | 295 | help='Path to config file', default=None) |
|---|
| 296 | options, args = parser.parse_args() | 296 | options, args = parser.parse_args() |
|---|
| 297 | | 297 | |
|---|
| 298 | if len(args) == 0: | 298 | if len(args) == 0: |
|---|
| 299 | parser.print_help() | 299 | parser.print_help() |
|---|
| 300 | return 1 | 300 | return 1 |
|---|
| 301 | else: | 301 | else: |
|---|
| 302 | cmd = ShakespeareAdmin(verbose=options.verbose, config=options.config) | 302 | cmd = ShakespeareAdmin(verbose=options.verbose, config=options.config) |
|---|
| 303 | args = ' '.join(args) | 303 | args = ' '.join(args) |
|---|
| 304 | args = args.replace('-','_') | 304 | args = args.replace('-','_') |
|---|
| 305 | cmd.onecmd(args) | 305 | cmd.onecmd(args) |
|---|
| 306 | | 306 | |
|---|