diff --git a/inquisitor/__main__.py b/inquisitor/__main__.py index f3c8323..288817b 100644 --- a/inquisitor/__main__.py +++ b/inquisitor/__main__.py @@ -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__": - run() - + sys.exit(main()) diff --git a/inquisitor/app.py b/inquisitor/app.py index ba79ed9..e592076 100644 --- a/inquisitor/app.py +++ b/inquisitor/app.py @@ -6,7 +6,7 @@ import logging from flask import Flask, render_template, request, jsonify # Application imports -from inquisitor import dungeon +import dungeon as dungeonlib # Globals logger = logging.getLogger("inquisitor.app") @@ -18,24 +18,31 @@ console.setFormatter(formatter) logger.addHandler(console) app = Flask(__name__) -dungeon = dungeon.Dungeon("dungeon") @app.route("/") 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))) - 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]) @app.route("/deactivate/", methods=['POST']) def deactivate(): + dungeon = dungeonlib.Dungeon("dungeon") params = request.get_json() if 'source' not in params and 'itemid' not in 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']}) diff --git a/inquisitor/cli.py b/inquisitor/cli.py index a7cfbe3..e7aefa2 100644 --- a/inquisitor/cli.py +++ b/inquisitor/cli.py @@ -1,5 +1,4 @@ # Standard library imports -import argparse import logging import os @@ -10,51 +9,18 @@ import dungeon as dungeonlib 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): - """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. dungeon = dungeonlib.Dungeon(args.dungeon) @@ -62,9 +28,17 @@ def command_update(args): for source_arg in args.sources: dungeon.update(source_arg, args) + return 0 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. dungeon = dungeonlib.Dungeon(args.dungeon) @@ -82,3 +56,5 @@ def command_deactivate(args): item.deactivate() count += 1 logger.info("Deactivated {} items in '{}'".format(count, source_name)) + + return 0