Skip to content

Commit

Permalink
Merge pull request #13 from ONLYOFFICE/develop
Browse files Browse the repository at this point in the history
Release/2.0.0
  • Loading branch information
LinneyS authored Jul 24, 2023
2 parents 976b41c + 0ea36b6 commit fed128b
Show file tree
Hide file tree
Showing 45 changed files with 1,658 additions and 41 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "onlyoffice_odoo/static/assets/document_templates"]
path = onlyoffice_odoo/static/assets/document_templates
url = https://github.com/ONLYOFFICE/document-templates
branch = main/new
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Change Log

## 2.0.0
## Added
- support Documents module
- opening file from Documents module
- creating file in Document module

## 1.0.0
## Added
- edit option for DOCX, DOCXF, XLSX, PPTX
- view option for DJVU, DOC, DOCM, DOT, DOTM, DOTX, EPUB, FB2, FODT, HTML, MHT, ODT, OFORM, OTT, OXPS, PDF, RTF, TXT, XPS, XML, CSV, FODS, ODS, OTS, XLS, XLSB, XLSM, XLT, XLTM, XLTX, FODP, ODP, OTP, POT, POTM, POTX, PPS, PPSM, PPSX, PPT, PPTM
- collaboration editing
- configuration page
- Translations for DE, EN, ES, FR, IT, PT-BR, RU, ZH-CN
- Translations for DE, EN, ES, FR, IT, PT-BR, RU, ZH-CN
2 changes: 1 addition & 1 deletion onlyoffice_odoo/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
'website': "https://www.onlyoffice.com",

'category': 'Productivity',
'version': '1.0.0',
'version': '2.0.0',

'depends': ['base', 'mail'],

Expand Down
28 changes: 16 additions & 12 deletions onlyoffice_odoo/controllers/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from odoo.addons.onlyoffice_odoo.utils import jwt_utils
from odoo.addons.onlyoffice_odoo.utils import config_utils

from mimetypes import guess_type
from urllib.request import urlopen

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -84,7 +85,16 @@ def render_editor(self, attachment_id, access_token=None):

attachment.validate_access(access_token)

return request.render("onlyoffice_odoo.onlyoffice_editor", self.prepare_editor_values(attachment, access_token))
data = attachment.read(["id", "checksum", "public", "name", "access_token"])[0]
filename = data["name"]

can_read = attachment.check_access_rights("read", raise_exception=False) and file_utils.can_view(filename)
can_write = attachment.check_access_rights("write", raise_exception=False) and file_utils.can_edit(filename)

if (not can_read):
raise Exception("cant read")

return request.render("onlyoffice_odoo.onlyoffice_editor", self.prepare_editor_values(attachment, access_token, can_write))

@http.route("/onlyoffice/editor/callback/<int:attachment_id>", auth="public", methods=["POST"], type="http", csrf=False)
def editor_callback(self, attachment_id, oo_security_token=None, access_token=None):
Expand Down Expand Up @@ -120,7 +130,7 @@ def editor_callback(self, attachment_id, oo_security_token=None, access_token=No

if (status == 2) | (status == 3): # mustsave, corrupted
file_url = body.get("url")
attachment.write({"raw": urlopen(file_url).read()})
attachment.write({"raw": urlopen(file_url).read(), "mimetype": guess_type(file_url)[0]})

except Exception as ex:
response_json["error"] = 1
Expand All @@ -131,21 +141,15 @@ def editor_callback(self, attachment_id, oo_security_token=None, access_token=No
status=500 if response_json["error"] == 1 else 200,
headers=[("Content-Type", "application/json")],
)

def prepare_editor_values(self, attachment, access_token):
def prepare_editor_values(self, attachment, access_token, can_write):
data = attachment.read(["id", "checksum", "public", "name", "access_token"])[0]

docserver_url = config_utils.get_doc_server_public_url(request.env)
odoo_url = config_utils.get_odoo_url(request.env)

filename = data["name"]

can_read = attachment.check_access_rights("read", raise_exception=False) and file_utils.can_view(filename)
can_write = attachment.check_access_rights("write", raise_exception=False) and file_utils.can_edit(filename)

if (not can_read):
raise Exception("cant read")

security_token = jwt_utils.encode_payload(request.env, { "id": request.env.user.id }, config_utils.get_internal_jwt_secret(request.env))
path_part = str(data["id"]) + "?oo_security_token=" + security_token + ("&access_token=" + access_token if access_token else "")

Expand All @@ -162,7 +166,7 @@ def prepare_editor_values(self, attachment, access_token):
"title": filename,
"url": odoo_url + "onlyoffice/file/content/" + path_part,
"fileType": file_utils.get_file_ext(filename),
"key": str(data["id"]) + data["checksum"],
"key": str(data["id"]) + str(data["checksum"]),
"permissions": { "edit": can_write },
},
"editorConfig": {
Expand Down Expand Up @@ -197,4 +201,4 @@ def get_user_from_token(self, token):

user_id = jwt_utils.decode_token(request.env, token, config_utils.get_internal_jwt_secret(request.env))["id"]
user = request.env["res.users"].sudo().browse(user_id).exists().ensure_one()
return user
return user
2 changes: 1 addition & 1 deletion onlyoffice_odoo/i18n/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ msgstr ""

#. module: onlyoffice_odoo
#: model_terms:ir.ui.view,arch_db:onlyoffice_odoo.res_config_settings_view_form
msgid "<span class=\"o_form_label\">Document Server Url</span>"
msgid "<span class=\"o_form_label\">Document Server URL</span>"
msgstr ""

#. module: onlyoffice_odoo
Expand Down
1 change: 1 addition & 0 deletions onlyoffice_odoo/static/assets/document_templates
Submodule document_templates added at f00ab3
Binary file modified onlyoffice_odoo/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.
Binary file modified onlyoffice_odoo/static/description/main_screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 56 additions & 26 deletions onlyoffice_odoo/utils/file_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,9 @@
# terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
#

from odoo.addons.onlyoffice_odoo.utils import format_utils
import os

locale_path = {
"az": "az-Latn-AZ",
"bg": "bg-BG",
"cs": "cs-CZ",
"de": "de-DE",
"el": "el-GR",
"en-gb": "en-GB",
"en": "en-US",
"es": "es-ES",
"fr": "fr-FR",
"it": "it-IT",
"ja": "ja-JP",
"ko": "ko-KR",
"lv": "lv-LV",
"nl": "nl-NL",
"pl": "pl-PL",
"pt-br": "pt-BR",
"pt": "pt-PT",
"ru": "ru-RU",
"sk": "sk-SK",
"sv": "sv-SE",
"uk": "uk-UA",
"vi": "vi-VN",
"zh": "zh-CN",
}
from odoo.addons.onlyoffice_odoo.utils import format_utils


def get_file_title_without_ext(name):
Expand Down Expand Up @@ -128,3 +104,57 @@ def get_default_name_by_type(str):
return "Form template"

return None

def get_mime_by_ext(str):
if str == "docx":
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
if str == "xlsx":
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
if str == "pptx":
return "application/vnd.openxmlformats-officedocument.presentationml.presentation"

return None

def get_default_file_template(lang, ext):
locale_path = {
"az": "az-Latn-AZ",
"bg": "bg-BG",
"cs": "cs-CZ",
"de": "de-DE",
"el": "el-GR",
"en-gb": "en-GB",
"en": "en-US",
"es": "es-ES",
"fr": "fr-FR",
"it": "it-IT",
"ja": "ja-JP",
"ko": "ko-KR",
"lv": "lv-LV",
"nl": "nl-NL",
"pl": "pl-PL",
"pt-br": "pt-BR",
"pt": "pt-PT",
"ru": "ru-RU",
"sk": "sk-SK",
"sv": "sv-SE",
"uk": "uk-UA",
"vi": "vi-VN",
"zh": "zh-CN",
}

lang = lang.replace("_", "-")

locale = locale_path.get(lang)
if locale is None:
lang = lang.split("-")[0]
locale = locale_path.get(lang)
if locale is None:
locale = locale_path.get("en")

file = open(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "static", "assets", "document_templates", locale, "new." + ext), "rb")

try:
file_data = file.read()
return file_data
finally:
file.close()
4 changes: 4 additions & 0 deletions onlyoffice_odoo_documents/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-

from . import controllers
from . import models
39 changes: 39 additions & 0 deletions onlyoffice_odoo_documents/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
{
'name': "ONLYOFFICE Documents",

'summary': "Edit and collaborate on office files within Odoo Documents.",

'description': "The ONLYOFFICE connector allows users to edit and collaborate on office files within Odoo Documents using ONLYOFFICE Docs. You can work with text documents, spreadsheets, and presentations, co-author documents in real time using two co-editing modes (Fast and Strict), Track Changes, comments, and built-in chat.",

'author': "ONLYOFFICE",
'website': "https://www.onlyoffice.com",

'category': 'Productivity',
'version': '2.0.1',

'depends': ['onlyoffice_odoo', 'documents'],

# always loaded
'data': [
],

'license': 'AGPL-3',
'support': 'support@onlyoffice.com',

'images': [],

'installable': True,
'application': True,

'assets': {
'mail.assets_messaging': [
'onlyoffice_odoo_documents/static/src/models/*.js',
],
'web.assets_backend': [
'onlyoffice_odoo_documents/static/src/components/*/*.xml',
'onlyoffice_odoo_documents/static/src/documents_view/**/*',
'onlyoffice_odoo_documents/static/src/onlyoffice_create_template/**/*',
],
},
}
3 changes: 3 additions & 0 deletions onlyoffice_odoo_documents/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import controllers
97 changes: 97 additions & 0 deletions onlyoffice_odoo_documents/controllers/controllers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-

#
# (c) Copyright Ascensio System SIA 2023
#
# This program is a free software product. You can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License (AGPL)
# version 3 as published by the Free Software Foundation. In accordance with
# Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
# that Ascensio System SIA expressly excludes the warranty of non-infringement
# of any third-party rights.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
# details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
#
# You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
# street, Riga, Latvia, EU, LV-1050.
#
# The interactive user interfaces in modified source and object code versions
# of the Program must display Appropriate Legal Notices, as required under
# Section 5 of the GNU AGPL version 3.
#
# Pursuant to Section 7(b) of the License you must retain the original Product
# logo when distributing the program. Pursuant to Section 7(e) we decline to
# grant you any rights under trademark law for use of our trademarks.
#
# All the Product's GUI elements, including illustrations and icon sets, as
# well as technical writing content are licensed under the terms of the
# Creative Commons Attribution-ShareAlike 4.0 International. See the License
# terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
#

import logging
import json

from odoo import http
from odoo.http import request
from odoo.tools.translate import _

from werkzeug.exceptions import Forbidden
from odoo.exceptions import AccessError

from odoo.addons.onlyoffice_odoo.utils import file_utils
from odoo.addons.onlyoffice_odoo.controllers.controllers import Onlyoffice_Connector

_logger = logging.getLogger(__name__)

class OnlyofficeDocuments_Connector(http.Controller):
@http.route("/onlyoffice/documents/file/create", auth="user", methods=["POST"], type="json")
def post_file_create(self, folder_id, format, title):
result = {"error": None, "file_id": None}

try:
_logger.info("Getting new file template %s %s" % (request.env.user.lang, format))
file_data = file_utils.get_default_file_template(request.env.user.lang, format)

data = {
'name': title + "." + format,
'mimetype': file_utils.get_mime_by_ext(format),
'raw': file_data,
'folder_id': int(folder_id)
}

document = request.env["documents.document"].create(data)
result["file_id"] = document.attachment_id.id

except Exception as ex:
_logger.exception("Failed to create document %s" % str(ex))
result["error"] = _("Failed to create document")

return json.dumps(result)

class OnlyofficeDocuments_Inherited_Connector(Onlyoffice_Connector):
@http.route("/onlyoffice/editor/document/<int:document_id>", auth="public", type="http", website=True)
def render_document_editor(self, document_id, access_token=None):
return request.render("onlyoffice_odoo.onlyoffice_editor", self.prepare_document_editor(document_id, access_token))

def prepare_document_editor(self, document_id, access_token):
document = request.env['documents.document'].browse(int(document_id))
try:
document.check_access_rule("read")
except AccessError:
_logger.error("User has no read access rights to open this document")
raise Forbidden()

attachment = self.get_attachment(document.attachment_id.id)
if not attachment:
_logger.error("Current document has no attachments")
raise Forbidden()

try:
document.check_access_rule("write")
return self.prepare_editor_values(attachment, access_token, True)
except AccessError:
_logger.debug("Current user has no write access")
return self.prepare_editor_values(attachment, access_token, False)
31 changes: 31 additions & 0 deletions onlyoffice_odoo_documents/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Prerequisites
=============

To be able to work with office files within Odoo Enterprise, you will need an instance of ONLYOFFICE Docs. You can install the `self-hosted version`_ of the editors or opt for `ONLYOFFICE Docs`_ which doesn't require downloading and installation.

ONLYOFFICE app configuration
============================

**Please note**: All the settings are configured from the `main ONLYOFFICE app for Odoo`_ which is installed automatically when you install ONLYOFFICE app for Odoo Enterprise.
To adjust the main app settings within your Odoo, go to *Home menu -> Settings -> ONLYOFFICE*.

In the **Document Server Url**, specify the URL of the installed ONLYOFFICE Docs or the address of ONLYOFFICE Docs Cloud.

**Document Server JWT Secret**: JWT is enabled by default and the secret key is generated automatically to restrict the access to ONLYOFFICE Docs. if you want to specify your own secret key in this field, also specify the same secret key in the ONLYOFFICE Docs `config file`_ to enable the validation.

**Document Server JWT Header**: Standard JWT header used in ONLYOFFICE is Authorization. In case this header is in conflict with your setup, you can change the header to the custom one.


.. image:: settings.png
:width: 800


Contact us
==========

If you have any questions or suggestions regarding the ONLYOFFICE app for Odoo, please let us know at https://forum.onlyoffice.com

.. _self-hosted version: https://www.onlyoffice.com/download-docs.aspx
.. _ONLYOFFICE Docs: https://www.onlyoffice.com/docs-registration.aspx
.. _config file: https://api.onlyoffice.com/editors/signature/
.. _main ONLYOFFICE app for Odoo: https://apps.odoo.com/apps/modules/16.0/onlyoffice_odoo/
Binary file added onlyoffice_odoo_documents/doc/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit fed128b

Please sign in to comment.