mirror of
https://github.com/bringout/oca-storage.git
synced 2026-04-19 00:12:00 +02:00
Initial commit: OCA Storage packages (17 packages)
This commit is contained in:
commit
7a380f05d3
659 changed files with 41828 additions and 0 deletions
|
|
@ -0,0 +1,2 @@
|
|||
from . import base_adapter
|
||||
from . import filesystem_adapter
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# Copyright 2017 Akretion (http://www.akretion.com).
|
||||
# @author Sébastien BEAU <sebastien.beau@akretion.com>
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
# Copyright 2020 ACSONE SA/NV (<http://acsone.eu>)
|
||||
# @author Simone Orsi <simahawk@gmail.com>
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from odoo.addons.component.core import AbstractComponent
|
||||
|
||||
|
||||
class BaseStorageAdapter(AbstractComponent):
|
||||
_name = "base.storage.adapter"
|
||||
_collection = "storage.backend"
|
||||
|
||||
def _fullpath(self, relative_path):
|
||||
dp = self.collection.directory_path
|
||||
if not dp or relative_path.startswith(dp):
|
||||
return relative_path
|
||||
return os.path.join(dp, relative_path)
|
||||
|
||||
def add(self, relative_path, data, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
def get(self, relative_path, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
def list(self, relative_path=""):
|
||||
raise NotImplementedError
|
||||
|
||||
def find_files(self, pattern, relative_path="", **kwargs):
|
||||
"""Find files matching given pattern.
|
||||
|
||||
:param pattern: regex expression
|
||||
:param relative_path: optional relative path containing files
|
||||
:return: list of file paths as full paths from the root
|
||||
"""
|
||||
regex = re.compile(pattern)
|
||||
filelist = self.list(relative_path)
|
||||
files_matching = [
|
||||
regex.match(file_).group() for file_ in filelist if regex.match(file_)
|
||||
]
|
||||
filepaths = []
|
||||
if files_matching:
|
||||
filepaths = [
|
||||
os.path.join(self._fullpath(relative_path) or "", filename)
|
||||
for filename in files_matching
|
||||
]
|
||||
return filepaths
|
||||
|
||||
def move_files(self, files, destination_path, **kwargs):
|
||||
"""Move files to given destination.
|
||||
|
||||
:param files: list of file paths to be moved
|
||||
:param destination_path: directory path where to move files
|
||||
:return: None
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def delete(self, relative_path):
|
||||
raise NotImplementedError
|
||||
|
||||
# You can define `validate_config` on your own adapter
|
||||
# to make validation button available on UI.
|
||||
# This method should simply pass smoothly when validation is ok,
|
||||
# otherwise it should raise an exception.
|
||||
# def validate_config(self):
|
||||
# raise NotImplementedError
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
# Copyright 2017 Akretion (http://www.akretion.com).
|
||||
# @author Sébastien BEAU <sebastien.beau@akretion.com>
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from odoo import _
|
||||
from odoo.exceptions import AccessError
|
||||
|
||||
from odoo.addons.component.core import Component
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def is_safe_path(basedir, path):
|
||||
return os.path.realpath(path).startswith(basedir)
|
||||
|
||||
|
||||
class FileSystemStorageBackend(Component):
|
||||
_name = "filesystem.adapter"
|
||||
_inherit = "base.storage.adapter"
|
||||
_usage = "filesystem"
|
||||
|
||||
def _basedir(self):
|
||||
return os.path.join(self.env["ir.attachment"]._filestore(), "storage")
|
||||
|
||||
def _fullpath(self, relative_path):
|
||||
"""This will build the full path for the file, we force to
|
||||
store the data inside the filestore in the directory 'storage".
|
||||
Becarefull if you implement your own custom path, end user
|
||||
should never be able to write or read unwanted filesystem file"""
|
||||
full_path = super(FileSystemStorageBackend, self)._fullpath(relative_path)
|
||||
base_dir = self._basedir()
|
||||
full_path = os.path.join(base_dir, full_path)
|
||||
if not is_safe_path(base_dir, full_path):
|
||||
raise AccessError(_("Access to %s is forbidden") % full_path)
|
||||
return full_path
|
||||
|
||||
def add(self, relative_path, data, **kwargs):
|
||||
full_path = self._fullpath(relative_path)
|
||||
dirname = os.path.dirname(full_path)
|
||||
if not os.path.isdir(dirname):
|
||||
os.makedirs(dirname)
|
||||
with open(full_path, "wb") as my_file:
|
||||
my_file.write(data)
|
||||
|
||||
def get(self, relative_path, **kwargs):
|
||||
full_path = self._fullpath(relative_path)
|
||||
with open(full_path, "rb") as my_file:
|
||||
data = my_file.read()
|
||||
return data
|
||||
|
||||
def list(self, relative_path=""):
|
||||
full_path = self._fullpath(relative_path)
|
||||
if os.path.isdir(full_path):
|
||||
return os.listdir(full_path)
|
||||
return []
|
||||
|
||||
def delete(self, relative_path):
|
||||
full_path = self._fullpath(relative_path)
|
||||
try:
|
||||
os.remove(full_path)
|
||||
except FileNotFoundError:
|
||||
_logger.warning("File not found in %s", full_path)
|
||||
|
||||
def move_files(self, files, destination_path):
|
||||
result = []
|
||||
for file_path in files:
|
||||
if not os.path.exists(destination_path):
|
||||
os.makedirs(destination_path)
|
||||
filename = os.path.basename(file_path)
|
||||
destination_file = os.path.join(destination_path, filename)
|
||||
result.append(shutil.move(file_path, destination_file))
|
||||
return result
|
||||
Loading…
Add table
Add a link
Reference in a new issue