summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2017-03-24 17:11:48 +0100
committerChristophe Simonis <chs@odoo.com>2017-03-24 17:11:48 +0100
commit8376f538b568c7a679db414bbb2379c66a78cff0 (patch)
tree810980414ddf3cfa7aaeafd083feba3d7d3dd7fe
parent52b3b1f1bfb15c747e8f2381eaf939b85f2454db (diff)
parent9d04d14669f97da002c04bfdbdde1f5b44b1b6bb (diff)
[MERGE] forward port branch saas-6 up to 9d04d14669f
-rw-r--r--addons/hw_escpos/controllers/main.py7
-rw-r--r--addons/hw_posbox_homepage/controllers/main.py5
-rw-r--r--addons/hw_screen/__init__.py4
-rw-r--r--addons/hw_screen/__openerp__.py21
-rw-r--r--addons/hw_screen/controllers/__init__.py4
-rw-r--r--addons/hw_screen/controllers/main.py166
-rw-r--r--addons/hw_screen/static/src/css/cust_css.css21
-rw-r--r--addons/hw_screen/static/src/js/worker.js60
-rwxr-xr-xaddons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh2
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf8
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart6
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf32
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.rsabin0 -> 4197 bytes
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf4
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README3
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest4
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js34
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul175
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskunknownContentType.xul9
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskxpinstallConfirm.xul9
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/install.rdf19
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js7
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo2
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh47
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules2
-rwxr-xr-xaddons/point_of_sale/tools/posbox/posbox_create_image.sh23
-rw-r--r--addons/web/static/src/js/framework/pyeval.js44
-rw-r--r--addons/web/static/test/evals.js5
-rw-r--r--addons/web_calendar/static/src/js/web_calendar.js4
-rw-r--r--openerp/http.py13
30 files changed, 711 insertions, 29 deletions
diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py
index c5273154e8c..0829a384a21 100644
--- a/addons/hw_escpos/controllers/main.py
+++ b/addons/hw_escpos/controllers/main.py
@@ -86,10 +86,15 @@ class EscposDriver(Thread):
printers = usb.core.find(find_all=True, idVendor=0x0519)
for printer in printers:
+ try:
+ description = usb.util.get_string(printer, 256, printer.iManufacturer) + " " + usb.util.get_string(printer, 256, printer.iProduct)
+ except Exception as e:
+ _logger.error("Can not get printer description: %s" % (e.message or repr(e)))
+ description = 'Unknown printer'
connected.append({
'vendor': printer.idVendor,
'product': printer.idProduct,
- 'name': usb.util.get_string(printer, 256, printer.iManufacturer) + " " + usb.util.get_string(printer, 256, printer.iProduct)
+ 'name': description
})
return connected
diff --git a/addons/hw_posbox_homepage/controllers/main.py b/addons/hw_posbox_homepage/controllers/main.py
index 65b276075d2..8a448e386f5 100644
--- a/addons/hw_posbox_homepage/controllers/main.py
+++ b/addons/hw_posbox_homepage/controllers/main.py
@@ -58,7 +58,10 @@ index_template = """
If you need to grant remote debugging access to a developer, you can do it <a href='/remote_connect'>here</a>.
</p>
<p>
- The PosBox software installed on this posbox is <b>version 15</b>,
+ If you need to display the current customer basket on another device, you can do it <a href='/point_of_sale/display'>here</a>.
+ </p>
+ <p>
+ The PosBox software installed on this posbox is <b>version 16</b>,
the posbox version number is independent from Odoo. You can upgrade
the software on the <a href='/hw_proxy/upgrade/'>upgrade page</a>.
</p>
diff --git a/addons/hw_screen/__init__.py b/addons/hw_screen/__init__.py
new file mode 100644
index 00000000000..bf7fb7b45c1
--- /dev/null
+++ b/addons/hw_screen/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import controllers
diff --git a/addons/hw_screen/__openerp__.py b/addons/hw_screen/__openerp__.py
new file mode 100644
index 00000000000..8ed5711b836
--- /dev/null
+++ b/addons/hw_screen/__openerp__.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+{
+ 'name': 'Screen Driver',
+ 'version': '1.0',
+ 'category': 'Hardware Drivers',
+ 'sequence': 6,
+ 'summary': 'Provides support for customer facing displays',
+ 'website': 'https://www.odoo.com/page/point-of-sale',
+ 'description': """
+Screen Driver
+=============
+
+This module allows the POS client to send rendered HTML to a remotely
+installed screen. This module then displays this HTML using a web
+browser.
+""",
+ 'depends': ['hw_proxy'],
+ 'installable': False,
+ 'auto_install': False,
+}
diff --git a/addons/hw_screen/controllers/__init__.py b/addons/hw_screen/controllers/__init__.py
new file mode 100644
index 00000000000..f48716d3a69
--- /dev/null
+++ b/addons/hw_screen/controllers/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import main
diff --git a/addons/hw_screen/controllers/main.py b/addons/hw_screen/controllers/main.py
new file mode 100644
index 00000000000..716f3117115
--- /dev/null
+++ b/addons/hw_screen/controllers/main.py
@@ -0,0 +1,166 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from openerp import http
+from openerp.tools import config
+from openerp.addons.web.controllers import main as web
+
+import logging
+import netifaces as ni
+import os
+from subprocess import call
+import time
+import threading
+
+self_port = str(config['xmlrpc_port'] or 8069)
+
+_logger = logging.getLogger(__name__)
+
+
+class HardwareScreen(web.Home):
+
+ event_data = threading.Event()
+ pos_client_data = {'rendered_html': False,
+ 'ip_from': False}
+ display_in_use = ''
+ failure_count = {}
+
+ def _call_xdotools(self, keystroke):
+ os.environ['DISPLAY'] = ":0.0"
+ os.environ['XAUTHORITY'] = "/run/lightdm/pi/xauthority"
+ try:
+ call(['xdotool', 'key', keystroke])
+ return "xdotool succeeded in stroking " + keystroke
+ except:
+ return "xdotool threw an error, maybe it is not installed on the posbox"
+
+ @http.route('/hw_proxy/display_refresh', type='json', auth='none', cors='*')
+ def display_refresh(self):
+ return self._call_xdotools('F5')
+
+ # POS CASHIER'S ROUTES
+ @http.route('/hw_proxy/customer_facing_display', type='json', auth='none', cors='*')
+ def update_user_facing_display(self, html=None):
+ request_ip = http.request.httprequest.remote_addr
+ if request_ip == HardwareScreen.pos_client_data.get('ip_from', ''):
+ HardwareScreen.pos_client_data['rendered_html'] = html
+ HardwareScreen.event_data.set()
+
+ return {'status': 'updated'}
+ else:
+ return {'status': 'failed'}
+
+ @http.route('/hw_proxy/take_control', type='json', auth='none', cors='*')
+ def take_control(self, html=None):
+ # ALLOW A CASHIER TO TAKE CONTROL OVER THE POSBOX, IN CASE OF MULTIPLE CASHIER PER POSBOX
+ HardwareScreen.pos_client_data['rendered_html'] = html
+ HardwareScreen.pos_client_data['ip_from'] = http.request.httprequest.remote_addr
+ HardwareScreen.event_data.set()
+
+ return {'status': 'success',
+ 'message': 'You now have access to the display'}
+
+ @http.route('/hw_proxy/test_ownership', type='json', auth='none', cors='*')
+ def test_ownership(self):
+ if HardwareScreen.pos_client_data.get('ip_from') == http.request.httprequest.remote_addr:
+ return {'status': 'OWNER'}
+ else:
+ return {'status': 'NOWNER'}
+
+ # POSBOX ROUTES (SELF)
+ @http.route('/point_of_sale/display', type='http', auth='none')
+ def render_main_display(self):
+ return self._get_html()
+
+ @http.route('/point_of_sale/get_serialized_order', type='json', auth='none')
+ def get_serialized_order(self):
+ request_addr = http.request.httprequest.remote_addr
+ result = HardwareScreen.pos_client_data
+ if HardwareScreen.display_in_use and request_addr != HardwareScreen.display_in_use:
+ if not HardwareScreen.failure_count.get(request_addr):
+ HardwareScreen.failure_count[request_addr] = 0
+ if HardwareScreen.failure_count[request_addr] > 0:
+ time.sleep(10)
+ HardwareScreen.failure_count[request_addr] += 1
+ return {'rendered_html': """<div class="pos-customer_facing_display"><p>Not Authorized. Another browser is in use to display for the client. Please refresh.</p></div> """,
+ 'stop_longpolling': True,
+ 'ip_from': request_addr}
+
+ # IMPLEMENTATION OF LONGPOLLING
+ # Times out 2 seconds before the JS request does
+ if HardwareScreen.event_data.wait(28):
+ HardwareScreen.event_data.clear()
+ HardwareScreen.failure_count[request_addr] = 0
+ return result
+ return {'rendered_html': False,
+ 'ip_from': HardwareScreen.pos_client_data['ip_from']}
+
+ def _get_html(self):
+ cust_js = None
+ interfaces = ni.interfaces()
+ my_ip = '127.0.0.1'
+ HardwareScreen.display_in_use = http.request.httprequest.remote_addr
+
+ with open(os.path.join(os.path.dirname(__file__), "../static/src/js/worker.js")) as js:
+ cust_js = js.read()
+
+ with open(os.path.join(os.path.dirname(__file__), "../static/src/css/cust_css.css")) as css:
+ cust_css = css.read()
+
+ display_ifaces = ""
+ 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'):
+ display_ifaces += "<tr><td>" + iface_id + "</td>"
+ display_ifaces += "<td>" + conf.get('addr') + "</td>"
+ display_ifaces += "<td>" + conf.get('netmask') + "</td></tr>"
+ # What is my external IP ?
+ if iface_id != 'lo':
+ my_ip = conf.get('addr')
+
+ my_ip_port = my_ip + ":" + self_port
+
+ html = """
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title class="origin">Odoo -- Point of Sale</title>
+ <script type="text/javascript" class="origin" src="http://""" + my_ip_port + """/web/static/lib/jquery/jquery.js" >
+ </script>
+ <script type="text/javascript" class="origin">
+ """ + cust_js + """
+ </script>
+ <link rel="stylesheet" class="origin" href="http://""" + my_ip_port + """/web/static/lib/bootstrap/css/bootstrap.css" >
+ </link>
+ <script class="origin" src="http://""" + my_ip_port + """/web/static/lib/bootstrap/js/bootstrap.min.js"></script>
+ <style class="origin">
+ """ + cust_css + """
+ </style>
+ </head>
+ <body class="original_body">
+ <div hidden class="shadow"></div>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-4 col-md-offset-4">
+ <h1>Odoo Point of Sale</h1>
+ <h2>POSBox Client display</h2>
+ <h3>My IPs</h3>
+ <table id="table_ip" class="table table-condensed">
+ <tr>
+ <th>Interface</th>
+ <th>IP</th>
+ <th>Netmask</th>
+ </tr>
+ """ + display_ifaces + """
+ </table>
+ <p>The customer cart will be displayed here once a Point of Sale session is started.</p>
+ <p>Odoo version 11 or above is required.</p>
+ </div>
+ </div>
+ </div>
+ </body>
+ </html>
+ """
+ return html
diff --git a/addons/hw_screen/static/src/css/cust_css.css b/addons/hw_screen/static/src/css/cust_css.css
new file mode 100644
index 00000000000..69fddb25457
--- /dev/null
+++ b/addons/hw_screen/static/src/css/cust_css.css
@@ -0,0 +1,21 @@
+html {
+ width: 100%;
+ height: 100%;
+ font-size: 11px;
+}
+
+body {
+ width: 100%;
+ height: 100%;
+ font-size: 14px;
+ margin: 0;
+}
+
+.original_body {
+ background-color: #797083;
+ color: white;
+}
+
+.ajax_got_body {
+ color: black;
+} \ No newline at end of file
diff --git a/addons/hw_screen/static/src/js/worker.js b/addons/hw_screen/static/src/js/worker.js
new file mode 100644
index 00000000000..55e389e78ab
--- /dev/null
+++ b/addons/hw_screen/static/src/js/worker.js
@@ -0,0 +1,60 @@
+ $(function() {
+ "use strict";
+ // mergedHead will be turned to true the first time we receive something from a new host
+ // It allows to transform the <head> only once
+ var mergedHead = false;
+ var current_client_url = "";
+ var stop_longpolling = false;
+
+ function longpolling() {
+ $.ajax({
+ type: 'POST',
+ url: 'http://'+window.location.host+'/point_of_sale/get_serialized_order',
+ dataType: 'json',
+ beforeSend: function(xhr){xhr.setRequestHeader('Content-Type', 'application/json');},
+ data: JSON.stringify({jsonrpc: '2.0'}),
+
+ success: function(data) {
+ if (typeof data.result.stop_longpolling !== 'undefined') {
+ stop_longpolling = data.result.stop_longpolling;
+ }
+ if (data.result.ip_from && data.result.rendered_html) {
+ var trimmed = $.trim(data.result.rendered_html);
+ var $parsedHTML = $('<div>').html($.parseHTML(trimmed,true)); // WARNING: the true here will executes any script present in the string to parse
+ var new_client_url = $parsedHTML.find(".resources > base").attr('href');
+
+ if (!mergedHead || (current_client_url !== new_client_url)) {
+
+ mergedHead = true;
+ current_client_url = new_client_url;
+ $("body").removeClass('original_body').addClass('ajax_got_body');
+ $("head").children().not('.origin').remove();
+ $("head").append($parsedHTML.find(".resources").html());
+ }
+
+ $(".container").html($parsedHTML.find('.pos-customer_facing_display').html());
+ $(".container").attr('class', 'container').addClass($parsedHTML.find('.pos-customer_facing_display').attr('class'));
+
+ var d = $('.pos_orderlines_list');
+ d.scrollTop(d.prop("scrollHeight"));
+
+ // Here we execute the code coming from the pos, apparently $.parseHTML() executes scripts right away,
+ // Since we modify the dom afterwards, the script might not have any effect
+ if (typeof foreign_js !== 'undefined' && $.isFunction(foreign_js)) {
+ foreign_js();
+ }
+ }
+ },
+
+ complete: function(jqXHR,err) {
+ if (!stop_longpolling) {
+ longpolling();
+ }
+ },
+
+ timeout: 30000,
+ });
+ };
+
+ longpolling();
+ }); \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh b/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh
index ce2f2e633e6..618c4b1fd48 100755
--- a/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh
+++ b/addons/point_of_sale/tools/posbox/configuration/setup_ramdisks.sh
@@ -11,7 +11,7 @@ create_ramdisk () {
echo "Creating ramdisk for ${1} of size ${SIZE}..."
mount -t tmpfs -o size="${SIZE}" tmpfs "${RAMDISK}"
- rsync -a --exclude="swap" --exclude="apt" --exclude="dpkg" "${ORIGINAL}/" "${RAMDISK}/"
+ rsync -a --exclude="swap" --exclude="apt" --exclude="dpkg" --exclude=".mozilla" "${ORIGINAL}/" "${RAMDISK}/"
mount --bind "${RAMDISK}" "${ORIGINAL}"
}
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf
new file mode 100644
index 00000000000..977903c1c90
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf
@@ -0,0 +1,8 @@
+
+[LightDM]
+user-authority-in-system-dir=true
+
+[SeatDefaults]
+xserver-command=/usr/bin/X -s 0 dpms -nolisten tcp
+greeter-hide-users=false
+autologin-user=pi \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart
new file mode 100755
index 00000000000..e2b61e2f591
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/xdg/openbox/autostart
@@ -0,0 +1,6 @@
+#!/bin/bash
+xset s off
+xset -dpms
+
+export HOME=/tmp
+/usr/bin/firefox http://localhost:8069/point_of_sale/display &
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf
new file mode 100644
index 00000000000..63a9098e00d
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/manifest.mf
@@ -0,0 +1,32 @@
+Manifest-Version: 1.0
+
+Name: install.rdf
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: xnFKNbJgc33dy/FJ+4cmHA==
+SHA1-Digest: 4YLgHgdgCw4lGCfsX7+r4zVmKJ4=
+
+Name: chrome.manifest
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: O5ce4bajAqUxG6iVul0K2w==
+SHA1-Digest: wb6VleWnV5GgLypmg1ij9TfmPLE=
+
+Name: content/rkioskbrowser.js
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: /cF15tfVnbkfbxRVTL5N+g==
+SHA1-Digest: lvbY92PbsjwY+0TguEYoXWw0lxQ=
+
+Name: content/rkioskbrowser.xul
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: NFOIpAmZtn20Y+XfTo4cpw==
+SHA1-Digest: VVIo7GdG+4mvAOtgR0DJUsSc/yg=
+
+Name: content/rkioskunknownContentType.xul
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 6cNGoHJS9Xvm+wmvo4IesQ==
+SHA1-Digest: T8i1MkMKjmn5HICqWv+iXSPRKIU=
+
+Name: content/rkioskxpinstallConfirm.xul
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: SxN1YnRJiuood2WhU85v9g==
+SHA1-Digest: Msj21u4bTAKUi496xld5YCGdjiA=
+
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.rsa b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.rsa
new file mode 100644
index 00000000000..521b08d182a
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.rsa
Binary files differ
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf
new file mode 100644
index 00000000000..37eae3e21fb
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/META-INF/mozilla.sf
@@ -0,0 +1,4 @@
+Signature-Version: 1.0
+MD5-Digest-Manifest: 7hFyhNW67+H+rf9OhWGDkA==
+SHA1-Digest-Manifest: HvfAQQLXphSZ9m8KBorJMX8MUnE=
+
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README
new file mode 100644
index 00000000000..c8c1ce58823
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/README
@@ -0,0 +1,3 @@
+The R-kiosk module has been downloaded from https://addons.mozilla.org/en-US/firefox/addon/r-kiosk/
+It is in the public domain as stated on https://addons.mozilla.org/en-US/firefox/addon/r-kiosk/eula/
+This mozilla module is shipped by Odoo to provide out of the box Client facing display to Odoo's Posbox \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest
new file mode 100644
index 00000000000..e4957b8d5e8
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/chrome.manifest
@@ -0,0 +1,4 @@
+content RKiosk content/
+overlay chrome://browser/content/browser.xul chrome://rkiosk/content/rkioskbrowser.xul
+overlay chrome://mozapps/content/xpinstall/xpinstallConfirm.xul chrome://rkiosk/content/rkioskxpinstallConfirm.xul
+overlay chrome://mozapps/content/downloads/unknownContentType.xul chrome://rkiosk/content/rkioskunknownContentType.xul
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js
new file mode 100644
index 00000000000..5ece9a9e06b
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.js
@@ -0,0 +1,34 @@
+function Rkiosk_donothing()
+{
+
+
+}
+
+function rkioskclose()
+{
+ close();
+}
+
+function Rkiosk_navbar_setting()
+{
+ var rkiosk_navbar_enable="true";
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"].
+ getService(Components.interfaces.nsIPrefBranch);
+ if (prefs.getPrefType("rkiosk.navbar") == prefs.PREF_BOOL){
+ if (prefs.getBoolPref("rkiosk.navbar")) rkiosk_navbar_enable = "false";
+ }
+ var rkiosk_element = document.getElementById("navigator-toolbox");
+ rkiosk_element.setAttribute("hidden", rkiosk_navbar_enable);
+}
+
+function RkioskBrowserStartup()
+{
+ Rkiosk_navbar_setting();
+ BrowserStartup();
+ setTimeout(RkioskdelayedStartup, 1000);
+}
+
+function RkioskdelayedStartup()
+{
+ window.fullScreen = true;
+}
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul
new file mode 100644
index 00000000000..d5fb0c140d1
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskbrowser.xul
@@ -0,0 +1,175 @@
+<?xml version="1.0"?>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+<window id="main-window"
+ onload="RkioskBrowserStartup()">
+</window>
+
+<script type="application/x-javascript" src="rkioskbrowser.js"/>
+
+ <menubar id="main-menubar" hidden="true" fullscreentoolbar="false" disabled="true">
+ <menuitem id="menu_preferences" disabled="true"/>
+ </menubar>
+
+ <popup id="contentAreaContextMenu"
+ onpopupshowing="if (event.target != this) return true; return false;"
+ onpopuphiding="if (event.target == this) gContextMenu = null;">
+ </popup>
+
+ <commandset id="mainCommandSet">
+ <command id="cmd_newNavigator" disabled="true"/>
+ <command id="cmd_handleBackspace" disabled="true"/>
+ <command id="cmd_handleShiftBackspace" disabled="true"/>
+ <command id="cmd_newNavigatorTab" disabled="true"/>
+ <command id="Browser:OpenFile" disabled="true"/>
+ <command id="Browser:SavePage" disabled="true"/>
+ <command id="Browser:SaveFrame" disabled="true"/>
+ <command id="Browser:SendLink" disabled="true"/>
+ <command id="cmd_pageSetup" disabled="true"/>
+ <command id="cmd_print" oncommand="PrintUtils.print();"/>
+ <command id="cmd_printPreview" disabled="true"/>
+ <command id="cmd_close" disabled="true"/>
+ <command id="cmd_closeWindow" disabled="true"/>
+ <command id="cmd_ToggleTabsOnTop" disabled="true"/>
+ <command id="cmd_quitApplication" disabled="true"/>
+ <command id="cmd_toggleTaskbar" disabled="true"/>
+ <command id="cmd_CustomizeToolbars" disabled="true"/>
+ <commandset id="editMenuCommands"/>
+ <command id="View:PageSource" disabled="true"/>
+ <command id="View:PageInfo" disabled="true"/>
+ <command id="View:FullScreen" disabled="true"/>
+ <command id="cmd_find" disabled="true"/>
+ <command id="cmd_findAgain" disabled="true"/>
+ <command id="cmd_findPrevious" disabled="true"/>
+ <command id="Browser:AddBookmarkAs" disabled="true"/>
+ <command id="Browser:BookmarkAllTabs" disabled="true"/>
+ <command id="Browser:Home" oncommand="BrowserHome();"/>
+ <command id="Browser:Back" disabled="true"/>
+ <command id="Browser:Forward" disabled="true"/>
+ <command id="Browser:Stop" disabled="true"/>
+ <command id="Browser:Reload" disabled="true"/>
+ <command id="Browser:ReloadSkipCache" disabled="true"/>
+ <command id="Browser:BackOrBackDuplicate" disabled="true"/>
+ <command id="Browser:Forward" disabled="true"/>
+ <command id="Browser:ForwardOrForwardDuplicate" disabled="true"/>
+ <command id="Browser:ReloadOrDuplicate" disabled="true"/>
+ <command id="Browser:NextTab" disabled="true"/>
+ <command id="Browser:PrevTab" disabled="true"/>
+ <command id="Browser:ShowAllTabs" disabled="true"/>
+ <command id="Browser:ToggleTabView" disabled="true"/>
+ <command id="Browser:ToggleAddonBar" disabled="true"/>
+ <command id="cmd_fullZoomReduce" disabled="true"/>
+ <command id="cmd_fullZoomEnlarge" disabled="true"/>
+ <command id="cmd_fullZoomReset" disabled="true"/>
+ <command id="cmd_fullZoomToggle" disabled="true"/>
+ <command id="Browser:OpenLocation" disabled="true"/>
+ <command id="Tools:Search" disabled="true"/>
+ <command id="Tools:Downloads" disabled="true"/>
+ <command id="Tools:Addons" disabled="true"/>
+ <command id="Tools:Sanitize" disabled="true"/>
+ <command id="Tools:Inspect" disabled="true"/>
+ <command id="Tools:PrivateBrowsing" disabled="true"/>
+ <command id="History:UndoCloseTab" disabled="true"/>
+ <command id="History:UndoCloseWindow" disabled="true"/>
+ <command id="cmd_bm_open" disabled="true"/>
+ <command id="cmd_bm_openinnewwindow" disabled="true"/>
+ <command id="cmd_bm_openinnewtab" disabled="true"/>
+ <command id="cmd_bm_openfolder" disabled="true"/>
+ <command id="cmd_bm_managefolder" disabled="true"/>
+ <command id="cmd_bm_newfolder" disabled="true"/>
+ <command id="cmd_bm_newbookmark" disabled="true"/>
+ <command id="cmd_bm_newseparator" disabled="true"/>
+ <command id="cmd_bm_properties" disabled="true"/>
+ <command id="cmd_bm_refreshlivemark" disabled="true"/>
+ <command id="cmd_bm_refreshmicrosummary" disabled="true"/>
+ <command id="cmd_bm_rename" disabled="true"/>
+ <command id="cmd_bm_moveBookmark" disabled="true"/>
+ <command id="cmd_bm_sortbyname" disabled="true"/>
+ <command id="cmd_copyLink" disabled="true"/>
+ <command id="cmd_copyImageLocation" disabled="true"/>
+ <command id="cmd_copyImageContents" disabled="true"/>
+ <command id="cmd_undo" disabled="true"/>
+ <command id="cmd_redo" disabled="true"/>
+ <command id="cmd_cut" disabled="true"/>
+ <command id="cmd_copy" disabled="true"/>
+ <command id="cmd_paste" disabled="true"/>
+ <command id="cmd_delete" disabled="true"/>
+ <command id="cmd_selectAll" disabled="true"/>
+ <command id="cmd_switchTextDirection" disabled="true"/>
+ <command id="cmd_textZoomReduce" disabled="true"/>
+ <command id="cmd_textZoomEnlarge" disabled="true"/>
+ <command id="cmd_textZoomReset" disabled="true"/>
+ </commandset>
+ <commandset id="placesCommands">
+ <command id="Browser:ShowAllBookmarks" disabled="true"/>
+ <command id="Browser:ShowAllHistory" disabled="true"/>
+ </commandset>
+
+ <keyset id="mainKeyset">
+ <key id="rkiosk_f1" keycode="VK_F1" oncommand="Rkiosk_donothing();"/>
+ <key id="key_newNavigator" disabled="true"/>
+ <key id="key_newNavigatorTab" disabled="true"/>
+ <key id="focusURLBar" disabled="true"/>
+ <key id="focusURLBar2" disabled="true"/>
+ <key id="key_search" disabled="true"/>
+ <key id="key_search2" disabled="true"/>
+ <key id="key_openDownloads" disabled="true"/>
+ <key id="openFileKb" disabled="true"/>
+ <key id="key_savePage" disabled="true"/>
+ <key id="printKb" disabled="true"/>
+ <key id="key_close" disabled="true"/>
+ <key id="key_closeWindow" disabled="true"/>
+ <key id="key_undo" disabled="true"/>
+ <key id="key_redo" disabled="true"/>
+ <key id="key_cut" disabled="true"/>
+ <key id="key_copy" disabled="true"/>
+ <key id="key_paste" disabled="true"/>
+ <key id="key_delete" disabled="true"/>
+ <key id="key_selectAll" disabled="true"/>
+ <key id="goBackKb" disabled="true"/>
+ <key id="goForwardKb" disabled="true"/>
+ <key id="goHome" keycode="VK_HOME" command="Browser:Home" modifiers="alt"/>
+ <key id="key_viewSource" disabled="true"/>
+ <key id="key_find" disabled="true"/>
+ <key id="key_findAgain" disabled="true"/>
+ <key id="key_findPrevious" disabled="true"/>
+ <key id="addBookmarkAsKb" disabled="true"/>
+ <key id="bookmarkAllTabsKb" disabled="true"/>
+ <key id="key_stop" disabled="true"/>
+ <key id="key_gotoHistory" command="Rkiosk_donothing();"/>
+ <key id="key_switchTextDirection" disabled="true"/>
+ <key id="key_sanitize" disabled="true"/>
+ <key id="key_undoCloseTab" disabled="true"/>
+ <key id="viewBookmarksSidebarKb" command="Rkiosk_donothing();"/>
+ <key id="viewBookmarksSidebarWinKb" command="Rkiosk_donothing();"/>
+ <key id="key_fullScreen" disabled="true"/>
+ <key id="key_textZoomReduce" disabled="true"/>
+ <key id="key_textZoomEnlarge" disabled="true"/>
+ <key id="key_textZoomReset" disabled="true"/>
+ <key id="showAllHistoryKb" disabled="true"/>
+ <key id="key_errorConsole" disabled="true"/>
+ <key id="manBookmarkKb" disabled="true"/>
+ <key id="key_fullZoomReduce" disabled="true"/>
+ <key id="key_fullZoomEnlarge" disabled="true"/>
+ <key id="key_fullZoomReset" disabled="true"/>
+ <key id="key_openAddons" disabled="true"/>
+ <key id="key_webConsole" disabled="true"/>
+ <key id="key_inspect" disabled="true"/>
+ <key id="key_scratchpad" disabled="true"/>
+ <key id="key_showAllTabs" disabled="true"/>
+ <key id="key_tabview" disabled="true"/>
+ <key id="key_privatebrowsing" disabled="true"/>
+ <key id="key_undoCloseWindow" disabled="true"/>
+ <key id="key_selectTab1" disabled="true"/>
+ <key id="key_selectTab2" disabled="true"/>
+ <key id="key_selectTab3" disabled="true"/>
+ <key id="key_selectTab4" disabled="true"/>
+ <key id="key_selectTab5" disabled="true"/>
+ <key id="key_selectTab6" disabled="true"/>
+ <key id="key_selectTab7" disabled="true"/>
+ <key id="key_selectTab8" disabled="true"/>
+ <key id="key_selectLastTab" disabled="true"/>
+ <key id="key_toggleAddonBar" disabled="true"/>
+ </keyset>
+</overlay> \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskunknownContentType.xul b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskunknownContentType.xul
new file mode 100644
index 00000000000..faf2381d1fa
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskunknownContentType.xul
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+
+<overlay>
+ <dialog id="unknownContentType"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="rkioskclose();">
+ <script src="rkioskbrowser.js"/>
+ </dialog>
+</overlay>
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskxpinstallConfirm.xul b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskxpinstallConfirm.xul
new file mode 100644
index 00000000000..b96deadeee6
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/content/rkioskxpinstallConfirm.xul
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+
+<overlay>
+ <dialog id="xpinstallConfirm"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="rkioskclose();">
+ <script src="rkioskbrowser.js"/>
+ </dialog>
+</overlay>
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/install.rdf b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/install.rdf
new file mode 100644
index 00000000000..5be400e52e8
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/lib/firefox-esr/browser/extensions/{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}/install.rdf
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='utf-8'?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+ <Description about="urn:mozilla:install-manifest">
+
+ <em:id>{4D498D0A-05AD-4fdb-97B5-8A0AABC1FC5B}</em:id>
+ <em:name>R-kiosk</em:name>
+ <em:version>0.9.0.1-signed.1-signed</em:version>
+ <em:description>RKiosk (Real Kiosk), fullscreen kiosk mode: all menus, keys etc. disabled</em:description>
+ <em:creator>Kimmo Heinaaro</em:creator>
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>2.0</em:minVersion>
+ <em:maxVersion>6.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF> \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js
new file mode 100644
index 00000000000..8de5d5d60a4
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/usr/share/firefox-esr/browser/defaults/preferences/all-posbox.js
@@ -0,0 +1,7 @@
+// Preferences to allow unattended install of R-Kiosk extension
+// Needed for Odoo posbox Client display
+pref("app.update.checkInstallTime", false);
+pref("devtools.webide.widget.autoinstall", false);
+pref("xpinstall.customConfirmationUI", false);
+pref("xpinstall.signatures.required", false);
+pref("browser.shell.checkDefaultBrowser",false)
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo
index 30be4bd26d3..4ab50a456a1 100755
--- a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init.d/odoo
@@ -26,7 +26,7 @@ test -x $DAEMON || exit 0
set -e
function _start() {
- start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$USER --background --make-pidfile --exec $DAEMON -- --config $CONFIG --logfile $LOGFILE --load=web,hw_proxy,hw_posbox_homepage,hw_posbox_upgrade,hw_scale,hw_scanner,hw_escpos,hw_blackbox_be
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$USER --background --make-pidfile --exec $DAEMON -- --config $CONFIG --logfile $LOGFILE --load=web,hw_proxy,hw_posbox_homepage,hw_posbox_upgrade,hw_scale,hw_scanner,hw_escpos,hw_blackbox_be,hw_screen
}
function _stop() {
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
index a05dfc897ae..00058bef68c 100755
--- a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
@@ -8,17 +8,25 @@ __dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
+# Since we are emulating, the real /boot is not mounted,
+# leading to mismatch between kernel image and modules.
+mount /dev/sda1 /boot
+
# Recommends: antiword, graphviz, ghostscript, postgresql, python-gevent, poppler-utils
export DEBIAN_FRONTEND=noninteractive
+echo "nameserver 8.8.8.8" >> /etc/resolv.conf
-mount /dev/sda1 /boot
apt-get update
apt-get -y dist-upgrade
+# Do not be too fast to upgrade to more recent firmware and kernel than 4.38
+# Firmware 4.44 seems to prevent the LED mechanism from working
-PKGS_TO_INSTALL="adduser postgresql-client python python-dateutil python-decorator python-docutils python-feedparser python-imaging python-jinja2 python-ldap python-libxslt1 python-lxml python-mako python-mock python-openid python-passlib python-psutil python-psycopg2 python-pybabel python-pychart python-pydot python-pyparsing python-pypdf python-reportlab python-requests python-tz python-vatnumber python-vobject python-werkzeug python-xlwt python-yaml postgresql python-gevent python-serial python-pip python-dev localepurge vim mc mg screen iw hostapd isc-dhcp-server git rsync console-data"
+PKGS_TO_INSTALL="adduser postgresql-client python python-dateutil python-decorator python-docutils python-feedparser python-imaging python-jinja2 python-ldap python-libxslt1 python-lxml python-mako python-mock python-openid python-passlib python-psutil python-psycopg2 python-pybabel python-pychart python-pydot python-pyparsing python-pypdf python-reportlab python-requests python-tz python-vatnumber python-vobject python-werkzeug python-xlwt python-yaml postgresql python-gevent python-serial python-pip python-dev localepurge vim mc mg screen iw hostapd isc-dhcp-server git rsync console-data lightdm xserver-xorg-video-fbdev xserver-xorg-input-evdev iceweasel xdotool unclutter x11-utils openbox python-netifaces rpi-update"
-apt-get -y install ${PKGS_TO_INSTALL}
+# KEEP OWN CONFIG FILES DURING PACKAGE CONFIGURATION
+# http://serverfault.com/questions/259226/automatically-keep-current-version-of-config-files-when-apt-get-install
+apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" --force-yes install ${PKGS_TO_INSTALL}
apt-get clean
localepurge
@@ -32,13 +40,20 @@ pip install pyusb==1.0.0b1
pip install qrcode
pip install evdev
+# --upgrade because websocket_client in wheezy is bad:
+# https://github.com/docker/compose/issues/1288
+pip install --upgrade websocket_client
+
groupadd usbusers
usermod -a -G usbusers pi
usermod -a -G lp pi
+usermod -a -G input lightdm
sudo -u postgres createuser -s pi
mkdir /var/log/odoo
chown pi:pi /var/log/odoo
+chown pi:pi -R /home/pi/odoo/
+chmod 770 -R /home/pi/odoo/
# logrotate is very picky when it comes to file permissions
chown -R root:root /etc/logrotate.d/
@@ -54,6 +69,31 @@ update-rc.d -f isc-dhcp-server remove
systemctl daemon-reload
systemctl enable ramdisks.service
systemctl disable dphys-swapfile.service
+systemctl enable ssh
+
+# USER PI AUTO LOGIN (from nano raspi-config)
+# We take the whole algorithm from raspi-config in order to stay compatible with raspbian infrastructure
+if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
+ SYSTEMD=1
+elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
+ SYSTEMD=0
+else
+ echo "Unrecognised init system"
+ return 1
+fi
+if [ $SYSTEMD -eq 1 ]; then
+ systemctl set-default graphical.target
+ ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
+else
+ update-rc.d lightdm enable 2
+fi
+
+# disable overscan in /boot/config.txt, we can't use
+# overwrite_after_init because it's on a different device
+# (/dev/mmcblk0p1) and we don't mount that afterwards.
+# This option disables any black strips around the screen
+# cf: https://www.raspberrypi.org/documentation/configuration/raspi-config.md
+echo "disable_overscan=1" >> /boot/config.txt
# https://www.raspberrypi.org/forums/viewtopic.php?p=79249
# to not have "setting up console font and keymap" during boot take ages
@@ -68,5 +108,6 @@ create_ramdisk_dir "/var"
create_ramdisk_dir "/etc"
create_ramdisk_dir "/tmp"
mkdir /root_bypass_ramdisks
+umount /dev/sda1
reboot
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules
new file mode 100644
index 00000000000..aab19f2d1c7
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/udev/rules.d/99-z-input.rules
@@ -0,0 +1,2 @@
+SUBSYSTEM=="input", GROUP="input", MODE="0660"
+KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660" \ No newline at end of file
diff --git a/addons/point_of_sale/tools/posbox/posbox_create_image.sh b/addons/point_of_sale/tools/posbox/posbox_create_image.sh
index 1e4c9d1277c..a9ec8bc102d 100755
--- a/addons/point_of_sale/tools/posbox/posbox_create_image.sh
+++ b/addons/point_of_sale/tools/posbox/posbox_create_image.sh
@@ -36,20 +36,25 @@ fi
cp -a *raspbian*.img posbox.img
CLONE_DIR="${OVERWRITE_FILES_BEFORE_INIT_DIR}/home/pi/odoo"
+
rm -rf "${CLONE_DIR}"
-mkdir "${CLONE_DIR}"
-git clone -b 8.0 --no-checkout --depth 1 https://github.com/odoo/odoo.git "${CLONE_DIR}"
-cd "${CLONE_DIR}"
-git config core.sparsecheckout true
-echo "addons/web
+
+if [ ! -d $CLONE_DIR ]; then
+ echo "Clone Github repo"
+ mkdir -p "${CLONE_DIR}"
+ git clone -b 8.0 --no-local --no-checkout --depth 1 https://github.com/odoo/odoo.git "${CLONE_DIR}"
+ cd "${CLONE_DIR}"
+ git config core.sparsecheckout true
+ echo "addons/web
addons/web_kanban
addons/hw_*
addons/point_of_sale/tools/posbox/configuration
openerp/
odoo.py" | tee --append .git/info/sparse-checkout > /dev/null
-git read-tree -mu HEAD
-cd "${__dir}"
+ git read-tree -mu HEAD
+fi
+cd "${__dir}"
USR_BIN="${OVERWRITE_FILES_BEFORE_INIT_DIR}/usr/bin/"
mkdir -p "${USR_BIN}"
cd "/tmp"
@@ -60,9 +65,11 @@ cd "${__dir}"
mv /tmp/ngrok "${USR_BIN}"
# zero pad the image to be around 3.5 GiB, by default the image is only ~1.3 GiB
+echo "Enlarging the image..."
dd if=/dev/zero bs=1M count=2048 >> posbox.img
# resize partition table
+echo "Fdisking"
START_OF_ROOT_PARTITION=$(fdisk -l posbox.img | tail -n 1 | awk '{print $2}')
(echo 'p'; # print
echo 'd'; # delete
@@ -75,7 +82,7 @@ START_OF_ROOT_PARTITION=$(fdisk -l posbox.img | tail -n 1 | awk '{print $2}')
echo 'p'; # print
echo 'w') | fdisk posbox.img # write and quit
-LOOP_MAPPER_PATH=$(kpartx -av posbox.img | tail -n 1 | cut -d ' ' -f 3)
+LOOP_MAPPER_PATH=$(kpartx -avs posbox.img | tail -n 1 | cut -d ' ' -f 3)
LOOP_MAPPER_PATH="/dev/mapper/${LOOP_MAPPER_PATH}"
sleep 5
diff --git a/addons/web/static/src/js/framework/pyeval.js b/addons/web/static/src/js/framework/pyeval.js
index d0708bdf356..0430aee9274 100644
--- a/addons/web/static/src/js/framework/pyeval.js
+++ b/addons/web/static/src/js/framework/pyeval.js
@@ -850,31 +850,61 @@ function eval_contexts (contexts, evaluation_context) {
function eval_domains (domains, evaluation_context) {
evaluation_context = _.extend(pycontext(), evaluation_context || {});
var result_domain = [];
+ // Normalize only if the first domain is the array ["|"] or ["!"]
+ var need_normalization = (
+ domains.length > 0 &&
+ domains[0].length === 1 &&
+ (domains[0][0] === "|" || domains[0][0] === "!")
+ );
_(domains).each(function (domain) {
if (_.isString(domain)) {
// wrap raw strings in domain
domain = { __ref: 'domain', __debug: domain };
}
+ var domain_array_to_combine;
switch(domain.__ref) {
case 'domain':
evaluation_context.context = evaluation_context;
- result_domain.push.apply(
- result_domain, py.eval(domain.__debug, wrap_context(evaluation_context)));
+ domain_array_to_combine = py.eval(domain.__debug, wrap_context(evaluation_context));
break;
case 'compound_domain':
var eval_context = eval_contexts([domain.__eval_context]);
- result_domain.push.apply(
- result_domain, eval_domains(
- domain.__domains, _.extend(
- {}, evaluation_context, eval_context)));
+ domain_array_to_combine = eval_domains(
+ domain.__domains, _.extend({}, evaluation_context, eval_context)
+ );
break;
default:
- result_domain.push.apply(result_domain, domain);
+ domain_array_to_combine = domain;
+ }
+ if (need_normalization) {
+ domain_array_to_combine = get_normalized_domain(domain_array_to_combine);
}
+ result_domain.push.apply(result_domain, domain_array_to_combine);
});
return result_domain;
}
+/**
+ * Returns a normalized copy of the given domain array. Normalization is
+ * is making the implicit "&" at the start of the domain explicit, e.g.
+ * [A, B, C] would become ["&", "&", A, B, C].
+ *
+ * @param {Array} domain_array
+ * @returns {Array} normalized copy of the given array
+ */
+function get_normalized_domain(domain_array) {
+ var expected = 1; // Holds the number of expected domain expressions
+ _.each(domain_array, function (item) {
+ if (item === "&" || item === "|") {
+ expected++;
+ } else if (item !== "!") {
+ expected--;
+ }
+ });
+ var new_explicit_ands = _.times(-expected, _.constant("&"));
+ return new_explicit_ands.concat(domain_array);
+}
+
function eval_groupbys (contexts, evaluation_context) {
evaluation_context = _.extend(pycontext(), evaluation_context || {});
var result_group = [];
diff --git a/addons/web/static/test/evals.js b/addons/web/static/test/evals.js
index 69c7e7b2aa0..62ce6998dba 100644
--- a/addons/web/static/test/evals.js
+++ b/addons/web/static/test/evals.js
@@ -536,7 +536,7 @@ odoo.define_section('eval.edc.nonliterals', ['web.pyeval', 'web.session'], funct
var result = pyeval.sync_eval_domains_and_contexts({
domains: [
[['type', '=', 'contract']],
- { "__domains": [["|"], [["state", "in", ["open", "draft"]]], [["state", "=", "pending"]]],
+ { "__domains": [["|"], [["state", "in", ["open", "draft"]]], [["type", "=", "contract"], ["state", "=", "pending"]]],
"__eval_context": null,
"__ref": "compound_domain"
},
@@ -552,7 +552,8 @@ odoo.define_section('eval.edc.nonliterals', ['web.pyeval', 'web.session'], funct
assert.deepEqual(result.domain, [
["type", "=", "contract"],
"|", ["state", "in", ["open", "draft"]],
- ["state", "=", "pending"],
+ "&", ["type", "=", "contract"],
+ ["state", "=", "pending"],
"|",
"&", ["date", "!=", false],
["date", "<=", today],
diff --git a/addons/web_calendar/static/src/js/web_calendar.js b/addons/web_calendar/static/src/js/web_calendar.js
index 4f83cd02b50..9885b8e7e17 100644
--- a/addons/web_calendar/static/src/js/web_calendar.js
+++ b/addons/web_calendar/static/src/js/web_calendar.js
@@ -334,7 +334,7 @@ var CalendarView = View.extend({
self.proxy('update_record')(event._id, data);
},
eventRender: function (event, element, view) {
- element.find('.fc-event-title').html(event.title);
+ element.find('.fc-event-title').html(event.title + event.attendee_avatars);
},
eventAfterRender: function (event, element, view) {
if ((view.name !== 'month') && (((event.end-event.start)/60000)<=30)) {
@@ -630,7 +630,6 @@ var CalendarView = View.extend({
if (attendee_other.length>2) {
the_title_avatar += '<span class="o_attendee_head" title="' + attendee_other.slice(0, -2) + '">+</span>';
}
- the_title = the_title_avatar + the_title;
}
}
@@ -642,6 +641,7 @@ var CalendarView = View.extend({
'start': moment(date_start).toString(),
'end': moment(date_stop).toString(),
'title': the_title,
+ 'attendee_avatars': the_title_avatar,
'allDay': (this.fields[this.date_start].type == 'date' || (this.all_day && evt[this.all_day]) || false),
'id': evt.id,
'attendees':attendees
diff --git a/openerp/http.py b/openerp/http.py
index a2364175bef..84847f13590 100644
--- a/openerp/http.py
+++ b/openerp/http.py
@@ -1555,9 +1555,16 @@ class Root(object):
httprequest.session.db = db_monodb(httprequest)
def setup_lang(self, httprequest):
- if not "lang" in httprequest.session.context:
- lang = httprequest.accept_languages.best or "en_US"
- lang = babel.core.LOCALE_ALIASES.get(lang, lang).replace('-', '_')
+ if "lang" not in httprequest.session.context:
+ alang = httprequest.accept_languages.best or "en-US"
+ try:
+ code, territory, _, _ = babel.core.parse_locale(alang, sep='-')
+ if territory:
+ lang = '%s_%s' % (code, territory)
+ else:
+ lang = babel.core.LOCALE_ALIASES[code]
+ except (ValueError, KeyError):
+ lang = 'en_US'
httprequest.session.context["lang"] = lang
def get_request(self, httprequest):