mirror of
https://github.com/OCA/knowledge.git
synced 2025-07-26 18:38:41 -06:00
[ADD] module attachment_file_extension
This commit is contained in:
parent
420ae2218a
commit
ee62a2f628
34
attachment_file_extension/README.rst
Normal file
34
attachment_file_extension/README.rst
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||||
|
:alt: License: AGPL-3
|
||||||
|
|
||||||
|
Attachment File Extension
|
||||||
|
=========================
|
||||||
|
|
||||||
|
This module was written to get attachment files readable by any external
|
||||||
|
software, expecially by those that need to recognise the file type from their
|
||||||
|
extension to open them properly. It allows to store attachments on filesystem
|
||||||
|
adding the file extension to their filename.
|
||||||
|
|
||||||
|
Credits
|
||||||
|
=======
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Alex Comba <alex.comba@agilebg.com>
|
||||||
|
* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
|
||||||
|
|
||||||
|
Maintainer
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. image:: http://odoo-community.org/logo.png
|
||||||
|
:alt: Odoo Community Association
|
||||||
|
:target: http://odoo-community.org
|
||||||
|
|
||||||
|
This module is maintained by the OCA.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
To contribute to this module, please visit http://odoo-community.org.
|
21
attachment_file_extension/__init__.py
Normal file
21
attachment_file_extension/__init__.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||||
|
# @author Alex Comba <alex.comba@agilebg.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
from . import models
|
35
attachment_file_extension/__openerp__.py
Normal file
35
attachment_file_extension/__openerp__.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||||
|
# @author Alex Comba <alex.comba@agilebg.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
{
|
||||||
|
"name": "Attachment File Extension",
|
||||||
|
"version": "1.0",
|
||||||
|
"category": "Knowledge Management",
|
||||||
|
"summary": """
|
||||||
|
It allows to store attachments on filesystem adding the extension file to
|
||||||
|
their filename.
|
||||||
|
""",
|
||||||
|
'author': "Agile Business Group, Odoo Community Association (OCA)",
|
||||||
|
"website": "http://www.agilebg.com",
|
||||||
|
"license": "AGPL-3",
|
||||||
|
"depends": [],
|
||||||
|
"data": [],
|
||||||
|
"installable": True,
|
||||||
|
}
|
21
attachment_file_extension/models/__init__.py
Normal file
21
attachment_file_extension/models/__init__.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||||
|
# @author Alex Comba <alex.comba@agilebg.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
from . import ir_attachment
|
85
attachment_file_extension/models/ir_attachment.py
Normal file
85
attachment_file_extension/models/ir_attachment.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 Agile Business Group sagl
|
||||||
|
# (<http://www.agilebg.com>)
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp.osv import orm, fields
|
||||||
|
import os.path
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
|
class IrAttachment(orm.Model):
|
||||||
|
_inherit = 'ir.attachment'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self._file_extension_lock = threading.RLock()
|
||||||
|
self._extension = None
|
||||||
|
super(IrAttachment, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def _full_path(self, cr, uid, path):
|
||||||
|
# every calls to this method is managed using by _file_extension_lock
|
||||||
|
# to avoid the risk of overwriting the _extension attribute
|
||||||
|
full_path = super(IrAttachment, self)._full_path(cr, uid, path)
|
||||||
|
if self._extension:
|
||||||
|
full_path += self._extension
|
||||||
|
return full_path
|
||||||
|
|
||||||
|
def _data_set(self, cr, uid, id, name, value, arg, context=None):
|
||||||
|
with self._file_extension_lock:
|
||||||
|
attachment = self.browse(cr, uid, id, context=context)
|
||||||
|
if attachment.datas_fname:
|
||||||
|
filename, extension = os.path.splitext(attachment.datas_fname)
|
||||||
|
self._extension = extension
|
||||||
|
attachment.write({'extension': extension})
|
||||||
|
super(IrAttachment, self)._data_set(
|
||||||
|
cr, uid, id, name, value, arg, context=context)
|
||||||
|
|
||||||
|
def _data_get(self, cr, uid, ids, name, arg, context=None):
|
||||||
|
res = {}
|
||||||
|
for attachment in self.browse(cr, uid, ids, context=context):
|
||||||
|
if attachment.extension:
|
||||||
|
with self._file_extension_lock:
|
||||||
|
self._extension = attachment.extension
|
||||||
|
res.update(
|
||||||
|
super(IrAttachment, self)._data_get(
|
||||||
|
cr, uid, [attachment.id], name, arg,
|
||||||
|
context=context))
|
||||||
|
else:
|
||||||
|
res.update(
|
||||||
|
super(IrAttachment, self)._data_get(
|
||||||
|
cr, uid, [attachment.id], name, arg,
|
||||||
|
context=context))
|
||||||
|
return res
|
||||||
|
|
||||||
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
|
for attachment in self.browse(cr, uid, ids, context=context):
|
||||||
|
if attachment.extension:
|
||||||
|
with self._file_extension_lock:
|
||||||
|
self._extension = attachment.extension
|
||||||
|
super(IrAttachment, self).unlink(
|
||||||
|
cr, uid, ids, context=context)
|
||||||
|
else:
|
||||||
|
super(IrAttachment, self).unlink(cr, uid, ids, context=context)
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'datas': fields.function(
|
||||||
|
_data_get, fnct_inv=_data_set, string='File Content',
|
||||||
|
type="binary", nodrop=True),
|
||||||
|
'extension': fields.char(string='Attachment File Extension', size=4),
|
||||||
|
}
|
BIN
attachment_file_extension/static/description/icon.png
Normal file
BIN
attachment_file_extension/static/description/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,38 @@
|
|||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
from openerp.tests.common import TransactionCase
|
||||||
|
|
||||||
|
HASH_SPLIT = 2
|
||||||
|
|
||||||
|
|
||||||
|
class TestAttachmentFileEstension(TransactionCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestAttachmentFileEstension, self).setUp()
|
||||||
|
registry, cr, uid = self.registry, self.cr, self.uid
|
||||||
|
self.ira = registry('ir.attachment')
|
||||||
|
self.filestore = self.ira._filestore(cr, uid)
|
||||||
|
|
||||||
|
# Blob
|
||||||
|
self.blob = 'blob'
|
||||||
|
self.blob_b64 = self.blob.encode('base64')
|
||||||
|
blob_hash = hashlib.sha1(self.blob).hexdigest()
|
||||||
|
self.blob_fname = blob_hash[:HASH_SPLIT] + '/' + blob_hash
|
||||||
|
self.blob_datas_fname = 'ira.ext'
|
||||||
|
|
||||||
|
def test_01_store_on_disk(self):
|
||||||
|
cr, uid = self.cr, self.uid
|
||||||
|
|
||||||
|
ira_id = self.ira.create(
|
||||||
|
cr, uid, {'name': 'ira',
|
||||||
|
'datas': self.blob_b64,
|
||||||
|
'datas_fname': self.blob_datas_fname})
|
||||||
|
attachment = self.ira.browse(cr, uid, ira_id)
|
||||||
|
filename, extension = os.path.splitext(self.blob_datas_fname)
|
||||||
|
|
||||||
|
self.assertEqual(attachment.store_fname, self.blob_fname)
|
||||||
|
self.assertEqual(attachment.extension, extension)
|
||||||
|
self.assertTrue(
|
||||||
|
os.path.isfile(os.path.join(
|
||||||
|
self.filestore,
|
||||||
|
attachment.store_fname + attachment.extension)))
|
Loading…
Reference in New Issue
Block a user