Public release from ruodoo-project: 19.0 - 2026-05-10 21:19:01 UTC
This commit is contained in:
103
dms/tools/file.py
Normal file
103
dms/tools/file.py
Normal file
@ -0,0 +1,103 @@
|
||||
# Copyright 2020 Antoni Romera
|
||||
# Copyright 2017-2019 MuK IT GmbH
|
||||
# Copyright 2024 Subteno - Timothée Vannier (https://www.subteno.com).
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from odoo.tools.mimetypes import guess_mimetype
|
||||
|
||||
|
||||
def check_name(name):
|
||||
"""
|
||||
Check if a file name is valid.
|
||||
|
||||
:param str name: The file name to check.
|
||||
:return: True if the file name is valid, False otherwise.
|
||||
:rtype: bool
|
||||
"""
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
try:
|
||||
open(os.path.join(tmp_dir, name), "a").close()
|
||||
except OSError:
|
||||
return False
|
||||
finally:
|
||||
shutil.rmtree(tmp_dir)
|
||||
return True
|
||||
|
||||
|
||||
def compute_name(name, suffix, escape_suffix):
|
||||
"""
|
||||
Compute a new name by adding a suffix to the original name.
|
||||
|
||||
:param str name: The original name.
|
||||
:param int suffix: The suffix to add.
|
||||
:param bool escape_suffix: If True, the suffix is added in between the name and
|
||||
the file extension.
|
||||
:return: The new name.
|
||||
:rtype: str
|
||||
"""
|
||||
if escape_suffix:
|
||||
name, extension = os.path.splitext(name)
|
||||
return f"{name}({suffix}){extension}"
|
||||
|
||||
return f"{name}({suffix})"
|
||||
|
||||
|
||||
def unique_name(name, names, escape_suffix=False):
|
||||
"""
|
||||
Generate a unique name by adding a suffix to the original name.
|
||||
|
||||
:param str name: The original name.
|
||||
:param list names: The list of existing names.
|
||||
:param bool escape_suffix: If True, the suffix is added in between the name and
|
||||
the file extension.
|
||||
:return: The unique name.
|
||||
:rtype: str
|
||||
"""
|
||||
if name not in names:
|
||||
return name
|
||||
|
||||
# Extract the suffix from the name
|
||||
# e.g: "file(1).txt" -> "1"
|
||||
# "Directory (1)(2)" -> "2"
|
||||
digits = re.compile(r"\((\d+)\)(\.\w+)?$")
|
||||
match = digits.search(name)
|
||||
suffix = 1
|
||||
if match:
|
||||
suffix = int(match.group(1)) + 1
|
||||
# get the name without the suffix and append the extension
|
||||
name = name[: match.span()[0]] + (match.group(2) or "")
|
||||
|
||||
name = compute_name(name, suffix, escape_suffix)
|
||||
while name in names:
|
||||
# has to check recursively if the new name is unique because the user can
|
||||
# rename the file with suffix n+1
|
||||
# and then duplicate the file n, leading to a new file with suffix n+1 which
|
||||
# is already used.
|
||||
return unique_name(name, names, escape_suffix)
|
||||
return name
|
||||
|
||||
|
||||
def guess_extension(filename=None, mimetype=None, binary=None):
|
||||
"""
|
||||
Guess the extension of a file.
|
||||
|
||||
:param str filename: The name of the file.
|
||||
:param str mimetype: The mimetype of the file.
|
||||
:param str binary: The binary content of the file.
|
||||
|
||||
:return: The extension of the file.
|
||||
:rtype: str
|
||||
"""
|
||||
extension = filename and os.path.splitext(filename)[1][1:].strip().lower()
|
||||
if not extension and mimetype and mimetype != "application/x-empty":
|
||||
extension = mimetypes.guess_extension(mimetype)[1:].strip().lower()
|
||||
if not extension and binary:
|
||||
mimetype = guess_mimetype(binary, default="")
|
||||
extension = mimetypes.guess_extension(mimetype)[1:].strip().lower()
|
||||
return extension
|
||||
Reference in New Issue
Block a user