Compare commits
1 commit
e3a004df20
...
b4a788826b
Author | SHA1 | Date | |
---|---|---|---|
b4a788826b |
1 changed files with 117 additions and 0 deletions
117
tutor/cli.py
Normal file
117
tutor/cli.py
Normal 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()
|
Loading…
Reference in a new issue