145 lines
5.5 KiB
Python
145 lines
5.5 KiB
Python
from pathlib import Path
|
|
from lxml import etree
|
|
from App_State import App_State, Attr_Dict
|
|
from filesystem_watcher import \
|
|
_Logger_, WindowsApiObserverExcpetionHandler, \
|
|
WindowsApiEmitterExceptionHandling, Directory_Handler
|
|
import time
|
|
import json
|
|
import datetime
|
|
|
|
class Order_Handler (Directory_Handler) :
|
|
|
|
def __init__ (self, path, client, config) :
|
|
super ().__init__ (path)
|
|
self.client = client
|
|
mqr = config.mqtt ["topic-root"]
|
|
baskets = f"{mqr}/baskets"
|
|
self.mqtt = Attr_Dict \
|
|
( basket_topic = f"{baskets}/{{basket_no}}"
|
|
, basket_state = f"{baskets}/{{basket_no}}/state"
|
|
, basket_user = f"{baskets}/{{basket_no}}/user"
|
|
, basket_changed = f"{baskets}/{{basket_no}}/changed"
|
|
, baskets = baskets
|
|
)
|
|
# end def __init__
|
|
|
|
def on_any_event (self, event) :
|
|
if event.event_type == 'created' :
|
|
file = Path (event.src_path)
|
|
if file.suffix == ".txt" :
|
|
xml = file.with_suffix (".xml")
|
|
if xml.exists () :
|
|
self.new_order (xml)
|
|
if file.suffix == ".xml" :
|
|
txt = file.with_suffix (".txt")
|
|
if txt.exists () :
|
|
self.new_order (file)
|
|
elif event.event_type == 'deleted' :
|
|
file = Path (event.src_path)
|
|
if file.suffix == ".xml" :
|
|
basket_no = file.stem
|
|
for t in self.mqtt.values () :
|
|
self.client.publish \
|
|
( t.format (basket_no = basket_no)
|
|
, payload = None, retain = False
|
|
)
|
|
self.L.info ("Order removed %s", basket_no)
|
|
super ().on_any_event (event)
|
|
# end def on_any_event
|
|
|
|
def new_order (self, xml_file : Path) :
|
|
try :
|
|
self.L.info ("New basket %s", xml_file.name)
|
|
xml = etree.parse (xml_file).getroot ()
|
|
com = xml.xpath ("//TEXT_SHORT") [0].text
|
|
user, line = xml.xpath ("//INFO8") [0].text.split ("/")
|
|
basket_no = xml_file.stem
|
|
self.client.publish \
|
|
( self.mqtt.basket_state.format (basket_no = basket_no)
|
|
, payload = "new", retain = True
|
|
)
|
|
self.client.publish \
|
|
( self.mqtt.basket_changed.format (basket_no = basket_no)
|
|
, payload = App_State.snow ("import"), retain = True
|
|
)
|
|
basket = dict \
|
|
(user = user, line = line, commission = com)
|
|
basket ["positions"] = self._scan_order_pos (xml)
|
|
self.client.publish \
|
|
( self.mqtt.basket_topic.format (basket_no = basket_no)
|
|
, payload = json.dumps (basket), retain = True
|
|
)
|
|
self.L.info ("Created new basket %s", basket_no)
|
|
except Exception as e :
|
|
self.L.error (e, exc_info = True)
|
|
# end def new_order
|
|
|
|
def _scan_order_pos (self, xml) :
|
|
result = []
|
|
bl = xml.xpath ("//BuilderList") [0]
|
|
for a in bl.getchildren () :
|
|
art_name = a.xpath ("Pname") [0].text.strip ()
|
|
count = int (a.xpath ("Count") [0].text)
|
|
pos = a.get ("LineNo")
|
|
text = a.xpath ("ARTICLE_TEXT_INFO1" ) [0].text.strip ()
|
|
price = float (a.xpath ("ARTICLE_PRICE_INFO1") [0].text)
|
|
result.append \
|
|
( dict ( art_name = art_name
|
|
, count = count
|
|
, pos = pos
|
|
, text = text
|
|
, price = price
|
|
)
|
|
)
|
|
return result
|
|
# end def _scan_order_pos
|
|
|
|
# end class Order_Handler
|
|
|
|
class Order_Watch (App_State) :
|
|
|
|
order_incomming_dir = r"n:\glueck\watch-me\inbox"
|
|
|
|
def __init__ (self, config_file) :
|
|
self.load_config (config_file)
|
|
self.client = self.connect_to_mqtt ()
|
|
# end def __init__
|
|
|
|
def _start_watchdog (self) :
|
|
handler = Order_Handler \
|
|
(self.order_incomming_dir, self.client, self.config)
|
|
return WindowsApiObserverExcpetionHandler.Start_Directory_Watcher \
|
|
(handler)
|
|
# end def _start_watchdog
|
|
|
|
def run (self) :
|
|
observer = None
|
|
try:
|
|
observer = self._start_watchdog ()
|
|
while True:
|
|
time.sleep (1)
|
|
if WindowsApiEmitterExceptionHandling.Exception :
|
|
App_State.L.exception \
|
|
(str (WindowsApiEmitterExceptionHandling.Exception))
|
|
WindowsApiEmitterExceptionHandling.Exception = None
|
|
if observer :
|
|
observer.stop ()
|
|
observer = self._start_watchdog ()
|
|
finally :
|
|
if observer :
|
|
observer.stop ()
|
|
observer.join ()
|
|
# end def run
|
|
|
|
# end class Order_Watch
|
|
|
|
if __name__ == "__main__" :
|
|
parser = Order_Watch.Add_Logging_Attributes ()
|
|
parser.add_argument ("config_file", type = str)
|
|
cmd = parser.parse_args ()
|
|
|
|
_Logger_.L = Order_Watch.Setup_Logging (cmd)
|
|
ow = Order_Watch (cmd.config_file)
|
|
ow.run ()
|
|
|