Skip to content
Snippets Groups Projects
Commit ba2ffdb0841f authored by Vincent Hatakeyama's avatar Vincent Hatakeyama
Browse files

:sparkles: Update with odoo 16 module template files :shirt: black/isort/pylint

parent 348da1ea1b62
No related branches found
No related tags found
1 merge request!35Migrate to Odoo 16.0
env:
browser: true
es6: true
# See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449
parserOptions:
ecmaVersion: 2019
overrides:
- files:
- "**/*.esm.js"
parserOptions:
sourceType: module
# Globals available in Odoo that shouldn't produce errorings
globals:
_: readonly
$: readonly
fuzzy: readonly
jQuery: readonly
moment: readonly
odoo: readonly
openerp: readonly
owl: readonly
# Styling is handled by Prettier, so we only need to enable AST rules;
# see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890
rules:
accessor-pairs: warn
array-callback-return: warn
callback-return: warn
capitalized-comments:
- warn
- always
- ignoreConsecutiveComments: true
ignoreInlineComments: true
complexity:
- warn
- 15
constructor-super: warn
dot-notation: warn
eqeqeq: warn
global-require: warn
handle-callback-err: warn
id-blacklist: warn
id-match: warn
init-declarations: error
max-depth: warn
max-nested-callbacks: warn
max-statements-per-line: warn
no-alert: warn
no-array-constructor: warn
no-caller: warn
no-case-declarations: warn
no-class-assign: warn
no-cond-assign: error
no-const-assign: error
no-constant-condition: warn
no-control-regex: warn
no-debugger: error
no-delete-var: warn
no-div-regex: warn
no-dupe-args: error
no-dupe-class-members: error
no-dupe-keys: error
no-duplicate-case: error
no-duplicate-imports: error
no-else-return: warn
no-empty-character-class: warn
no-empty-function: error
no-empty-pattern: error
no-empty: warn
no-eq-null: error
no-eval: error
no-ex-assign: error
no-extend-native: warn
no-extra-bind: warn
no-extra-boolean-cast: warn
no-extra-label: warn
no-fallthrough: warn
no-func-assign: error
no-global-assign: error
no-implicit-coercion:
- warn
- allow: ["~"]
no-implicit-globals: warn
no-implied-eval: warn
no-inline-comments: warn
no-inner-declarations: warn
no-invalid-regexp: warn
no-irregular-whitespace: warn
no-iterator: warn
no-label-var: warn
no-labels: warn
no-lone-blocks: warn
no-lonely-if: error
no-mixed-requires: error
no-multi-str: warn
no-native-reassign: error
no-negated-condition: warn
no-negated-in-lhs: error
no-new-func: warn
no-new-object: warn
no-new-require: warn
no-new-symbol: warn
no-new-wrappers: warn
no-new: warn
no-obj-calls: warn
no-octal-escape: warn
no-octal: warn
no-param-reassign: warn
no-path-concat: warn
no-process-env: warn
no-process-exit: warn
no-proto: warn
no-prototype-builtins: warn
no-redeclare: warn
no-regex-spaces: warn
no-restricted-globals: warn
no-restricted-imports: warn
no-restricted-modules: warn
no-restricted-syntax: warn
no-return-assign: error
no-script-url: warn
no-self-assign: warn
no-self-compare: warn
no-sequences: warn
no-shadow-restricted-names: warn
no-shadow: warn
no-sparse-arrays: warn
no-sync: warn
no-this-before-super: warn
no-throw-literal: warn
no-undef-init: warn
no-undef: error
no-unmodified-loop-condition: warn
no-unneeded-ternary: error
no-unreachable: error
no-unsafe-finally: error
no-unused-expressions: error
no-unused-labels: error
no-unused-vars: error
no-use-before-define: error
no-useless-call: warn
no-useless-computed-key: warn
no-useless-concat: warn
no-useless-constructor: warn
no-useless-escape: warn
no-useless-rename: warn
no-void: warn
no-with: warn
operator-assignment: [error, always]
prefer-const: warn
radix: warn
require-yield: warn
sort-imports: warn
spaced-comment: [error, always]
strict: [error, function]
use-isnan: error
valid-jsdoc:
- warn
- prefer:
arg: param
argument: param
augments: extends
constructor: class
exception: throws
func: function
method: function
prop: property
return: returns
virtual: abstract
yield: yields
preferType:
array: Array
bool: Boolean
boolean: Boolean
number: Number
object: Object
str: String
string: String
requireParamDescription: false
requireReturn: false
requireReturnDescription: false
requireReturnType: false
valid-typeof: warn
yoda: warn
[flake8]
# Some leniancy for docstrings black puts in single lines (add 3 ", 79+3=82).
max-line-length = 82
max-line-length = 88
per-file-ignores=
__init__.py:F401
__manifest__.py:B018
[converter]
pulluri = https://orus.io/xcg/odoo-modules/converter
layout = ../converter
track = 16.0
expand =
......@@ -23,5 +23,5 @@
|coverage| |pylint| |maturity| |license| |black| |prettier|
Produce reports & emails with Redner_.
Produce reports & emails with Rednerd_.
......@@ -27,7 +27,7 @@
Redner_ is an innovative solution to produce transactional emails
Rednerd_ is an innovative solution to produce transactional emails
and documents in PDF or HTML format.
It's designed to help applications or websites that need to send transactional
email like password resets, order confirmations, and welcome messages.
......@@ -29,9 +29,9 @@
and documents in PDF or HTML format.
It's designed to help applications or websites that need to send transactional
email like password resets, order confirmations, and welcome messages.
Redner_ offers advanced tracking, easy-to-understand reports & email
Rednerd_ offers advanced tracking, easy-to-understand reports & email
templates.
This Module allow you to use email template designed with mailjet app
(languages uses in template must be mjml or mustache) which you can add
......@@ -59,4 +59,4 @@
"Send to redner server".
.. _mjml-app: http://mjmlio.github.io/mjml-app/
.. _Redner: https://orus.io/orus-io/rednerd
.. _Rednerd: https://orus.io/orus-io/rednerd
from . import controllers, models, tests
from . import controllers, models
##############################################################################
#
# Redner Odoo module
# Copyright (C) 2016 XCG Consulting <https://xcg-consulting.fr>
# Copyright (C) 2016, 2023 XCG Consulting <https://xcg-consulting.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
......@@ -35,8 +35,6 @@
"views/menu.xml",
],
"assets": {
"web.assets_backend": [
"redner/static/src/js/redner_report_action.esm.js"
],
"web.assets_backend": ["redner/static/src/js/redner_report_action.esm.js"],
},
"installable": True,
......@@ -41,5 +39,4 @@
},
"installable": True,
# These dependencies are in the "requirements" file.
"external_dependencies": {"python": ["requests_unixsocket"]},
}
......@@ -27,9 +27,7 @@
from odoo.http import content_disposition, request, route, serialize_exception
from odoo.tools import html_escape
from odoo.addons.web.controllers.report import (
ReportController as BaseReportController,
)
from odoo.addons.web.controllers.report import ReportController as BaseReportController
class ReportController(BaseReportController):
......@@ -71,9 +69,7 @@
"%s" % reportname
)
res, filetype = action_redner_report._render(reportname, docids, data)
filename = action_redner_report.gen_report_download_filename(
docids, data
)
filename = action_redner_report.gen_report_download_filename(docids, data)
if not filename.endswith(filetype):
filename = "{}.{}".format(filename, filetype)
content_type = mimetypes.guess_type("x." + filetype)[0]
......@@ -116,9 +112,9 @@
# decoding the args represented in JSON
data = list(url_decode(url.split("?")[1]).items())
if "context" in data:
context, data_context = json.loads(
context or "{}"
), json.loads(data.pop("context"))
context, data_context = json.loads(context or "{}"), json.loads(
data.pop("context")
)
context = json.dumps({**context, **data_context})
response = self.report_routes(
reportname, converter="redner", context=context, **data
......
......@@ -55,9 +55,7 @@
path = i[0]
line = i[1]
lines = (line - 3, min(line + 4, path_file_length[path]))
class_name = ":class:`%s`" % os.path.basename(
os.path.splitext(path)[0]
)
class_name = ":class:`%s`" % os.path.basename(os.path.splitext(path)[0])
f.write(
"%s\n"
"%s\n\n"
......@@ -101,8 +99,8 @@
res[tag].extend(info)
def scan_file(filename, tags) -> tuple[dict[str, tuple[str, int, str]], int]:
res = {tag: [] for tag in tags}
def scan_file(filename, tags) -> tuple[dict[str, list[tuple[str, int, str]]], int]:
res: dict[str, list[tuple[str, int, str]]] = {tag: [] for tag in tags}
line_num: int = 0
with open(filename, "r") as f:
for line_num, line in enumerate(f):
......
......@@ -122,9 +122,7 @@
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, module_lowercase, "%s Documentation" % project, [author], 1)
]
man_pages = [(master_doc, module_lowercase, "%s Documentation" % project, [author], 1)]
# -- Options for Texinfo output -------------------------------------------
......@@ -151,10 +149,9 @@
# odoo-sphinx-autodoc
#
# sphinxodoo_addons : List of addons name to load (if empty, no addon will be
# loaded)
# sphinxodoo_addons : List of addons name to load (if empty, no addon will be loaded)
this_module = os.path.basename(
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
)
sphinxodoo_addons = [this_module]
# sphinxodoo_root_path : Path of the Odoo root directory
......@@ -156,11 +153,9 @@
this_module = os.path.basename(
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
)
sphinxodoo_addons = [this_module]
# sphinxodoo_root_path : Path of the Odoo root directory
sphinxodoo_root_path = os.path.dirname(
os.path.dirname(os.path.abspath(odoo.__file__))
)
sphinxodoo_root_path = os.path.dirname(os.path.dirname(os.path.abspath(odoo.__file__)))
# sphinxodoo_addons_path : List of paths were Odoo addons to load are located
c = None
# find setup file of superproject, if any
......@@ -181,7 +176,7 @@
else:
directory = None
sphinxodoo_addons_path = list()
sphinxodoo_addons_path = []
if c:
addon_dirs = set(os.path.dirname(path) for path in c.modules)
......@@ -190,9 +185,7 @@
sphinxodoo_addons_path.append(os.path.join(directory, line))
else:
# add this directory top dir
sphinxodoo_addons_path.append(
os.path.dirname(os.path.dirname(os.getenv("PWD")))
)
sphinxodoo_addons_path.append(os.path.dirname(os.path.dirname(os.getenv("PWD"))))
other_addons = os.getenv("ODOO_ADDONS_PATH", default=None)
if other_addons:
for addon_path in other_addons.split(","):
......
......@@ -87,9 +87,7 @@
selection="_get_redner_filetypes", string="Redner Output Format"
)
is_redner_native_format = fields.Boolean(
compute="_compute_is_redner_native_format"
)
is_redner_native_format = fields.Boolean(compute="_compute_is_redner_native_format")
redner_tmpl_id = fields.Many2one(
comodel_name="redner.template",
......@@ -195,9 +193,7 @@
report = self.get_from_report_name(self.report_name, self.report_type)
if report.print_report_name and not len(res_ids) > 1:
obj = self.env[self.model].browse(res_ids)
return safe_eval(
report.print_report_name, {"object": obj, "time": time}
)
return safe_eval(report.print_report_name, {"object": obj, "time": time})
return "{}.{}".format(self.name, self.redner_filetype)
def _get_attachments(self, res_ids):
......@@ -223,9 +219,7 @@
self.ensure_one()
attachment_name = safe_eval(
self.attachment, {"object": record, "time": time}
)
attachment_name = safe_eval(self.attachment, {"object": record, "time": time})
if not attachment_name:
return None
......@@ -245,9 +239,7 @@
try:
self.env["ir.attachment"].create(attachment_vals)
except AccessError:
_logger.info(
"Cannot save report %r as attachment", attachment_vals["name"]
)
_logger.info("Cannot save report %r as attachment", attachment_vals["name"])
else:
_logger.info(
"The document %s is now saved in the database",
......
......@@ -40,9 +40,7 @@
_inherit = "mail.template"
is_redner_template = fields.Boolean(
string="Rendered by Redner", default=False
)
is_redner_template = fields.Boolean(string="Rendered by Redner", default=False)
redner_tmpl_id = fields.Many2one(
comodel_name="redner.template",
......@@ -81,7 +79,6 @@
deprecated_keys.unlink()
def _patch_email_values(self, values, res_id):
conv = self.redner_substitution_ids.filtered(
lambda r: r.depth == 0
).build_converter()
......
......@@ -73,9 +73,7 @@
data = self._get_report_data(model_instances)
metadata = report_xml.get_report_metadata()
fformat = Formats().get_format(
self.ir_actions_report_id.redner_filetype
)
fformat = Formats().get_format(self.ir_actions_report_id.redner_filetype)
try:
res = report_xml.redner_tmpl_id.redner.templates.render(
......@@ -168,9 +166,7 @@
try:
os.unlink(temporary_file)
except OSError:
logger.error(
"Error when trying to remove file %s", temporary_file
)
logger.error("Error when trying to remove file %s", temporary_file)
def create_report(self, res_ids, data):
"""Produce the report, return PDF data & file extension"""
......@@ -183,9 +179,7 @@
reports_path = []
if len(res_ids) > 1 and report_xml.redner_multi_in_one:
reports_path.append(
self._create_single_report(model_instances, data)
)
reports_path.append(self._create_single_report(model_instances, data))
else:
existing_reports_attachment = report_xml._get_attachments(res_ids)
for model_instance in model_instances:
......@@ -222,8 +216,6 @@
)
if filtered_lines:
down_conv = filtered_lines.build_converter()
ret["records"] = [
down_conv.odoo_to_message(record) for record in records
]
ret["records"] = [down_conv.odoo_to_message(record) for record in records]
return ret
......@@ -34,9 +34,7 @@
keyword = fields.Char(string="Variable", help="Template variable name")
template_id = fields.Many2one(
comodel_name="mail.template", string="Email Template"
)
template_id = fields.Many2one(comodel_name="mail.template", string="Email Template")
ir_actions_report_id = fields.Many2one(
comodel_name="ir.actions.report", string="Report"
......@@ -57,9 +55,7 @@
]
)
depth = fields.Integer(
string="Depth", compute="_compute_depth", store=True
)
depth = fields.Integer(string="Depth", compute="_compute_depth", store=True)
@api.depends("keyword")
def _compute_depth(self):
......@@ -115,9 +111,7 @@
elif sub.converter is False:
continue
else:
raise ValidationError(
_("invalid converter type: %s") % sub.converter
)
raise ValidationError(_("invalid converter type: %s") % sub.converter)
d[sub.keyword.rsplit(".", 2)[-1]] = conv
return converter.Model("", d)
......@@ -31,7 +31,6 @@
class RednerTemplate(models.Model):
_name = "redner.template"
_description = "Redner Template"
......@@ -98,7 +97,6 @@
"""Try to avoid Redner instance to be over created"""
global _redner
if _redner is None:
# Bypass security rules when reading these configuration params. By
# default, only some administrators have access to that model.
config_model = self.env["ir.config_parameter"].sudo()
......@@ -228,8 +226,6 @@
if not self.redner_id:
return []
return self.redner.templates.account_template_varlist(
self.redner_id
)
return self.redner.templates.account_template_varlist(self.redner_id)
except Exception as e:
......@@ -234,6 +230,6 @@
except Exception as e:
logger.warning("Failed to fetch account template varlist: %s" % e)
logger.warning("Failed to fetch account template varlist: %s", e)
return []
def send_to_rednerd_server(self):
......
[project]
name = "odoo-addon-redner"
dynamic = ["version"]
readme = "README.rst"
requires-python = "~=3.10.0"
license = { file = "LICENSE", name = "GNU Affero General Public License v3" }
keywords = ["odoo"]
authors = [{ name = "XCG Consulting" }]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Framework :: Odoo",
"Framework :: Odoo :: 16.0",
"License :: OSI Approved :: GNU Affero General Public License v3"
]
dependencies = [
"odoo==16.0.*",
"odoo-addon-converter >=16.0.dev,<16.0.2",
"requests_unixsocket"
]
[project.optional-dependencies]
doc = ["sphinx", "sphinx-odoo-autodoc"]
test = []
[project.urls]
repository = "https://orus.io/xcg/odoo-modules/redner"
changelog = "https://orus.io/xcg/odoo-modules/redner/-/blob/branch/16.0/NEWS.rst"
[build-system]
requires = ["setuptools >=64.0.0", "wheel", "setuptools_scm[toml] >=6.2"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
package-dir = { "odoo.addons.redner" = "." }
[tool.setuptools.package-data]
"*" = ["*"]
[tool.setuptools_scm]
[tool.black]
target = 3.10
[tool.isort]
......@@ -1,5 +45,4 @@
[tool.isort]
line_length = 79
py_version = 310
profile = "black"
known_odoo = ['odoo']
......@@ -13,7 +56,3 @@
'FIRSTPARTY',
'LOCALFOLDER'
]
[tool.black]
line-length = 79
target = 3.10
......@@ -50,9 +50,7 @@
if server_url.startswith("/"):
self.session = requests_unixsocket.Session()
self.server_url = "http+unix://{}/".format(
quote(server_url, safe="")
)
self.server_url = "http+unix://{}/".format(quote(server_url, safe=""))
else:
self.session = requests.sessions.Session()
self.server_url = server_url
......
requests_unixsocket
......@@ -100,6 +100,4 @@
]
)
self.assertEqual(len(attachment), 1)
self.assertEqual(
base64.b64decode(attachment.datas), b"test-rendered-report"
)
self.assertEqual(base64.b64decode(attachment.datas), b"test-rendered-report")
......@@ -57,9 +57,7 @@
"produces": "text/html",
"body-format": "text",
"locale": "fr_FR",
"version": fields.Datetime.to_string(
redner_template.create_date
),
"version": fields.Datetime.to_string(redner_template.create_date),
},
headers={"Rednerd-API-Key": "test-api-key"},
timeout=20,
......@@ -78,9 +76,7 @@
"produces": "text/html",
"body-format": "text",
"locale": "fr_FR",
"version": fields.Datetime.to_string(
redner_template.write_date
),
"version": fields.Datetime.to_string(redner_template.write_date),
},
headers={"Rednerd-API-Key": "test-api-key"},
timeout=20,
......
......@@ -56,5 +56,4 @@
class Formats:
def __init__(self):
self._formats = {
......@@ -60,10 +59,8 @@
self._formats = {
FORMAT_WORD97: Format(
FORMAT_WORD97, "MS Word 97", "application/msword"
),
FORMAT_WORD97: Format(FORMAT_WORD97, "MS Word 97", "application/msword"),
FORMAT_WORD2003: Format(
FORMAT_WORD2003,
"MS Word 2003 XML",
"application/vnd.openxmlformats-officedocument"
".wordprocessingml.document",
),
......@@ -64,15 +61,11 @@
FORMAT_WORD2003: Format(
FORMAT_WORD2003,
"MS Word 2003 XML",
"application/vnd.openxmlformats-officedocument"
".wordprocessingml.document",
),
FORMAT_PDF: Format(
FORMAT_PDF, "writer_pdf_Export", "application/pdf"
),
FORMAT_DOCBOOK: Format(
FORMAT_DOCBOOK, "DocBook File", "application/xml"
),
FORMAT_PDF: Format(FORMAT_PDF, "writer_pdf_Export", "application/pdf"),
FORMAT_DOCBOOK: Format(FORMAT_DOCBOOK, "DocBook File", "application/xml"),
FORMAT_HTML: Format(FORMAT_HTML, "HTML", "text/html"),
FORMAT_ODT: Format(
FORMAT_ODT,
......@@ -86,9 +79,7 @@
"application/vnd.oasis.opendocument.spreadsheet",
native=True,
),
FORMAT_XLS: Format(
FORMAT_XLS, "MS Excel 97", "application/msexcel"
),
FORMAT_XLS: Format(FORMAT_XLS, "MS Excel 97", "application/msexcel"),
FORMAT_DOCX: Format(
FORMAT_DOCX,
"Office Open XML Text",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment