diff --git a/requirements.txt b/requirements.txt index aed5f53ba5eb..8ba17c323f03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ beautifulsoup4 bokeh==3.1.1 mpld3==0.5.9 +msoffice2pdf plotly==5.13.1 diff --git a/setup/web_preview_ms_office/odoo/addons/web_preview_ms_office b/setup/web_preview_ms_office/odoo/addons/web_preview_ms_office new file mode 120000 index 000000000000..131134e1d2cb --- /dev/null +++ b/setup/web_preview_ms_office/odoo/addons/web_preview_ms_office @@ -0,0 +1 @@ +../../../../web_preview_ms_office \ No newline at end of file diff --git a/setup/web_preview_ms_office/setup.py b/setup/web_preview_ms_office/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/web_preview_ms_office/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_preview_ms_office/README.rst b/web_preview_ms_office/README.rst new file mode 100644 index 000000000000..2683ee28008c --- /dev/null +++ b/web_preview_ms_office/README.rst @@ -0,0 +1,109 @@ +================= +Preview MS Office +================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:95dca921a936f35530178c093fe48f1326b5096651e1f9d6da4ab494dcb6b614 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/16.0/web_preview_ms_office + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-16-0/web-16-0-web_preview_ms_office + :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/web&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides a preview of Microsoft Office documents in Odoo. It +allows users to view documents such as Word, Excel, and PowerPoint files +directly within the Odoo interface without needing to download them. + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +You need to install the python msoffice2pdf library: + +:: + + pip install msoffice2pdf + +Usage +===== + +1. Install the module in your Odoo instance. + +2. Add field in your model to include the ``attachment_ids`` field. + +.. code:: python + + attachment_ids = fields.Many2Many('ir.attachment', string='Attachments') + +3. In your xml file, include the ``many2many_binary`` widget: + +.. code:: xml + + + +4. The MS Office file will be displayed in the form view of the model + where you added the ``attachment_ids`` field. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Phan Hong Phuc + +Contributors +------------ + +- `Trobz `__ + + - Phan Hong Phuc phucph@trobz.com + +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/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_preview_ms_office/__init__.py b/web_preview_ms_office/__init__.py new file mode 100644 index 000000000000..91c5580fed36 --- /dev/null +++ b/web_preview_ms_office/__init__.py @@ -0,0 +1,2 @@ +from . import controllers +from . import models diff --git a/web_preview_ms_office/__manifest__.py b/web_preview_ms_office/__manifest__.py new file mode 100644 index 000000000000..a532ae8db376 --- /dev/null +++ b/web_preview_ms_office/__manifest__.py @@ -0,0 +1,24 @@ +{ + "name": "Preview MS Office", + "version": "16.0.1.0.0", + "summary": "Preview MS Office Documents in Odoo", + "category": "Tools", + "website": "https://github.com/OCA/web", + "maintainer": "Phan Hong Phuc", + "author": "Phan Hong Phuc, Odoo Community Association (OCA)", + "license": "LGPL-3", + "depends": ["web_preview_attachment_base"], + "external_dependencies": {"python": ["msoffice2pdf"]}, + "assets": { + "web.assets_backend": [ + "web_preview_ms_office/static/src/attachment/attachment_viewer_viewable.js", + "web_preview_ms_office/static/src/attachment/attachment_viewer.xml", + "web_preview_ms_office/static/src/attachment/attachment.js", + "web_preview_ms_office/static/src/many2many_binary/attachment_preview.js", + ], + }, + "installable": True, + "application": False, + "images": ["static/description/icon.png"], + "auto_install": False, +} diff --git a/web_preview_ms_office/controllers/__init__.py b/web_preview_ms_office/controllers/__init__.py new file mode 100644 index 000000000000..12a7e529b674 --- /dev/null +++ b/web_preview_ms_office/controllers/__init__.py @@ -0,0 +1 @@ +from . import main diff --git a/web_preview_ms_office/controllers/main.py b/web_preview_ms_office/controllers/main.py new file mode 100644 index 000000000000..fdcf0ece9024 --- /dev/null +++ b/web_preview_ms_office/controllers/main.py @@ -0,0 +1,35 @@ +import base64 + +from odoo import http +from odoo.http import request + + +class OfficeConvertController(http.Controller): + @http.route("/preview-msoffice/", auth="user") + def convert_pdf_attachment(self, attachment_id): + Attachment = request.env["ir.attachment"].sudo() + attachment = Attachment.browse(attachment_id) + + headers = [ + ("Content-Type", "application/pdf"), + ("Content-Disposition", 'inline; filename="converted_attachment.pdf"'), + ] + + if not attachment.exists() or not attachment.datas: + return request.make_response( + "Attachment not found or empty.", + headers=[("Content-Type", "text/plain")], + ) + try: + attachment_bytes = base64.b64decode(attachment.datas) + pdf_data = request.env["converter.msoffice2pdf"].convert_msoffice2pdf( + binary_data=attachment_bytes, filename=attachment.name + ) + return request.make_response( + pdf_data, headers=headers + [("Content-Length", str(len(pdf_data)))] + ) + except Exception as e: + return request.make_response( + f"Error preview attachment: {str(e)}", + headers=[("Content-Type", "text/plain")], + ) diff --git a/web_preview_ms_office/models/__init__.py b/web_preview_ms_office/models/__init__.py new file mode 100644 index 000000000000..c254409f44ce --- /dev/null +++ b/web_preview_ms_office/models/__init__.py @@ -0,0 +1 @@ +from . import convert_msoffice2pdf diff --git a/web_preview_ms_office/models/convert_msoffice2pdf.py b/web_preview_ms_office/models/convert_msoffice2pdf.py new file mode 100644 index 000000000000..18500d6994b8 --- /dev/null +++ b/web_preview_ms_office/models/convert_msoffice2pdf.py @@ -0,0 +1,40 @@ +import logging +import os +import tempfile + +from odoo import models + +_logger = logging.getLogger(__name__) + +try: + from msoffice2pdf import convert +except (OSError, ImportError) as err: + _logger.debug(err) + + +class ConverterOffice2PDF(models.AbstractModel): + _name = "converter.msoffice2pdf" + + def convert_msoffice2pdf(self, binary_data, filename): + with tempfile.TemporaryDirectory() as tmpdir: + input_path = os.path.join(tmpdir, filename) + output = "" + with open(input_path, "wb") as f: + f.write(binary_data) + try: + output = convert(source=input_path, output_dir=tmpdir, soft=1) + with open(output, "rb") as f: + pdf_data = f.read() + return pdf_data + + except Exception as e: + raise ValueError( + f"Error converting file {filename} to PDF: {str(e)}" + ) from e + + finally: + # Clean up the temporary files + if os.path.exists(input_path): + os.remove(input_path) + if os.path.exists(output): + os.remove(output) diff --git a/web_preview_ms_office/readme/CONTRIBUTORS.md b/web_preview_ms_office/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..d3b16f651bfd --- /dev/null +++ b/web_preview_ms_office/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +* [Trobz](https://trobz.com) + + * Phan Hong Phuc diff --git a/web_preview_ms_office/readme/DESCRIPTION.md b/web_preview_ms_office/readme/DESCRIPTION.md new file mode 100644 index 000000000000..675467ce2702 --- /dev/null +++ b/web_preview_ms_office/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module provides a preview of Microsoft Office documents in Odoo. +It allows users to view documents such as Word, Excel, and PowerPoint files directly within the Odoo interface without needing to download them. \ No newline at end of file diff --git a/web_preview_ms_office/readme/INSTALL.md b/web_preview_ms_office/readme/INSTALL.md new file mode 100644 index 000000000000..b6260572936e --- /dev/null +++ b/web_preview_ms_office/readme/INSTALL.md @@ -0,0 +1,3 @@ +You need to install the python msoffice2pdf library: + + pip install msoffice2pdf \ No newline at end of file diff --git a/web_preview_ms_office/readme/USAGE.md b/web_preview_ms_office/readme/USAGE.md new file mode 100644 index 000000000000..004a696bf3b0 --- /dev/null +++ b/web_preview_ms_office/readme/USAGE.md @@ -0,0 +1,13 @@ +1. Install the module in your Odoo instance. + +2. Add field in your model to include the `attachment_ids` field. +```python +attachment_ids = fields.Many2Many('ir.attachment', string='Attachments') +``` + +3. In your xml file, include the `many2many_binary` widget: +```xml + +``` + +4. The MS Office file will be displayed in the form view of the model where you added the `attachment_ids` field. \ No newline at end of file diff --git a/web_preview_ms_office/static/description/icon.png b/web_preview_ms_office/static/description/icon.png new file mode 100644 index 000000000000..d96bb9762c57 Binary files /dev/null and b/web_preview_ms_office/static/description/icon.png differ diff --git a/web_preview_ms_office/static/description/index.html b/web_preview_ms_office/static/description/index.html new file mode 100644 index 000000000000..7917452cfce7 --- /dev/null +++ b/web_preview_ms_office/static/description/index.html @@ -0,0 +1,457 @@ + + + + + +Preview MS Office + + + +
+

Preview MS Office

+ + +

Beta License: LGPL-3 OCA/web Translate me on Weblate Try me on Runboat

+

This module provides a preview of Microsoft Office documents in Odoo. It +allows users to view documents such as Word, Excel, and PowerPoint files +directly within the Odoo interface without needing to download them.

+

Table of contents

+ +
+

Installation

+

You need to install the python msoffice2pdf library:

+
+pip install msoffice2pdf
+
+
+
+

Usage

+
    +
  1. Install the module in your Odoo instance.
  2. +
  3. Add field in your model to include the attachment_ids field.
  4. +
+
+attachment_ids = fields.Many2Many('ir.attachment', string='Attachments')
+
+
    +
  1. In your xml file, include the many2many_binary widget:
  2. +
+
+<field name="attachment_ids" widget="many2many_binary"/>
+
+
    +
  1. The MS Office file will be displayed in the form view of the model +where you added the attachment_ids field.
  2. +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Phan Hong Phuc
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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/web project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/web_preview_ms_office/static/description/msoffice_preview.gif b/web_preview_ms_office/static/description/msoffice_preview.gif new file mode 100644 index 000000000000..3b8c003df19b Binary files /dev/null and b/web_preview_ms_office/static/description/msoffice_preview.gif differ diff --git a/web_preview_ms_office/static/src/attachment/attachment.js b/web_preview_ms_office/static/src/attachment/attachment.js new file mode 100644 index 000000000000..15719db85672 --- /dev/null +++ b/web_preview_ms_office/static/src/attachment/attachment.js @@ -0,0 +1,42 @@ +/** @odoo-module **/ + +import {registerPatch} from "@mail/model/model_core"; +import {attr} from "@mail/model/model_field"; + +registerPatch({ + name: "Attachment", + fields: { + isMsOfficeDocument: attr({ + compute() { + const officeMimeTypes = [ + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // .docx + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xlsx + "application/vnd.openxmlformats-officedocument.presentationml.presentation", // .pptx + "application/msword", // .doc + "application/vnd.ms-excel", // .xls + "application/vnd.ms-powerpoint", // .ppt + ]; + return officeMimeTypes.includes(this.mimetype); + }, + }), + isViewable: { + compute() { + if (this.isMsOfficeDocument) { + return this.isMsOfficeDocument; + } + return this._super(); + }, + }, + defaultSource: { + compute() { + if (this.isMsOfficeDocument) { + const encodedRoute = encodeURIComponent( + `/preview-msoffice/${this.id}` + ); + return encodedRoute; + } + return this._super(); + }, + }, + }, +}); diff --git a/web_preview_ms_office/static/src/attachment/attachment_viewer.xml b/web_preview_ms_office/static/src/attachment/attachment_viewer.xml new file mode 100644 index 000000000000..a0e88f3cd138 --- /dev/null +++ b/web_preview_ms_office/static/src/attachment/attachment_viewer.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + +