def connect_box(self, token): """ This route is called when we want that a IoT Box will be connected to a COffice DB token is a base 64 encoded string and have 2 argument separate by | 1 - url of coffice DB 2 - token. This token will be compared to the token of COffice. He have 1 hour lifetime """ server = helpers.get_coffice_server_url() image = get_resource_path('hw_drivers', 'static/img', 'False.jpg') if server == '': credential = b64decode(token).decode('utf-8').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) try: subprocess.check_call([get_resource_path('point_of_sale', 'tools/posbox/configuration/connect_to_server.sh'), url, '', token, 'noreboot']) helpers.check_certificate() m.send_alldevices() m.load_drivers() image = get_resource_path('hw_drivers', 'static/img', 'True.jpg') except subprocess.CalledProcessError as e: _logger.error('A error encountered : %s ' % e.output) if os.path.isfile(image): with open(image, 'rb') as f: return f.read()
def _get_default_favicon(self, original=False): img_path = get_resource_path('web', 'static/src/img/favicon.ico') with tools.file_open(img_path, 'rb') as f: if original: return base64.b64encode(f.read()) # Modify the source image to add a colored bar on the bottom # This could seem overkill to modify the pixels 1 by 1, but # Pillow doesn't provide an easy way to do it, and this # is acceptable for a 16x16 image. color = (randrange(32, 224, 24), randrange(32, 224, 24), randrange(32, 224, 24)) original = Image.open(f) new_image = Image.new('RGBA', original.size) height = original.size[1] width = original.size[0] bar_size = 1 for y in range(height): for x in range(width): pixel = original.getpixel((x, y)) if height - bar_size <= y + 1 <= height: new_image.putpixel((x, y), (color[0], color[1], color[2], 255)) else: new_image.putpixel( (x, y), (pixel[0], pixel[1], pixel[2], pixel[3])) stream = io.BytesIO() new_image.save(stream, format="ICO") return base64.b64encode(stream.getvalue())
def test_01_debug_mode_assets(self): """ Checks that the ir.attachments records created for compiled assets in debug mode are correctly invalidated. """ # Compile for the first time self._bundle(self._get_asset(), True, False) # Compile a second time, without changes self._bundle(self._get_asset(), False, False) # Touch the file and compile a third time path = get_resource_path('test_assetsbundle', 'static', 'src', 'scss', 'test_file1.scss') t = time.time() + 5 asset = self._get_asset() with self._touch(path, t): self._bundle(asset, True, True) # Because we are in the same transaction since the beginning of the test, the first asset # created and the second one have the same write_date, but the file's last modified date # has really been modified. If we do not update the write_date to a posterior date, we are # not able to reproduce the case where we compile this bundle again without changing # anything. self.env['ir.attachment'].flush(['checksum']) self.cr.execute( "update ir_attachment set write_date=clock_timestamp() + interval '10 seconds' where id = (select max(id) from ir_attachment)" ) # Compile a fourth time, without changes self._bundle(self._get_asset(), False, False)
def download_drivers(auto=True): """ Get the drivers from the configured COffice server """ server = get_coffice_server_url() if server: urllib3.disable_warnings() pm = urllib3.PoolManager(cert_reqs='CERT_NONE') server = server + '/iot/get_drivers' try: resp = pm.request('POST', server, fields={ 'mac': get_mac_address(), 'auto': auto }) if resp.data: subprocess.check_call( ["sudo", "mount", "-o", "remount,rw", "/"]) zip_file = zipfile.ZipFile(io.BytesIO(resp.data)) zip_file.extractall(get_resource_path('hw_drivers', 'drivers')) subprocess.check_call( ["sudo", "mount", "-o", "remount,ro", "/"]) subprocess.check_call([ "sudo", "mount", "-o", "remount,rw", "/root_bypass_ramdisks/etc/cups" ]) except Exception as e: _logger.error('Could not reach configured server') _logger.error('A error encountered : %s ' % e)
def stat(self): if not (self.inline or self._filename or self._ir_attach): path = (segment for segment in self.url.split('/') if segment) self._filename = get_resource_path(*path) if self._filename: return try: # Test url against ir.attachments attach = self.bundle.env['ir.attachment'].sudo( ).get_serve_attachment(self.url) self._ir_attach = attach[0] except Exception: raise AssetNotFound("Could not find %s" % self.name)
def test_17_css_bundle_date_invalidation(self): """ Checks that both css bundles are invalidated when one of its assets' modification date is changed """ # Assets access for en_US language ltr_bundle0 = self._get_asset(self.cssbundle_xmlid) ltr_bundle0.css() ltr_last_modified0 = ltr_bundle0.last_modified ltr_version0 = ltr_bundle0.version # Assets access for ar_SY language rtl_bundle0 = self._get_asset(self.cssbundle_xmlid, env=self.env(context={'lang': 'ar_SY'})) rtl_bundle0.css() rtl_last_modified0 = rtl_bundle0.last_modified rtl_version0 = rtl_bundle0.version # Touch test_cssfile1.css # Note: No lang specific context given while calling _get_asset so it will load assets for en_US path = get_resource_path('test_assetsbundle', 'static', 'src', 'css', 'test_cssfile1.css') ltr_bundle1 = self._get_asset(self.cssbundle_xmlid) with self._touch(path): ltr_bundle1.css() ltr_last_modified1 = ltr_bundle1.last_modified ltr_version1 = ltr_bundle1.version ltr_ira1 = self._any_ira_for_bundle('css') self.assertNotEquals(ltr_last_modified0, ltr_last_modified1) self.assertNotEquals(ltr_version0, ltr_version1) rtl_bundle1 = self._get_asset( self.cssbundle_xmlid, env=self.env(context={'lang': 'ar_SY'})) rtl_bundle1.css() rtl_last_modified1 = rtl_bundle1.last_modified rtl_version1 = rtl_bundle1.version rtl_ira1 = self._any_ira_for_bundle('css', lang='ar_SY') self.assertNotEquals(rtl_last_modified0, rtl_last_modified1) self.assertNotEquals(rtl_version0, rtl_version1) # Checks rtl and ltr bundles are different self.assertNotEquals(ltr_ira1.id, rtl_ira1.id) # check if the previous attachment is correctly cleaned css_bundles = self.env['ir.attachment'].search([ ('url', '=like', '/web/content/%-%/{0}%.{1}'.format(self.cssbundle_xmlid, 'css')) ]) self.assertEquals(len(css_bundles), 2)
def get_command(self): try: if os.name == 'nt': lessc = misc.find_in_path('lessc.cmd') else: lessc = misc.find_in_path('lessc') except IOError: lessc = 'lessc' lesspath = get_resource_path('web', 'static', 'lib', 'bootstrap', 'less') return [ lessc, '-', '--no-js', '--no-color', '--include-path=%s' % lesspath ]
def load_drivers(self): """ This method loads local files: 'coffice/addons/hw_drivers/drivers' And execute these python drivers """ helpers.download_drivers() path = get_resource_path('hw_drivers', 'drivers') driversList = os.listdir(path) self.devices = {} for driver in driversList: path_file = os.path.join(path, driver) spec = util.spec_from_file_location(driver, path_file) if spec: module = util.module_from_spec(spec) spec.loader.exec_module(module)
def _compute_rating_image(self): # Due to some new widgets, we may have ratings different from 0/1/5/10 (e.g. slide.channel review) # Let us have some custom rounding while finding a better solution for images. for rating in self: rating_for_img = 0 if rating.rating >= 8: rating_for_img = 10 elif rating.rating > 3: rating_for_img = 5 elif rating.rating >= 1: rating_for_img = 1 try: image_path = get_resource_path('rating', 'static/src/img', 'rating_%s.png' % rating_for_img) rating.rating_image = base64.b64encode(open(image_path, 'rb').read()) except (IOError, OSError): rating.rating_image = False
def test_product_margin(self): ''' In order to test the product_margin module ''' # load account_minimal_test.xml file for chart of account in configuration tools.convert_file( self.cr, 'product_margin', get_resource_path('account', 'test', 'account_minimal_test.xml'), {}, 'init', False, 'test', self.registry._assertion_report) supplier = self.env['res.partner'].create({'name': 'Supplier'}) customer = self.env['res.partner'].create({'name': 'Customer'}) ipad = self.env.ref("product.product_product_4") # Create supplier invoice and customer invoice to test product margin. # Define supplier invoices self.create_account_invoice('in_invoice', supplier, ipad, 10.0, 300.00) self.create_account_invoice('in_invoice', supplier, ipad, 4.0, 450.00) # Define Customer Invoices self.create_account_invoice('out_invoice', customer, ipad, 20.0, 750.00) self.create_account_invoice('out_invoice', customer, ipad, 10.0, 550.00) result = ipad._compute_product_margin_fields_values() # Sale turnover ( Quantity * Price Subtotal / Quantity) sale_turnover = ((20.0 * 750.00) + (10.0 * 550.00)) # Expected sale (Total quantity * Sale price) sale_expected = (750.00 * 30.0) # Purchase total cost (Quantity * Unit price) purchase_total_cost = ((10.0 * 300.00) + (4.0 * 450.00)) # Purchase normal cost ( Total quantity * Cost price) purchase_normal_cost = (14.0 * 500.00) total_margin = sale_turnover - purchase_total_cost expected_margin = sale_expected - purchase_normal_cost # Check total margin self.assertEqual(result[ipad.id]['total_margin'], total_margin, "Wrong Total Margin.") # Check expected margin self.assertEqual(result[ipad.id]['expected_margin'], expected_margin, "Wrong Expected Margin.")
def get_asset_content(self, url, url_info=None, custom_attachments=None): """ Fetch the content of an asset (scss / js) file. That content is either the one of the related file on the disk or the one of the corresponding custom ir.attachment record. Params: url (str): the URL of the asset (scss / js) file/ir.attachment url_info (dict, optional): the related url info (see get_asset_info) (allows to optimize some code which already have the info and do not want this function to re-get it) custom_attachments (ir.attachment(), optional): the related custom ir.attachment records the function might need to search into (allows to optimize some code which already have that info and do not want this function to re-get it) Returns: utf-8 encoded content of the asset (scss / js) """ if url_info is None: url_info = self.get_asset_info(url) if url_info["customized"]: # If the file is already customized, the content is found in the # corresponding attachment attachment = None if custom_attachments is None: attachment = self._get_custom_attachment(url) else: attachment = custom_attachments.filtered(lambda r: r.url == url) return attachment and base64.b64decode(attachment.datas) or False # If the file is not yet customized, the content is found by reading # the local scss file module = url_info["module"] module_path = get_module_path(module) module_resource_path = get_resource_path(module, url_info["resource_path"]) if module_path and module_resource_path: module_path = os.path.join(os.path.normpath(module_path), '') # join ensures the path ends with '/' module_resource_path = os.path.normpath(module_resource_path) if module_resource_path.startswith(module_path): with open(module_resource_path, "rb") as f: return f.read()
def test_03_date_invalidation(self): """ Checks that a bundle is invalidated when one of its assets' modification date is changed. """ bundle0 = self._get_asset(self.jsbundle_xmlid) bundle0.js() last_modified0 = bundle0.last_modified version0 = bundle0.version path = get_resource_path('test_assetsbundle', 'static', 'src', 'js', 'test_jsfile1.js') bundle1 = self._get_asset(self.jsbundle_xmlid) with self._touch(path): bundle1.js() last_modified1 = bundle1.last_modified version1 = bundle1.version self.assertNotEquals(last_modified0, last_modified1) self.assertNotEquals(version0, version1) # check if the previous attachment is correctly cleaned self.assertEquals(len(self._any_ira_for_bundle('js')), 1)
def _binary_ir_attachment_redirect_content( cls, record, default_mimetype='application/octet-stream'): # mainly used for theme images attachemnts status = content = filename = filehash = None mimetype = getattr(record, 'mimetype', False) if record.type == 'url' and record.url: # if url in in the form /somehint server locally url_match = re.match("^/(\w+)/(.+)$", record.url) if url_match: module = url_match.group(1) module_path = get_module_path(module) module_resource_path = get_resource_path( module, url_match.group(2)) if module_path and module_resource_path: module_path = os.path.join( os.path.normpath(module_path), '') # join ensures the path ends with '/' module_resource_path = os.path.normpath( module_resource_path) if module_resource_path.startswith(module_path): with open(module_resource_path, 'rb') as f: content = base64.b64encode(f.read()) status = 200 filename = os.path.basename(module_resource_path) mimetype = guess_mimetype(base64.b64decode(content), default=default_mimetype) filehash = '"%s"' % hashlib.md5( pycompat.to_text(content).encode( 'utf-8')).hexdigest() if not content: status = 301 content = record.url return status, content, filename, mimetype, filehash
# -*- coding: utf-8 -*- import importlib.util import os import sys from coffice.tools import config from coffice.modules.module import get_resource_path for path in config.get("upgrades_paths", "").split(","): if os.path.exists(os.path.join(path, "__init__.py")): break else: # failback to legacy "maintenance/migrations" package path = get_resource_path("base", "maintenance", "migrations") if not path: raise ImportError("No package found in `upgrades_paths`") spec = importlib.util.spec_from_file_location( "coffice.upgrades", os.path.join(path, "__init__.py")) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # shadow module and register under legacy name sys.modules["coffice.upgrades"] = sys.modules[ "coffice.addons.base.maintenance.migrations"] = module
def _get_asset_content(self, xmlid, options): options = dict(options, inherit_branding=False, inherit_branding_auto=False, edit_translations=False, translatable=False, rendering_bundle=True) options['website_id'] = self.env.context.get('website_id') IrQweb = self.env['ir.qweb'].with_context(options) def can_aggregate(url): return not urls.url_parse(url).scheme and not urls.url_parse( url).netloc and not url.startswith('/web/content') # TODO: This helper can be used by any template that wants to embedd the backend. # It is currently necessary because the ir.ui.view bundle inheritance does not # match the module dependency graph. def get_modules_order(): if request: from coffice.addons.web.controllers.main import module_boot return json.dumps(module_boot()) return '[]' template = IrQweb.render(xmlid, {"get_modules_order": get_modules_order}) files = [] remains = [] for el in html.fragments_fromstring(template): if isinstance(el, html.HtmlElement): href = el.get('href', '') src = el.get('src', '') atype = el.get('type') media = el.get('media') if can_aggregate(href) and ( el.tag == 'style' or (el.tag == 'link' and el.get('rel') == 'stylesheet')): if href.endswith('.sass'): atype = 'text/sass' elif href.endswith('.scss'): atype = 'text/scss' elif href.endswith('.less'): atype = 'text/less' if atype not in ('text/less', 'text/scss', 'text/sass'): atype = 'text/css' path = [segment for segment in href.split('/') if segment] filename = get_resource_path(*path) if path else None files.append({ 'atype': atype, 'url': href, 'filename': filename, 'content': el.text, 'media': media }) elif can_aggregate(src) and el.tag == 'script': atype = 'text/javascript' path = [segment for segment in src.split('/') if segment] filename = get_resource_path(*path) if path else None files.append({ 'atype': atype, 'url': src, 'filename': filename, 'content': el.text, 'media': media }) else: remains.append((el.tag, OrderedDict(el.attrib), el.text)) else: # the other cases are ignored pass return (files, remains)
def bootstrap_path(self): return get_resource_path('web', 'static', 'lib', 'bootstrap', 'scss')