def clear_drivers_list(self): for driver in os.listdir(get_resource_path('hw_drivers', 'drivers')): if driver != '__pycache__': helpers.unlink_file( get_resource_path('hw_drivers', 'drivers', driver)) return "<meta http-equiv='refresh' content='0; url=http://" + helpers.get_ip( ) + ":8069/list_drivers'>"
def connect_box(self, token): """ This route is called when we want that a IoT Box will be connected to a Swerp DB token is a base 64 encoded string and have 2 argument separate by | 1 - url of swerp DB 2 - token. This token will be compared to the token of Swerp. He have 1 hour lifetime """ server = helpers.get_swerp_server_url() image = get_resource_path('hw_drivers', 'static/img', 'False.jpg') if not 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' ]) m.send_alldevices() image = get_resource_path('hw_drivers', 'static/img', 'True.jpg') helpers.swerp_restart(3) 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 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_swerp_server_url() res_payload = { 'message': 'Connecting to ' + essid, } if server: res_payload['server'] = { 'url': server, 'message': 'Redirect to Swerp Server' } else: res_payload['server'] = { 'url': 'http://' + helpers.get_ip() + ':8069', 'message': 'Redirect to IoT Box' } return json.dumps(res_payload)
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 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', 'supplier': True }) customer = self.env['res.partner'].create({ 'name': 'Customer', 'customer': True }) 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 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 _get_files(self): def get_scripts(path): if not path: return {} return { version: glob.glob1(opj(path, version), '*.py') for version in os.listdir(path) if os.path.isdir(opj(path, version)) } for pkg in self.graph: if not (hasattr(pkg, 'update') or pkg.state == 'to upgrade' or getattr(pkg, 'load_state', None) == 'to upgrade'): continue self.migrations[pkg.name] = { 'module': get_scripts(get_resource_path(pkg.name, 'migrations')), 'maintenance': get_scripts( get_resource_path('base', 'maintenance', 'migrations', pkg.name)), }
def list_drivers(self): drivers_list = [] for driver in os.listdir(get_resource_path('hw_drivers', 'drivers')): if driver != '__pycache__': drivers_list.append(driver) return driver_list_template.render({ 'title': "Swerp's IoT Box - Drivers list", 'breadcrumb': 'Drivers list', 'drivers_list': drivers_list, 'server': helpers.get_swerp_server_url() })
def _connect_to_server(self, url, token, db_uuid, enterprise_code): if db_uuid and enterprise_code: helpers.add_credential(db_uuid, enterprise_code) # Save DB URL and token subprocess.check_call([ get_resource_path( 'point_of_sale', 'tools/posbox/configuration/connect_to_server.sh'), url, '', token, 'noreboot' ]) # Notify the DB, so that the kanban view already shows the IoT Box m.send_alldevices() # Restart to checkout the git branch, get a certificate, load the IoT handlers... subprocess.check_call(["sudo", "service", "swerp", "restart"])
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 load_drivers(self): """ This method loads local files: 'swerp/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) http.addons_manifest = {} http.root = http.Root()
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
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_swerp_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'
def binary_content(cls, xmlid=None, model='ir.attachment', id=None, field='datas', unique=False, filename=None, filename_field='datas_fname', download=False, mimetype=None, default_mimetype='application/octet-stream', access_token=None, related_id=None, access_mode=None, env=None): """ Get file, attachment or downloadable content If the ``xmlid`` and ``id`` parameter is omitted, fetches the default value for the binary field (via ``default_get``), otherwise fetches the field for that precise record. :param str xmlid: xmlid of the record :param str model: name of the model to fetch the binary from :param int id: id of the record from which to fetch the binary :param str field: binary field :param bool unique: add a max-age for the cache control :param str filename: choose a filename :param str filename_field: if not create an filename with model-id-field :param bool download: apply headers to download the file :param str mimetype: mintype of the field (for headers) :param related_id: the id of another record used for custom_check :param access_mode: if truthy, will call custom_check to fetch the object that contains the binary. :param str default_mimetype: default mintype if no mintype found :param str access_token: optional token for unauthenticated access only available for ir.attachment :param Environment env: by default use request.env :returns: (status, headers, content) """ env = env or request.env # get object and content obj = None if xmlid: obj = cls._xmlid_to_obj(env, xmlid) elif id and model in env.registry: obj = env[model].browse(int(id)) # obj exists if not obj or not obj.exists() or field not in obj: return (404, [], None) # access token grant access if model == 'ir.attachment' and access_token: obj = obj.sudo() if access_mode: if not cls._check_access_mode(env, id, access_mode, model, access_token=access_token, related_id=related_id): return (403, [], None) elif not consteq(obj.access_token or u'', access_token): return (403, [], None) # check read access try: last_update = obj['__last_update'] except AccessError: return (403, [], None) status, headers, content = None, [], None # attachment by url check module_resource_path = None if model == 'ir.attachment' and obj.type == 'url' and obj.url: url_match = re.match("^/(\w+)/(.+)$", obj.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()) last_update = pycompat.text_type(os.path.getmtime(module_resource_path)) if not module_resource_path: module_resource_path = obj.url if not content: status = 301 content = module_resource_path else: content = obj[field] or '' # filename default_filename = False if not filename: if filename_field in obj: filename = obj[filename_field] if not filename and module_resource_path: filename = os.path.basename(module_resource_path) if not filename: default_filename = True filename = "%s-%s-%s" % (obj._name, obj.id, field) # mimetype mimetype = 'mimetype' in obj and obj.mimetype or False if not mimetype: if filename: mimetype = mimetypes.guess_type(filename)[0] if not mimetype and getattr(env[model]._fields[field], 'attachment', False): # for binary fields, fetch the ir_attachement for mimetype check attach_mimetype = env['ir.attachment'].search_read(domain=[('res_model', '=', model), ('res_id', '=', id), ('res_field', '=', field)], fields=['mimetype'], limit=1) mimetype = attach_mimetype and attach_mimetype[0]['mimetype'] if not mimetype: try: decoded_content = base64.b64decode(content) except base64.binascii.Error: # if we could not decode it, no need to pass it down: it would crash elsewhere... return (404, [], None) mimetype = guess_mimetype(decoded_content, default=default_mimetype) # extension _, existing_extension = os.path.splitext(filename) if not existing_extension or default_filename: extension = mimetypes.guess_extension(mimetype) if extension: filename = "%s%s" % (filename, extension) headers += [('Content-Type', mimetype), ('X-Content-Type-Options', 'nosniff')] # cache etag = bool(request) and request.httprequest.headers.get('If-None-Match') retag = '"%s"' % hashlib.md5(pycompat.to_text(content).encode('utf-8')).hexdigest() status = status or (304 if etag == retag else 200) headers.append(('ETag', retag)) headers.append(('Cache-Control', 'max-age=%s' % (STATIC_CACHE if unique else 0))) # content-disposition default name if download: headers.append(('Content-Disposition', cls.content_disposition(filename))) return (status, headers, content)
def load_script(path, module_name): full_path = get_resource_path(*path.split(os.path.sep)) spec = importlib.util.spec_from_file_location(module_name, full_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module
def bootstrap_path(self): return get_resource_path('web', 'static', 'lib', 'bootstrap', 'scss')
def get_assets_editor_resources(self, key, get_views=True, get_scss=True, bundles=False, bundles_restriction=[]): # Related views must be fetched if the user wants the views and/or the style views = request.env["ir.ui.view"].get_related_views(key, bundles=bundles) views = views.read(self._get_view_fields_to_read()) scss_files_data_by_bundle = [] # Load scss only if asked by the user if get_scss: # Compile regex outside of the loop # This will used to exclude library scss files from the result excluded_url_matcher = re.compile("^(.+/lib/.+)|(.+import_bootstrap.+\.scss)$") # Load already customized scss files attachments custom_url = self._make_custom_scss_file_url("%%.%%", "%%") custom_attachments = self.get_custom_attachment(custom_url, op='=like') # First check the t-call-assets used in the related views url_infos = dict() for v in views: for asset_call_node in etree.fromstring(v["arch"]).xpath("//t[@t-call-assets]"): if asset_call_node.get("t-css") == "false": continue asset_name = asset_call_node.get("t-call-assets") # Loop through bundle files to search for scss file info scss_files_data = [] for file_info in request.env["ir.qweb"]._get_asset_content(asset_name, {})[0]: if file_info["atype"] != "text/scss": continue url = file_info["url"] # Exclude library files (see regex above) if excluded_url_matcher.match(url): continue # Check if the file is customized and get bundle/path info scss_file_data = self._match_scss_file_url(url) if not scss_file_data: continue # Save info (arch will be fetched later) url_infos[url] = scss_file_data scss_files_data.append(url) # scss data is returned sorted by bundle, with the bundles names and xmlids if len(scss_files_data): scss_files_data_by_bundle.append([dict(xmlid=asset_name, name=request.env.ref(asset_name).name), scss_files_data]) # Filter bundles/files: # - A file which appears in multiple bundles only appears in the first one (the first in the DOM) # - Only keep bundles with files which appears in the asked bundles and only keep those files for i in range(0, len(scss_files_data_by_bundle)): bundle_1 = scss_files_data_by_bundle[i] for j in range(0, len(scss_files_data_by_bundle)): bundle_2 = scss_files_data_by_bundle[j] # In unwanted bundles, keep only the files which are in wanted bundles too (_assets_helpers) if bundle_1[0]["xmlid"] not in bundles_restriction and bundle_2[0]["xmlid"] in bundles_restriction: bundle_1[1] = [item_1 for item_1 in bundle_1[1] if item_1 in bundle_2[1]] for i in range(0, len(scss_files_data_by_bundle)): bundle_1 = scss_files_data_by_bundle[i] for j in range(i+1, len(scss_files_data_by_bundle)): bundle_2 = scss_files_data_by_bundle[j] # In every bundle, keep only the files which were not found in previous bundles bundle_2[1] = [item_2 for item_2 in bundle_2[1] if item_2 not in bundle_1[1]] # Only keep bundles which still have files and that were requested scss_files_data_by_bundle = [ data for data in scss_files_data_by_bundle if (len(data[1]) > 0 and (not bundles_restriction or data[0]["xmlid"] in bundles_restriction)) ] # Fetch the arch of each kept file, in each bundle for bundle_data in scss_files_data_by_bundle: for i in range(0, len(bundle_data[1])): url = bundle_data[1][i] url_info = url_infos[url] content = None if url_info["customized"]: # If the file is already customized, the content is found in the corresponding attachment content = base64.b64decode(custom_attachments.filtered(lambda a: a.url == url).datas) else: # 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: content = f.read() bundle_data[1][i] = dict( url = "/%s/%s" % (url_info["module"], url_info["resource_path"]), arch = content, customized = url_info["customized"], ) return dict( views = get_views and views or [], scss = get_scss and scss_files_data_by_bundle or [], )
def _load(self, module, *args): tools.convert_file(self.cr, 'account_voucher', get_resource_path(module, *args), {}, 'init', False, 'test', self.registry._assertion_report)
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 swerp.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)