mirror of
https://github.com/OCA/knowledge.git
synced 2025-07-25 18:08:42 -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