]> us-delaporte.pagekite.me Git - matrix-shop-bot.git/commitdiff
Initial draft
authorEdward Delaporte <edward@delaporte.us>
Sun, 29 Mar 2026 15:09:22 +0000 (10:09 -0500)
committerEdward Delaporte <edward@delaporte.us>
Sun, 29 Mar 2026 15:09:22 +0000 (10:09 -0500)
app.py [new file with mode: 0644]
matrix_shop_bot/__init__.py [new file with mode: 0644]
matrix_shop_bot/db.py [new file with mode: 0644]

diff --git a/app.py b/app.py
new file mode 100644 (file)
index 0000000..c2550ef
--- /dev/null
+++ b/app.py
@@ -0,0 +1,9 @@
+from matrix_shop_bot.bot import get_bot, shop_bot
+
+bot = get_bot()
+
+@bot.listener.on_message_event
+async def do_bot_stuff(room, message):
+    await shop_bot(room, message, bot)
+
+bot.run()
diff --git a/matrix_shop_bot/__init__.py b/matrix_shop_bot/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/matrix_shop_bot/db.py b/matrix_shop_bot/db.py
new file mode 100644 (file)
index 0000000..be4b09d
--- /dev/null
@@ -0,0 +1,137 @@
+import logging
+import os
+from datetime import datetime as dt
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select, text, Relationship
+
+MODULE='shop'
+
+DATE_FORMAT = '%Y-%m-%d'
+
+def today():
+    return dt.now().strftime(DATE_FORMAT)
+
+
+logger = logging.getLogger(__name__)
+logging.basicConfig(filename=f'{MODULE}.log', encoding='utf-8', level=logging.DEBUG)
+
+class Item(SQLModel, table=True):
+    id: int | None = Field(default=None, primary_key=True)
+    name: str = Field(default=None, unique=True)
+    price: Decimal | None = Field(decimal_places=2)
+    stores: list["Store"] = Relationship(back_populates="shopping_list")
+    purchase_date: dt | None = Field(default=None)
+    def __str__(self):
+        return f'- [ ] {self.name} (#{self.id})'
+
+class Store(SQLModel, table=True):
+    id: int | None = Field(default=None, primary_key=True)
+    name: str = Field(default=None, unique=True)
+    shopping_list: list["Item"] = Relationship(back_populates="stores")
+    purchase_history: list["PurchaseRecord"] = Relationship(back_populates="store")
+    def __str__(self):
+        return f'{self.name} (#{self.id})'
+
+
+# May get used later...
+class PurchaseRecord(SQLModel, table=True):
+    id: int | None = Field(default=None, primary_key=True)
+    name: str = Field(default=None, unique=True)
+    price: Decimal | None = Field(decimal_places=2)
+    store: Store = Relationship(back_populates="purchase_history")
+    purchase_date: dt | None = Field(default=None)
+
+
+
+
+class Data():
+    def __init__(self, db_file=None):
+        if not db_file:
+            db_file = os.path.join(os.environ.get('MATRIX_DATA_DIR', ''), 'goals.db')
+
+        self.file = db_file
+        self.engine = self.get_engine()
+
+    def _add_with_name(self, cls, name):
+        id = -1
+        with Session(self.engine) as session:
+            new = cls(name=name)
+            session.add(new)
+            session.commit()
+            id = new.id
+        return id
+
+    def _get_with_id(self, cls, item_id):
+        with Session(self.engine) as session:
+            cmd = select(cls).where(cls.id == item_id)
+            return session.exec(cmd).first()
+
+    def add_store(self, name):
+        return self.add_with_name(Store, name)
+            
+    def add_item(self, name):
+        return self.add_with_name(Item, name)
+
+    def assign_store(self, store_id, item_id):
+        with Session(self.engine) as session:
+            store = self.get_with_id(Store, store_id)
+            item = self.get_with_id(Item, item_id)
+            item.stores.append(store)
+            session.commit()
+
+    def purchase_item(self, item_id):
+        with Session(self.engine) as session:
+            item = self.get_with_id(Item, item_id)
+            item.purchase_date = dt.today()
+            session.commit()
+
+    def clear_list(self, store_id, clear_all=False):
+        with Session(self.engine) as session:
+            store = self.get_with_id(Store, store_id)
+            for item in store.items:
+                if clear_all or item.purchased_date:
+                    item.remove()
+            session.commit()
+
+    def get_unsorted_list(self):
+
+        results = []
+        with Session(self.engine) as session:
+            cmd = select(Item).where(Item.store == None)
+            items = session.exec(cmd).all()
+
+            if not items:
+                return [f'No unsorted items!']
+            return items
+
+    def get_shopping_list(self, store_id) -> List(str):
+        results = []
+        with Session(self.engine) as session:
+            cmd = select(Store).where(Store.id == store_id)
+            store = session.exec(cmd).first()
+            if not store:
+                return [f'Store {store_id} not found.']
+
+            results.append(f' ## {store.name}')
+
+            items = store.shopping_list
+            if not items:
+                results.append('-- Nothing to shop for at {store.name} --')
+
+            for item in items:
+                if(item.purchase_date):
+                    results.append(f' - [x] {item}')
+                else:
+                    results.append(f' - [ ] {item}')
+        return results
+
+    def get_engine(self):
+        return create_engine(f"sqlite:///{self.file}")
+
+    def setup(self):
+        SQLModel.metadata.create_all(self.engine)
+        return 'Success'
+
+
+
+