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 ()