From: Edward Delaporte Date: Sun, 29 Mar 2026 15:09:22 +0000 (-0500) Subject: Initial draft X-Git-Tag: 1.0.0~5 X-Git-Url: https://us-delaporte.pagekite.me/gitweb/matrix-shop-bot.git/commitdiff_plain/adccaf550240b56ce5e5d7dd8775006f7f02fc0c?ds=inline Initial draft --- diff --git a/app.py b/app.py new file mode 100644 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 index 0000000..e69de29 diff --git a/matrix_shop_bot/db.py b/matrix_shop_bot/db.py new file mode 100644 index 0000000..be4b09d --- /dev/null +++ b/matrix_shop_bot/db.py @@ -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' + + + +