2 from optparse
import OptionParser
8 import pokedex
.db
.tables
10 from pokedex
import defaults
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
=None)
39 parser
.add_option('-i', '--index', dest
='index_dir', default
=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
50 got_from
= 'command line'
52 if engine_uri
is None:
53 engine_uri
, got_from
= defaults
.get_default_db_uri_with_origin()
55 session
= pokedex
.db
.connect(engine_uri
)
58 print "Connected to database %(engine)s (from %(got_from)s)" \
59 % dict
(engine
=session
.bind
.url
, got_from
=got_from
)
63 def get_lookup(options
, session
=None, recreate
=False):
64 """Given a parsed options object, opens the whoosh index and returns a
68 if recreate
and not session
:
69 raise ValueError("get_lookup() needs an explicit session to regen the index")
71 index_dir
= options
.index_dir
72 got_from
= 'command line'
75 index_dir
, got_from
= defaults
.get_default_index_dir_with_origin()
78 print "Opened lookup index %(index_dir)s (from %(got_from)s)" \
79 % dict
(index_dir
=index_dir
, got_from
=got_from
)
81 lookup
= pokedex
.lookup
.PokedexLookup(index_dir
, session
=session
)
84 lookup
.rebuild_index()
88 def get_csv_directory(options
):
89 """Prints and returns the csv directory we're about to use."""
91 if not options
.verbose
:
94 csvdir
= options
.directory
95 got_from
= 'command line'
98 csvdir
, got_from
= defaults
.get_default_csv_dir_with_origin()
100 print "Using CSV directory %(csvdir)s (from %(got_from)s)" \
101 % dict
(csvdir
=csvdir
, got_from
=got_from
)
106 ### Plumbing commands
108 def command_dump(*args
):
109 parser
= get_parser(verbose
=True)
110 parser
.add_option('-d', '--directory', dest
='directory', default
=None)
111 parser
.add_option('-l', '--langs', dest
='langs', default
='en',
112 help="Comma-separated list of languages to dump all strings for. "
113 "Default is English ('en')")
114 options
, tables
= parser
.parse_args(list(args
))
116 session
= get_session(options
)
117 get_csv_directory(options
)
119 langs
= [l
.strip() for l
in options
.langs
.split(',')]
121 pokedex
.db
.load
.dump(session
, directory
=options
.directory
,
123 verbose
=options
.verbose
,
126 def command_load(*args
):
127 parser
= get_parser(verbose
=True)
128 parser
.add_option('-d', '--directory', dest
='directory', default
=None)
129 parser
.add_option('-D', '--drop-tables', dest
='drop_tables', default
=False, action
='store_true')
130 parser
.add_option('-r', '--recursive', dest
='recursive', default
=False, action
='store_true')
131 parser
.add_option('-S', '--safe', dest
='safe', default
=False, action
='store_true',
132 help="Do not use backend-specific optimalizations.")
133 parser
.add_option('-l', '--langs', dest
='langs', default
=None,
134 help="Comma-separated list of extra languages to load, or 'none' for none. "
135 "Default is to load 'em all. Example: 'fr,de'")
136 options
, tables
= parser
.parse_args(list(args
))
138 if not options
.engine_uri
:
139 print "WARNING: You're reloading the default database, but not the lookup index. They"
140 print " might get out of sync, and pokedex commands may not work correctly!"
141 print "To fix this, run `pokedex reindex` when this command finishes. Or, just use"
142 print "`pokedex setup` to do both at once."
145 if options
.langs
== 'none':
147 elif options
.langs
is None:
150 langs
= [l
.strip() for l
in options
.langs
.split(',')]
152 session
= get_session(options
)
153 get_csv_directory(options
)
155 pokedex
.db
.load
.load(session
, directory
=options
.directory
,
156 drop_tables
=options
.drop_tables
,
158 verbose
=options
.verbose
,
160 recursive
=options
.recursive
,
163 def command_reindex(*args
):
164 parser
= get_parser(verbose
=True)
165 options
, _
= parser
.parse_args(list(args
))
167 session
= get_session(options
)
168 lookup
= get_lookup(options
, session
=session
, recreate
=True)
170 print "Recreated lookup index."
173 def command_setup(*args
):
174 parser
= get_parser(verbose
=False)
175 options
, _
= parser
.parse_args(list(args
))
177 options
.directory
= None
179 session
= get_session(options
)
180 get_csv_directory(options
)
181 pokedex
.db
.load
.load(session
, directory
=None, drop_tables
=True,
182 verbose
=options
.verbose
,
185 lookup
= get_lookup(options
, session
=session
, recreate
=True)
187 print "Recreated lookup index."
190 def command_status(*args
):
191 parser
= get_parser(verbose
=True)
192 options
, _
= parser
.parse_args(list(args
))
193 options
.verbose
= True
194 options
.directory
= None
196 # Database, and a lame check for whether it's been inited at least once
197 session
= get_session(options
)
198 print " - OK! Connected successfully."
200 if pokedex
.db
.tables
.Pokemon
.__table__
.exists(session
.bind
):
201 print " - OK! Database seems to contain some data."
203 print " - WARNING: Database appears to be empty."
205 # CSV; simple checks that the dir exists
206 csvdir
= get_csv_directory(options
)
207 if not os
.path
.exists(csvdir
):
208 print " - ERROR: No such directory!"
209 elif not os
.path
.isdir(csvdir
):
210 print " - ERROR: Not a directory!"
212 print " - OK! Directory exists."
214 if os
.access(csvdir
, os
.R_OK
):
215 print " - OK! Can read from directory."
217 print " - ERROR: Can't read from directory!"
219 if os
.access(csvdir
, os
.W_OK
):
220 print " - OK! Can write to directory."
222 print " - WARNING: Can't write to directory! " \
223 "`dump` will not work. You may need to sudo."
225 # Index; the PokedexLookup constructor covers most tests and will
226 # cheerfully bomb if they fail
227 lookup
= get_lookup(options
, recreate
=False)
228 print " - OK! Opened successfully."
231 ### User-facing commands
233 def command_lookup(*args
):
234 parser
= get_parser(verbose
=False)
235 options
, words
= parser
.parse_args(list(args
))
237 name
= u
' '.join(words
)
239 session
= get_session(options
)
240 lookup
= get_lookup(options
, session
=session
, recreate
=False)
242 results
= lookup
.lookup(name
)
245 elif results
[0].exact
:
248 print "Fuzzy-matched:"
250 for result
in results
:
251 if hasattr(result
.object, 'full_name'):
252 name
= result
.object.full_name
254 name
= result
.object.name
256 print "%s: %s" %
(result
.object.__tablename__
, name
),
258 print "(%s in %s)" %
(result
.name
, result
.language
)
264 print u
"""pokedex -- a command-line Pokédex interface
265 usage: pokedex {command} [options...]
266 Run `pokedex setup` first, or nothing will work!
267 See http://bugs.veekun.com/projects/pokedex/wiki/CLI for more documentation.
270 help Displays this message.
271 lookup [thing] Look up something in the Pokédex.
274 load Load Pokédex data into a database from CSV files.
275 dump Dump Pokédex data from a database into CSV files.
276 reindex Rebuilds the lookup index from the database.
277 setup Combines load and reindex.
278 status No effect, but prints which engine, index, and csv
279 directory would be used for other commands.
282 -e|--engine=URI By default, all commands try to use a SQLite database
283 in the pokedex install directory. Use this option (or
284 a POKEDEX_DB_ENGINE environment variable) to specify an
286 -i|--index=DIR By default, all commands try to put the lookup index in
287 the pokedex install directory. Use this option (or a
288 POKEDEX_INDEX_DIR environment variable) to specify an
290 -q|--quiet Don't print system output. This is the default for
291 non-system commands and setup.
292 -v|--verbose Print system output. This is the default for system
293 commands, except setup.
296 -d|--directory=DIR By default, load and dump will use the CSV files in the
297 pokedex install directory. Use this option to specify
298 a different directory.
301 -D|--drop-tables Drop all tables before loading data.
302 -S|--safe Disable engine-specific optimizations.
303 -r|--recursive Load (and drop) all dependent tables.
304 -l|--langs Load translations for the given languages.
305 By default, all available translations are loaded.
306 Separate multiple languages by a comma (-l en,de,fr)
309 -l|--langs Dump unofficial texts for given languages.
310 By default, English (en) is dumped.
311 Separate multiple languages by a comma (-l en,de,fr)
312 Use 'none' to not dump any unofficial texts.
314 Additionally, load and dump accept a list of table names (possibly with
315 wildcards) and/or csv fileames as an argument list.
316 """.encode(sys
.getdefaultencoding(), 'replace')