Bring flask run under the CLI unbrella

This commit is contained in:
Tim Van Baak 2019-06-14 12:39:01 -07:00
parent f284faee92
commit 24c393d41f
3 changed files with 97 additions and 56 deletions

View File

@ -1,5 +1,63 @@
from cli import run # Standard library imports
import argparse
import os
import logging
import sys
# Application imports
import cli
# Globals
logger = logging.getLogger("inquisitor.__main__")
def parse_args(valid_commands):
command_descs = "\n".join([
"- {0}: {1}".format(name, func.__doc__)
for name, func in valid_commands.items()])
parser = argparse.ArgumentParser(description="Available commands:\n{}\n".format(command_descs), formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("command", default="help", help="The command to execute", choices=valid_commands, metavar="COMMAND")
parser.add_argument("--srcdir", help="Path to sources folder (default ./sources)", default="./sources")
parser.add_argument("--dungeon", help="Path to item cache folder (default ./dungeon)", default="./dungeon")
parser.add_argument("--sources", help="Sources to update, by name", nargs="*")
parser.add_argument("--log", default="INFO", help="Set the log level (default: INFO)")
args = parser.parse_args()
return args
def run_flask_server(args):
"""Run the default flask server serving from the specified dungeon."""
try:
from app import app
app.run()
return 0
except Exception as e:
logger.error(e)
return (-1)
def main():
# Enumerate valid commands.
commands = {
name[8:] : func
for name, func in vars(cli).items()
if name.startswith("command_")}
commands["run"] = run_flask_server
args = parse_args(commands)
# Configure logging.
loglevel = getattr(logging, args.log.upper())
if not isinstance(loglevel, int):
raise ValueError("Invalid log level: {}".format(args.log))
logging.basicConfig(format='[%(levelname)s:%(filename)s:%(lineno)d] %(message)s', level=loglevel)
# Execute command.
if args.command:
return commands[args.command](args)
if __name__ == "__main__": if __name__ == "__main__":
run() sys.exit(main())

View File

@ -6,7 +6,7 @@ import logging
from flask import Flask, render_template, request, jsonify from flask import Flask, render_template, request, jsonify
# Application imports # Application imports
from inquisitor import dungeon import dungeon as dungeonlib
# Globals # Globals
logger = logging.getLogger("inquisitor.app") logger = logging.getLogger("inquisitor.app")
@ -18,24 +18,31 @@ console.setFormatter(formatter)
logger.addHandler(console) logger.addHandler(console)
app = Flask(__name__) app = Flask(__name__)
dungeon = dungeon.Dungeon("dungeon")
@app.route("/") @app.route("/")
def root(): def root():
active_items = dungeon.get_active_items() dungeon = dungeonlib.Dungeon("dungeon")
active_items = []
for cell in dungeon:
for item_id in dungeon[cell]:
try:
item = dungeon[cell][item_id]
if item['active']:
active_items.append(item)
except:
logger.error("Exception reading {}/{}".format(cell, item_id))
logger.info("Found {} active items".format(len(active_items))) logger.info("Found {} active items".format(len(active_items)))
for item in active_items:
item['time_readable'] = str(datetime.fromtimestamp(item['time']))
active_items.sort(key=lambda i: i['time'])
return render_template("feed.html", items=active_items[:100]) return render_template("feed.html", items=active_items[:100])
@app.route("/deactivate/", methods=['POST']) @app.route("/deactivate/", methods=['POST'])
def deactivate(): def deactivate():
dungeon = dungeonlib.Dungeon("dungeon")
params = request.get_json() params = request.get_json()
if 'source' not in params and 'itemid' not in params: if 'source' not in params and 'itemid' not in params:
logger.error("Bad request params: {}".format(params)) logger.error("Bad request params: {}".format(params))
item = dungeon.deactivate_item(params['source'], params['itemid']) item = dungeon[params['source']][params['itemid']]
item.deactivate()
return jsonify({'active': item['active']}) return jsonify({'active': item['active']})

View File

@ -1,5 +1,4 @@
# Standard library imports # Standard library imports
import argparse
import logging import logging
import os import os
@ -10,51 +9,18 @@ import dungeon as dungeonlib
logger = logging.getLogger("inquisitor.cli") logger = logging.getLogger("inquisitor.cli")
def parse_args(commands):
parser = argparse.ArgumentParser()
parser.add_argument("command", default="help", help="The command to execute", choices=list(commands.keys()))
parser.add_argument("--srcdir", help="Path to sources folder (default ./sources)", default="./sources")
parser.add_argument("--dungeon", help="Path to item cache folder (default ./dungeon)", default="./dungeon")
parser.add_argument("--sources", help="Sources to update, by name", nargs="*")
parser.add_argument("--log", default="INFO", help="Set the log level (default: INFO)")
args = parser.parse_args()
if not os.path.isdir(args.srcdir):
print("Error: srcdir must be a directory")
exit(-1)
if not os.path.isdir(args.dungeon):
logger.error("Error: dungeon must be a directory")
exit(-1)
if not args.sources:
logger.error("Error: No sources specified")
exit(-1)
return args
def run():
# Enumerate valid commands.
g = globals()
commands = {
name[8:] : g[name]
for name in g
if name.startswith("command_")}
args = parse_args(commands)
# Configure logging.
loglevel = getattr(logging, args.log.upper())
if not isinstance(loglevel, int):
raise ValueError("Invalid log level: {}".format(args.log))
logging.basicConfig(format='[%(levelname)s:%(filename)s:%(lineno)d] %(message)s', level=loglevel)
# Execute command.
commands[args.command](args)
def command_update(args): def command_update(args):
"""Fetches new items from sources and stores them in the dungeon.""" """Fetch and store new items from the specified sources."""
if not os.path.isdir(args.srcdir):
print("update: Error: srcdir must be a directory")
return (-1)
if not os.path.isdir(args.dungeon):
logger.error("update: Error: dungeon must be a directory")
return (-1)
if not args.sources:
logger.error("update: Error: No sources specified")
return (-1)
# Initialize dungeon. # Initialize dungeon.
dungeon = dungeonlib.Dungeon(args.dungeon) dungeon = dungeonlib.Dungeon(args.dungeon)
@ -62,9 +28,17 @@ def command_update(args):
for source_arg in args.sources: for source_arg in args.sources:
dungeon.update(source_arg, args) dungeon.update(source_arg, args)
return 0
def command_deactivate(args): def command_deactivate(args):
"""Deactivates all items in the given sources.""" """Deactivate all items in the specified dungeon cells."""
if not os.path.isdir(args.dungeon):
logger.error("deactivate: Error: dungeon must be a directory")
return (-1)
if not args.sources:
logger.error("deactivate: Error: No sources specified")
return (-1)
# Initialize dungeon. # Initialize dungeon.
dungeon = dungeonlib.Dungeon(args.dungeon) dungeon = dungeonlib.Dungeon(args.dungeon)
@ -82,3 +56,5 @@ def command_deactivate(args):
item.deactivate() item.deactivate()
count += 1 count += 1
logger.info("Deactivated {} items in '{}'".format(count, source_name)) logger.info("Deactivated {} items in '{}'".format(count, source_name))
return 0