mirror of
https://github.com/bringout/oca-storage.git
synced 2026-04-18 05:52:04 +02:00
273 lines
9.4 KiB
ReStructuredText
273 lines
9.4 KiB
ReStructuredText
=======
|
|
Fs File
|
|
=======
|
|
|
|
..
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
!! This file is generated by oca-gen-addon-readme !!
|
|
!! changes will be overwritten. !!
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
!! source digest: sha256:cec7431f1becb99516793e51833fe9606ccd7459d148d15df61b03c14de1f6e4
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
|
|
:target: https://odoo-community.org/page/development-status
|
|
:alt: Alpha
|
|
.. |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%2Fstorage-lightgray.png?logo=github
|
|
:target: https://github.com/OCA/storage/tree/16.0/fs_file
|
|
:alt: OCA/storage
|
|
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
|
:target: https://translation.odoo-community.org/projects/storage-16-0/storage-16-0-fs_file
|
|
:alt: Translate me on Weblate
|
|
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
|
|
:target: https://runboat.odoo-community.org/builds?repo=OCA/storage&target_branch=16.0
|
|
:alt: Try me on Runboat
|
|
|
|
|badge1| |badge2| |badge3| |badge4| |badge5|
|
|
|
|
This addon defines a new field type `FSFile` which is a file field that stores
|
|
a file in an external filesystem instead of the odoo's filestore. This is useful for
|
|
large files that you don't want to store in the filestore. Moreover, the field
|
|
value provides you an interface to access the file's contents and metadata.
|
|
|
|
.. IMPORTANT::
|
|
This is an alpha version, the data model and design can change at any time without warning.
|
|
Only for development or testing purpose, do not use in production.
|
|
`More details on development status <https://odoo-community.org/page/development-status>`_
|
|
|
|
**Table of contents**
|
|
|
|
.. contents::
|
|
:local:
|
|
|
|
Usage
|
|
=====
|
|
|
|
The new field **FSFile** has been developed to allows you to store files
|
|
in an external filesystem storage. Its design is based on the following
|
|
principles:
|
|
|
|
* The content of the file must be read from the filesystem only when
|
|
needed.
|
|
* It must be possible to manipulate the file content as a stream by default.
|
|
* Unlike Odoo's Binary field, the content is the raw file content by default
|
|
(no base64 encoding).
|
|
* To allows to exchange the file content with other systems, writing the
|
|
content as base64 is possible. The read operation will return a json
|
|
structure with the filename, the mimetype, the size and a url to download the file.
|
|
|
|
This design allows to minimize the memory consumption of the server when
|
|
manipulating large files and exchanging them with other systems through
|
|
the default jsonrpc interface.
|
|
|
|
Concretely, this design allows you to write code like this:
|
|
|
|
.. code-block:: python
|
|
|
|
from IO import BytesIO
|
|
from odoo import models, fields
|
|
from odoo.addons.fs_file.fields import FSFile
|
|
|
|
class MyModel(models.Model):
|
|
_name = 'my.model'
|
|
|
|
name = fields.Char()
|
|
file = FSFile()
|
|
|
|
# Create a new record with a raw content
|
|
my_model = MyModel.create({
|
|
'name': 'My File',
|
|
'file': BytesIO(b"content"),
|
|
})
|
|
|
|
assert(my_model.file.read() == b"content")
|
|
|
|
# Create a new record with a base64 encoded content
|
|
my_model = MyModel.create({
|
|
'name': 'My File',
|
|
'file': b"content".encode('base64'),
|
|
})
|
|
assert(my_model.file.read() == b"content")
|
|
|
|
# Create a new record with a file content
|
|
my_model = MyModel.create({
|
|
'name': 'My File',
|
|
'file': open('my_file.txt', 'rb'),
|
|
})
|
|
assert(my_model.file.read() == b"content")
|
|
assert(my_model.file.name == "my_file.txt")
|
|
|
|
# create a record with a file content as base64 encoded and a filename
|
|
# This method is useful to create a record from a file uploaded
|
|
# through the web interface.
|
|
my_model = MyModel.create({
|
|
'name': 'My File',
|
|
'file': {
|
|
'filename': 'my_file.txt',
|
|
'content': base64.b64encode(b"content"),
|
|
},
|
|
})
|
|
assert(my_model.file.read() == b"content")
|
|
assert(my_model.file.name == "my_file.txt")
|
|
|
|
# write the content of the file as base64 encoded and a filename
|
|
# This method is useful to update a record from a file uploaded
|
|
# through the web interface.
|
|
my_model.write({
|
|
'file': {
|
|
'name': 'my_file.txt',
|
|
'file': base64.b64encode(b"content"),
|
|
},
|
|
})
|
|
|
|
# the call to read() will return a json structure with the filename,
|
|
# the mimetype, the size and a url to download the file.
|
|
info = my_model.file.read()
|
|
assert(info["file"] == {
|
|
"filename": "my_file.txt",
|
|
"mimetype": "text/plain",
|
|
"size": 7,
|
|
"url": "/web/content/1234/my_file.txt",
|
|
})
|
|
|
|
# use the field as a file stream
|
|
# In such a case, the content is read from the filesystem without being
|
|
# stored in memory.
|
|
with my_model.file.open("rb) as f:
|
|
assert(f.read() == b"content")
|
|
|
|
# use the field as a file stream to write the content
|
|
# In such a case, the content is written to the filesystem without being
|
|
# stored in memory. This kind of approach is useful to manipulate large
|
|
# files and to avoid to use too much memory.
|
|
# Transactional behaviour is ensured by the implementation!
|
|
with my_model.file.open("wb") as f:
|
|
f.write(b"content")
|
|
|
|
Changelog
|
|
=========
|
|
|
|
16.0.1.0.6 (2024-02-23)
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**Bugfixes**
|
|
|
|
- Fixes the creation of empty files.
|
|
|
|
Before this change, the creation of empty files resulted in a constraint
|
|
violation error. This was due to the fact that even if a name was given
|
|
to the file it was not preserved into the FSFileValue object if no content
|
|
was given. As result, when the corresponding ir.attachment was created in
|
|
the database, the name was not set and the 'required' constraint was violated. (`#341 <https://github.com/OCA/storage/issues/341>`_)
|
|
|
|
|
|
16.0.1.0.5 (2023-11-30)
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**Bugfixes**
|
|
|
|
- Ensure the cache is properly set when a new value is assigned to a FSFile field.
|
|
If the field is stored the value to the cache must be a FSFileValue object
|
|
linked to the attachment record used to store the file. Otherwise the value
|
|
must be one given since it could be the result of a compute method. (`#290 <https://github.com/OCA/storage/issues/290>`_)
|
|
|
|
|
|
16.0.1.0.4 (2023-10-17)
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**Bugfixes**
|
|
|
|
- Browse attachment with sudo() to avoid read access errors
|
|
|
|
In models that have a multi fs image relation, a new line
|
|
in form will trigger onchanges and will call the fs.file model
|
|
'convert_to_cache()' method that will try to browse the attachment
|
|
with user profile that could have no read rights on attachment model. (`#288 <https://github.com/OCA/storage/issues/288>`_)
|
|
|
|
|
|
16.0.1.0.3 (2023-10-05)
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**Bugfixes**
|
|
|
|
- Fix the *mimetype* property on *FSFileValue* objects.
|
|
|
|
The *mimetype* value is computed as follow:
|
|
|
|
* If an attachment is set, the mimetype is taken from the attachment.
|
|
* If no attachment is set, the mimetype is guessed from the name of the file.
|
|
* If the mimetype cannot be guessed from the name, the mimetype is guessed from
|
|
the content of the file. (`#284 <https://github.com/OCA/storage/issues/284>`_)
|
|
|
|
|
|
16.0.1.0.1 (2023-09-29)
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
**Features**
|
|
|
|
- Add a *url_path* property on the *FSFileValue* object. This property
|
|
allows you to easily get access to the relative path of the file on
|
|
the filesystem. This value is only available if the filesystem storage
|
|
is configured with a *Base URL* value. (`#281 <https://github.com/OCA/storage/issues/281>`__)
|
|
|
|
|
|
**Bugfixes**
|
|
|
|
- The *url_path*, *url* and *internal_url* properties on the *FSFileValue*
|
|
object return *None* if the information is not available (instead of *False*).
|
|
|
|
The *url* property on the *FSFileValue* object returns the filesystem url nor
|
|
the url field of the attachment. (`#281 <https://github.com/OCA/storage/issues/281>`__)
|
|
|
|
Bug Tracker
|
|
===========
|
|
|
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/storage/issues>`_.
|
|
In case of trouble, please check there if your issue has already been reported.
|
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
|
`feedback <https://github.com/OCA/storage/issues/new?body=module:%20fs_file%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
|
|
|
Do not contact contributors directly about support or help with technical issues.
|
|
|
|
Credits
|
|
=======
|
|
|
|
Authors
|
|
~~~~~~~
|
|
|
|
* ACSONE SA/NV
|
|
|
|
Contributors
|
|
~~~~~~~~~~~~
|
|
|
|
Laurent Mignon <laurent.mignon@acsone.eu>
|
|
Marie Lejeune <marie.lejeune@acsone.eu>
|
|
Hugues Damry <hughes.damry@acsone.eu>
|
|
|
|
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.
|
|
|
|
.. |maintainer-lmignon| image:: https://github.com/lmignon.png?size=40px
|
|
:target: https://github.com/lmignon
|
|
:alt: lmignon
|
|
|
|
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|
|
|
|
|maintainer-lmignon|
|
|
|
|
This module is part of the `OCA/storage <https://github.com/OCA/storage/tree/16.0/fs_file>`_ project on GitHub.
|
|
|
|
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|