810783f2ba72a2c67b2d476f66c5aa17cd28764e
2 from optparse
import OptionParser
9 import pokedex
.db
.tables
13 if len(sys
.argv
) <= 1:
19 # XXX there must be a better way to get Unicode argv
20 # XXX this doesn't work on Windows durp
21 enc
= sys
.stdin
.encoding
or 'utf8'
22 args
= [_
.decode(enc
) for _
in args
]
24 # Find the command as a function in this file
25 func
= globals().get("command_%s" % command
, None)
32 def get_parser(verbose
=True):
33 """Returns an OptionParser prepopulated with the global options.
35 `verbose` is whether or not the options should be verbose by default.
37 parser
= OptionParser()
38 parser
.add_option('-e', '--engine', dest
='engine_uri', default
=os
.environ
.get('POKEDEX_DB_ENGINE', None))
39 parser
.add_option('-i', '--index', dest
='index_dir', default
=os
.environ
.get('POKEDEX_INDEX_DIR', None))
40 parser
.add_option('-q', '--quiet', dest
='verbose', default
=verbose
, action
='store_false')
41 parser
.add_option('-v', '--verbose', dest
='verbose', default
=verbose
, action
='store_true')
44 def get_session(options
):
45 """Given a parsed options object, connects to the database and returns a
49 engine_uri
= options
.engine_uri
52 got_from
= 'command line'
54 engine_uri
= os
.environ
.get('POKEDEX_DB_ENGINE', None)
56 got_from
= 'environment'
58 got_from
= 'default setting'
60 session
= pokedex
.db
.connect(engine_uri
)
63 print "Connected to database {engine} (from {got_from})" \
64 .format(engine
=session
.bind
.url
, got_from
=got_from
)
68 def get_lookup(options
, session
=None, recreate
=False):
69 """Given a parsed options object, opens the whoosh index and returns a
73 if recreate
and not session
:
74 raise ValueError("get_lookup() needs an explicit session to regen the index")
76 index_dir
= options
.index_dir
79 got_from
= 'command line'
81 index_dir
= os
.environ
.get('POKEDEX_INDEX_DIR', None)
83 got_from
= 'environment'
85 index_dir
= pkg_resources
.resource_filename('pokedex',
87 got_from
= 'default setting'
90 print "Opened lookup index {index_dir} (from {got_from})" \
91 .format(index_dir
=index_dir
, got_from
=got_from
)
93 lookup
= pokedex
.lookup
.PokedexLookup(index_dir
, session
=session
)
96 lookup
.rebuild_index()
100 def get_csv_directory(options
):
101 """Prints and returns the csv directory we're about to use."""
103 if not options
.verbose
:
106 if options
.directory
:
107 csvdir
= options
.directory
108 got_from
= 'command line'
110 # This is the same as the db.load default
111 csvdir
= pkg_resources
.resource_filename('pokedex', 'data/csv')
112 got_from
= 'default setting'
114 print "Using CSV directory {csvdir} (from {got_from})" \
115 .format(csvdir
=csvdir
, got_from
=got_from
)
120 ### Plumbing commands
122 def command_dump(*args
):
123 parser
= get_parser(verbose
=True)
124 parser
.add_option('-d', '--directory', dest
='directory', default
=None)
125 options
, tables
= parser
.parse_args(list(args
))
127 session
= get_session(options
)
128 get_csv_directory(options
)
130 pokedex
.db
.load
.dump(session
, directory
=options
.directory
,
132 verbose
=options
.verbose
)
134 def command_load(*args
):
135 parser
= get_parser(verbose
=True)
136 parser
.add_option('-d', '--directory', dest
='directory', default
=None)
137 parser
.add_option('-D', '--drop-tables', dest
='drop_tables', default
=False, action
='store_true')
138 options
, tables
= parser
.parse_args(list(args
))
140 if not options
.engine_uri
:
141 print "WARNING: You're reloading the default database, but not the lookup index. They"
142 print " might get out of sync, and pokedex commands may not work correctly!"
143 print "To fix this, run `pokedex reindex` when this command finishes. Or, just use"
144 print "`pokedex setup` to do both at once."
147 session
= get_session(options
)
148 get_csv_directory(options
)
150 pokedex
.db
.load
.load(session
, directory
=options
.directory
,
151 drop_tables
=options
.drop_tables
,
153 verbose
=options
.verbose
)
155 def command_reindex(*args
):
156 parser
= get_parser(verbose
=True)
157 options
, _
= parser
.parse_args(list(args
))
159 session
= get_session(options
)
160 lookup
= get_lookup(options
, session
=session
, recreate
=True)
162 print "Recreated lookup index."
165 def command_setup(*args
):
166 parser
= get_parser(verbose
=False)
167 options
, _
= parser
.parse_args(list(args
))
169 options
.directory
= None
171 session
= get_session(options
)
172 get_csv_directory(options
)
173 pokedex
.db
.load
.load(session
, directory
=None, drop_tables
=True,
174 verbose
=options
.verbose
)
176 lookup
= get_lookup(options
, session
=session
, recreate
=True)
178 print "Recreated lookup index."
181 def command_status(*args
):
182 parser
= get_parser(verbose
=True)
183 options
, _
= parser
.parse_args(list(args
))
184 options
.verbose
= True
185 options
.directory
= None
187 # Database, and a lame check for whether it's been inited at least once
188 session
= get_session(options
)
189 print " - OK! Connected successfully."
191 if pokedex
.db
.tables
.Pokemon
.__table__
.exists(session
.bind
):
192 print " - OK! Database seems to contain some data."
194 print " - WARNING: Database appears to be empty."
196 # CSV; simple checks that the dir exists
197 csvdir
= get_csv_directory(options
)
198 if not os
.path
.exists(csvdir
):
199 print " - ERROR: No such directory!"
200 elif not os
.path
.isdir(csvdir
):
201 print " - ERROR: Not a directory!"
203 print " - OK! Directory exists."
205 if os
.access(csvdir
, os
.R_OK
):
206 print " - OK! Can read from directory."
208 print " - ERROR: Can't read from directory!"
210 if os
.access(csvdir
, os
.W_OK
):
211 print " - OK! Can write to directory."
213 print " - WARNING: Can't write to directory! " \
214 "`dump` will not work. You may need to sudo."
216 # Index; the PokedexLookup constructor covers most tests and will
217 # cheerfully bomb if they fail
218 lookup
= get_lookup(options
, recreate
=False)
219 print " - OK! Opened successfully."
222 ### User-facing commands
224 def command_lookup(*args
):
225 parser
= get_parser(verbose
=False)
226 options
, words
= parser
.parse_args(list(args
))
228 name
= u
' '.join(words
)
230 session
= get_session(options
)
231 lookup
= get_lookup(options
, session
=session
, recreate
=False)
233 results
= lookup
.lookup(name
)
236 elif results
[0].exact
:
239 print "Fuzzy-matched:"
241 for result
in results
:
242 if hasattr(result
.object, 'full_name'):
243 name
= result
.object.full_name
245 name
= result
.object.name
247 print "%s: %s" %
(result
.object.__tablename__
, name
),
249 print "(%s in %s)" %
(result
.name
, result
.language
)
255 print u
"""pokedex -- a command-line Pokédex interface
256 usage: pokedex {command} [options...]
257 Run `pokedex setup` first, or nothing will work!
258 See http://bugs.veekun.com/projects/pokedex/wiki/CLI for more documentation.
261 help Displays this message.
262 lookup [thing] Look up something in the Pokédex.
265 load Load Pokédex data into a database from CSV files.
266 dump Dump Pokédex data from a database into CSV files.
267 reindex Rebuilds the lookup index from the database.
268 setup Combines load and reindex.
269 status No effect, but prints which engine, index, and csv
270 directory would be used for other commands.
273 -e|--engine=URI By default, all commands try to use a SQLite database
274 in the pokedex install directory. Use this option (or
275 a POKEDEX_DB_ENGINE environment variable) to specify an
277 -i|--index=DIR By default, all commands try to put the lookup index in
278 the pokedex install directory. Use this option (or a
279 POKEDEX_INDEX_DIR environment variable) to specify an
281 -q|--quiet Don't print system output. This is the default for
282 non-system commands and setup.
283 -v|--verbose Print system output. This is the default for system
284 commands, except setup.
287 -d|--directory=DIR By default, load and dump will use the CSV files in the
288 pokedex install directory. Use this option to specify
289 a different directory.
290 -D|--drop-tables With load, drop all tables before loading data.
292 Additionally, load and dump accept a list of table names (possibly with
293 wildcards) and/or csv fileames as an argument list.
294 """.encode(sys
.getdefaultencoding(), 'replace')