summaryrefslogtreecommitdiff
path: root/addons/hw_posbox_homepage/controllers/main.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/hw_posbox_homepage/controllers/main.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/hw_posbox_homepage/controllers/main.py')
-rw-r--r--addons/hw_posbox_homepage/controllers/main.py359
1 files changed, 359 insertions, 0 deletions
diff --git a/addons/hw_posbox_homepage/controllers/main.py b/addons/hw_posbox_homepage/controllers/main.py
new file mode 100644
index 00000000..146860cf
--- /dev/null
+++ b/addons/hw_posbox_homepage/controllers/main.py
@@ -0,0 +1,359 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import json
+import jinja2
+import logging
+import os
+from pathlib import Path
+import socket
+import subprocess
+import sys
+import threading
+
+from odoo import http
+from odoo.http import Response
+from odoo.modules.module import get_resource_path
+
+from odoo.addons.hw_drivers.main import iot_devices
+from odoo.addons.hw_drivers.tools import helpers
+from odoo.addons.web.controllers import main as web
+
+_logger = logging.getLogger(__name__)
+
+
+#----------------------------------------------------------
+# Controllers
+#----------------------------------------------------------
+
+if hasattr(sys, 'frozen'):
+ # When running on compiled windows binary, we don't have access to package loader.
+ path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'views'))
+ loader = jinja2.FileSystemLoader(path)
+else:
+ loader = jinja2.PackageLoader('odoo.addons.hw_posbox_homepage', "views")
+
+jinja_env = jinja2.Environment(loader=loader, autoescape=True)
+jinja_env.filters["json"] = json.dumps
+
+homepage_template = jinja_env.get_template('homepage.html')
+server_config_template = jinja_env.get_template('server_config.html')
+wifi_config_template = jinja_env.get_template('wifi_config.html')
+handler_list_template = jinja_env.get_template('handler_list.html')
+remote_connect_template = jinja_env.get_template('remote_connect.html')
+configure_wizard_template = jinja_env.get_template('configure_wizard.html')
+six_payment_terminal_template = jinja_env.get_template('six_payment_terminal.html')
+list_credential_template = jinja_env.get_template('list_credential.html')
+upgrade_page_template = jinja_env.get_template('upgrade_page.html')
+
+class IoTboxHomepage(web.Home):
+ def __init__(self):
+ super(IoTboxHomepage,self).__init__()
+ self.updating = threading.Lock()
+
+ def clean_partition(self):
+ subprocess.check_call(['sudo', 'bash', '-c', '. /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/upgrade.sh; cleanup'])
+
+ def get_six_terminal(self):
+ terminal_id = helpers.read_file_first_line('odoo-six-payment-terminal.conf')
+ return terminal_id or 'Not Configured'
+
+ def get_homepage_data(self):
+ hostname = str(socket.gethostname())
+ ssid = helpers.get_ssid()
+ wired = subprocess.check_output(['cat', '/sys/class/net/eth0/operstate']).decode('utf-8').strip('\n')
+ if wired == 'up':
+ network = 'Ethernet'
+ elif ssid:
+ if helpers.access_point():
+ network = 'Wifi access point'
+ else:
+ network = 'Wifi : ' + ssid
+ else:
+ network = 'Not Connected'
+
+ iot_device = []
+ for device in iot_devices:
+ iot_device.append({
+ 'name': iot_devices[device].device_name + ' : ' + str(iot_devices[device].data['value']),
+ 'type': iot_devices[device].device_type.replace('_', ' '),
+ 'identifier': iot_devices[device].device_identifier,
+ })
+
+ return {
+ 'hostname': hostname,
+ 'ip': helpers.get_ip(),
+ 'mac': helpers.get_mac_address(),
+ 'iot_device_status': iot_device,
+ 'server_status': helpers.get_odoo_server_url() or 'Not Configured',
+ 'six_terminal': self.get_six_terminal(),
+ 'network_status': network,
+ 'version': helpers.get_version(),
+ }
+
+ @http.route('/', type='http', auth='none')
+ def index(self):
+ wifi = Path.home() / 'wifi_network.txt'
+ remote_server = Path.home() / 'odoo-remote-server.conf'
+ if (wifi.exists() == False or remote_server.exists() == False) and helpers.access_point():
+ return "<meta http-equiv='refresh' content='0; url=http://" + helpers.get_ip() + ":8069/steps'>"
+ else:
+ return homepage_template.render(self.get_homepage_data())
+
+ @http.route('/list_handlers', type='http', auth='none', website=True)
+ def list_handlers(self):
+ drivers_list = []
+ for driver in os.listdir(get_resource_path('hw_drivers', 'iot_handlers/drivers')):
+ if driver != '__pycache__':
+ drivers_list.append(driver)
+ interfaces_list = []
+ for interface in os.listdir(get_resource_path('hw_drivers', 'iot_handlers/interfaces')):
+ if interface != '__pycache__':
+ interfaces_list.append(interface)
+ return handler_list_template.render({
+ 'title': "Odoo's IoT Box - Handlers list",
+ 'breadcrumb': 'Handlers list',
+ 'drivers_list': drivers_list,
+ 'interfaces_list': interfaces_list,
+ 'server': helpers.get_odoo_server_url()
+ })
+
+ @http.route('/load_iot_handlers', type='http', auth='none', website=True)
+ def load_iot_handlers(self):
+ helpers.download_iot_handlers(False)
+ subprocess.check_call(["sudo", "service", "odoo", "restart"])
+ return "<meta http-equiv='refresh' content='20; url=http://" + helpers.get_ip() + ":8069/list_handlers'>"
+
+ @http.route('/list_credential', type='http', auth='none', website=True)
+ def list_credential(self):
+ return list_credential_template.render({
+ 'title': "Odoo's IoT Box - List credential",
+ 'breadcrumb': 'List credential',
+ 'db_uuid': helpers.read_file_first_line('odoo-db-uuid.conf'),
+ 'enterprise_code': helpers.read_file_first_line('odoo-enterprise-code.conf'),
+ })
+
+ @http.route('/save_credential', type='http', auth='none', cors='*', csrf=False)
+ def save_credential(self, db_uuid, enterprise_code):
+ helpers.add_credential(db_uuid, enterprise_code)
+ subprocess.check_call(["sudo", "service", "odoo", "restart"])
+ return "<meta http-equiv='refresh' content='20; url=http://" + helpers.get_ip() + ":8069'>"
+
+ @http.route('/clear_credential', type='http', auth='none', cors='*', csrf=False)
+ def clear_credential(self):
+ helpers.unlink_file('odoo-db-uuid.conf')
+ helpers.unlink_file('odoo-enterprise-code.conf')
+ subprocess.check_call(["sudo", "service", "odoo", "restart"])
+ return "<meta http-equiv='refresh' content='20; url=http://" + helpers.get_ip() + ":8069'>"
+
+ @http.route('/wifi', type='http', auth='none', website=True)
+ def wifi(self):
+ return wifi_config_template.render({
+ 'title': 'Wifi configuration',
+ 'breadcrumb': 'Configure Wifi',
+ 'loading_message': 'Connecting to Wifi',
+ 'ssid': helpers.get_wifi_essid(),
+ })
+
+ @http.route('/wifi_connect', type='http', auth='none', cors='*', csrf=False)
+ def connect_to_wifi(self, essid, password, persistent=False):
+ if persistent:
+ persistent = "1"
+ else:
+ persistent = ""
+
+ subprocess.check_call([get_resource_path('point_of_sale', 'tools/posbox/configuration/connect_to_wifi.sh'), essid, password, persistent])
+ server = helpers.get_odoo_server_url()
+ res_payload = {
+ 'message': 'Connecting to ' + essid,
+ }
+ if server:
+ res_payload['server'] = {
+ 'url': server,
+ 'message': 'Redirect to Odoo Server'
+ }
+ else:
+ res_payload['server'] = {
+ 'url': 'http://' + helpers.get_ip() + ':8069',
+ 'message': 'Redirect to IoT Box'
+ }
+
+ return json.dumps(res_payload)
+
+ @http.route('/wifi_clear', type='http', auth='none', cors='*', csrf=False)
+ def clear_wifi_configuration(self):
+ helpers.unlink_file('wifi_network.txt')
+ return "<meta http-equiv='refresh' content='0; url=http://" + helpers.get_ip() + ":8069'>"
+
+ @http.route('/server_clear', type='http', auth='none', cors='*', csrf=False)
+ def clear_server_configuration(self):
+ helpers.unlink_file('odoo-remote-server.conf')
+ return "<meta http-equiv='refresh' content='0; url=http://" + helpers.get_ip() + ":8069'>"
+
+ @http.route('/handlers_clear', type='http', auth='none', cors='*', csrf=False)
+ def clear_handlers_list(self):
+ for directory in ['drivers', 'interfaces']:
+ for file in os.listdir(get_resource_path('hw_drivers', 'iot_handlers', directory)):
+ if file != '__pycache__':
+ helpers.unlink_file(get_resource_path('hw_drivers', 'iot_handlers', directory, file))
+ return "<meta http-equiv='refresh' content='0; url=http://" + helpers.get_ip() + ":8069/list_handlers'>"
+
+ @http.route('/server_connect', type='http', auth='none', cors='*', csrf=False)
+ def connect_to_server(self, token, iotname):
+ if token:
+ credential = token.split('|')
+ url = credential[0]
+ token = credential[1]
+ if len(credential) > 2:
+ # IoT Box send token with db_uuid and enterprise_code only since V13
+ db_uuid = credential[2]
+ enterprise_code = credential[3]
+ helpers.add_credential(db_uuid, enterprise_code)
+ else:
+ url = helpers.get_odoo_server_url()
+ token = helpers.get_token()
+ reboot = 'reboot'
+ subprocess.check_call([get_resource_path('point_of_sale', 'tools/posbox/configuration/connect_to_server.sh'), url, iotname, token, reboot])
+ return 'http://' + helpers.get_ip() + ':8069'
+
+ @http.route('/steps', type='http', auth='none', cors='*', csrf=False)
+ def step_by_step_configure_page(self):
+ return configure_wizard_template.render({
+ 'title': 'Configure IoT Box',
+ 'breadcrumb': 'Configure IoT Box',
+ 'loading_message': 'Configuring your IoT Box',
+ 'ssid': helpers.get_wifi_essid(),
+ 'server': helpers.get_odoo_server_url() or '',
+ 'hostname': subprocess.check_output('hostname').decode('utf-8').strip('\n'),
+ })
+
+ @http.route('/step_configure', type='http', auth='none', cors='*', csrf=False)
+ def step_by_step_configure(self, token, iotname, essid, password, persistent=False):
+ if token:
+ url = token.split('|')[0]
+ token = token.split('|')[1]
+ else:
+ url = ''
+ subprocess.check_call([get_resource_path('point_of_sale', 'tools/posbox/configuration/connect_to_server_wifi.sh'), url, iotname, token, essid, password, persistent])
+ return url
+
+ # Set server address
+ @http.route('/server', type='http', auth='none', website=True)
+ def server(self):
+ return server_config_template.render({
+ 'title': 'IoT -> Odoo server configuration',
+ 'breadcrumb': 'Configure Odoo Server',
+ 'hostname': subprocess.check_output('hostname').decode('utf-8').strip('\n'),
+ 'server_status': helpers.get_odoo_server_url() or 'Not configured yet',
+ 'loading_message': 'Configure Domain Server'
+ })
+
+ @http.route('/remote_connect', type='http', auth='none', cors='*')
+ def remote_connect(self):
+ """
+ Establish a link with a customer box trough internet with a ssh tunnel
+ 1 - take a new auth_token on https://dashboard.ngrok.com/
+ 2 - copy past this auth_token on the IoT Box : http://IoT_Box:8069/remote_connect
+ 3 - check on ngrok the port and url to get access to the box
+ 4 - you can connect to the box with this command : ssh -p port -v pi@url
+ """
+ return remote_connect_template.render({
+ 'title': 'Remote debugging',
+ 'breadcrumb': 'Remote Debugging',
+ })
+
+ @http.route('/enable_ngrok', type='http', auth='none', cors='*', csrf=False)
+ def enable_ngrok(self, auth_token):
+ if subprocess.call(['pgrep', 'ngrok']) == 1:
+ subprocess.Popen(['ngrok', 'tcp', '-authtoken', auth_token, '-log', '/tmp/ngrok.log', '22'])
+ return 'starting with ' + auth_token
+ else:
+ return 'already running'
+
+ @http.route('/six_payment_terminal', type='http', auth='none', cors='*', csrf=False)
+ def six_payment_terminal(self):
+ return six_payment_terminal_template.render({
+ 'title': 'Six Payment Terminal',
+ 'breadcrumb': 'Six Payment Terminal',
+ 'terminalId': self.get_six_terminal(),
+ })
+
+ @http.route('/six_payment_terminal_add', type='http', auth='none', cors='*', csrf=False)
+ def add_six_payment_terminal(self, terminal_id):
+ helpers.write_file('odoo-six-payment-terminal.conf', terminal_id)
+ subprocess.check_call(["sudo", "service", "odoo", "restart"])
+ return 'http://' + helpers.get_ip() + ':8069'
+
+ @http.route('/six_payment_terminal_clear', type='http', auth='none', cors='*', csrf=False)
+ def clear_six_payment_terminal(self):
+ helpers.unlink_file('odoo-six-payment-terminal.conf')
+ subprocess.check_call(["sudo", "service", "odoo", "restart"])
+ return "<meta http-equiv='refresh' content='0; url=http://" + helpers.get_ip() + ":8069'>"
+
+ @http.route('/hw_proxy/upgrade', type='http', auth='none', )
+ def upgrade(self):
+ commit = subprocess.check_output(["git", "--work-tree=/home/pi/odoo/", "--git-dir=/home/pi/odoo/.git", "log", "-1"]).decode('utf-8').replace("\n", "<br/>")
+ flashToVersion = helpers.check_image()
+ actualVersion = helpers.get_version()
+ if flashToVersion:
+ flashToVersion = '%s.%s' % (flashToVersion.get('major', ''), flashToVersion.get('minor', ''))
+ return upgrade_page_template.render({
+ 'title': "Odoo's IoTBox - Software Upgrade",
+ 'breadcrumb': 'IoT Box Software Upgrade',
+ 'loading_message': 'Updating IoT box',
+ 'commit': commit,
+ 'flashToVersion': flashToVersion,
+ 'actualVersion': actualVersion,
+ })
+
+ @http.route('/hw_proxy/perform_upgrade', type='http', auth='none')
+ def perform_upgrade(self):
+ self.updating.acquire()
+ os.system('/home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/posbox_update.sh')
+ self.updating.release()
+ return 'SUCCESS'
+
+ @http.route('/hw_proxy/get_version', type='http', auth='none')
+ def check_version(self):
+ return helpers.get_version()
+
+ @http.route('/hw_proxy/perform_flashing_create_partition', type='http', auth='none')
+ def perform_flashing_create_partition(self):
+ try:
+ response = subprocess.check_output(['sudo', 'bash', '-c', '. /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/upgrade.sh; create_partition']).decode().split('\n')[-2]
+ if response in ['Error_Card_Size', 'Error_Upgrade_Already_Started']:
+ raise Exception(response)
+ return Response('success', status=200)
+ except subprocess.CalledProcessError as e:
+ raise Exception(e.output)
+ except Exception as e:
+ _logger.error('A error encountered : %s ' % e)
+ return Response(str(e), status=500)
+
+ @http.route('/hw_proxy/perform_flashing_download_raspios', type='http', auth='none')
+ def perform_flashing_download_raspios(self):
+ try:
+ response = subprocess.check_output(['sudo', 'bash', '-c', '. /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/upgrade.sh; download_raspios']).decode().split('\n')[-2]
+ if response == 'Error_Raspios_Download':
+ raise Exception(response)
+ return Response('success', status=200)
+ except subprocess.CalledProcessError as e:
+ raise Exception(e.output)
+ except Exception as e:
+ self.clean_partition()
+ _logger.error('A error encountered : %s ' % e)
+ return Response(str(e), status=500)
+
+ @http.route('/hw_proxy/perform_flashing_copy_raspios', type='http', auth='none')
+ def perform_flashing_copy_raspios(self):
+ try:
+ response = subprocess.check_output(['sudo', 'bash', '-c', '. /home/pi/odoo/addons/point_of_sale/tools/posbox/configuration/upgrade.sh; copy_raspios']).decode().split('\n')[-2]
+ if response == 'Error_Iotbox_Download':
+ raise Exception(response)
+ return Response('success', status=200)
+ except subprocess.CalledProcessError as e:
+ raise Exception(e.output)
+ except Exception as e:
+ self.clean_partition()
+ _logger.error('A error encountered : %s ' % e)
+ return Response(str(e), status=500)