]>
apps.delaporte.us Git - matrix-shop-bot.git/blob - matrix_shop_bot/db.py
be4b09db5e4243f057f099e9d99bdf0723895983
3 from datetime
import datetime
as dt
5 from sqlmodel
import Field
, Session
, SQLModel
, create_engine
, select
, text
, Relationship
9 DATE_FORMAT
= '%Y-%m-%d'
12 return dt
.now().strftime(DATE_FORMAT
)
15 logger
= logging
.getLogger(__name__
)
16 logging
.basicConfig(filename
=f
'{MODULE}.log', encoding
='utf-8', level
=logging
.DEBUG
)
18 class Item(SQLModel
, table
=True):
19 id: int |
None = Field(default
=None, primary_key
=True)
20 name
: str = Field(default
=None, unique
=True)
21 price
: Decimal |
None = Field(decimal_places
=2)
22 stores
: list["Store"] = Relationship(back_populates
="shopping_list")
23 purchase_date
: dt |
None = Field(default
=None)
25 return f
'- [ ] {self.name} (#{self.id})'
27 class Store(SQLModel
, table
=True):
28 id: int |
None = Field(default
=None, primary_key
=True)
29 name
: str = Field(default
=None, unique
=True)
30 shopping_list
: list["Item"] = Relationship(back_populates
="stores")
31 purchase_history
: list["PurchaseRecord"] = Relationship(back_populates
="store")
33 return f
'{self.name} (#{self.id})'
36 # May get used later...
37 class PurchaseRecord(SQLModel
, table
=True):
38 id: int |
None = Field(default
=None, primary_key
=True)
39 name
: str = Field(default
=None, unique
=True)
40 price
: Decimal |
None = Field(decimal_places
=2)
41 store
: Store
= Relationship(back_populates
="purchase_history")
42 purchase_date
: dt |
None = Field(default
=None)
48 def __init__(self
, db_file
=None):
50 db_file
= os
.path
.join(os
.environ
.get('MATRIX_DATA_DIR', ''), 'goals.db')
53 self
.engine
= self
.get_engine()
55 def _add_with_name(self
, cls
, name
):
57 with Session(self
.engine
) as session
:
64 def _get_with_id(self
, cls
, item_id
):
65 with Session(self
.engine
) as session
:
66 cmd
= select(cls
).where(cls
.id == item_id
)
67 return session
.exec(cmd
).first()
69 def add_store(self
, name
):
70 return self
.add_with_name(Store
, name
)
72 def add_item(self
, name
):
73 return self
.add_with_name(Item
, name
)
75 def assign_store(self
, store_id
, item_id
):
76 with Session(self
.engine
) as session
:
77 store
= self
.get_with_id(Store
, store_id
)
78 item
= self
.get_with_id(Item
, item_id
)
79 item
.stores
.append(store
)
82 def purchase_item(self
, item_id
):
83 with Session(self
.engine
) as session
:
84 item
= self
.get_with_id(Item
, item_id
)
85 item
.purchase_date
= dt
.today()
88 def clear_list(self
, store_id
, clear_all
=False):
89 with Session(self
.engine
) as session
:
90 store
= self
.get_with_id(Store
, store_id
)
91 for item
in store
.items
:
92 if clear_all
or item
.purchased_date
:
96 def get_unsorted_list(self
):
99 with Session(self
.engine
) as session
:
100 cmd
= select(Item
).where(Item
.store
== None)
101 items
= session
.exec(cmd
).all()
104 return [f
'No unsorted items!']
107 def get_shopping_list(self
, store_id
) -> List(str):
109 with Session(self
.engine
) as session
:
110 cmd
= select(Store
).where(Store
.id == store_id
)
111 store
= session
.exec(cmd
).first()
113 return [f
'Store {store_id} not found.']
115 results
.append(f
' ## {store.name}')
117 items
= store
.shopping_list
119 results
.append('-- Nothing to shop for at {store.name} --')
122 if(item
.purchase_date
):
123 results
.append(f
' - [x] {item}')
125 results
.append(f
' - [ ] {item}')
128 def get_engine(self
):
129 return create_engine(f
"sqlite:///{self.file}")
132 SQLModel
.metadata
.create_all(self
.engine
)