Before this commit: Using the "Download logs" button from the IoT box form view will fail every time due to an Internal Server Error on the IoT side. ```py File "/home/pi/odoo/odoo/tools/misc.py", line 189, in file_path FileNotFoundError: File not found: /var/log/odoo/odoo-server.log ``` This happened due to changes introduced in: https://github.com/odoo/odoo/pull/99658 The changes enforced to double check that the file path was in an odoo addons (for security reasons). However, it is generally not the case, thus the error After this commit: The log file is downloaded as intended opw-3827121 closes odoo/odoo#160576 X-original-commit: a7aa4c6e58d6448556c85c393f2910490a0519f5 Signed-off-by: Loan Sens (lse) <lse@odoo.com>
98 lines
3.9 KiB
Python
Executable File
98 lines
3.9 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from base64 import b64decode
|
|
import json
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import time
|
|
from zlib import adler32
|
|
|
|
from odoo import http, tools
|
|
|
|
from odoo.addons.hw_drivers.event_manager import event_manager
|
|
from odoo.addons.hw_drivers.main import iot_devices, manager
|
|
from odoo.addons.hw_drivers.tools import helpers
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class DriverController(http.Controller):
|
|
@http.route('/hw_drivers/action', type='json', auth='none', cors='*', csrf=False, save_session=False)
|
|
def action(self, session_id, device_identifier, data):
|
|
"""
|
|
This route is called when we want to make a action with device (take picture, printing,...)
|
|
We specify in data from which session_id that action is called
|
|
And call the action of specific device
|
|
"""
|
|
iot_device = iot_devices.get(device_identifier)
|
|
if iot_device:
|
|
iot_device.data['owner'] = session_id
|
|
data = json.loads(data)
|
|
|
|
# Skip the request if it was already executed (duplicated action calls)
|
|
iot_idempotent_id = data.get("iot_idempotent_id")
|
|
if iot_idempotent_id:
|
|
idempotent_session = iot_device._check_idempotency(iot_idempotent_id, session_id)
|
|
if idempotent_session:
|
|
_logger.info("Ignored request from %s as iot_idempotent_id %s already received from session %s",
|
|
session_id, iot_idempotent_id, idempotent_session)
|
|
return False
|
|
iot_device.action(data)
|
|
return True
|
|
return False
|
|
|
|
@http.route('/hw_drivers/check_certificate', type='http', auth='none', cors='*', csrf=False, save_session=False)
|
|
def check_certificate(self):
|
|
"""
|
|
This route is called when we want to check if certificate is up-to-date
|
|
Used in cron.daily
|
|
"""
|
|
helpers.get_certificate_status()
|
|
|
|
@http.route('/hw_drivers/event', type='json', auth='none', cors='*', csrf=False, save_session=False)
|
|
def event(self, listener):
|
|
"""
|
|
listener is a dict in witch there are a sessions_id and a dict of device_identifier to listen
|
|
"""
|
|
req = event_manager.add_request(listener)
|
|
|
|
# Search for previous events and remove events older than 5 seconds
|
|
oldest_time = time.time() - 5
|
|
for event in list(event_manager.events):
|
|
if event['time'] < oldest_time:
|
|
del event_manager.events[0]
|
|
continue
|
|
if event['device_identifier'] in listener['devices'] and event['time'] > listener['last_event']:
|
|
event['session_id'] = req['session_id']
|
|
return event
|
|
|
|
# Wait for new event
|
|
if req['event'].wait(50):
|
|
req['event'].clear()
|
|
req['result']['session_id'] = req['session_id']
|
|
return req['result']
|
|
|
|
@http.route('/hw_drivers/download_logs', type='http', auth='none', cors='*', csrf=False, save_session=False)
|
|
def download_logs(self):
|
|
"""
|
|
Downloads the log file
|
|
"""
|
|
log_path = tools.config['logfile']
|
|
if log_path:
|
|
check = adler32(log_path.encode())
|
|
stat = os.stat(log_path)
|
|
# intentionally don't use Stream.from_path as the path used is not in the addons path
|
|
# for instance, for the iot-box it will be in /var/log/odoo
|
|
return http.Stream(
|
|
type='path',
|
|
path=log_path,
|
|
download_name=os.path.basename(log_path),
|
|
etag=f'{int(stat.st_mtime)}-{stat.st_size}-{check}',
|
|
last_modified=stat.st_mtime,
|
|
size=stat.st_size,
|
|
).get_response(
|
|
mimetype='text/plain', as_attachment=True
|
|
)
|