Compare commits

..

1 commit

Author SHA1 Message Date
b4a788826b Paginate search results 2021-07-15 20:57:54 -04:00

117
tutor/cli.py Normal file
View file

@ -0,0 +1,117 @@
import json
import logging
import aiosqlite
import click
import httpx
import humanize
import tornado.ioloop
import tornado.web
import tutor.csvimport
import tutor.database
import tutor.scryfall
import tutor.server
@click.group()
@click.option(
"--database",
envvar="TUTOR_DATABASE",
type=click.Path(dir_okay=False),
required=True,
)
@click.option(
"--log-level",
type=click.Choice(
["debug", "info", "warn", "error"],
case_sensitive=False,
),
default="warn",
)
@click.pass_context
def main(ctx, database, log_level):
logging.basicConfig(
level={
"debug": logging.DEBUG,
"info": logging.INFO,
"warn": logging.WARN,
"error": logging.ERROR,
}.get(log_level.lower())
)
ctx.ensure_object(dict)
ctx.obj["database"] = database
@main.command()
@click.option("--port", type=int, envvar="TUTOR_PORT", default=8888)
@click.option("--static", envvar="TUTOR_STATIC", type=click.Path(file_okay=False))
@click.option("--debug", is_flag=True)
@click.pass_context
def server(ctx, port, static, debug):
app = tutor.server.make_app(
{
**ctx.obj,
"static": static,
"debug": debug,
}
)
app.listen(port)
tornado.ioloop.IOLoop.current().start()
@main.command("import")
@click.argument("filename", type=click.Path(dir_okay=False))
@click.pass_context
def import_cards(ctx, filename):
tornado.ioloop.IOLoop.current().run_sync(
lambda: tutor.csvimport.load(ctx.obj, filename)
)
@main.command("update_scryfall")
@click.option("--filename", type=click.Path(dir_okay=False))
@click.pass_context
def update_scryfall(ctx, filename):
if filename:
with open(filename) as f:
cards = json.loads(f.read())
else:
response = httpx.get("https://api.scryfall.com/bulk-data/oracle_cards")
info = response.json()
buffer = b""
with httpx.stream("GET", info["download_uri"]) as response:
downloaded = response.num_bytes_downloaded
total = int(response.headers["Content-Length"])
with click.progressbar(
length=total,
label=f"Downloading {humanize.naturalsize(total)}"
" of card data from Scryfall",
) as bar:
for chunk in response.iter_bytes():
buffer += chunk
bar.update(response.num_bytes_downloaded - downloaded)
downloaded = response.num_bytes_downloaded
cards = json.loads(buffer)
async def import_cards():
async with aiosqlite.connect(ctx.obj["database"]) as db:
with click.progressbar(
cards,
label=f"Importing {humanize.intcomma(len(cards))} cards",
) as bar:
for card_object in bar:
await tutor.database.store_card(
db, tutor.scryfall.to_card(card_object)
)
await tutor.database.store_set(
db, card_object["set"].upper(), card_object["set_name"]
)
await db.commit()
tornado.ioloop.IOLoop.current().run_sync(import_cards)
if __name__ == "__main__":
main()