fix converter module path

This commit is contained in:
user 2025-08-24 14:13:14 +03:00
parent 4da4cd1526
commit d67135849c
2 changed files with 26 additions and 18 deletions

View File

@ -7,7 +7,12 @@ load_dotenv(dotenv_path='.env')
PROJECT_HOST = os.getenv('PROJECT_HOST', 'http://127.0.0.1:8080') PROJECT_HOST = os.getenv('PROJECT_HOST', 'http://127.0.0.1:8080')
SANIC_PORT = int(os.getenv('SANIC_PORT', '8080')) SANIC_PORT = int(os.getenv('SANIC_PORT', '8080'))
# Path inside the running backend container where content files are visible
UPLOADS_DIR = os.getenv('UPLOADS_DIR', '/app/data') UPLOADS_DIR = os.getenv('UPLOADS_DIR', '/app/data')
# Host path where the same content directory is mounted (used for docker -v from within container)
BACKEND_DATA_DIR_HOST = os.getenv('BACKEND_DATA_DIR_HOST', '/Storage/storedContent')
# Host path for converter logs (used for docker -v). Optional.
BACKEND_LOGS_DIR_HOST = os.getenv('BACKEND_LOGS_DIR_HOST', '/Storage/logs/converter')
if not os.path.exists(UPLOADS_DIR): if not os.path.exists(UPLOADS_DIR):
os.makedirs(UPLOADS_DIR) os.makedirs(UPLOADS_DIR)

View File

@ -14,7 +14,7 @@ from app.core.logger import make_log
from app.core.models.user import User from app.core.models.user import User
from app.core.models import WalletConnection from app.core.models import WalletConnection
from app.core.storage import db_session from app.core.storage import db_session
from app.core._config import UPLOADS_DIR from app.core._config import UPLOADS_DIR, BACKEND_DATA_DIR_HOST, BACKEND_LOGS_DIR_HOST
from app.core.content.content_id import ContentId from app.core.content.content_id import ContentId
@ -43,13 +43,16 @@ async def convert_loop(memory):
return return
# Определяем путь и расширение входного файла # Определяем путь и расширение входного файла
input_file_path = f"/Storage/storedContent/{decrypted_content.hash}" # Путь внутри текущего контейнера (доступен Python процессу)
input_file_container = os.path.join(UPLOADS_DIR, decrypted_content.hash)
# Хостовый путь (нужен для docker -v маппинга при запуске конвертера)
input_file_host = os.path.join(BACKEND_DATA_DIR_HOST, decrypted_content.hash)
input_ext = (unprocessed_encrypted_content.filename.split('.')[-1] input_ext = (unprocessed_encrypted_content.filename.split('.')[-1]
if '.' in unprocessed_encrypted_content.filename else "mp4") if '.' in unprocessed_encrypted_content.filename else "mp4")
# ==== Новая логика: определение MIME-тип через python-magic ==== # ==== Новая логика: определение MIME-тип через python-magic ====
try: try:
mime_type = magic.from_file(input_file_path.replace("/Storage/storedContent", "/app/data"), mime=True) mime_type = magic.from_file(input_file_container, mime=True)
except Exception as e: except Exception as e:
make_log("ConvertProcess", f"magic probe failed: {e}", level="warning") make_log("ConvertProcess", f"magic probe failed: {e}", level="warning")
mime_type = "" mime_type = ""
@ -100,7 +103,8 @@ async def convert_loop(memory):
REQUIRED_CONVERT_OPTIONS = ['high', 'low'] # no preview for audio REQUIRED_CONVERT_OPTIONS = ['high', 'low'] # no preview for audio
converted_content = {} converted_content = {}
logs_dir = "/Storage/logs/converter" # Директория логов на хосте для docker-контейнера конвертера
logs_dir_host = BACKEND_LOGS_DIR_HOST
for option in REQUIRED_CONVERT_OPTIONS: for option in REQUIRED_CONVERT_OPTIONS:
# Set quality parameter and trim option (only for preview) # Set quality parameter and trim option (only for preview)
@ -113,14 +117,19 @@ async def convert_loop(memory):
# Generate a unique output directory for docker container # Generate a unique output directory for docker container
output_uuid = str(uuid.uuid4()) output_uuid = str(uuid.uuid4())
output_dir = f"/Storage/storedContent/converter-output/{output_uuid}" # Директория вывода в текущем контейнере (та же что и в UPLOADS_DIR, смонтирована с хоста)
output_dir_container = os.path.join(UPLOADS_DIR, "converter-output", output_uuid)
os.makedirs(output_dir_container, exist_ok=True)
# Соответствующая директория на хосте — нужна для docker -v
output_dir_host = os.path.join(BACKEND_DATA_DIR_HOST, "converter-output", output_uuid)
# Build the docker command # Build the docker command
cmd = [ cmd = [
"docker", "run", "--rm", "docker", "run", "--rm",
"-v", f"{input_file_path}:/app/input", # Важно: источники - это ХОСТОВЫЕ пути, так как docker демону они нужны на хосте
"-v", f"{output_dir}:/app/output", "-v", f"{input_file_host}:/app/input:ro",
"-v", f"{logs_dir}:/app/logs", "-v", f"{output_dir_host}:/app/output",
"-v", f"{logs_dir_host}:/app/logs",
"media_converter", "media_converter",
"--ext", input_ext, "--ext", input_ext,
"--quality", quality "--quality", quality
@ -142,7 +151,7 @@ async def convert_loop(memory):
# List files in output dir # List files in output dir
try: try:
files = os.listdir(output_dir.replace("/Storage/storedContent", "/app/data")) files = os.listdir(output_dir_container)
except Exception as e: except Exception as e:
make_log("ConvertProcess", f"Error reading output directory {output_dir}: {e}", level="error") make_log("ConvertProcess", f"Error reading output directory {output_dir}: {e}", level="error")
return return
@ -152,10 +161,7 @@ async def convert_loop(memory):
make_log("ConvertProcess", f"Expected one media file, found {len(media_files)} for option {option}", level="error") make_log("ConvertProcess", f"Expected one media file, found {len(media_files)} for option {option}", level="error")
return return
output_file = os.path.join( output_file = os.path.join(output_dir_container, media_files[0])
output_dir.replace("/Storage/storedContent", "/app/data"),
media_files[0]
)
# Compute SHA256 hash of the output file # Compute SHA256 hash of the output file
hash_process = await asyncio.create_subprocess_exec( hash_process = await asyncio.create_subprocess_exec(
@ -198,10 +204,7 @@ async def convert_loop(memory):
converted_content[option] = file_hash converted_content[option] = file_hash
# Process output.json for ffprobe_meta # Process output.json for ffprobe_meta
output_json_path = os.path.join( output_json_path = os.path.join(output_dir_container, "output.json")
output_dir.replace("/Storage/storedContent", "/app/data"),
"output.json"
)
if os.path.exists(output_json_path) and unprocessed_encrypted_content.meta.get('ffprobe_meta') is None: if os.path.exists(output_json_path) and unprocessed_encrypted_content.meta.get('ffprobe_meta') is None:
try: try:
with open(output_json_path, "r") as f: with open(output_json_path, "r") as f:
@ -215,7 +218,7 @@ async def convert_loop(memory):
# Cleanup output directory # Cleanup output directory
try: try:
shutil.rmtree(output_dir.replace("/Storage/storedContent", "/app/data")) shutil.rmtree(output_dir_container)
except Exception as e: except Exception as e:
make_log("ConvertProcess", f"Error removing output dir {output_dir}: {e}", level="warning") make_log("ConvertProcess", f"Error removing output dir {output_dir}: {e}", level="warning")