hunk.code_window:         #response = requests.get(url, auth=(username, db_uuid.split('\n')[0]), stream=True)
           server = self.get_server_status()
           if server:
               pm = urllib3.PoolManager()
               resp = False
               server = server + '/iot/get_drivers'
               try:
                   resp = pm.request('POST',
  
hunk.labels: keep keep keep replace keep keep keep keep
hunk.after_edit:             urllib3.disable_warnings()
               pm = urllib3.PoolManager(cert_reqs='CERT_NONE')
  
hunk.file_path: addons/hw_posbox_homepage/controllers/main.py
hunk.type: replace
file: #!/usr/bin/python3
  import logging
  import time
  from threading import Thread
  import usb
  import gatt
  import subprocess
  import netifaces as ni
  import json
  import re
  from odoo import http
  import urllib3
  from odoo.http import request as httprequest
  import datetime
  
  logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(name)s: %(message)s')
  _logger = logging.getLogger('dispatcher')
  
  owner_dict = {}
  last_ping = {}
  
  class StatusController(http.Controller):
  
      @http.route('/hw_drivers/owner/check', type='json', auth='none', cors='*', csrf=False)
      def check_cantakeowner(self): #, devices, tab
          data = httprequest.jsonrequest
          for device in data['devices']:
              if owner_dict.get(device) and owner_dict[device] != data['tab']:
                  before_date = datetime.datetime.now() - datetime.timedelta(seconds=10)
                  if last_ping.get(owner_dict[device]) and last_ping.get(owner_dict[device]) > before_date:
                      return 'no'
                  else:
                      old_tab = owner_dict[device]
                      for dev2 in owner_dict:
                          if owner_dict[dev2] == old_tab:
                              owner_dict[dev2] = ''
          return 'yes'
  
      @http.route('/hw_drivers/owner/take', type='json', auth='none', cors='*', csrf=False)
      def take_ownership(self): #, devices, tab
          data = httprequest.jsonrequest
          for device in data['devices']:
              owner_dict[device] = data['tab']
              last_ping[data['tab']] = datetime.datetime.now()
          return data['tab']
  
      @http.route('/hw_drivers/owner/ping', type='json', auth='none', cors='*', csrf=False)
      def ping_trigger(self): #, tab
          data = httprequest.jsonrequest
          ping_dict = {}
          last_ping[data['tab']] = datetime.datetime.now()
          for dev in data['devices']:
              if owner_dict.get(dev) and owner_dict[dev] == data['tab']:
                  for driver_path in drivers:
                      if driver_path.find(dev) == 0 and drivers[driver_path].ping_value:
                          ping_dict[dev] = drivers[driver_path].ping_value
                          drivers[driver_path].ping_value = ''  # or set it to nothing
              else:
                  ping_dict[dev] = 'STOP'
          return ping_dict
  
      @http.route('/hw_drivers/box/connect', type='json', auth='none', cors='*', csrf=False)
      def connect_box(self):
          data = httprequest.jsonrequest
          server = ""  # read from file
          try:
              f = open('/home/pi/odoo-remote-server.conf', 'r')
              for line in f:
                  server += line
              f.close()
              server = server.split('\n')[0]
          except:
              server = ''
          if server:
              return 'This IoTBox has already been connected'
          else:
              iotname = ''
              token = data['token'].split('|')[1]
              url = data['token'].split('|')[0]
              reboot = 'noreboot'
              subprocess.call(['/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/connect_to_server.sh', url, iotname, token, reboot])
              send_iot_box_device(False)
              return 'IoTBox connected'
  
      @http.route('/hw_drivers/drivers/status', type='http', auth='none', cors='*')
      def status(self):
          result = "<html><head></head><body>List of drivers and values: <br/> <ul>"
          for path in drivers:
              result += "<li>" + path + ":" + str(drivers[path].value) + "</li>"
          result += "</ul>"
          result +=" </body></html>"
          return result
  
      @http.route('/hw_drivers/driverdetails/<string:identifier>', type='http', auth='none', cors='*')
      def statusdetail(self, identifier):
          for device in drivers:
              if device.find(identifier) != -1:
                  return str(drivers[device].value)
          return ''
  
      @http.route('/hw_drivers/driveraction/<string:identifier>', type='json', auth='none', cors='*', csrf=False)
      def driveraction(self, identifier):
          data = httprequest.jsonrequest
          result = 'device not found'
          if data.get('action') == 'print':
              with open('/tmp/toprinter', 'w') as file:
                  file.write(data['data'])
              subprocess.call("cat /tmp/toprinter | base64 -d | lp -d " + identifier, shell=True)
              result = 'ok'
          if data.get('action') == 'camera':
              cameras = subprocess.check_output("v4l2-ctl --list-devices", shell=True).decode('utf-8').split('\n\n')
              adrress = '/dev/video0'
              for camera in cameras:
                  if camera:
                      camera = camera.split('\n\t')
                      serial = re.sub('[^a-zA-Z0-9 ]+', '', camera[0].split(': ')[0]).replace(' ','_')
                      if serial == data.get('identifier'):
                          adrress = camera[1]
              picture = subprocess.check_output("v4l2-ctl --list-formats-ext|grep 'Size'|awk '{print $3}'|sort -rn|awk NR==1", shell=True).decode('utf-8')
              subprocess.call("fswebcam -d " + adrress + " /tmp/testimage -r " + picture, shell=True)
              image_bytes = subprocess.check_output('cat /tmp/testimage | base64',shell=True)
              result = {'image': image_bytes}
          return result
  
      @http.route('/hw_drivers/send_iot_box', type='http', auth='none', cors='*')
      def send_iot_box(self):
          send_iot_box_device(False)
          return 'ok'
  
  #----------------------------------------------------------
  # Driver common interface
  #----------------------------------------------------------
  class Driver(Thread):
      ping_value = ""
  
      def supported(self):
          pass
  
      def value(self):
          pass
  
      def get_name(self):
          pass
  
      def get_connection(self):
          pass
  
      def action(self, action):
          pass
  
  #----------------------------------------------------------
  # Usb drivers
  #----------------------------------------------------------
  usbdrivers = []
  drivers = {}
  
  class UsbMetaClass(type):
      def __new__(cls, clsname, bases, attrs):
          newclass = super(UsbMetaClass, cls).__new__(cls, clsname, bases, attrs)
          usbdrivers.append(newclass)
          return newclass
  
  class USBDriver(Driver,metaclass=UsbMetaClass):
      def __init__(self, dev):
          super(USBDriver, self).__init__()
          self.dev = dev
          self.value = ""
  
      def get_name(self):
          lsusb = str(subprocess.check_output('lsusb')).split("\\n")
          for usbpath in lsusb:  # Should filter on usb devices or inverse loops?
              device = self.dev
              if "%04x:%04x" % (device.idVendor, device.idProduct) in usbpath:
                  return usbpath.split("%04x:%04x" % (device.idVendor, device.idProduct))[1]
          return str(device.idVendor) + ":" + str(device.idProduct)
  
      def get_connection(self):
          return 'direct'
  
      def value(self):
          return self.value
  
  
  #----------------------------------------------------------
  # Bluetooth
  #----------------------------------------------------------
  class GattBtManager(gatt.DeviceManager):
  
      def device_discovered(self, device):
          # TODO: need some kind of updated_devices mechanism or not?
          path = "bt_%s" % (device.mac_address,)
          if path not in drivers:
              for driverclass in btdrivers:
                  d = driverclass(device = device, manager=self)
                  if d.supported():
                      drivers[path] = d
                      d.connect()
                      send_iot_box_device(False)
  
  
  class BtManager(Thread):
      gatt_manager = False
  
      def run(self):
          dm = GattBtManager(adapter_name='hci0')
          self.gatt_manager = dm
          dm.start_discovery()
          dm.run()
  
  #----------------------------------------------------------
  # Bluetooth drivers
  #----------------------------------------------------------
  btdrivers = []
  
  class BtMetaClass(type):
      def __new__(cls, clsname, bases, attrs):
          newclass = super(BtMetaClass, cls).__new__(cls, clsname, bases, attrs)
          btdrivers.append(newclass)
          return newclass
  
  
  class BtDriver(Driver, metaclass=BtMetaClass):
  
  
      def __init__(self, device, manager):
          super(BtDriver, self).__init__()
          self.dev = device
          self.manager = manager
          self.value = ''
          self.gatt_device = False
  
      def disconnect(self):
          path = "bt_%s" % (self.dev.mac_address,)
          del drivers[path]
  
      def get_name(self):
          return self.dev.alias()
  
      def value(self):
          return self.value
  
      def action(self, action):
          pass
  
      def get_connection(self):
          return 'bluetooth'
  
      def connect(self):
          pass
  
  
  
  
  
  
  class USBDeviceManager(Thread):
      devices = {}
      def run(self):
          first_time = True
          send_iot_box_device(False)
          while 1:
              sendJSON = False
              devs = usb.core.find(find_all=True)
              updated_devices = {}
              for dev in devs:
                  path =  "usb_%04x:%04x_%03d_%03d_" % (dev.idVendor, dev.idProduct, dev.bus, dev.address)
                  updated_devices[path] = self.devices.get(path, dev)
              added = updated_devices.keys() - self.devices.keys()
              removed = self.devices.keys() - updated_devices.keys()
              self.devices = updated_devices
              if (removed):
                  for path in list(drivers):
                      if (path in removed):
                          del drivers[path]
                          sendJSON = True
              for path in added:
                  dev = updated_devices[path]
                  for driverclass in usbdrivers:
                      d = driverclass(updated_devices[path])
                      if d.supported():
                          _logger.info('For device %s will be driven', path)
                          drivers[path] = d
                          # launch thread
                          d.daemon = True
                          d.start()
                          sendJSON = True
              if sendJSON or first_time:
                  send_iot_box_device(send_printer = first_time)
                  first_time = False
              time.sleep(3)
              
  
  
  
  
  def send_iot_box_device(send_printer):
      maciotbox = subprocess.check_output("/sbin/ifconfig eth0 |grep -Eo ..\(\:..\){5}", shell=True).decode('utf-8').split('\n')[0]
      server = "" # read from file
      try:
          f = open('/home/pi/odoo-remote-server.conf', 'r')
          for line in f:
              server += line
          f.close()
      except: #In case the file does not exist
          server=''
      server = server.split('\n')[0]
      if server:
          url = server + "/iot/setup"
          interfaces = ni.interfaces()
          for iface_id in interfaces:
              iface_obj = ni.ifaddresses(iface_id)
              ifconfigs = iface_obj.get(ni.AF_INET, [])
              for conf in ifconfigs:
                  if conf.get('addr') and conf.get('addr') != '127.0.0.1':
                      ips = conf.get('addr')
                      break
  
          # Build device JSON
          devicesList = {}
          for path in drivers:
              device_name = drivers[path].get_name()
              device_connection = drivers[path].get_connection()
              identifier = path.split('_')[0] + '_' + path.split('_')[1]
              devicesList[identifier] = {'name': device_name,
                                   'type': 'device',
                                   'connection': device_connection}
  
          # Build camera JSON
          try:
              cameras = subprocess.check_output("v4l2-ctl --list-devices", shell=True).decode('utf-8').split('\n\n')
              for camera in cameras:
                  if camera:
                      camera = camera.split('\n\t')
                      serial = re.sub('[^a-zA-Z0-9 ]+', '', camera[0].split(': ')[0]).replace(' ','_')
                      devicesList[serial] = {
                                              'name': camera[0].split(': ')[0],
                                              'connection': 'direct',
                                              'type': 'camera'
                                          }
          except:
              pass
  
          # Build printer JSON
          printerList = {}
          if send_printer:
              printers = subprocess.check_output("sudo lpinfo -lv", shell=True).decode('utf-8').split('Device')
              printers_installed = ''
              try:
                  printers_installed = subprocess.check_output("sudo lpstat -a", shell=True).decode('utf-8')
              except:
                  pass
              for printer in printers:
                  printerTab = printer.split('\n')
                  if printer and printerTab[4].split('=')[1] != ' ':
                      device_connection = printerTab[1].split('= ')[1]
                      model = ''
                      for device_id in printerTab[4].split('= ')[1].split(';'):
                          if any(x in device_id for x in ['MDL','MODEL']):
                              model = device_id.split(':')[1]
                      serial = re.sub('[^a-zA-Z0-9 ]+', '', model).replace(' ','_')
                      identifier = ''
                      if device_connection == 'direct':
                          identifier = serial + '_' + maciotbox  #name + macIOTBOX
                      elif device_connection == 'network' and 'socket' in printerTab[0]:
                          socketIP = printerTab[0].split('://')[1]
                          macprinter = subprocess.check_output("arp -a " + socketIP + " |awk NR==1'{print $4}'", shell=True).decode('utf-8').split('\n')[0]
                          identifier = macprinter  # macPRINTER
                      elif device_connection == 'network' and 'dnssd' in printerTab[0]:
                          hostname_printer = subprocess.check_output("ippfind -n \"" + model + "\" | awk \'{split($0,a,\"/\"); print a[3]}\' | awk \'{split($0,b,\":\"); print b[1]}\'", shell=True).decode('utf-8').split('\n')[0]
                          if hostname_printer:
                              macprinter = subprocess.check_output("arp -a " + hostname_printer + " |awk NR==1'{print $4}'", shell=True).decode('utf-8').split('\n')[0]
                              identifier = macprinter  # macprinter
  
                      identifier = identifier.replace(':','_')
                      if identifier and identifier not in printerList:
                          printerList[identifier] = {
                                              'name': model,
                                              'connection': device_connection,
                                              'type': 'printer'
                          }
  
                          if identifier not in printers_installed:
                              # install these printers
                              try:
                                  ppd = subprocess.check_output("sudo lpinfo -m |grep '" + model + "'", shell=True).decode('utf-8').split('\n')
                                  if len(ppd) > 2:
                                      subprocess.call("sudo lpadmin -p '" + identifier + "' -E -v '" + printerTab[0].split('= ')[1] + "'", shell=True)
                                  else:
                                      subprocess.call("sudo lpadmin -p '" + identifier + "' -E -v '" + printerTab[0].split('= ')[1] + "' -m '" + ppd[0].split(' ')[0] + "'", shell=True)
                              except:
                                  subprocess.call("sudo lpadmin -p '" + identifier + "' -E -v '" + printerTab[0].split('= ')[1] + "'", shell=True)
              subprocess.call('> /tmp/printers', shell=True)
              for printer in printerList:
                  subprocess.call('echo "' + printerList[printer]['name'] + '" >> /tmp/printers', shell=True)
  
          if devicesList:
              subprocess.call('> /tmp/devices', shell=True)
              for device in devicesList:
                  subprocess.call('echo "' + str(device) + '|' + devicesList[device]['name'] + '" >> /tmp/devices', shell=True)
  
          #build JSON with all devices
          hostname = subprocess.check_output('hostname').decode('utf-8').split('\n')[0]
          token = "" # read from file
          try:
              f = open('/home/pi/token', 'r')
              for line in f:
                  token += line
              f.close()
          except: #In case the file does not exist
              token=''
          token = token.split('\n')[0]
          data = {'name': hostname,'identifier': maciotbox, 'ip': ips, 'token': token}
          devicesList.update(printerList)
          data['devices'] = devicesList
          data_json = json.dumps(data).encode('utf8')
          headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
          http = urllib3.PoolManager()
          req = False
          try:
              req = http.request('POST',
                                  url,
                                  body=data_json,
                                  headers=headers)
          except:
              _logger.warning('Could not reach configured server')
  
  
  