From 8885cfecf160d8bb97a5fa68854e56792a0dc41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Tue, 15 Mar 2022 15:06:13 +0100 Subject: [PATCH 01/17] [ADD] attachment_zipped_download: New addon. TT33403 [UPD] Update attachment_zipped_download.pot [UPD] README.rst --- attachment_zipped_download/README.rst | 84 ++++ attachment_zipped_download/__init__.py | 2 + attachment_zipped_download/__manifest__.py | 15 + .../controllers/__init__.py | 1 + .../controllers/main.py | 21 + .../i18n/attachment_zipped_download.pot | 51 +++ attachment_zipped_download/i18n/es.po | 55 +++ attachment_zipped_download/models/__init__.py | 1 + .../models/ir_attachment.py | 36 ++ .../readme/CONTRIBUTORS.rst | 6 + .../readme/DESCRIPTION.rst | 1 + attachment_zipped_download/readme/USAGE.rst | 2 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 432 ++++++++++++++++++ attachment_zipped_download/tests/__init__.py | 3 + .../tests/test_attachment_zipped_download.py | 35 ++ .../views/ir_attachment_view.xml | 13 + 17 files changed, 758 insertions(+) create mode 100644 attachment_zipped_download/README.rst create mode 100644 attachment_zipped_download/__init__.py create mode 100644 attachment_zipped_download/__manifest__.py create mode 100644 attachment_zipped_download/controllers/__init__.py create mode 100644 attachment_zipped_download/controllers/main.py create mode 100644 attachment_zipped_download/i18n/attachment_zipped_download.pot create mode 100644 attachment_zipped_download/i18n/es.po create mode 100644 attachment_zipped_download/models/__init__.py create mode 100644 attachment_zipped_download/models/ir_attachment.py create mode 100644 attachment_zipped_download/readme/CONTRIBUTORS.rst create mode 100644 attachment_zipped_download/readme/DESCRIPTION.rst create mode 100644 attachment_zipped_download/readme/USAGE.rst create mode 100644 attachment_zipped_download/static/description/icon.png create mode 100644 attachment_zipped_download/static/description/index.html create mode 100644 attachment_zipped_download/tests/__init__.py create mode 100644 attachment_zipped_download/tests/test_attachment_zipped_download.py create mode 100644 attachment_zipped_download/views/ir_attachment_view.xml diff --git a/attachment_zipped_download/README.rst b/attachment_zipped_download/README.rst new file mode 100644 index 00000000000..58bb48c4f38 --- /dev/null +++ b/attachment_zipped_download/README.rst @@ -0,0 +1,84 @@ +========================== +Attachment Zipped Download +========================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fknowledge-lightgray.png?logo=github + :target: https://github.com/OCA/knowledge/tree/14.0/attachment_zipped_download + :alt: OCA/knowledge +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/knowledge-14-0/knowledge-14-0-attachment_zipped_download + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/118/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows downloading multiple attachments as a zip file. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +#. Go to *Settings > Technical > Database Structure > Attachments* and select some files. +#. Go to *Actions > Download* and a zip file containing the selected files will be downloaded. + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* César Fernández Domínguez + +* `Tecnativa `_: + + * Víctor Martínez + * Pedro M. Baeza + +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/knowledge `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/attachment_zipped_download/__init__.py b/attachment_zipped_download/__init__.py new file mode 100644 index 00000000000..91c5580fed3 --- /dev/null +++ b/attachment_zipped_download/__init__.py @@ -0,0 +1,2 @@ +from . import controllers +from . import models diff --git a/attachment_zipped_download/__manifest__.py b/attachment_zipped_download/__manifest__.py new file mode 100644 index 00000000000..97b5f90fe07 --- /dev/null +++ b/attachment_zipped_download/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Attachment Zipped Download", + "version": "14.0.1.0.0", + "category": "Tools", + "website": "https://github.com/OCA/knowledge", + "author": "Tecnativa, Odoo Community Association (OCA)", + "license": "AGPL-3", + "depends": ["base"], + "data": [ + "views/ir_attachment_view.xml", + ], + "installable": True, +} diff --git a/attachment_zipped_download/controllers/__init__.py b/attachment_zipped_download/controllers/__init__.py new file mode 100644 index 00000000000..12a7e529b67 --- /dev/null +++ b/attachment_zipped_download/controllers/__init__.py @@ -0,0 +1 @@ +from . import main diff --git a/attachment_zipped_download/controllers/main.py b/attachment_zipped_download/controllers/main.py new file mode 100644 index 00000000000..f4b5f973a01 --- /dev/null +++ b/attachment_zipped_download/controllers/main.py @@ -0,0 +1,21 @@ +# Copyright 2019 César Fernández Domínguez +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +from odoo import _, http +from odoo.http import request + + +class AttachmentZippedDownloadController(http.Controller): + @http.route("/web/attachment/download_zip", type="http", auth="user") + def download_zip(self, ids=None, debug=0): + ids = [] if not ids else ids + if len(ids) == 0: + return + list_ids = map(int, ids.split(",")) + out_file = request.env["ir.attachment"].browse(list_ids)._create_temp_zip() + return http.send_file( + filepath_or_fp=out_file, + mimetype="application/zip", + as_attachment=True, + filename=_("attachments.zip"), + ) diff --git a/attachment_zipped_download/i18n/attachment_zipped_download.pot b/attachment_zipped_download/i18n/attachment_zipped_download.pot new file mode 100644 index 00000000000..89025db4009 --- /dev/null +++ b/attachment_zipped_download/i18n/attachment_zipped_download.pot @@ -0,0 +1,51 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_zipped_download +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: attachment_zipped_download +#: model:ir.model,name:attachment_zipped_download.model_ir_attachment +msgid "Attachment" +msgstr "" + +#. module: attachment_zipped_download +#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__display_name +msgid "Display Name" +msgstr "" + +#. module: attachment_zipped_download +#: model:ir.actions.server,name:attachment_zipped_download.action_attachments_download +msgid "Download" +msgstr "" + +#. module: attachment_zipped_download +#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__id +msgid "ID" +msgstr "" + +#. module: attachment_zipped_download +#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment____last_update +msgid "Last Modified on" +msgstr "" + +#. module: attachment_zipped_download +#: code:addons/attachment_zipped_download/models/ir_attachment.py:0 +#, python-format +msgid "None attachment selected. Only binary attachments allowed." +msgstr "" + +#. module: attachment_zipped_download +#: code:addons/attachment_zipped_download/controllers/main.py:0 +#, python-format +msgid "attachments.zip" +msgstr "" diff --git a/attachment_zipped_download/i18n/es.po b/attachment_zipped_download/i18n/es.po new file mode 100644 index 00000000000..bd6ee4c0d32 --- /dev/null +++ b/attachment_zipped_download/i18n/es.po @@ -0,0 +1,55 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_zipped_download +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-03-15 14:04+0000\n" +"PO-Revision-Date: 2022-03-15 15:05+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 2.3\n" + +#. module: attachment_zipped_download +#: model:ir.model,name:attachment_zipped_download.model_ir_attachment +msgid "Attachment" +msgstr "Adjunto" + +#. module: attachment_zipped_download +#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: attachment_zipped_download +#: model:ir.actions.server,name:attachment_zipped_download.action_attachments_download +msgid "Download" +msgstr "Descargar" + +#. module: attachment_zipped_download +#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__id +msgid "ID" +msgstr "ID" + +#. module: attachment_zipped_download +#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: attachment_zipped_download +#: code:addons/attachment_zipped_download/models/ir_attachment.py:0 +#, python-format +msgid "None attachment selected. Only binary attachments allowed." +msgstr "No se seleccionó ningún archivo adjunto. Solo se permiten archivos adjuntos binarios." + +#. module: attachment_zipped_download +#: code:addons/attachment_zipped_download/controllers/main.py:0 +#, python-format +msgid "attachments.zip" +msgstr "adjuntos.zip" diff --git a/attachment_zipped_download/models/__init__.py b/attachment_zipped_download/models/__init__.py new file mode 100644 index 00000000000..aaf38a167cd --- /dev/null +++ b/attachment_zipped_download/models/__init__.py @@ -0,0 +1 @@ +from . import ir_attachment diff --git a/attachment_zipped_download/models/ir_attachment.py b/attachment_zipped_download/models/ir_attachment.py new file mode 100644 index 00000000000..1f58adad0f7 --- /dev/null +++ b/attachment_zipped_download/models/ir_attachment.py @@ -0,0 +1,36 @@ +# Copyright 2019 César Fernández Domínguez +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) +import zipfile +from io import BytesIO + +from odoo import _, models +from odoo.exceptions import UserError + + +class IrAttachment(models.Model): + _inherit = "ir.attachment" + + def action_attachments_download(self): + items = self.filtered(lambda x: x.type == "binary") + if not items: + raise UserError( + _("None attachment selected. Only binary attachments allowed.") + ) + ids = ",".join(map(str, items.ids)) + return { + "type": "ir.actions.act_url", + "url": "/web/attachment/download_zip?ids=%s" % (ids), + "target": "self", + } + + def _create_temp_zip(self): + zip_buffer = BytesIO() + with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file: + for attachment in self: + zip_file.write( + attachment._full_path(attachment.store_fname), attachment.name + ) + zip_buffer.seek(0) + zip_file.close() + return zip_buffer diff --git a/attachment_zipped_download/readme/CONTRIBUTORS.rst b/attachment_zipped_download/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..536c589072d --- /dev/null +++ b/attachment_zipped_download/readme/CONTRIBUTORS.rst @@ -0,0 +1,6 @@ +* César Fernández Domínguez + +* `Tecnativa `_: + + * Víctor Martínez + * Pedro M. Baeza diff --git a/attachment_zipped_download/readme/DESCRIPTION.rst b/attachment_zipped_download/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..15f07dbb7a5 --- /dev/null +++ b/attachment_zipped_download/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows downloading multiple attachments as a zip file. diff --git a/attachment_zipped_download/readme/USAGE.rst b/attachment_zipped_download/readme/USAGE.rst new file mode 100644 index 00000000000..0acc421782a --- /dev/null +++ b/attachment_zipped_download/readme/USAGE.rst @@ -0,0 +1,2 @@ +#. Go to *Settings > Technical > Database Structure > Attachments* and select some files. +#. Go to *Actions > Download* and a zip file containing the selected files will be downloaded. diff --git a/attachment_zipped_download/static/description/icon.png b/attachment_zipped_download/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/attachment_zipped_download/static/description/index.html b/attachment_zipped_download/static/description/index.html new file mode 100644 index 00000000000..b302dc2a460 --- /dev/null +++ b/attachment_zipped_download/static/description/index.html @@ -0,0 +1,432 @@ + + + + + + +Attachment Zipped Download + + + +
+

Attachment Zipped Download

+ + +

Beta License: AGPL-3 OCA/knowledge Translate me on Weblate Try me on Runbot

+

This module allows downloading multiple attachments as a zip file.

+

Table of contents

+ +
+

Usage

+
    +
  1. Go to Settings > Technical > Database Structure > Attachments and select some files.
  2. +
  3. Go to Actions > Download and a zip file containing the selected files will be downloaded.
  4. +
+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

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

+

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

+
+
+
+ + diff --git a/attachment_zipped_download/tests/__init__.py b/attachment_zipped_download/tests/__init__.py new file mode 100644 index 00000000000..2654e07a6c8 --- /dev/null +++ b/attachment_zipped_download/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) + +from . import test_attachment_zipped_download diff --git a/attachment_zipped_download/tests/test_attachment_zipped_download.py b/attachment_zipped_download/tests/test_attachment_zipped_download.py new file mode 100644 index 00000000000..63799c8f880 --- /dev/null +++ b/attachment_zipped_download/tests/test_attachment_zipped_download.py @@ -0,0 +1,35 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import base64 + +import odoo.tests + + +class TestAttachmentZippedDownload(odoo.tests.HttpCase): + def setUp(self): + super().setUp() + test_1 = self._create_attachment("test1.txt") + test_2 = self._create_attachment("test2.txt") + self.attachments = test_1 + test_2 + self.user = self.env["res.users"].create( + { + "name": "test-user", + "login": "test-user", + "password": "test-user", + "groups_id": [(6, 0, [self.env.ref("base.group_user").id])], + } + ) + + def _create_attachment(self, name): + return self.env["ir.attachment"].create( + { + "name": name, + "datas": base64.b64encode(b"\xff data"), + } + ) + + def test_action_attachments_download(self): + self.authenticate("test-user", "test-user") + res = self.attachments.action_attachments_download() + response = self.url_open(res["url"], timeout=20) + self.assertEqual(response.status_code, 200) diff --git a/attachment_zipped_download/views/ir_attachment_view.xml b/attachment_zipped_download/views/ir_attachment_view.xml new file mode 100644 index 00000000000..4f4e2b1635c --- /dev/null +++ b/attachment_zipped_download/views/ir_attachment_view.xml @@ -0,0 +1,13 @@ + + + + Download + + + code + + if records: + action = records.action_attachments_download() + + + From f957b2e1b032f948cefe4264b060f1294b505070 Mon Sep 17 00:00:00 2001 From: FernandoRomera Date: Fri, 16 Dec 2022 11:26:14 +0100 Subject: [PATCH 02/17] [16.0][MIG] attachment_zipped_download: Migration to 16.0 [UPD] Update attachment_zipped_download.pot [UPD] README.rst Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: knowledge-16.0/knowledge-16.0-attachment_zipped_download Translate-URL: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-attachment_zipped_download/ --- attachment_zipped_download/README.rst | 10 +++---- attachment_zipped_download/__manifest__.py | 2 +- .../controllers/main.py | 4 ++- .../i18n/attachment_zipped_download.pot | 19 ++---------- attachment_zipped_download/i18n/es.po | 30 +++++++++---------- .../static/description/index.html | 6 ++-- .../tests/test_attachment_zipped_download.py | 3 +- 7 files changed, 31 insertions(+), 43 deletions(-) diff --git a/attachment_zipped_download/README.rst b/attachment_zipped_download/README.rst index 58bb48c4f38..b20ddf09c3c 100644 --- a/attachment_zipped_download/README.rst +++ b/attachment_zipped_download/README.rst @@ -14,13 +14,13 @@ Attachment Zipped Download :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fknowledge-lightgray.png?logo=github - :target: https://github.com/OCA/knowledge/tree/14.0/attachment_zipped_download + :target: https://github.com/OCA/knowledge/tree/16.0/attachment_zipped_download :alt: OCA/knowledge .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/knowledge-14-0/knowledge-14-0-attachment_zipped_download + :target: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-attachment_zipped_download :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/118/14.0 + :target: https://runbot.odoo-community.org/runbot/118/16.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -44,7 +44,7 @@ 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 smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -79,6 +79,6 @@ 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/knowledge `_ project on GitHub. +This module is part of the `OCA/knowledge `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/attachment_zipped_download/__manifest__.py b/attachment_zipped_download/__manifest__.py index 97b5f90fe07..df4b7908b56 100644 --- a/attachment_zipped_download/__manifest__.py +++ b/attachment_zipped_download/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Attachment Zipped Download", - "version": "14.0.1.0.0", + "version": "16.0.1.0.0", "category": "Tools", "website": "https://github.com/OCA/knowledge", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/attachment_zipped_download/controllers/main.py b/attachment_zipped_download/controllers/main.py index f4b5f973a01..fe9a4fd2dd1 100644 --- a/attachment_zipped_download/controllers/main.py +++ b/attachment_zipped_download/controllers/main.py @@ -12,7 +12,9 @@ def download_zip(self, ids=None, debug=0): if len(ids) == 0: return list_ids = map(int, ids.split(",")) - out_file = request.env["ir.attachment"].browse(list_ids)._create_temp_zip() + out_file = ( + request.env["ir.attachment"].sudo().browse(list_ids)._create_temp_zip() + ) return http.send_file( filepath_or_fp=out_file, mimetype="application/zip", diff --git a/attachment_zipped_download/i18n/attachment_zipped_download.pot b/attachment_zipped_download/i18n/attachment_zipped_download.pot index 89025db4009..7cd8b6de2a1 100644 --- a/attachment_zipped_download/i18n/attachment_zipped_download.pot +++ b/attachment_zipped_download/i18n/attachment_zipped_download.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -18,33 +18,20 @@ msgstr "" msgid "Attachment" msgstr "" -#. module: attachment_zipped_download -#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__display_name -msgid "Display Name" -msgstr "" - #. module: attachment_zipped_download #: model:ir.actions.server,name:attachment_zipped_download.action_attachments_download msgid "Download" msgstr "" #. module: attachment_zipped_download -#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__id -msgid "ID" -msgstr "" - -#. module: attachment_zipped_download -#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment____last_update -msgid "Last Modified on" -msgstr "" - -#. module: attachment_zipped_download +#. odoo-python #: code:addons/attachment_zipped_download/models/ir_attachment.py:0 #, python-format msgid "None attachment selected. Only binary attachments allowed." msgstr "" #. module: attachment_zipped_download +#. odoo-python #: code:addons/attachment_zipped_download/controllers/main.py:0 #, python-format msgid "attachments.zip" diff --git a/attachment_zipped_download/i18n/es.po b/attachment_zipped_download/i18n/es.po index bd6ee4c0d32..840609d9b3e 100644 --- a/attachment_zipped_download/i18n/es.po +++ b/attachment_zipped_download/i18n/es.po @@ -22,34 +22,32 @@ msgstr "" msgid "Attachment" msgstr "Adjunto" -#. module: attachment_zipped_download -#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__display_name -msgid "Display Name" -msgstr "Nombre mostrado" - #. module: attachment_zipped_download #: model:ir.actions.server,name:attachment_zipped_download.action_attachments_download msgid "Download" msgstr "Descargar" #. module: attachment_zipped_download -#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment__id -msgid "ID" -msgstr "ID" - -#. module: attachment_zipped_download -#: model:ir.model.fields,field_description:attachment_zipped_download.field_ir_attachment____last_update -msgid "Last Modified on" -msgstr "Última modificación el" - -#. module: attachment_zipped_download +#. odoo-python #: code:addons/attachment_zipped_download/models/ir_attachment.py:0 #, python-format msgid "None attachment selected. Only binary attachments allowed." -msgstr "No se seleccionó ningún archivo adjunto. Solo se permiten archivos adjuntos binarios." +msgstr "" +"No se seleccionó ningún archivo adjunto. Solo se permiten archivos adjuntos " +"binarios." #. module: attachment_zipped_download +#. odoo-python #: code:addons/attachment_zipped_download/controllers/main.py:0 #, python-format msgid "attachments.zip" msgstr "adjuntos.zip" + +#~ msgid "Display Name" +#~ msgstr "Nombre mostrado" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Última modificación el" diff --git a/attachment_zipped_download/static/description/index.html b/attachment_zipped_download/static/description/index.html index b302dc2a460..c4c17d872ff 100644 --- a/attachment_zipped_download/static/description/index.html +++ b/attachment_zipped_download/static/description/index.html @@ -367,7 +367,7 @@

Attachment Zipped Download

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/knowledge Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/knowledge Translate me on Weblate Try me on Runbot

This module allows downloading multiple attachments as a zip file.

Table of contents

@@ -394,7 +394,7 @@

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 smashing it by providing a detailed and welcomed -feedback.

+feedback.

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

@@ -423,7 +423,7 @@

Maintainers

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

+

This module is part of the OCA/knowledge project on GitHub.

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

diff --git a/attachment_zipped_download/tests/test_attachment_zipped_download.py b/attachment_zipped_download/tests/test_attachment_zipped_download.py index 63799c8f880..c6b8ef90d61 100644 --- a/attachment_zipped_download/tests/test_attachment_zipped_download.py +++ b/attachment_zipped_download/tests/test_attachment_zipped_download.py @@ -30,6 +30,7 @@ def _create_attachment(self, name): def test_action_attachments_download(self): self.authenticate("test-user", "test-user") - res = self.attachments.action_attachments_download() + # 16.0 WARNING odoo odoo.http: Sorry, you are not allowed to access this document. + res = self.attachments.sudo().action_attachments_download() response = self.url_open(res["url"], timeout=20) self.assertEqual(response.status_code, 200) From f5fa38924584b222755aadd34971495ec0a1ce5f Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 28 Dec 2022 20:15:34 +0000 Subject: [PATCH 03/17] Added translation using Weblate (Italian) Translated using Weblate (Italian) Currently translated at 100.0% (4 of 4 strings) Translation: knowledge-16.0/knowledge-16.0-attachment_zipped_download Translate-URL: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-attachment_zipped_download/it/ --- attachment_zipped_download/i18n/it.po | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 attachment_zipped_download/i18n/it.po diff --git a/attachment_zipped_download/i18n/it.po b/attachment_zipped_download/i18n/it.po new file mode 100644 index 00000000000..61869f42a09 --- /dev/null +++ b/attachment_zipped_download/i18n/it.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_zipped_download +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-12-28 21:46+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: attachment_zipped_download +#: model:ir.model,name:attachment_zipped_download.model_ir_attachment +msgid "Attachment" +msgstr "Allegati" + +#. module: attachment_zipped_download +#: model:ir.actions.server,name:attachment_zipped_download.action_attachments_download +msgid "Download" +msgstr "Scarica" + +#. module: attachment_zipped_download +#. odoo-python +#: code:addons/attachment_zipped_download/models/ir_attachment.py:0 +#, python-format +msgid "None attachment selected. Only binary attachments allowed." +msgstr "Nessun allegato selezionato. Consentiti solo allegati binari." + +#. module: attachment_zipped_download +#. odoo-python +#: code:addons/attachment_zipped_download/controllers/main.py:0 +#, python-format +msgid "attachments.zip" +msgstr "attachments.zip" From c565c586847ee797d9e45520e05c7838df1506c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?= Date: Tue, 24 Jan 2023 13:28:59 +0100 Subject: [PATCH 04/17] [FIX] attachment_zipped_download: Fix tests attachment_zipped_download 16.0.1.0.1 --- attachment_zipped_download/__manifest__.py | 2 +- .../controllers/main.py | 4 +- .../tests/test_attachment_zipped_download.py | 45 +++++++++++-------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/attachment_zipped_download/__manifest__.py b/attachment_zipped_download/__manifest__.py index df4b7908b56..ab7a08db8ea 100644 --- a/attachment_zipped_download/__manifest__.py +++ b/attachment_zipped_download/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Attachment Zipped Download", - "version": "16.0.1.0.0", + "version": "16.0.1.0.1", "category": "Tools", "website": "https://github.com/OCA/knowledge", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/attachment_zipped_download/controllers/main.py b/attachment_zipped_download/controllers/main.py index fe9a4fd2dd1..f4b5f973a01 100644 --- a/attachment_zipped_download/controllers/main.py +++ b/attachment_zipped_download/controllers/main.py @@ -12,9 +12,7 @@ def download_zip(self, ids=None, debug=0): if len(ids) == 0: return list_ids = map(int, ids.split(",")) - out_file = ( - request.env["ir.attachment"].sudo().browse(list_ids)._create_temp_zip() - ) + out_file = request.env["ir.attachment"].browse(list_ids)._create_temp_zip() return http.send_file( filepath_or_fp=out_file, mimetype="application/zip", diff --git a/attachment_zipped_download/tests/test_attachment_zipped_download.py b/attachment_zipped_download/tests/test_attachment_zipped_download.py index c6b8ef90d61..84a8910e13c 100644 --- a/attachment_zipped_download/tests/test_attachment_zipped_download.py +++ b/attachment_zipped_download/tests/test_attachment_zipped_download.py @@ -1,36 +1,43 @@ -# Copyright 2022 Tecnativa - Víctor Martínez +# Copyright 2022-2023 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import base64 import odoo.tests +from odoo.tests import new_test_user class TestAttachmentZippedDownload(odoo.tests.HttpCase): def setUp(self): super().setUp() - test_1 = self._create_attachment("test1.txt") - test_2 = self._create_attachment("test2.txt") - self.attachments = test_1 + test_2 - self.user = self.env["res.users"].create( - { - "name": "test-user", - "login": "test-user", - "password": "test-user", - "groups_id": [(6, 0, [self.env.ref("base.group_user").id])], - } + ctx = { + "mail_create_nolog": True, + "mail_create_nosubscribe": True, + "mail_notrack": True, + "no_reset_password": True, + } + self.user = new_test_user( + self.env, + login="test-user", + context=ctx, ) + test_1 = self._create_attachment(self.user, "test1.txt") + test_2 = self._create_attachment(self.user, "test2.txt") + self.attachments = test_1 + test_2 - def _create_attachment(self, name): - return self.env["ir.attachment"].create( - { - "name": name, - "datas": base64.b64encode(b"\xff data"), - } + def _create_attachment(self, user, name): + return ( + self.env["ir.attachment"] + .with_user(user) + .create( + { + "name": name, + "datas": base64.b64encode(b"\xff data"), + } + ) ) def test_action_attachments_download(self): self.authenticate("test-user", "test-user") - # 16.0 WARNING odoo odoo.http: Sorry, you are not allowed to access this document. - res = self.attachments.sudo().action_attachments_download() + res = self.attachments.action_attachments_download() response = self.url_open(res["url"], timeout=20) self.assertEqual(response.status_code, 200) From b36c91caae1ec62496df74bbfbd8f9b031145269 Mon Sep 17 00:00:00 2001 From: Francesco Foresti Date: Mon, 30 Jan 2023 17:23:44 +0000 Subject: [PATCH 05/17] Translated using Weblate (Italian) Currently translated at 100.0% (4 of 4 strings) Translation: knowledge-16.0/knowledge-16.0-attachment_zipped_download Translate-URL: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-attachment_zipped_download/it/ --- attachment_zipped_download/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/attachment_zipped_download/i18n/it.po b/attachment_zipped_download/i18n/it.po index 61869f42a09..6b4ad299984 100644 --- a/attachment_zipped_download/i18n/it.po +++ b/attachment_zipped_download/i18n/it.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2022-12-28 21:46+0000\n" -"Last-Translator: mymage \n" +"PO-Revision-Date: 2023-01-30 19:47+0000\n" +"Last-Translator: Francesco Foresti \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" @@ -19,7 +19,7 @@ msgstr "" #. module: attachment_zipped_download #: model:ir.model,name:attachment_zipped_download.model_ir_attachment msgid "Attachment" -msgstr "Allegati" +msgstr "Allegato" #. module: attachment_zipped_download #: model:ir.actions.server,name:attachment_zipped_download.action_attachments_download From a99bc0dde18284e32e53b5db295ba685b34bc509 Mon Sep 17 00:00:00 2001 From: Bole Date: Wed, 15 Feb 2023 18:34:11 +0000 Subject: [PATCH 06/17] Added translation using Weblate (Croatian) Translated using Weblate (Croatian) Currently translated at 100.0% (4 of 4 strings) Translation: knowledge-16.0/knowledge-16.0-attachment_zipped_download Translate-URL: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-attachment_zipped_download/hr/ --- attachment_zipped_download/i18n/hr.po | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 attachment_zipped_download/i18n/hr.po diff --git a/attachment_zipped_download/i18n/hr.po b/attachment_zipped_download/i18n/hr.po new file mode 100644 index 00000000000..e835301e67e --- /dev/null +++ b/attachment_zipped_download/i18n/hr.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * attachment_zipped_download +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-02-15 21:23+0000\n" +"Last-Translator: Bole \n" +"Language-Team: none\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: attachment_zipped_download +#: model:ir.model,name:attachment_zipped_download.model_ir_attachment +msgid "Attachment" +msgstr "Prilog" + +#. module: attachment_zipped_download +#: model:ir.actions.server,name:attachment_zipped_download.action_attachments_download +msgid "Download" +msgstr "Preuzimanje" + +#. module: attachment_zipped_download +#. odoo-python +#: code:addons/attachment_zipped_download/models/ir_attachment.py:0 +#, python-format +msgid "None attachment selected. Only binary attachments allowed." +msgstr "Nema odabranih priloga. Samo binarni prilozi su dozvoljeni." + +#. module: attachment_zipped_download +#. odoo-python +#: code:addons/attachment_zipped_download/controllers/main.py:0 +#, python-format +msgid "attachments.zip" +msgstr "attachments.zip" From 25ceed43770402bc01819d849946b5bb2c324f07 Mon Sep 17 00:00:00 2001 From: Pierre Verkest Date: Fri, 28 Apr 2023 13:51:35 +0200 Subject: [PATCH 07/17] [FIX] attachment_zipped_download: zip allowed document only The previous code allowed any authenticated to retreive any attachment present on odoo filesystem. So a WMS user could technically spoken download a zip with accounting documents. This implementation is calling attachemnt.check("read") to ensure access right and use attachemnt.raw attribute to retreive file to archive which (not test) should works with attachment saved somewhere else than the local filesystem (s3 storage, pgsql large object storage...). attachment_zipped_download 16.0.1.0.2 --- attachment_zipped_download/__manifest__.py | 2 +- .../models/ir_attachment.py | 11 ++- .../tests/test_attachment_zipped_download.py | 84 +++++++++++++++---- 3 files changed, 77 insertions(+), 20 deletions(-) diff --git a/attachment_zipped_download/__manifest__.py b/attachment_zipped_download/__manifest__.py index ab7a08db8ea..209dc5e5fa3 100644 --- a/attachment_zipped_download/__manifest__.py +++ b/attachment_zipped_download/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Attachment Zipped Download", - "version": "16.0.1.0.1", + "version": "16.0.1.0.2", "category": "Tools", "website": "https://github.com/OCA/knowledge", "author": "Tecnativa, Odoo Community Association (OCA)", diff --git a/attachment_zipped_download/models/ir_attachment.py b/attachment_zipped_download/models/ir_attachment.py index 1f58adad0f7..f91d8588a89 100644 --- a/attachment_zipped_download/models/ir_attachment.py +++ b/attachment_zipped_download/models/ir_attachment.py @@ -28,9 +28,16 @@ def _create_temp_zip(self): zip_buffer = BytesIO() with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file: for attachment in self: - zip_file.write( - attachment._full_path(attachment.store_fname), attachment.name + attachment.check("read") + zip_file.writestr( + attachment._compute_zip_file_name(), + attachment.raw, ) zip_buffer.seek(0) zip_file.close() return zip_buffer + + def _compute_zip_file_name(self): + """Give a chance of easily changing the name of the file inside the ZIP.""" + self.ensure_one() + return self.name diff --git a/attachment_zipped_download/tests/test_attachment_zipped_download.py b/attachment_zipped_download/tests/test_attachment_zipped_download.py index 84a8910e13c..1422905eee3 100644 --- a/attachment_zipped_download/tests/test_attachment_zipped_download.py +++ b/attachment_zipped_download/tests/test_attachment_zipped_download.py @@ -1,12 +1,30 @@ # Copyright 2022-2023 Tecnativa - Víctor Martínez # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import base64 +from unittest import TestCase -import odoo.tests -from odoo.tests import new_test_user +from odoo.exceptions import AccessError +from odoo.tests import HttpCase, SavepointCase, new_test_user -class TestAttachmentZippedDownload(odoo.tests.HttpCase): +class TestAttachmentZippedDownloadBase(TestCase): + @classmethod + def _create_attachment(cls, env, user, name, model=False, res_id=False): + return ( + env["ir.attachment"] + .with_user(user) + .create( + { + "name": name, + "datas": base64.b64encode(b"\xff data"), + "res_model": model, + "res_id": res_id, + } + ) + ) + + +class TestAttachmentZippedDownload(HttpCase, TestAttachmentZippedDownloadBase): def setUp(self): super().setUp() ctx = { @@ -20,24 +38,56 @@ def setUp(self): login="test-user", context=ctx, ) - test_1 = self._create_attachment(self.user, "test1.txt") - test_2 = self._create_attachment(self.user, "test2.txt") + test_1 = self._create_attachment(self.env, self.user, "test1.txt") + test_2 = self._create_attachment(self.env, self.user, "test2.txt") self.attachments = test_1 + test_2 - def _create_attachment(self, user, name): - return ( - self.env["ir.attachment"] - .with_user(user) - .create( - { - "name": name, - "datas": base64.b64encode(b"\xff data"), - } - ) - ) - def test_action_attachments_download(self): self.authenticate("test-user", "test-user") res = self.attachments.action_attachments_download() response = self.url_open(res["url"], timeout=20) self.assertEqual(response.status_code, 200) + + +class TestAttachmentZipped(SavepointCase, TestAttachmentZippedDownloadBase): + @classmethod + def setUpClass(cls): + super().setUpClass() + ctx = { + "mail_create_nolog": True, + "mail_create_nosubscribe": True, + "mail_notrack": True, + "no_reset_password": True, + } + cls.user = new_test_user( + cls.env, + login="test-user", + password="test-user", + groups="base.group_user,base.group_partner_manager", + context=ctx, + ) + test_1 = cls._create_attachment(cls.env, cls.user, "test1.txt") + test_2 = cls._create_attachment(cls.env, cls.user, "test2.txt") + test_3 = cls._create_attachment( + cls.env, + cls.user, + "test3.txt", + model="res.partner", + res_id=cls.user.partner_id.id, + ) + cls.attachments = test_1 + test_2 + test_3 + + def test_create_temp_zip(self): + res = self.attachments._create_temp_zip() + self.assertTrue(res) + + def test_create_temp_zip_access_denined(self): + attachments = self.attachments | self._create_attachment( + self.env, + self.uid, + "test4.txt", + model="ir.ui.view", + res_id=self.env.ref("base.view_view_form").id, + ) + with self.assertRaises(AccessError): + attachments._create_temp_zip() From e267b0b836477a3153cc09943aa0cfc12e8722ce Mon Sep 17 00:00:00 2001 From: Pierre Verkest Date: Fri, 28 Apr 2023 16:13:20 +0200 Subject: [PATCH 08/17] [IMP] attachment_zipped_download: provide ir.attachment.action_download mixin This helps to download multiple attachments from any models. [UPD] README.rst [UPD] Update attachment_zipped_download.pot [UPD] README.rst attachment_zipped_download 16.0.2.0.0 [UPD] README.rst Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: knowledge-16.0/knowledge-16.0-attachment_zipped_download Translate-URL: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-attachment_zipped_download/ --- attachment_zipped_download/README.rst | 96 ++++++++++++++- attachment_zipped_download/__manifest__.py | 2 +- .../i18n/attachment_zipped_download.pot | 22 ++++ attachment_zipped_download/i18n/es.po | 22 ++++ attachment_zipped_download/i18n/fr.po | 78 ++++++++++++ attachment_zipped_download/i18n/hr.po | 22 ++++ attachment_zipped_download/i18n/it.po | 31 +++++ attachment_zipped_download/models/__init__.py | 1 + .../models/ir_attachment_action_download.py | 55 +++++++++ .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 3 + attachment_zipped_download/readme/USAGE.rst | 76 ++++++++++++ .../static/description/index.html | 115 +++++++++++++++--- attachment_zipped_download/tests/__init__.py | 1 + .../tests/models/__init__.py | 0 .../tests/models/res_partner.py | 9 ++ .../test_ir_attachment_action_download.py | 81 ++++++++++++ 17 files changed, 591 insertions(+), 25 deletions(-) create mode 100644 attachment_zipped_download/i18n/fr.po create mode 100644 attachment_zipped_download/models/ir_attachment_action_download.py create mode 100644 attachment_zipped_download/tests/models/__init__.py create mode 100644 attachment_zipped_download/tests/models/res_partner.py create mode 100644 attachment_zipped_download/tests/test_ir_attachment_action_download.py diff --git a/attachment_zipped_download/README.rst b/attachment_zipped_download/README.rst index b20ddf09c3c..80f2bf69fda 100644 --- a/attachment_zipped_download/README.rst +++ b/attachment_zipped_download/README.rst @@ -2,10 +2,13 @@ Attachment Zipped Download ========================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ff7e96407afd1498d4d7a92046727ac078de41e9e3789dcbe61c469b4b13ae67 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,14 +22,17 @@ Attachment Zipped Download .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-attachment_zipped_download :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/118/16.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/knowledge&target_branch=16.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module allows downloading multiple attachments as a zip file. +This also provide a helper class `IrAttachmentActionDownloadMixin` +to be used by developer to add action method on models. + **Table of contents** .. contents:: @@ -38,12 +44,88 @@ Usage #. Go to *Settings > Technical > Database Structure > Attachments* and select some files. #. Go to *Actions > Download* and a zip file containing the selected files will be downloaded. +## For developer + +You can reuse the `IrAttachmentActionDownloadMixin` on your +favorite models:: + + from odoo import models + + + class StockPicking(models.Model): + _name = "stock.picking" + _inherit = ["stock.picking", "ir.attachment.action_download"] + + +Then you can add an action button on list view line or on the action button +(when multiple lines are selected) to download all files:: + + + + + + stock.picking.tree download attachments + stock.picking + + +