From 364480c08d2073cbda36f0789bd7d5a47a618a6c Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Thu, 6 Aug 2020 23:48:10 -0700 Subject: [PATCH] Add create and delete triggers --- inquisitor/cli.py | 5 ++--- inquisitor/loader.py | 3 +++ inquisitor/sources.py | 14 ++++++++++---- sources/triggerdemo.py | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 sources/triggerdemo.py diff --git a/inquisitor/cli.py b/inquisitor/cli.py index 4a0e385..8d6dcc4 100644 --- a/inquisitor/cli.py +++ b/inquisitor/cli.py @@ -150,8 +150,7 @@ def command_feed(args): if errors: items.insert(0, { - 'id': 'read-errors', - 'title': '{} read errors'.format(len(errors)), + 'title': '{} read errors: {}'.format(len(errors), ' '.join(errors)), 'body': "\n".join(errors) }) @@ -176,7 +175,7 @@ def command_feed(args): print("| {0:<{1}} |".format(info1, width - 4)) created = timestamp.stamp_to_readable(item['created']) if 'created' in item else "" info2 = "{0} {1} {2}".format( - item['source'], item['id'], created) + item.get('source', ''), item.get('id', ''), created) print("| {0:<{1}} |".format(info2, width - 4)) print('+' + (width - 2) * '-' + '+') print() diff --git a/inquisitor/loader.py b/inquisitor/loader.py index 4045250..3c22d0e 100644 --- a/inquisitor/loader.py +++ b/inquisitor/loader.py @@ -41,6 +41,9 @@ class WritethroughDict(): def __getitem__(self, key): return self.item[key] + def get(self, *args, **kwargs): + return self.item.get(*args, **kwargs) + def __setitem__(self, key, value): self.item[key] = value self.flush() diff --git a/inquisitor/sources.py b/inquisitor/sources.py index 508a5b9..7d6af86 100644 --- a/inquisitor/sources.py +++ b/inquisitor/sources.py @@ -62,7 +62,7 @@ def update_sources(*source_names): # Update the source try: logger.info(f'Updating source "{source_name}"') - update_source(source_name, source_module.fetch_new) + update_source(source_name, source_module) except Exception: error.as_item( f'Error updating source "{source_name}"', @@ -101,7 +101,7 @@ def load_source(source_name): os.chdir(cwd) -def update_source(source_name, fetch_new): +def update_source(source_name, source): """ Attempts to update the given source. Raises an exception if the source does. """ @@ -111,7 +111,7 @@ def update_source(source_name, fetch_new): # Get the feed items from the source's fetch method. state = loader.load_state(source_name) - fetched = fetch_new(state) + fetched = source.fetch_new(state) state.flush() logger.debug(f'Fetched {len(fetched)} items') fetched_items = {item['id']: item for item in fetched} @@ -130,9 +130,12 @@ def update_source(source_name, fetch_new): new_items.append(item) # Write all the new items to the source's cell. + has_create_handler = hasattr(source, 'on_create') for item in new_items: item_source = item.get('source', source_name) - loader.new_item(item_source, item) + created_item = loader.new_item(item_source, item) + if has_create_handler: + source.on_create(state, created_item) # Update the other items using the fetched items' values. for new_item in updated_items: @@ -152,6 +155,7 @@ def update_source(source_name, fetch_new): # fetch) and inactive. Some item fields can change this basic behavior. del_count = 0 now = timestamp.now() + has_delete_handler = hasattr(source, 'on_delete') fetched_ids = [item['id'] for item in updated_items] old_item_ids = [ item_id for item_id in prior_ids @@ -173,6 +177,8 @@ def update_source(source_name, fetch_new): remove = True # Items to be removed are deleted if remove: + if has_delete_handler: + source.on_delete(state, item) del_count += 1 file_path = os.path.join(DUNGEON_PATH, item['source'], item['id'] + ".item") try: diff --git a/sources/triggerdemo.py b/sources/triggerdemo.py new file mode 100644 index 0000000..17683e7 --- /dev/null +++ b/sources/triggerdemo.py @@ -0,0 +1,41 @@ +""" +Demonstrates the behavior of the on_create and on_delete triggers. +The items it creates spawn dummy messages on creation and deletion. +It assumes the dungeon is located at ./dungeon. +""" +# Standard library imports +from datetime import datetime +import json +import random + +def fetch_new(state): + if state.get('return_item'): + state['return_item'] = False + return [{ + 'source': 'triggerdemo', + 'id': 'triggerdemoitem', + 'title': 'This is the trigger demo item' + }] + else: + state['return_item'] = True + return [] + + +def on_create(state, item): + with open('dungeon/inquisitor/triggerdemo_create.item', 'w') as f: + json.dump({ + 'source': 'inquisitor', + 'id': 'triggerdemo_create.item', + 'title': 'Trigger demo on_create item', + 'active': True, + }, f) + + +def on_delete(state, item): + with open('dungeon/inquisitor/triggerdemo_delete.item', 'w') as f: + json.dump({ + 'source': 'inquisitor', + 'id': 'triggerdemo_delete.item', + 'title': 'Trigger demo on_delete item', + 'active': True, + }, f)