Browse Source

publish muk_attachment_lobject - 12.0

pull/30/head
MuK IT GmbH 5 years ago
parent
commit
70bc88fcb5
  1. 2
      muk_attachment_lobject/LICENSE
  2. 41
      muk_attachment_lobject/README.rst
  3. 25
      muk_attachment_lobject/__init__.py
  4. 35
      muk_attachment_lobject/__manifest__.py
  5. 41
      muk_attachment_lobject/doc/index.rst
  6. 1
      muk_attachment_lobject/i18n/ar.po
  7. 1
      muk_attachment_lobject/i18n/de.po
  8. 1
      muk_attachment_lobject/i18n/es.po
  9. 1
      muk_attachment_lobject/i18n/fr.po
  10. 1
      muk_attachment_lobject/i18n/hi.po
  11. 1
      muk_attachment_lobject/i18n/muk_attachment_lobject.pot
  12. 1
      muk_attachment_lobject/i18n/nl.po
  13. 1
      muk_attachment_lobject/i18n/pt.po
  14. 1
      muk_attachment_lobject/i18n/ru.po
  15. 2
      muk_attachment_lobject/models/__init__.py
  16. 121
      muk_attachment_lobject/models/ir_attachment.py
  17. 2
      muk_attachment_lobject/static/description/icon.svg
  18. 313
      muk_attachment_lobject/static/description/index.html
  19. 5
      muk_attachment_lobject/tests/__init__.py
  20. 46
      muk_attachment_lobject/tests/test_attachment.py
  21. 59
      muk_attachment_lobject/tests/test_download.py
  22. 4
      muk_attachment_lobject/views/ir_attachment.xml

2
muk_attachment_lobject/LICENSE

@ -162,4 +162,4 @@ General Public License ever published by the Free Software Foundation.
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
Library.

41
muk_attachment_lobject/README.rst

@ -1,6 +1,6 @@
===================================
MuK Large Object Attachment Storage
===================================
============================
MuK Large Objects Attachment
============================
Provides a new attachment location to save attachments as PostgreSQL large objects.
To enable the large object storage option change the `ir_attachment.location`
@ -17,7 +17,6 @@ parameter to `lobject`.
* They work out of the box in multi-system setups (So there is no need for NFS or similar file sharing tools.)
* Enables you to easily create backups of the entire system
Installation
============
@ -33,24 +32,24 @@ Another way to install this module is via the package management for Python
To install our modules using the package manager make sure
`odoo-autodiscover <https://pypi.org/project/odoo-autodiscover/>`_ is installed
correctly. Then open a console and install the module by entering the following
command:
correctly. Note that for Odoo version 11.0 and later this is not necessary anymore.
Then open a console and install the module by entering the following command:
``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
The module name consists of the Odoo version and the module name, where
underscores are replaced by a dash.
**Module:**
**Module:**
``odoo<version>-addon-<module_name>``
**Example:**
``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo13-addon-muk-utils``
Once the installation has been successfully completed, the app is already in the
correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
debug mode and update the list by clicking on the "Update Apps List" link. Now
install the module by clicking on the install button.
@ -59,17 +58,16 @@ using the "pip" command. To do this, enter the following command in your console
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
When the process is finished, restart your server and update the application in
Odoo. The steps are the same as for the installation only the button has changed
from "Install" to "Upgrade".
You can also view available Apps directly in our `repository <https://nexus.mukit.at/#browse/browse:odoo>`_
and find a more detailed installation guide on our `website <https://mukit.at/page/open-source>`_.
For modules licensed under OPL-1, you will receive access data when you purchase
the module. If the modules were not purchased directly from
`MuK IT <https://www.mukit.at/>`_ please contact our support (support@mukit.at)
with a confirmation of purchase to receive the corresponding access data.
For modules licensed under a proprietary license, you will receive the access data after you purchased
the module. If the purchase were made at the Odoo store please contact our `support <support@mukit.at>`_
with a confirmation of the purchase to receive the corresponding access data.
Upgrade
============
@ -85,9 +83,10 @@ module in the same way. Just type the following command into the console:
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
When the process is finished, restart your server and update the application in
Odoo, just like you would normally.
Configuration
=============
@ -96,13 +95,13 @@ large objects. To activate this hook the config parameter `auto_storage_migratio
has to be set to `true`.
Usage
=============
=====
This module has no direct visible effect on the system. However, existing and
future attachments are stored as large objects.
Credits
=======
Credit
======
Contributors
------------
@ -110,7 +109,7 @@ Contributors
* Mathias Markl <mathias.markl@mukit.at>
Images
------------
------
Some pictures are based on or inspired by the icon set of Font Awesome:
@ -125,5 +124,5 @@ MuK IT is an Austrian company specialized in customizing and extending Odoo.
We develop custom solutions for your individual needs to help you focus on
your strength and expertise to grow your business.
If you want to get in touch please contact us via mail
(sale@mukit.at) or visit our website (https://mukit.at).
If you want to get in touch please contact us via `mail <sale@mukit.at>`_
or visit our `website <https://mukit.at>`_.

25
muk_attachment_lobject/__init__.py

@ -2,7 +2,7 @@
#
# Copyright (c) 2017-2019 MuK IT GmbH.
#
# This file is part of MuK Large Objects Attachment
# This file is part of MuK Large Objects Attachment
# (see https://mukit.at).
#
# This program is free software: you can redistribute it and/or modify
@ -20,23 +20,24 @@
#
###################################################################################
from odoo import api, SUPERUSER_ID
from odoo import SUPERUSER_ID, api
from odoo.tools import config
from . import models
def _install_force_storage(cr, registry):
if config.get("auto_storage_migration", False):
env = api.Environment(cr, SUPERUSER_ID, {})
params = env['ir.config_parameter'].sudo()
params.set_param('ir_attachment.location', 'lobject')
attachment = env['ir.attachment'].sudo().force_storage()
params = env["ir.config_parameter"].sudo()
params.set_param("ir_attachment.location", "lobject")
env["ir.attachment"].sudo().force_storage()
def _uninstall_force_storage(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
params = env['ir.config_parameter'].sudo()
location = params.get_param('ir_attachment.location')
if location == 'lobject':
params.set_param('ir_attachment.location', 'file')
attachment = env['ir.attachment'].sudo().force_storage()
params = env["ir.config_parameter"].sudo()
location = params.get_param("ir_attachment.location")
if location == "lobject":
params.set_param("ir_attachment.location", "file")
env["ir.attachment"].sudo().force_storage()

35
muk_attachment_lobject/__manifest__.py

@ -2,7 +2,7 @@
#
# Copyright (c) 2017-2019 MuK IT GmbH.
#
# This file is part of MuK Large Objects Attachment
# This file is part of MuK Large Objects Attachment
# (see https://mukit.at).
#
# This program is free software: you can redistribute it and/or modify
@ -19,38 +19,23 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###################################################################################
{
"name": "MuK Large Objects Attachment",
"summary": """Large Objects Attachment Location""",
"version": '12.0.3.0.2',
"category": 'Extra Tools',
"version": "13.0.1.0.0",
"category": "Extra Tools",
"license": "LGPL-3",
"website": "http://www.mukit.at",
'live_test_url': 'https://mukit.at/r/SgN',
"live_test_url": "https://mukit.at/r/SgN",
"author": "MuK IT",
"contributors": [
"Mathias Markl <mathias.markl@mukit.at>",
],
'depends': [
'muk_fields_lobject',
],
"data": [
"views/ir_attachment.xml",
],
"qweb": [
"static/src/xml/*.xml",
],
"images": [
'static/description/banner.png'
],
"external_dependencies": {
"python": [],
"bin": [],
},
"contributors": ["Mathias Markl <mathias.markl@mukit.at>"],
"depends": ["muk_fields_lobject"],
"data": ["views/ir_attachment.xml"],
"images": ["static/description/banner.png"],
"application": False,
"installable": True,
"auto_install": False,
"post_init_hook": "_install_force_storage",
"uninstall_hook": "_uninstall_force_storage",
}
}

41
muk_attachment_lobject/doc/index.rst

@ -1,6 +1,6 @@
===================================
MuK Large Object Attachment Storage
===================================
============================
MuK Large Objects Attachment
============================
Provides a new attachment location to save attachments as PostgreSQL large objects.
To enable the large object storage option change the `ir_attachment.location`
@ -17,7 +17,6 @@ parameter to `lobject`.
* They work out of the box in multi-system setups (So there is no need for NFS or similar file sharing tools.)
* Enables you to easily create backups of the entire system
Installation
============
@ -33,24 +32,24 @@ Another way to install this module is via the package management for Python
To install our modules using the package manager make sure
`odoo-autodiscover <https://pypi.org/project/odoo-autodiscover/>`_ is installed
correctly. Then open a console and install the module by entering the following
command:
correctly. Note that for Odoo version 11.0 and later this is not necessary anymore.
Then open a console and install the module by entering the following command:
``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
The module name consists of the Odoo version and the module name, where
underscores are replaced by a dash.
**Module:**
**Module:**
``odoo<version>-addon-<module_name>``
**Example:**
``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo13-addon-muk-utils``
Once the installation has been successfully completed, the app is already in the
correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
debug mode and update the list by clicking on the "Update Apps List" link. Now
install the module by clicking on the install button.
@ -59,17 +58,16 @@ using the "pip" command. To do this, enter the following command in your console
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
When the process is finished, restart your server and update the application in
Odoo. The steps are the same as for the installation only the button has changed
from "Install" to "Upgrade".
You can also view available Apps directly in our `repository <https://nexus.mukit.at/#browse/browse:odoo>`_
and find a more detailed installation guide on our `website <https://mukit.at/page/open-source>`_.
For modules licensed under OPL-1, you will receive access data when you purchase
the module. If the modules were not purchased directly from
`MuK IT <https://www.mukit.at/>`_ please contact our support (support@mukit.at)
with a confirmation of purchase to receive the corresponding access data.
For modules licensed under a proprietary license, you will receive the access data after you purchased
the module. If the purchase were made at the Odoo store please contact our `support <support@mukit.at>`_
with a confirmation of the purchase to receive the corresponding access data.
Upgrade
============
@ -85,9 +83,10 @@ module in the same way. Just type the following command into the console:
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
When the process is finished, restart your server and update the application in
Odoo, just like you would normally.
Configuration
=============
@ -96,13 +95,13 @@ large objects. To activate this hook the config parameter `auto_storage_migratio
has to be set to `true`.
Usage
=============
=====
This module has no direct visible effect on the system. However, existing and
future attachments are stored as large objects.
Credits
=======
Credit
======
Contributors
------------
@ -110,7 +109,7 @@ Contributors
* Mathias Markl <mathias.markl@mukit.at>
Images
------------
------
Some pictures are based on or inspired by the icon set of Font Awesome:
@ -125,5 +124,5 @@ MuK IT is an Austrian company specialized in customizing and extending Odoo.
We develop custom solutions for your individual needs to help you focus on
your strength and expertise to grow your business.
If you want to get in touch please contact us via mail
(sale@mukit.at) or visit our website (https://mukit.at).
If you want to get in touch please contact us via `mail <sale@mukit.at>`_
or visit our `website <https://mukit.at>`_.

1
muk_attachment_lobject/i18n/ar.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

1
muk_attachment_lobject/i18n/de.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr "Speicher"

1
muk_attachment_lobject/i18n/es.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

1
muk_attachment_lobject/i18n/fr.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

1
muk_attachment_lobject/i18n/hi.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

1
muk_attachment_lobject/i18n/muk_attachment_lobject.pot

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

1
muk_attachment_lobject/i18n/nl.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

1
muk_attachment_lobject/i18n/pt.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

1
muk_attachment_lobject/i18n/ru.po

@ -35,4 +35,3 @@ msgstr ""
#: model_terms:ir.ui.view,arch_db:muk_attachment_lobject.view_attachment_form
msgid "Storage"
msgstr ""

2
muk_attachment_lobject/models/__init__.py

@ -2,7 +2,7 @@
#
# Copyright (c) 2017-2019 MuK IT GmbH.
#
# This file is part of MuK Large Objects Attachment
# This file is part of MuK Large Objects Attachment
# (see https://mukit.at).
#
# This program is free software: you can redistribute it and/or modify

121
muk_attachment_lobject/models/ir_attachment.py

@ -2,7 +2,7 @@
#
# Copyright (c) 2017-2019 MuK IT GmbH.
#
# This file is part of MuK Large Objects Attachment
# This file is part of MuK Large Objects Attachment
# (see https://mukit.at).
#
# This program is free software: you can redistribute it and/or modify
@ -22,96 +22,77 @@
import base64
import logging
import mimetypes
from odoo import api, models, _
from odoo.exceptions import AccessError
from odoo import api, models
from odoo.addons.muk_fields_lobject.fields.lobject import LargeObject
_logger = logging.getLogger(__name__)
class LObjectIrAttachment(models.Model):
_inherit = 'ir.attachment'
#----------------------------------------------------------
_inherit = "ir.attachment"
# ----------------------------------------------------------
# Database
#----------------------------------------------------------
store_lobject = LargeObject(
string="Data")
#----------------------------------------------------------
# ----------------------------------------------------------
store_lobject = LargeObject(string="Data")
# ----------------------------------------------------------
# Helper
#----------------------------------------------------------
# ----------------------------------------------------------
@api.model
def _get_datas_inital_vals(self):
vals = super(LObjectIrAttachment, self)._get_datas_inital_vals()
vals.update({'store_lobject': False})
return vals
#----------------------------------------------------------
def _get_storage_domain(self, storage):
if storage == "lobject":
return [("store_lobject", "=", False)]
return super(LObjectIrAttachment, self)._get_storage_domain(storage)
# ----------------------------------------------------------
# Function
#----------------------------------------------------------
# ----------------------------------------------------------
@api.model
def storage_locations(self):
locations = super(LObjectIrAttachment, self).storage_locations()
locations.append('lobject')
locations.append("lobject")
return locations
@api.model
def force_storage(self):
if not self.env.user._is_admin():
raise AccessError(_('Only administrators can execute this action.'))
if self._storage() != 'lobject':
return super(LObjectIrAttachment, self).force_storage()
else:
storage_domain = {
'lobject': ('store_lobject', '=', False),
}
record_domain = [
'&', ('type', '=', 'binary'),
'&', storage_domain[self._storage()],
'|', ('res_field', '=', False), ('res_field', '!=', False)
]
self.search(record_domain).migrate(batch_size=100)
return True
#----------------------------------------------------------
# ----------------------------------------------------------
# Read
#----------------------------------------------------------
@api.depends('store_lobject')
# ----------------------------------------------------------
@api.depends("store_lobject")
def _compute_datas(self):
bin_size = self._context.get('bin_size')
bin_size = self._context.get("bin_size")
for attach in self:
if attach.store_lobject:
if bin_size:
attach.datas = attach.with_context({'human_size': True}).store_lobject
attach.datas = attach.with_context(
{"human_size": True}
).store_lobject
else:
attach.datas = attach.with_context({'base64': True}).store_lobject
attach.datas = attach.with_context({"base64": True}).store_lobject
else:
super(LObjectIrAttachment, attach)._compute_datas()
#----------------------------------------------------------
# ----------------------------------------------------------
# Create, Write, Delete
#----------------------------------------------------------
@api.multi
def _inverse_datas(self):
location = self._storage()
if location == 'lobject':
for attach in self:
value = attach.datas
bin_data = base64.b64decode(value) if value else b''
vals = self._get_datas_inital_vals()
vals = self._update_datas_vals(vals, attach, bin_data)
vals['store_lobject'] = bin_data
clean_vals = self._get_datas_clean_vals(attach)
models.Model.write(attach.sudo(), vals)
self._clean_datas_after_write(clean_vals)
else:
super(LObjectIrAttachment, self)._inverse_datas()
# ----------------------------------------------------------
def _get_datas_related_values(self, data, mimetype):
if self._storage() == "lobject":
bin_data = base64.b64decode(data) if data else b""
values = {
"file_size": len(bin_data),
"checksum": self._compute_checksum(bin_data),
"index_content": self._index(bin_data, mimetype),
"store_lobject": bin_data,
"store_fname": False,
"db_datas": False,
}
return values
return super(LObjectIrAttachment, attach)._get_datas_related_values(
data, mimetype
)

2
muk_attachment_lobject/static/description/icon.svg
File diff suppressed because it is too large
View File

313
muk_attachment_lobject/static/description/index.html

@ -1,142 +1,197 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">MuK Large Objects Attachment</h2>
<h3 class="oe_slogan">Large Objects Attachment Location</h3>
<h4 class="oe_slogan" style="font-size: 23px;">MuK IT GmbH -
www.mukit.at</h4>
</div>
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">MuK Large Objects Attachment</h2>
<h3 class="oe_slogan">Large Objects Attachment Location</h3>
<h4 class="oe_slogan" style="font-size: 23px;">
MuK IT GmbH - www.mukit.at
</h4>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="text-justify" style="max-width: 84%; margin: 16px 8%;">
<h3 class="oe_slogan">Overview</h3>
<div class="oe_mt32"
style="padding-bottom: 10px; text-align: justify;">
<p>
Provides a new attachment location to save attachment as large
objects. To enable the large object storage option change the
<code>ir_attachment.location</code>
parameter to
<code>lobject</code>
.
</p>
<h5 style="padding-top: 10px;">Advantages over the in-database storage</h5>
<ul>
<li>Better RAM efficiency (This is more important for large files than for small ones.)</li>
<li>Possibility to easily dump the base without the large objects (This can be useful for reproducing bugs.)</li>
</ul>
<h5 style="padding-top: 10px;">Advantages over the file system storage</h5>
<ul>
<li>Large objects are transactional (fully ACID)</li>
<li>They work out of the box in multi-system setups (So there is no need for NFS or similar file sharing tools.)</li>
<li>Enables you to easily create backups of the entire system</li>
</ul>
</div>
</div>
</div>
<div class="oe_row oe_spaced">
<div class="text-justify" style="max-width: 84%; margin: 16px 8%;">
<h3 class="oe_slogan">Overview</h3>
<div class="oe_mt32" style="padding-bottom: 10px; text-align: justify;">
<p>
Provides a new attachment location to save attachment as large
objects. To enable the large object storage option change the
<code>ir_attachment.location</code>
parameter to
<code>lobject</code>
.
</p>
<h5 style="padding-top: 10px;">
Advantages over the in-database storage
</h5>
<ul>
<li>
Better RAM efficiency (This is more important for large files than
for small ones.)
</li>
<li>
Possibility to easily dump the base without the large objects (This
can be useful for reproducing bugs.)
</li>
</ul>
<h5 style="padding-top: 10px;">
Advantages over the file system storage
</h5>
<ul>
<li>Large objects are transactional (fully ACID)</li>
<li>
They work out of the box in multi-system setups (So there is no need
for NFS or similar file sharing tools.)
</li>
<li>Enables you to easily create backups of the entire system</li>
</ul>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Our Services</h3>
<div
style="display: flex; padding-top: 20px; justify-content: space-between;">
<div style="flex-basis: 18%;">
<a href="https://mukit.at/r/MQ5" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;">
<img src="service_implementation.png"
style="width: 100%; border-radius: 100%;">
</div>
<h3 class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;">
Odoo <br>Implementation
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href="https://mukit.at/r/u7c" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;">
<img src="service_integration.png"
style="width: 100%; border-radius: 100%;">
</div>
<h3 class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;">
Odoo <br>Integration
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href="https://mukit.at/r/xDJ" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;">
<img src="service_customization.png"
style="width: 100%; border-radius: 100%;">
</div>
<h3 class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;">
Odoo <br>Customization
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href=" https://mukit.at/r/J3A" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;">
<img src="service_development.png"
style="width: 100%; border-radius: 100%;">
</div>
<h3 class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;">
Odoo <br>Development
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href=" https://mukit.at/r/R1v" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;">
<img src="service_support.png"
style="width: 100%; border-radius: 100%;">
</div>
<h3 class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;">
Odoo <br>Support
</h3>
</a>
</div>
</div>
</div>
<div class="oe_row oe_spaced">
<h3 class="oe_slogan">Our Services</h3>
<div
style="display: flex; padding-top: 20px; justify-content: space-between;"
>
<div style="flex-basis: 18%;">
<a href="https://mukit.at/r/MQ5" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;"
>
<img
src="service_implementation.png"
style="width: 100%; border-radius: 100%;"
/>
</div>
<h3
class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;"
>
Odoo <br />Implementation
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href="https://mukit.at/r/u7c" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;"
>
<img
src="service_integration.png"
style="width: 100%; border-radius: 100%;"
/>
</div>
<h3
class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;"
>
Odoo <br />Integration
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href="https://mukit.at/r/xDJ" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;"
>
<img
src="service_customization.png"
style="width: 100%; border-radius: 100%;"
/>
</div>
<h3
class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;"
>
Odoo <br />Customization
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href=" https://mukit.at/r/J3A" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;"
>
<img
src="service_development.png"
style="width: 100%; border-radius: 100%;"
/>
</div>
<h3
class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;"
>
Odoo <br />Development
</h3>
</a>
</div>
<div style="flex-basis: 18%;">
<a href=" https://mukit.at/r/R1v" target="_blank">
<div
style="width: 75px; height: 75px; border-radius: 100%; margin: auto;"
>
<img
src="service_support.png"
style="width: 100%; border-radius: 100%;"
/>
</div>
<h3
class="oe_slogan"
style="text-align: center; font-size: 14px; width: 100%; margin: 0; margin-top: 14px; color: #000 !important; margin-top: 5px; opacity: 1 !important; line-height: 17px;"
>
Odoo <br />Support
</h3>
</a>
</div>
</div>
</div>
</section>
<section class="oe_container" style="padding: 32px 0;">
<div class="oe_row oe_spaced" style="margin: auto;">
<div class="oe_demo oe_picture oe_screenshot">
<a href="https://mukit.at/r/SgN" target="_blank"> <img src="preview.png">
</a>
</div>
</div>
<div class="oe_row oe_spaced" style="margin: auto;">
<div class="oe_demo oe_picture oe_screenshot">
<a href="https://mukit.at/r/SgN" target="_blank">
<img src="preview.png" />
</a>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<h3 class="oe_slogan">Help and Support</h3>
<h5 class="oe_slogan" style="font-size: 20px;">Feel free to
contact us, if you need any help with your Odoo integration or
addiontal features.</h5>
<div class="oe_slogan">
<a class="btn btn-primary btn-lg mt8" href="https://mukit.at" target="_blank">
<i class="fa fa-globe"></i> Website
</a>
<a class="btn btn-primary btn-lg mt8" href="mailto:sale@mukit.at">
<i class="fa fa-envelope"></i> Contact Us
</a>
<a class="btn btn-primary btn-lg mt8" href="https://github.com/muk-it" target="_blank">
<i class="fa fa-github"></i> Issues
</a>
</div>
<img src="logo.png"
style="width: 200px; margin-bottom: 20px; display: block;"
class="mx-auto center-block">
</section>
<h3 class="oe_slogan">Help and Support</h3>
<h5 class="oe_slogan" style="font-size: 20px;">
Feel free to contact us, if you need any help with your Odoo integration or
addiontal features.
</h5>
<div class="oe_slogan">
<a
class="btn btn-primary btn-lg mt8"
href="https://mukit.at"
target="_blank"
>
<i class="fa fa-globe"></i> Website
</a>
<a
class="btn btn-primary btn-lg mt8"
href="https://mukit.at/page/contactus"
target="_blank"
>
<i class="fa fa-envelope"></i> Contact Us
</a>
<a
class="btn btn-primary btn-lg mt8"
href="https://github.com/muk-it"
target="_blank"
>
<i class="fa fa-github"></i> Issues
</a>
</div>
<img
src="logo.png"
style="width: 200px; margin-bottom: 20px; display: block;"
class="mx-auto center-block"
/>
</section>

5
muk_attachment_lobject/tests/__init__.py

@ -2,7 +2,7 @@
#
# Copyright (c) 2017-2019 MuK IT GmbH.
#
# This file is part of MuK Large Objects Attachment
# This file is part of MuK Large Objects Attachment
# (see https://mukit.at).
#
# This program is free software: you can redistribute it and/or modify
@ -20,5 +20,4 @@
#
###################################################################################
from . import test_attachment
from . import test_download
from . import test_attachment, test_download

46
muk_attachment_lobject/tests/test_attachment.py

@ -2,7 +2,7 @@
#
# Copyright (c) 2017-2019 MuK IT GmbH.
#
# This file is part of MuK Large Objects Attachment
# This file is part of MuK Large Objects Attachment
# (see https://mukit.at).
#
# This program is free software: you can redistribute it and/or modify
@ -28,38 +28,38 @@ from odoo.tests import common
_logger = logging.getLogger(__name__)
class AttachmentTestCase(common.HttpCase):
def setUp(self):
super(AttachmentTestCase, self).setUp()
self.attachment = self.env['ir.attachment'].sudo()
self.params = self.env['ir.config_parameter'].sudo()
self.location = self.params.get_param('ir_attachment.location')
self.params.set_param('ir_attachment.location', 'lobject')
self.attachment = self.env["ir.attachment"].sudo()
self.params = self.env["ir.config_parameter"].sudo()
self.location = self.params.get_param("ir_attachment.location")
self.params.set_param("ir_attachment.location", "lobject")
def tearDown(self):
self.params.set_param('ir_attachment.location', self.location)
self.params.set_param("ir_attachment.location", self.location)
super(AttachmentTestCase, self).tearDown()
def test_attachment(self):
attach = self.attachment.create({
'name': "Test",
'datas': base64.b64encode(b"\xff data")})
attach = self.attachment.create(
{"name": "Test", "datas": base64.b64encode(b"\xff data")}
)
self.assertTrue(attach.datas)
self.assertTrue(attach.store_lobject)
self.assertTrue(attach.with_context({'bin_size': True}).datas)
self.assertTrue(attach.with_context({'bin_size': True}).store_lobject)
self.assertTrue(attach.with_context({'human_size': True}).store_lobject)
self.assertTrue(attach.with_context({'base64': True}).store_lobject)
self.assertTrue(attach.with_context({'stream': True}).store_lobject)
oid = attach.with_context({'oid': True}).store_lobject
self.assertTrue(attach.with_context({"bin_size": True}).datas)
self.assertTrue(attach.with_context({"bin_size": True}).store_lobject)
self.assertTrue(attach.with_context({"human_size": True}).store_lobject)
self.assertTrue(attach.with_context({"base64": True}).store_lobject)
self.assertTrue(attach.with_context({"stream": True}).store_lobject)
oid = attach.with_context({"oid": True}).store_lobject
self.assertTrue(oid)
attach.write({'datas': base64.b64encode(b"\xff data")})
self.assertTrue(oid != attach.with_context({'oid': True}).store_lobject)
self.assertTrue(attach.export_data(['datas']))
self.assertTrue(attach.export_data(['datas'], raw_data=True))
attach.write({"datas": base64.b64encode(b"\xff data")})
self.assertTrue(oid != attach.with_context({"oid": True}).store_lobject)
self.assertTrue(attach.export_data(["datas"]))
self.assertTrue(attach.export_data(["datas"], raw_data=True))
attach.unlink()
@unittest.skip("The test takes a long time and is therefore skipped by default.")
def test_migration(self):
self.attachment.force_storage()
self.attachment.force_storage()

59
muk_attachment_lobject/tests/test_download.py

@ -2,7 +2,7 @@
#
# Copyright (c) 2017-2019 MuK IT GmbH.
#
# This file is part of MuK Large Objects Attachment
# This file is part of MuK Large Objects Attachment
# (see https://mukit.at).
#
# This program is free software: you can redistribute it and/or modify
@ -20,59 +20,42 @@
#
###################################################################################
import os
import time
import hmac
import base64
import hashlib
import logging
from odoo.http import request
import os
from odoo.addons.muk_utils.tests import common
_path = os.path.dirname(os.path.dirname(__file__))
_logger = logging.getLogger(__name__)
class DownloadTestCase(common.HttpCase):
def setUp(self):
super(DownloadTestCase, self).setUp()
self.attachment = self.env['ir.attachment'].sudo()
self.params = self.env['ir.config_parameter'].sudo()
self.location = self.params.get_param('ir_attachment.location')
self.params.set_param('ir_attachment.location', 'lobject')
self.attachment = self.env["ir.attachment"].sudo()
self.params = self.env["ir.config_parameter"].sudo()
self.location = self.params.get_param("ir_attachment.location")
self.params.set_param("ir_attachment.location", "lobject")
def tearDown(self):
self.params.set_param('ir_attachment.location', self.location)
self.params.set_param("ir_attachment.location", self.location)
super(DownloadTestCase, self).tearDown()
def test_attachment_download(self):
self.authenticate('admin', 'admin')
attach_01 = self.attachment.create({
'name': "Test_01",
'datas': base64.b64encode(b"\xff data")
})
attach_02 = self.attachment.create({
'name': "Test_02",
})
self.authenticate("admin", "admin")
attach_01 = self.attachment.create(
{"name": "Test_01", "datas": base64.b64encode(b"\xff data")}
)
attach_02 = self.attachment.create({"name": "Test_02"})
self.assertTrue(attach_01.datas)
self.assertFalse(attach_02.datas)
data = {
'model': 'ir.attachment',
'field': 'store_lobject',
'filename_field': 'datas_fname',
"model": "ir.attachment",
"field": "store_lobject",
"filename_field": "datas_fname",
}
data.update({
'id': attach_01.id,
})
self.assertTrue(self.url_open('/web/lobject', data=data, csrf=True))
data.update({
'id': attach_02.id,
})
self.assertTrue(self.url_open('/web/lobject', data=data, csrf=True))
data.update({"id": attach_01.id})
self.assertTrue(self.url_open("/binary/content", data=data, csrf=True))
data.update({"id": attach_02.id})
self.assertTrue(self.url_open("/binary/content", data=data, csrf=True))

4
muk_attachment_lobject/views/ir_attachment.xml

@ -4,7 +4,7 @@
Copyright (c) 2017-2019 MuK IT GmbH.
This file is part of MuK Large Objects Attachment
This file is part of MuK Large Objects Attachment
(see https://mukit.at).
This program is free software: you can redistribute it and/or modify
@ -38,4 +38,4 @@
</field>
</record>
</odoo>
</odoo>
Loading…
Cancel
Save