aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--aggro.py45
-rw-r--r--app/ConcatPlugin.py44
-rw-r--r--app/DatabaseManager.py (renamed from app/database.py)3
-rw-r--r--app/FeedSinkPlugin.py4
-rw-r--r--app/server.py4
-rw-r--r--app/utils.py11
6 files changed, 100 insertions, 11 deletions
diff --git a/aggro.py b/aggro.py
index 09fb840..032956d 100644
--- a/aggro.py
+++ b/aggro.py
@@ -1,13 +1,17 @@
import json
import os
+import hashlib
# from multiprocessing import Process
from threading import Thread
import time
+from typing import Any
+
+from tinydb import Query
from app.AggroConfig import AggroConfig
from app.MemoryState import memory_state
from app.PluginManager import PluginManager
-from app.database import database_manager
+from app.DatabaseManager import database_manager
from app.server import run_web_server
@@ -29,18 +33,45 @@ if __name__ == "__main__":
aggrofile_path = os.environ.get("AGGRO_CONFIG_PATH", "Aggrofile")
with open(aggrofile_path) as f:
- aggrofile_content = json.loads(f.read())
+ aggrofile_content = f.read()
+ aggrofile = json.loads(aggrofile_content)
aggro_config = AggroConfig(
- server_host=aggrofile_content.get("server_host", "localhost"),
- server_port=aggrofile_content.get("server_port", 8080),
- db_path=aggrofile_content.get("db_path", "db.json"),
- plugins=aggrofile_content["plugins"],
- graph=aggrofile_content["graph"],
+ server_host=aggrofile.get("server_host", "localhost"),
+ server_port=aggrofile.get("server_port", 8080),
+ db_path=aggrofile.get("db_path", "db.json"),
+ plugins=aggrofile["plugins"],
+ graph=aggrofile["graph"],
)
database_manager.setup(aggro_config)
+ aggrofile_hash_q = Query().key == "aggrofile_hash"
+ aggrofile_stored_hash: str | None
+ if database_manager.meta_info.contains(aggrofile_hash_q):
+ aggrofile_stored_hash_obj: Any = database_manager.meta_info.get( # type: ignore
+ aggrofile_hash_q
+ )
+ aggrofile_stored_hash = aggrofile_stored_hash_obj["value"]
+ else:
+ aggrofile_stored_hash = None
+
+ aggrofile_current_hash = hashlib.sha256(aggrofile_content.encode("utf-8"))
+ aggrofile_current_hash_dig = aggrofile_current_hash.hexdigest()
+
+ if (
+ aggrofile_stored_hash is not None
+ and aggrofile_stored_hash != aggrofile_current_hash_dig
+ ):
+ # Aggrofile has been changed
+ print("Aggrofile has been changed. Truncating plugin states in DB...")
+ database_manager.plugin_states.truncate()
+
+ database_manager.meta_info.upsert( # type: ignore
+ {"key": "aggrofile_hash", "value": aggrofile_current_hash_dig},
+ aggrofile_hash_q,
+ )
+
manager = PluginManager(aggro_config)
manager.build_plugin_instances()
diff --git a/app/ConcatPlugin.py b/app/ConcatPlugin.py
new file mode 100644
index 0000000..14307ac
--- /dev/null
+++ b/app/ConcatPlugin.py
@@ -0,0 +1,44 @@
+from typing import Any
+
+from tinydb import Query
+from app.Item import Item
+from app.PluginInterface import PluginInterface
+from app.DatabaseManager import database_manager
+from app.utils import dict_to_item, item_to_dict
+
+# TODO
+
+
+class Plugin(PluginInterface):
+ def __init__(self, id: str, params: dict[str, Any]) -> None:
+ super().__init__(id, params)
+ print(f"[ConcatPlugin#{self.id}] initialized")
+
+ def process(self, source_id: str | None, items: list[Item]) -> list[Item]:
+ print(f"[ConcatPlugin#{self.id}] process called, n={len(items)}")
+ if source_id is None:
+ raise Exception(f"[ConcatPlugin#{self.id}] can not be scheduled")
+
+ Q = Query()
+ q_result = database_manager.plugin_states.search(Q.plugin_id == self.id)
+ if len(q_result) > 1:
+ raise Exception(
+ f"[ConcatPlugin#{self.id}] invalid database state, found more than 1 plugin state: {len(q_result)}"
+ )
+
+ d: Any = q_result[0] if len(q_result) == 1 else {}
+ data: dict[str, list[dict[str, str]]] = d
+
+ if source_id in data:
+ items_as_dicts = list(map(item_to_dict, items))
+ d[source_id] = items_as_dicts
+
+ aggregated_item_dicts: list[dict[str, str]] = []
+ for data_source_id in data:
+ item_dicts = data[data_source_id]
+ aggregated_item_dicts += item_dicts
+
+ ret = list(map(dict_to_item, aggregated_item_dicts))
+
+ print(f"[ConcatPlugin#{self.id}] process returning items, n={len(ret)}")
+ return ret
diff --git a/app/database.py b/app/DatabaseManager.py
index b796dc8..0ef3b49 100644
--- a/app/database.py
+++ b/app/DatabaseManager.py
@@ -9,6 +9,9 @@ class DatabaseManager:
def setup(self, config: AggroConfig):
self.db = TinyDB(config.db_path)
+ self.plugin_states = self.db.table("plugin_states") # type: ignore
+ self.feeds = self.db.table("feeds") # type: ignore
+ self.meta_info = self.db.table("meta_info") # type: ignore
database_manager: DatabaseManager = DatabaseManager()
diff --git a/app/FeedSinkPlugin.py b/app/FeedSinkPlugin.py
index 2c85167..237214f 100644
--- a/app/FeedSinkPlugin.py
+++ b/app/FeedSinkPlugin.py
@@ -6,7 +6,7 @@ from tinydb import Query
from app.Item import Item
from app.PluginInterface import PluginInterface
from app.utils import get_param
-from app.database import database_manager
+from app.DatabaseManager import database_manager
class Plugin(PluginInterface):
@@ -52,6 +52,6 @@ class Plugin(PluginInterface):
ret = self.build_xml(items)
Q = Query()
- database_manager.db.upsert({"feed_id": self.feed_id, "feed_xml": ret}, Q.feed_id == self.feed_id) # type: ignore
+ database_manager.feeds.upsert({"feed_id": self.feed_id, "feed_xml": ret}, Q.feed_id == self.feed_id) # type: ignore
print(f"[FeedSinkPlugin#{self.id}] processed")
return []
diff --git a/app/server.py b/app/server.py
index 785e30f..5de3018 100644
--- a/app/server.py
+++ b/app/server.py
@@ -2,7 +2,7 @@ from typing import Any
import bottle as _bottle # type: ignore
from tinydb import Query
-from app.database import database_manager
+from app.DatabaseManager import database_manager
bottle: Any = _bottle
@@ -13,7 +13,7 @@ def index(feed_id: str):
raise Exception("Database is not initialized")
Q = Query()
- res = database_manager.db.search(Q.feed_id == feed_id)
+ res = database_manager.feeds.search(Q.feed_id == feed_id)
if len(res) == 0:
bottle.abort(400, f"No feed found with id {feed_id}")
diff --git a/app/utils.py b/app/utils.py
index ac07bf7..d513ae9 100644
--- a/app/utils.py
+++ b/app/utils.py
@@ -1,5 +1,16 @@
+from app.Item import Item
+
+
def get_param(key: str, params: dict[str, str]) -> str:
if key not in params:
raise Exception(f"no {key} field in config entry: " + str(params))
return params[key]
+
+
+def item_to_dict(item: Item) -> dict[str, str]:
+ raise NotImplemented()
+
+
+def dict_to_item(d: dict[str, str]) -> Item:
+ raise NotImplemented()