order-processing/Order_Watch.py

144 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
class Order_Handler (Directory_Handler, App_State) :
def __init__ (self, path, client, config) :
super ().__init__ (path)
self.client = client
self.config = config
self._setup_topics (config)
# 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.basket.values () :
key = t.format (basket_no = basket_no)
self.client.delete (key)
self.L.debug ("Delete key %s", key)
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)
sim_xml = ( Path ( self.config.directories.sim_root)
/ "Archive" / xml_file.name
)
if not sim_xml.exists () :
self.L.error ("Archive order xml does not exist: %s", sim_xml)
xml = etree.parse (sim_xml).getroot ()
com = xml.xpath ("//TEXT_SHORT") [0].text
user, line = xml.xpath ("//INFO8") [0].text.split ("/")
basket_no = xml_file.stem
bt = self.mqtt.basket
self.client.publish \
( bt.state.format (basket_no = basket_no), 0)
self.client.publish \
( bt.changed.format (basket_no = basket_no)
, App_State.snow ("import")
)
basket = dict \
(shop_user = user, line = line, commission = com)
basket ["positions"] = self._scan_order_pos (xml)
self.client.publish \
( bt.data.format (basket_no = basket_no)
, json.dumps (basket)
)
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")
hpos = a.xpath ("hierarchicalPos") [0].text
text = a.xpath ("ARTICLE_TEXT_INFO1" ) [0].text.strip ()
price = float (a.xpath ("ARTICLE_PRICE_INFO1") [0].text)
tax = float (a.xpath ("ARTICLE_PRICE_INFO4") [0].text)
result.append \
( dict ( art_name = art_name
, count = count
, pos = pos
, hpos = hpos
, text = text
, tax = tax
, 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_db ()
# 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 = App_State.Setup_Logging (cmd)
ow = Order_Watch (cmd.config_file)
ow.run ()