-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Database notifications on stock changes
Adds triggers to send database notifications for changes to stock lines, stock types and stock items. Adds a command ('monitor') to output received notifications to the console. This also listens for previously defined notifications. This implements #276 on github. Apart from the 'monitor' command, the first consumer of these notifications is expected to be the EMF 2024 bar website.
- Loading branch information
Showing
3 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
"""Monitor till events | ||
""" | ||
|
||
from .cmdline import command | ||
from . import listen | ||
from . import td | ||
from . import event | ||
from .models import LogEntry, User, StockType, StockLine, StockItem | ||
from .models import Config, KeyCap | ||
from sqlalchemy.orm import joinedload | ||
from sqlalchemy.orm import undefer | ||
|
||
|
||
class monitor(command): | ||
@staticmethod | ||
def run(args): | ||
mainloop = event.SelectorsMainLoop() | ||
listener = listen.db_listener(mainloop, td.engine) | ||
|
||
# Start listening for all the types of notification we understand | ||
listener.listen_for("log", monitor.notify_log) | ||
listener.listen_for("user_register", monitor.notify_user_register) | ||
listener.listen_for("group_membership_changed", | ||
monitor.notify_group_membership_changed) | ||
listener.listen_for("group_grants_changed", | ||
monitor.notify_group_grants_changed) | ||
listener.listen_for("stockline_change", monitor.notify_stockline_change) | ||
listener.listen_for("stocktype_change", monitor.notify_stocktype_change) | ||
listener.listen_for("stockitem_change", monitor.notify_stockitem_change) | ||
listener.listen_for("keycaps", monitor.notify_keycaps) | ||
listener.listen_for("config", monitor.notify_config) | ||
listener.listen_for("update", monitor.notify_update) | ||
|
||
while True: | ||
mainloop.iterate() | ||
|
||
@staticmethod | ||
def notify_log(id_str): | ||
try: | ||
id = int(id_str) | ||
except Exception: | ||
return | ||
with td.orm_session(): | ||
logentry = td.s.query(LogEntry).get(id) | ||
if not logentry: | ||
return | ||
print(f"log: {logentry.id} {logentry.time} " | ||
f"{logentry.loguser.fullname}: {logentry}") | ||
|
||
@staticmethod | ||
def notify_user_register(id_str): | ||
try: | ||
id = int(id_str) | ||
except Exception: | ||
return | ||
with td.orm_session(): | ||
user = td.s.query(User).get(id) | ||
if not user: | ||
return | ||
print(f"user_register: {user.fullname} now at register " | ||
f"{user.register} with transaction {user.trans_id}") | ||
|
||
@staticmethod | ||
def notify_group_membership_changed(blank): | ||
# This notification doesn't have a payload | ||
print("group_membership_changed: a group has changed permissions") | ||
|
||
@staticmethod | ||
def notify_group_grants_changed(blank): | ||
# This notification doesn't have a payload | ||
print("group_grants_change: a user's groups have changed") | ||
|
||
@staticmethod | ||
def notify_stockline_change(id_str): | ||
try: | ||
id = int(id_str) | ||
except Exception: | ||
return | ||
with td.orm_session(): | ||
stockline = td.s.query(StockLine).get(id) | ||
if not stockline: | ||
print(f"stockline: id {id} deleted") | ||
return | ||
print(f"stockline: {stockline.name} note '{stockline.note}'") | ||
|
||
@staticmethod | ||
def notify_stocktype_change(id_str): | ||
try: | ||
id = int(id_str) | ||
except Exception: | ||
return | ||
with td.orm_session(): | ||
stocktype = td.s.query(StockType)\ | ||
.options(joinedload('meta'))\ | ||
.get(id) | ||
if not stocktype: | ||
print(f"stocktype: id {id} deleted") | ||
return | ||
print(f"stocktype: {stocktype}, price {stocktype.saleprice}, " | ||
f"dept {stocktype.department.description}") | ||
if stocktype.meta: | ||
print(f" metadata: {', '.join(stocktype.meta.keys())}") | ||
|
||
@staticmethod | ||
def notify_stockitem_change(id_str): | ||
try: | ||
id = int(id_str) | ||
except Exception: | ||
return | ||
with td.orm_session(): | ||
stock = td.s.query(StockItem)\ | ||
.options(undefer('remaining'))\ | ||
.options(joinedload('stocktype'), | ||
joinedload('stocktype.unit'))\ | ||
.get(id) | ||
if not stock: | ||
print(f"stock: id {id} deleted") | ||
return | ||
print(f"stock: {stock.id} {stock.stocktype} " | ||
f"{stock.remaining}/{stock.size} {stock.stocktype.unit.name}") | ||
if stock.finished: | ||
print(f" stock finished {stock.finished}") | ||
|
||
@staticmethod | ||
def notify_keycaps(keycode): | ||
with td.orm_session(): | ||
keycap = td.s.query(KeyCap).get(keycode) | ||
if not keycap: | ||
return | ||
print(f"keycap: {keycap.keycode} => '{keycap.keycap}' " | ||
f"class '{keycap.css_class}'") | ||
|
||
@staticmethod | ||
def notify_config(key): | ||
with td.orm_session(): | ||
config = td.s.query(Config).get(key) | ||
if not config: | ||
return | ||
print(f"config: {config.key} = {config.value}") | ||
|
||
@staticmethod | ||
def notify_update(blank): | ||
print("update: till update notified") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters