From 41cb41be5fac7cd87820f61ff89597e6c2d1ffe3 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 26 Jun 2019 22:28:31 +0200 Subject: [PATCH] initial work on odoo 12 --- README.md | 12 -- docker-compose.yml | 57 ++++--- iotbox/Dockerfile | 78 +++++++++ iotbox/bootstrap.min.js | 6 + {posbox => iotbox}/entrypoint.sh | 12 +- iotbox/odoo.conf | 4 + iotbox/python-v4l2-1664158-fix.patch | 22 +++ odoo/Dockerfile | 6 +- posbox/Dockerfile | 66 -------- posbox/hw_printer_network_controller.py | 209 ------------------------ posbox/hw_screen_main.py | 195 ---------------------- posbox/openerp-server.conf | 3 - 12 files changed, 151 insertions(+), 519 deletions(-) create mode 100644 iotbox/Dockerfile create mode 100644 iotbox/bootstrap.min.js rename {posbox => iotbox}/entrypoint.sh (77%) create mode 100644 iotbox/odoo.conf create mode 100644 iotbox/python-v4l2-1664158-fix.patch delete mode 100644 posbox/Dockerfile delete mode 100644 posbox/hw_printer_network_controller.py delete mode 100644 posbox/hw_screen_main.py delete mode 100644 posbox/openerp-server.conf diff --git a/README.md b/README.md index a7e78ec..ef5c6f8 100644 --- a/README.md +++ b/README.md @@ -5,18 +5,6 @@ Odoo PosBox in Docker. It additionally contains [pos-addons](https://github.com/it-projects-llc/pos-addons) for using receipt printers over the network. -## Running on Raspberry Pi - -The official Docker images of Odoo are not multi-arch -compatible, the image needs to be rebuilt on arm. - -1. Change the `FROM` in the [Dockerfile](https://github.com/odoo/docker/blob/master/11.0/Dockerfile) to -`FROM armhf/debian:stretch` and build it as `local/odoo:11`. -1. Change the `FROM` in [odoo/Dockerfile](odoo/Dockerfile) to - `local/odoo:11`. - -Corresponding issue on GitHub: [Support for ARM64v8 #195](https://github.com/odoo/docker/issues/195). - ## Backup configuration Example contents of `backup.env`: diff --git a/docker-compose.yml b/docker-compose.yml index 0d281a6..fb8c958 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,12 +8,16 @@ services: - 80:8069 volumes: - odoo-web-data:/var/lib/odoo + environment: + - HOST=db + - USER=odoo + - PASSWORD=odoo networks: localnet: ipv4_address: 10.5.0.2 - posbox: - build: ./posbox - command: -- --load=web,hw_proxy,hw_posbox_homepage,hw_escpos,hw_screen,hw_printer_network + iotbox: + build: ./iotbox + command: -- --load=web,hw_proxy,hw_posbox_homepage,hw_posbox_upgrade,hw_scale,hw_scanner,hw_escpos,hw_blackbox_be,hw_screen,hw_drivers,hw_printer_network ports: - 8070:8069 - 8072:8072 @@ -23,8 +27,9 @@ services: localnet: ipv4_address: 10.5.0.3 db: - image: postgres:9.6 + image: postgres:10 environment: + - POSTGRES_DB=postgres - POSTGRES_PASSWORD=odoo - POSTGRES_USER=odoo - PGDATA=/var/lib/postgresql/data/pgdata @@ -33,28 +38,28 @@ services: networks: localnet: ipv4_address: 10.5.0.4 - backup: - build: ./backup - environment: - - PGHOST=db - - PGUSER=odoo - - PGPASSWORD=odoo - - BACKUP_SCHEDULE=0 19 * * * - env_file: backup.env - volumes: - - odoo-db-data:/data/pg_raw:ro - - /home/pi:/data/home-pi:ro - networks: - localnet: - ipv4_address: 10.5.0.5 - monitoring: - build: ./monitoring - command: checkup every 10m - volumes: - - ./checkup.json:/opt/checkup/checkup.json:ro - networks: - localnet: - ipv4_address: 10.5.0.6 +# backup: +# build: ./backup +# environment: +# - PGHOST=db +# - PGUSER=odoo +# - PGPASSWORD=odoo +# - BACKUP_SCHEDULE=0 19 * * * +# env_file: backup.env +# volumes: +# - odoo-db-data:/data/pg_raw:ro +# - /home/pi:/data/home-pi:ro +# networks: +# localnet: +# ipv4_address: 10.5.0.5 +# monitoring: +# build: ./monitoring +# command: checkup every 10m +# volumes: +# - ./checkup.json:/opt/checkup/checkup.json:ro +# networks: +# localnet: +# ipv4_address: 10.5.0.6 volumes: odoo-web-data: odoo-db-data: diff --git a/iotbox/Dockerfile b/iotbox/Dockerfile new file mode 100644 index 0000000..cb65350 --- /dev/null +++ b/iotbox/Dockerfile @@ -0,0 +1,78 @@ +FROM odoo:12 + +USER root + +## Dependencies for iotbox +## See also https://github.com/odoo/odoo/blob/master/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh +RUN set -x; apt-get update \ + && apt-get -y install --no-install-recommends \ + bluez \ + cups \ + cups-ipp-utils \ + dbus \ + gcc \ + git \ + libcups2-dev \ + python3-babel \ + python3-dateutil \ + python3-dbus \ + python3-decorator \ + python3-dev \ + python3-docutils \ + python3-feedparser \ + python3-gi \ + python3-html2text \ + python3-jinja2 \ + python3-ldap3 \ + python3-libsass \ + python3-lxml \ + python3-mako \ + python3-mock \ + python3-netifaces \ + python3-openid \ + python3-passlib \ + python3-pil \ + python3-pip \ + python3-psutil \ + python3-psycopg2 \ + python3-pydot \ + python3-pyparsing \ + python3-pypdf2 \ + python3-pyscard \ + python3-qrcode \ + python3-reportlab \ + python3-requests \ + python3-serial \ + python3-simplejson \ + python3-simplejson \ + python3-tz \ + python3-unittest2 \ + python3-urllib3 \ + python3-vatnumber \ + python3-werkzeug \ + python3-wheel \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /opt/posbox/addons \ + && chown -R odoo.odoo /opt/posbox \ + && mkdir /usr/lib/python3/dist-packages/odoo/addons/hw_drivers/drivers + +RUN pip3 install \ + pyusb==1.0.0b1 \ + evdev \ + gatt \ + v4l2 \ + polib \ + pycups + +# See https://bugs.launchpad.net/python-v4l2/+bug/1664158 +COPY python-v4l2-1664158-fix.patch /tmp +RUN patch -p0 /usr/local/lib/python3.5/dist-packages/v4l2.py < /tmp/python-v4l2-1664158-fix.patch + +#USER odoo + +## Get pos-addons for pos_printer_network +RUN git clone --depth=1 -b 12.0 https://github.com/it-projects-llc/pos-addons.git \ + /opt/posbox/addons + +COPY odoo.conf /etc/odoo/odoo.conf +COPY entrypoint.sh / diff --git a/iotbox/bootstrap.min.js b/iotbox/bootstrap.min.js new file mode 100644 index 0000000..7c1561a --- /dev/null +++ b/iotbox/bootstrap.min.js @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.2.0 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.2.0",d.prototype.close=function(b){function c(){f.detach().trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",c).emulateTransitionEnd(150):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.2.0",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),d[e](null==f[b]?this.options[b]:f[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b).on("keydown.bs.carousel",a.proxy(this.keydown,this)),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.2.0",c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},c.prototype.keydown=function(a){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.to=function(b){var c=this,d=this.getItemIndex(this.$active=this.$element.find(".item.active"));return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=e[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:g});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,f&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(e)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:g});return a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one("bsTransitionEnd",function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger(m)),f&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(b=!b),e||d.data("bs.collapse",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};c.VERSION="3.2.0",c.DEFAULTS={toggle:!0},c.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},c.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var c=a.Event("show.bs.collapse");if(this.$element.trigger(c),!c.isDefaultPrevented()){var d=this.$parent&&this.$parent.find("> .panel > .in");if(d&&d.length){var e=d.data("bs.collapse");if(e&&e.transitioning)return;b.call(d,"hide"),e||d.data("bs.collapse",null)}var f=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[f](0),this.transitioning=1;var g=function(){this.$element.removeClass("collapsing").addClass("collapse in")[f](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return g.call(this);var h=a.camelCase(["scroll",f].join("-"));this.$element.one("bsTransitionEnd",a.proxy(g,this)).emulateTransitionEnd(350)[f](this.$element[0][h])}}},c.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},c.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var d=a.fn.collapse;a.fn.collapse=b,a.fn.collapse.Constructor=c,a.fn.collapse.noConflict=function(){return a.fn.collapse=d,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(c){var d,e=a(this),f=e.attr("data-target")||c.preventDefault()||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),g=a(f),h=g.data("bs.collapse"),i=h?"toggle":e.data(),j=e.attr("data-parent"),k=j&&a(j);h&&h.transitioning||(k&&k.find('[data-toggle="collapse"][data-parent="'+j+'"]').not(e).addClass("collapsed"),e[g.hasClass("in")?"addClass":"removeClass"]("collapsed")),b.call(g,i)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.2.0",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('