Add backend infrastructure for item callbacks

This commit is contained in:
Tim Van Baak 2020-06-08 22:38:33 -07:00
parent ee23a34cf2
commit 128cc7b1f9
3 changed files with 37 additions and 17 deletions

View File

@ -8,7 +8,7 @@ from flask import Flask, render_template, request, jsonify
# Application imports # Application imports
from inquisitor.configs import logger, DUNGEON_PATH from inquisitor.configs import logger, DUNGEON_PATH
from inquisitor import loader, timestamp from inquisitor import importer, loader, timestamp
# Globals # Globals
app = Flask(__name__) app = Flask(__name__)
@ -146,4 +146,5 @@ def callback():
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))
importer.item_callback(params['source'], params['itemid'])
return jsonify({}) return jsonify({})

View File

@ -43,22 +43,23 @@ def load_source(source_name):
""" """
# Push the sources directory # Push the sources directory
cwd = os.getcwd() cwd = os.getcwd()
os.chdir(SOURCES_PATH) try:
# Check if the named source is present. os.chdir(SOURCES_PATH)
source_file_name = source_name + ".py" # Check if the named source is present.
if not os.path.isfile(source_file_name): source_file_name = source_name + ".py"
if not os.path.isfile(source_file_name):
raise FileNotFoundError("Missing '{}' in '{}'".format(source_name, SOURCES_PATH))
# Try to import the source module.
logger.debug("Loading module {}".format(source_file_name))
spec = importlib.util.spec_from_file_location("itemsource", source_file_name)
itemsource = importlib.util.module_from_spec(spec)
spec.loader.exec_module(itemsource)
if not hasattr(itemsource, 'fetch_new'):
raise ImportError("Missing fetch_new in '{}'".format(source_file_name))
# Since the source is valid, get or create the source cell.
return itemsource
finally:
os.chdir(cwd) os.chdir(cwd)
raise FileNotFoundError("Missing '{}' in '{}'".format(source_name, SOURCES_PATH))
# Try to import the source module.
logger.debug("Loading module {}".format(source_file_name))
spec = importlib.util.spec_from_file_location("itemsource", source_file_name)
itemsource = importlib.util.module_from_spec(spec)
spec.loader.exec_module(itemsource)
if not hasattr(itemsource, 'fetch_new'):
raise ImportError("Missing fetch_new in '{}'".format(source_file_name))
# Since the source is valid, get or create the source cell.
os.chdir(cwd)
return itemsource
def update_source(source_name, fetch_new): def update_source(source_name, fetch_new):
""" """
@ -169,3 +170,20 @@ def populate_old(prior, new):
if 'ttd' in new: prior['ttd'] = new['ttd'] if 'ttd' in new: prior['ttd'] = new['ttd']
if 'tts' in new: prior['tts'] = new['tts'] if 'tts' in new: prior['tts'] = new['tts']
if 'callback' in new: prior['callback'] = new['callback'] if 'callback' in new: prior['callback'] = new['callback']
def item_callback(source_name, itemid):
try:
# Load the module with the callback function
source_module = load_source(source_name)
if not hasattr(source_module, 'callback'):
raise ImportError(f"Missing callback in '{source_name}'")
# Load the source state and the origin item
state = loader.load_state(source_name)
item = loader.WritethroughDict(os.path.join(DUNGEON_PATH, source_name, itemid + ".item"))
# Execute callback
source_module.callback(state, item)
# Save any changes
item.flush()
state.flush()
except Exception:
error.as_item(f"Error executing callback for {source_name}/{itemid}", traceback.format_exc())

View File

@ -2,6 +2,7 @@
Demonstrates the behavior of the callback field. Demonstrates the behavior of the callback field.
""" """
# Standard library imports # Standard library imports
from datetime import datetime
import random import random
def fetch_new(state): def fetch_new(state):
@ -16,4 +17,4 @@ def fetch_new(state):
return [item] return [item]
def callback(state, item): def callback(state, item):
print(item) item['body'] = f"Last callback at {datetime.now()}"