]>
us-delaporte.pagekite.me Git - matrix-shop-bot.git/blob - matrix_shop_bot/db.py
407a12a733633fcc82e6f02269fbd69ece961615
3 from datetime
import datetime
as dt
4 from decimal
import Decimal
5 from typing
import List
7 from sqlmodel
import Field
, Session
, SQLModel
, create_engine
, select
, text
, Relationship
11 DATE_FORMAT
= '%Y-%m-%d'
14 return dt
.now().strftime(DATE_FORMAT
)
17 logger
= logging
.getLogger(__name__
)
18 logging
.basicConfig(filename
=f
'{MODULE}.log', encoding
='utf-8', level
=logging
.DEBUG
)
20 class ItemStoreLink(SQLModel
, table
=True):
21 item_id
: int |
None = Field(default
=None, foreign_key
="item.id", primary_key
=True)
22 store_id
: int |
None = Field(default
=None, foreign_key
="store.id", primary_key
=True)
25 class Item(SQLModel
, table
=True):
26 id: int |
None = Field(default
=None, primary_key
=True)
27 name
: str = Field(default
=None, unique
=True)
28 price
: Decimal |
None = Field(decimal_places
=2)
29 stores
: list["Store"] = Relationship(back_populates
="shopping_list", link_model
=ItemStoreLink
)
30 purchase_date
: dt |
None = Field(default
=None)
32 return f
'{self.name} (#{self.id})'
34 class Store(SQLModel
, table
=True):
35 id: int |
None = Field(default
=None, primary_key
=True)
36 name
: str = Field(default
=None, unique
=True)
37 shopping_list
: list["Item"] = Relationship(back_populates
="stores", link_model
=ItemStoreLink
)
38 # purchase_history: list["PurchaseRecord"] = Relationship(back_populates="store")
40 return f
'{self.name} (#{self.id})'
46 # May get used later...
47 #class PurchaseRecord(SQLModel, table=True):
48 # id: int | None = Field(default=None, primary_key=True)
49 # name: str = Field(default=None, unique=True)
50 # price: Decimal | None = Field(decimal_places=2)
51 # store: Store = Relationship(back_populates="purchase_history")
52 # purchase_date: dt | None = Field(default=None)
54 def _get_with_id(cls
, item_id
):
55 return select(cls
).where(cls
.id == item_id
)
59 def __init__(self
, db_file
=None):
61 db_file
= os
.path
.join(os
.environ
.get('MATRIX_DATA_DIR', ''), f
'{MODULE}.db')
64 self
.engine
= self
.get_engine()
66 def _add_with_name(self
, cls
, name
):
68 with Session(self
.engine
) as session
:
75 def add_store(self
, name
):
76 return self
._add
_with
_name
(Store
, name
)
78 def add_item(self
, name
):
79 return self
._add
_with
_name
(Item
, name
)
81 def assign_store(self
, store_id
, item_id
):
82 with Session(self
.engine
) as session
:
83 store
= session
.exec(_get_with_id(Store
, store_id
)).first()
84 item
= session
.exec(_get_with_id(Item
, item_id
)).first()
85 item
.stores
.append(store
)
88 def purchase_item(self
, item_id
):
89 with Session(self
.engine
) as session
:
90 item
= session
.exec(_get_with_id(Item
, item_id
)).first()
91 item
.purchase_date
= dt
.today()
94 def clear_list(self
, store_id
, clear_all
=False):
95 with Session(self
.engine
) as session
:
96 store
= session
.exec(_get_with_id(Store
, store_id
)).first()
97 for item
in store
.items
:
98 if clear_all
or item
.purchased_date
:
102 def get_unsorted_list(self
):
105 with Session(self
.engine
) as session
:
106 cmd
= select(Item
).where(Item
.store
== None)
107 items
= session
.exec(cmd
).all()
110 return [f
'No unsorted items!']
113 def get_shopping_list(self
, store_id
) -> List
[str]:
115 with Session(self
.engine
) as session
:
116 cmd
= select(Store
).where(Store
.id == store_id
)
117 store
= session
.exec(cmd
).first()
119 return [f
'Store {store_id} not found.']
121 results
.append(f
' ## {store.name}')
123 items
= store
.shopping_list
125 results
.append(f
'-- Nothing to shop for at {store.name} --')
128 if(item
.purchase_date
):
129 results
.append(f
' - [x] {item}')
131 results
.append(f
' - [ ] {item}')
134 def get_engine(self
):
135 return create_engine(f
"sqlite:///{self.file}")
138 SQLModel
.metadata
.create_all(self
.engine
)