87 lines
3.4 KiB
Python
87 lines
3.4 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import uuid
|
|
|
|
from odoo import models, fields, _
|
|
from odoo.exceptions import UserError
|
|
from odoo.http import Stream
|
|
|
|
|
|
class CloudStorageAttachment(models.Model):
|
|
_inherit = 'ir.attachment'
|
|
_cloud_storage_upload_url_time_to_expiry = 300 # 300 seconds
|
|
_cloud_storage_download_url_time_to_expiry = 300 # 300 seconds
|
|
|
|
type = fields.Selection(
|
|
selection_add=[('cloud_storage', 'Cloud Storage')],
|
|
ondelete={'cloud_storage': 'set url'}
|
|
)
|
|
|
|
def _to_http_stream(self):
|
|
if (self.type == 'cloud_storage' and
|
|
self.env['res.config.settings']._get_cloud_storage_configuration()):
|
|
self.ensure_one()
|
|
info = self._generate_cloud_storage_download_info()
|
|
stream = Stream(type='url', url=info['url'])
|
|
if 'time_to_expiry' in info:
|
|
# cache the redirection until 10 seconds before the expiry
|
|
stream.max_age = max(info['time_to_expiry'] - 10, 0)
|
|
return stream
|
|
return super()._to_http_stream()
|
|
|
|
def _post_add_create(self, **kwargs):
|
|
super()._post_add_create(**kwargs)
|
|
if kwargs.get('cloud_storage'):
|
|
if not self.env['ir.config_parameter'].sudo().get_param('cloud_storage_provider'):
|
|
raise UserError(_('Cloud Storage is not enabled'))
|
|
for record in self:
|
|
record.write({
|
|
'raw': False,
|
|
'type': 'cloud_storage',
|
|
'url': record._generate_cloud_storage_url(),
|
|
})
|
|
|
|
def _generate_cloud_storage_blob_name(self):
|
|
"""
|
|
Generate a unique blob name for the attachment
|
|
:param attachment: an ir.attachment record
|
|
:return: A unique blob name str
|
|
"""
|
|
return f'{self.id}/{uuid.uuid4()}/{self.name}'
|
|
|
|
# Implement the following methods for each cloud storage provider.
|
|
def _generate_cloud_storage_url(self):
|
|
"""
|
|
Generate a cloud blob url without signature or token for the attachment.
|
|
This url is only used to identify the cloud blob.
|
|
:param attachment: an ir.attachment record
|
|
:return: A cloud blob url str
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
def _generate_cloud_storage_download_info(self):
|
|
"""
|
|
Generate the download info for the public client to directly download
|
|
the attachment's blob from the cloud storage.
|
|
:param attachment: an ir.attachment record
|
|
:return: An download_info dictionary containing:
|
|
* download_url: cloud storage url with permission to download the file
|
|
* time_to_expiry: the time in seconds before the download url expires
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
def _generate_cloud_storage_upload_info(self):
|
|
"""
|
|
Generate the upload info for the public client to directly upload a
|
|
file to the cloud storage.
|
|
:param attachment: an ir.attachment record
|
|
:return: An upload_info dictionary containing:
|
|
* upload_url: cloud storage url with permission to upload the file
|
|
* method: the request method used to upload the file
|
|
* response_status: the status of the response for a successful
|
|
upload request
|
|
* [Optionally] headers: a dictionary of headers to be added to the
|
|
upload request
|
|
"""
|
|
raise NotImplementedError()
|