Загрузка данных


CREATE OR REPLACE FUNCTION utils.move_processed_file(
    p_folder text,
    p_file_name text
)
RETURNS text
LANGUAGE plpython3u
SECURITY DEFINER
AS $function$
import os

if not p_folder or not p_file_name:
    plpy.error("Не указана папка или имя файла")

# Имя должно содержать только название файла.
if (
    p_file_name in (".", "..")
    or "/" in p_file_name
    or "\\" in p_file_name
):
    plpy.error("Недопустимое имя файла")

rows = plpy.execute(
    "SELECT value FROM robot.params WHERE name = 'root'",
    1
)

if not rows or not rows[0]["value"]:
    plpy.error("Не задан robot.params.root")

root = os.path.realpath(rows[0]["value"])
source_dir = os.path.realpath(os.path.join(root, p_folder))

# Разрешены только папки внутри настроенного корня.
if (
    os.path.isabs(p_folder)
    or os.path.commonpath([root, source_dir]) != root
):
    plpy.error("Папка находится вне robot.params.root")

source_file = os.path.join(source_dir, p_file_name)
target_dir = os.path.realpath(
    os.path.join(source_dir, "Обработано")
)

if os.path.commonpath([source_dir, target_dir]) != source_dir:
    plpy.error("Подпапка Обработано находится вне исходной папки")

target_file = os.path.join(target_dir, p_file_name)

if not os.path.isfile(source_file):
    plpy.error("Исходный файл не найден: " + source_file)

if os.path.islink(source_file):
    plpy.error("Перемещение символической ссылки запрещено")

try:
    os.makedirs(target_dir, exist_ok=True)

    if os.path.lexists(target_file):
        plpy.error(
            "В папке Обработано уже есть файл: " + p_file_name
        )

    os.rename(source_file, target_file)
except OSError as exc:
    plpy.error("Ошибка перемещения файла: " + str(exc))

return target_file
$function$;