Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADD] report_py3o_index: Update TOC and other indices in Py3o reports #907

Open
wants to merge 2 commits into
base: 12.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-python@v2
with:
python-version: "3.6"
python-version: "3.8"
- name: Get python version
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
- uses: actions/cache@v1
Expand Down
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ exclude: |
# You don't usually want a bot to modify your legal texts
(LICENSE.*|COPYING.*)
default_language_version:
python: python3.6
python: python3.8
repos:
- repo: https://github.com/oca/maintainer-tools
rev: ab1d7f6
rev: 9a170331575a265c092ee6b24b845ec508e8ef75
hooks:
# update the NOT INSTALLABLE ADDONS section above
- id: oca-update-pre-commit-excluded-addons
- id: oca-fix-manifest-website
args: ["https://github.com/OCA/reporting-engine"]
- repo: https://github.com/acsone/setuptools-odoo
rev: 3.1.8
rev: 3.2.1
hooks:
- id: setuptools-odoo-make-default
- id: setuptools-odoo-get-requirements
Expand All @@ -35,13 +35,13 @@ repos:
- --header
- "# generated from manifests external_dependencies"
- repo: https://github.com/OCA/mirrors-flake8
rev: v3.4.1
rev: v4.0.1
hooks:
- id: flake8
name: flake8 excluding __init__.py
exclude: __init__\.py
- repo: https://github.com/pre-commit/mirrors-pylint
rev: v2.5.3
rev: v3.0.0a5
hooks:
- id: pylint
name: pylint with optional checks
Expand All @@ -50,7 +50,7 @@ repos:
- --exit-zero
verbose: true
additional_dependencies: &pylint_deps
- pylint-odoo==3.5.0
- pylint-odoo==9.0.5
- id: pylint
name: pylint with mandatory checks
args:
Expand Down
92 changes: 92 additions & 0 deletions report_py3o_index/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
==============================================
Py3o Report Engine: Update Indices (TOC, etc.)
==============================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:527b4bd77cfdd3ff1f069091cc2701f01df1c9cbbd7ffab7ab5a207b0fc7a58d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
:target: https://github.com/OCA/reporting-engine/tree/12.0/report_py3o_index
:alt: OCA/reporting-engine
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/reporting-engine-12-0/reporting-engine-12-0-report_py3o_index
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=12.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module fills in the document indexes (e.g. a Table of Content) in a generated py3o document.

This is to work around the missing feature first reported in 2012: https://bugs.documentfoundation.org/show_bug.cgi?id=44448

It uses the workaround given in https://ask.libreoffice.org/t/update-toc-via-command-line/52518 and other similar threads.

Note that to work, the macro has to be installed in libreoffice first.
This is done at module install.
It assumes the macro files are stored at `~/.config/libreoffice/4/user/basic/Standard`.
If it fails, the function can be manually called with the real path using:
`self.env["py3o.report"]._install_update_index_macro(real_path)`

Make sure that this is correct as most failure paths of the macro application are silent.

Once this is done, py3o templates have an "has index" boolean.
If set, the macro is applied after generation (and before pdf conversion) to update all indices.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_py3o_index%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Lambdao

Contributors
~~~~~~~~~~~~

* Fanny He (`Lambdao <https://lambdao.dev/>`_) <fanny@lambdao.dev>,
* Nans Lefebvre (`Lambdao <https://lambdao.dev/>`_) <len@lambdao.dev>,

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/12.0/report_py3o_index>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
7 changes: 7 additions & 0 deletions report_py3o_index/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright 2024 fah-mili/Lambdao
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).


from . import models

from .hooks import post_init_hook
17 changes: 17 additions & 0 deletions report_py3o_index/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2024 fah-mili/Lambdao
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).


{
'name': 'Py3o Report Engine: Update Indices (TOC, etc.)',
'summary': 'Update indices (TOC, etc.) in Py3o reports',
'version': '12.0.1.0.0',
'category': 'Reporting',
'license': 'AGPL-3',
'author': 'Lambdao, Odoo Community Association (OCA)',
"website": "https://github.com/OCA/reporting-engine",
'depends': ['report_py3o'],
'data': ["views/ir_actions_report.xml", "views/py3o_template.xml"],
'installable': True,
'post_init_hook': 'post_init_hook',
}
28 changes: 28 additions & 0 deletions report_py3o_index/data/ModuleUpdateIndex.xba
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="ModuleUpdateIndex" script:language="StarBasic">REM ***** BASIC *****

Option Explicit

Sub UpdateIndexes(path As String)
&apos;&apos;&apos;Update indexes, such as for the table of contents&apos;&apos;&apos;
Dim doc As Object
Dim args()

doc = StarDesktop.loadComponentFromUrl(convertToUrl(path), &quot;_default&quot;, 0, args())

Dim i As Integer

With doc &apos; Only process Writer documents
If .supportsService(&quot;com.sun.star.text.GenericTextDocument&quot;) Then
For i = 0 To .getDocumentIndexes().count - 1
.getDocumentIndexes().getByIndex(i).update()
Next i
End If
End With &apos; ThisComponent

doc.store()
doc.close(True)

End Sub &apos; UpdateIndexes
</script:module>
20 changes: 20 additions & 0 deletions report_py3o_index/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2024 fah-mili/Lambdao
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import logging

from odoo import SUPERUSER_ID, api

_logger = logging.getLogger(__name__)


def post_init_hook(cr, registry):
_logger.info("Install index update macro with default path.")
env = api.Environment(cr, SUPERUSER_ID, {})
try:
env["py3o.report"]._install_update_index_macro()
except Exception as e:
_logger.warn("Failed to install index update macro.")
_logger.warn("--------")
_logger.warn(e)
_logger.warn("--------")
7 changes: 7 additions & 0 deletions report_py3o_index/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright 2024 fah-mili/Lambdao
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).


from . import py3o_template
from . import ir_actions_report
from . import py3o_report
16 changes: 16 additions & 0 deletions report_py3o_index/models/ir_actions_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2024 fah-mili/Lambdao
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).


from odoo import fields, models


class IrActionsReport(models.Model):

_inherit = 'ir.actions.report'
py3o_has_index_fallback = fields.Boolean(
"Has Py3o Index? (Fallback)",
default=False,
help="Check if the template fallback has a py3o index. "
"It needs to be compiled twice to get the index right."
)
92 changes: 92 additions & 0 deletions report_py3o_index/models/py3o_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copyright 2024 fah-mili/Lambdao
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).


import logging
import os
import subprocess
import pkg_resources

from odoo import api, fields, models

logger = logging.getLogger(__name__)


class Py3oReport(models.TransientModel):
_inherit = "py3o.report"

py3o_has_index = fields.Boolean(
"Has Py3o Index?",
default=False,
compute='_compute_py3o_has_index',
help="Check if the template has a py3o index. "
"It needs to be compiled twice to get the index right."
)

@api.depends(
'ir_actions_report_id.py3o_template_id.py3o_has_index',
'ir_actions_report_id.py3o_has_index_fallback'
)
def _compute_py3o_has_index(self):
for rec in self:
if rec.ir_actions_report_id.py3o_template_id:
value = rec.ir_actions_report_id.py3o_template_id.py3o_has_index
else:
value = rec.ir_actions_report_id.py3o_has_index_fallback
rec.py3o_has_index = value

@api.model
def _install_update_index_macro(self, path=None):
""" Install or update the py3o index macro
"""
# the real path is an argument so that in case it fails it can be
# called again with the correct one; after that it's LO's internal
# macro naming that will be used
# we could also have a parameter for the macro name but
# is it worth the complexity?
if not path:
path = "~/.config/libreoffice/4/user/basic/Standard"
real_path = os.path.realpath(os.path.expanduser(path))
file_macro = "ModuleUpdateIndex.xba"
macro_path = os.path.join(real_path, file_macro)
if not os.path.exists(macro_path):
# copy the new macro to libreoffice macro folder
content_path = pkg_resources.resource_filename(
'odoo.addons.report_py3o_index',
'data/ModuleUpdateIndex.xba'
)
with open(content_path, 'r') as f:
content = f.read()
with open(macro_path, 'w') as f:
f.write(content)
file_script = "script.xlb"
script_path = os.path.join(real_path, file_script)
mac = '<library:element library:name="ModuleUpdateIndex"/>'
with open(script_path, 'r') as f:
script_content = f.read()
if mac not in script_content:
end_marker = '</library:library>'
marker_line = mac + "\n" + end_marker
new_content = script_content.replace(end_marker, marker_line)
with open(script_path, 'w') as f:
f.write(new_content)

@api.multi
def _convert_single_report(self, result_path, model_instance, data):
# this needs to be done before the report is converted to pdf!
# data is an unused dict, the file is obtained from the result_path
if self.py3o_has_index:
self._update_index(result_path)
result = super(Py3oReport, self)._convert_single_report(
result_path, model_instance, data
)
return result

def _update_index(self, result_path):
"""Run a command to update the index"""
path = "macro:///Standard.ModuleUpdateIndex.UpdateIndexes(%s)" % result_path
lo_bin = self.ir_actions_report_id.lo_bin_path
cmd = [lo_bin, '--headless', path]
# if something goes wrong, it's not giving any error message...
subprocess.check_output(cmd, cwd=os.path.dirname(result_path))
return result_path
16 changes: 16 additions & 0 deletions report_py3o_index/models/py3o_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2024 fah-mili/Lambdao
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).


from odoo import fields, models


class Py3oTemplate(models.Model):
_inherit = 'py3o.template'

py3o_has_index = fields.Boolean(
"Has Py3o Index?",
default=False,
help="Check if the template has a py3o index. "
"It needs to be compiled twice to get the index right."
)
2 changes: 2 additions & 0 deletions report_py3o_index/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Fanny He (`Lambdao <https://lambdao.dev/>`_) <fanny@lambdao.dev>,
* Nans Lefebvre (`Lambdao <https://lambdao.dev/>`_) <len@lambdao.dev>,
15 changes: 15 additions & 0 deletions report_py3o_index/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
This module fills in the document indexes (e.g. a Table of Content) in a generated py3o document.

This is to work around the missing feature first reported in 2012: https://bugs.documentfoundation.org/show_bug.cgi?id=44448

It uses the workaround given in https://ask.libreoffice.org/t/update-toc-via-command-line/52518 and other similar threads.

Note that to work, the macro has to be installed in libreoffice first.
This is done at module install.
It assumes the macro files are stored at `~/.config/libreoffice/4/user/basic/Standard`.
If it fails, the function can be manually called with the real path using:
`self.env["py3o.report"]._install_update_index_macro(real_path)`
Make sure that this is correct as most failure paths of the macro application are silent.

Once this is done, py3o templates have an "has index" boolean.
If set, the macro is applied after generation (and before pdf conversion) to update all indices.
Binary file added report_py3o_index/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading