X-Git-Url: https://apps.delaporte.us/gitweb/matrix-shop-bot.git/blobdiff_plain/17242e775a86365e2e2e1a7bfea3b9a6b7847b53..068a02cde78b07286384ee7de34cc442eb5b7233:/matrix_shop_bot/db.py diff --git a/matrix_shop_bot/db.py b/matrix_shop_bot/db.py index 407a12a..58bb4ff 100644 --- a/matrix_shop_bot/db.py +++ b/matrix_shop_bot/db.py @@ -6,6 +6,8 @@ from typing import List from sqlmodel import Field, Session, SQLModel, create_engine, select, text, Relationship +from sqlite3 import IntegrityError + MODULE='shop' DATE_FORMAT = '%Y-%m-%d' @@ -31,6 +33,9 @@ class Item(SQLModel, table=True): def __str__(self): return f'{self.name} (#{self.id})' +class PreferStore(SQLModel, table=True): + store_id: int | None = Field(default=None, foreign_key="store.id", primary_key=True) + class Store(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str = Field(default=None, unique=True) @@ -62,54 +67,110 @@ class Data(): self.file = db_file self.engine = self.get_engine() + self.last_store_id = None - def _add_with_name(self, cls, name): - id = -1 + def _set_pref_store_id(self, store_id): with Session(self.engine) as session: - new = cls(name=name) - session.add(new) + prefs = session.exec(select(PreferStore)).all() + for pref in prefs: + session.delete(pref) + pref = PreferStore() + pref.store_id = store_id + session.add(pref) session.commit() - id = new.id - return id + + def _get_pref_store_id(self): + with Session(self.engine) as session: + pref = session.exec(select(PreferStore)).one() + return pref.store_id + + def _add_with_name(self, cls, name): + item_id = -1 + try: + with Session(self.engine) as session: + new = cls(name=name) + session.add(new) + session.commit() + item_id = new.id + except: + # duplicate add + # recover by returning the item_id + item = session.exec(select(Item).where(Item.name == name)).first() + item_id = item.id + + return item_id def add_store(self, name): - return self._add_with_name(Store, name) + store_id = self._add_with_name(Store, name) + self._set_pref_store_id(store_id) + return store_id def add_item(self, name): - return self._add_with_name(Item, name) + names = name.split(',') + for name in names: + item_id = self._add_with_name(Item, name.strip()) + store_id = self._get_pref_store_id() + self.assign_store(item_id, store_id) + return item_id + + def assign_last_store(self, item_id): + store_id = self._get_pref_store_id() + self.assign_store(item_id, store_id) + return store_id + + def assign_store(self, item_id, store_id): + self._set_pref_store_id(store_id) - def assign_store(self, store_id, item_id): with Session(self.engine) as session: store = session.exec(_get_with_id(Store, store_id)).first() item = session.exec(_get_with_id(Item, item_id)).first() - item.stores.append(store) - session.commit() + try: + item.stores.append(store) + session.commit() + except: + pass # Already assigned + return ['Success'] def purchase_item(self, item_id): with Session(self.engine) as session: item = session.exec(_get_with_id(Item, item_id)).first() item.purchase_date = dt.today() session.commit() + return ['Success'] def clear_list(self, store_id, clear_all=False): with Session(self.engine) as session: store = session.exec(_get_with_id(Store, store_id)).first() - for item in store.items: - if clear_all or item.purchased_date: - item.remove() + for item in store.shopping_list: + if clear_all or item.purchase_date: + session.delete(item) session.commit() + def get_stores(self): + with Session(self.engine) as session: + cmd = select(Store) + return session.exec(cmd).all() + def get_unsorted_list(self): results = [] with Session(self.engine) as session: - cmd = select(Item).where(Item.store == None) + cmd = select(Item).where(Item.stores == None) items = session.exec(cmd).all() if not items: return [f'No unsorted items!'] return items + + def get_shopping_list_for_store(self, store_id) -> List[str]: + self._set_pref_store_id(store_id) + return self.get_shopping_list(store_id) + + def get_last_shopping_list(self) -> List[str]: + store_id = self._get_pref_store_id() + return self.get_shopping_list(store_id) + def get_shopping_list(self, store_id) -> List[str]: results = [] with Session(self.engine) as session: @@ -123,14 +184,26 @@ class Data(): items = store.shopping_list if not items: results.append(f'-- 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}') + else: + for item in items: + if(item.purchase_date): + results.append(f' - [x] {item}') + else: + results.append(f' - [ ] {item}') return results + def remove_item(self, item_id): + with Session(self.engine) as session: + item = session.exec(_get_with_id(Item, item_id)).first() + session.delete(item) + session.commit() + + def remove_store(self, store_id): + with Session(self.engine) as session: + store = session.exec(_get_with_id(Store, store_id)).first() + session.delete(store) + session.commit() + def get_engine(self): return create_engine(f"sqlite:///{self.file}")