refactor: _shared.py vira subpacote, um módulo por papel
Eram 882 linhas de seis papéis sem relação, sob um nome que só dizia
"compartilhado" — o depósito onde tudo que servia a mais de um handler
acabava caindo.
media 316 transcrição em cache, corte por fala, relatório
paths 206 sandbox, limites, caminho de saída
project 116 abrir projeto, preparar modifier/generator
captions 112 SRT, VTT, listas com timestamp
detection 99 flash frames, buracos, duplicados
formatting 86 tabelas e relatórios dos handlers
O __init__ reexporta os 46 nomes, então os treze pontos que importam daqui
não mudaram.
_transcript_cut_report saiu de formatting para media: ele precisa do hint de
instalação e do _text_result, ou seja, é relatório de transcrição e não
formatação genérica — mover foi mais honesto que cruzar imports entre os
dois módulos.
Quatro testes patchavam `server_tools._shared.transcribe`; o nome agora é
ligado por _shared/media.py, então o patch passou a apontar para lá — mesmo
padrão da experiência #23.
Lint zerado, 1454 testes passando.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
368bb62706
commit
ffaebb3f72
@@ -0,0 +1,89 @@
|
||||
"""Abrir um projeto e preparar modifier/generator para editá-lo.
|
||||
|
||||
Extraído de _shared.py — ver server_tools/_shared/__init__.py.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mcp.types import TextContent
|
||||
|
||||
from fcpxml.parser import FCPXMLParser
|
||||
from fcpxml.rough_cut import RoughCutGenerator
|
||||
from fcpxml.writer import FCPXMLModifier
|
||||
|
||||
from .paths import _resolve_io_paths, _validate_filepath
|
||||
|
||||
|
||||
def _parse_project(filepath: str):
|
||||
"""Parse an FCPXML file and return the project with its primary timeline."""
|
||||
filepath = _validate_filepath(filepath, ('.fcpxml', '.fcpxmld'))
|
||||
project = FCPXMLParser().parse_file(filepath)
|
||||
if not project.timelines:
|
||||
return None, None
|
||||
return project, project.primary_timeline
|
||||
|
||||
def _text_result(text: str) -> list[TextContent]:
|
||||
"""Wrap a string in the MCP TextContent list that every tool handler returns."""
|
||||
return [TextContent(type="text", text=text)]
|
||||
|
||||
def _no_timeline():
|
||||
"""Standard response when no timelines are found."""
|
||||
return _text_result("No timelines found")
|
||||
|
||||
def _require_timeline(filepath: str):
|
||||
"""Parse FCPXML and return (project, timeline), raising if no timeline exists.
|
||||
|
||||
Centralises the repeated _parse_project + _no_timeline guard that
|
||||
appears in every read-only timeline handler. Returns a tuple so
|
||||
callers can destructure directly::
|
||||
|
||||
project, tl = _require_timeline(arguments["filepath"])
|
||||
"""
|
||||
project, tl = _parse_project(filepath)
|
||||
if not tl:
|
||||
raise _NoTimelineError()
|
||||
return project, tl
|
||||
|
||||
class _NoTimelineError(Exception):
|
||||
"""Sentinel raised by _require_timeline when no timelines exist."""
|
||||
|
||||
def _setup_modifier(
|
||||
arguments: dict,
|
||||
suffix: str = "_modified",
|
||||
) -> tuple[str, str, "FCPXMLModifier"]:
|
||||
"""Common setup for write handlers: validate paths and create modifier.
|
||||
|
||||
Consolidates the repeated validate-filepath → resolve-output-path →
|
||||
create-modifier boilerplate shared by 18+ write handlers.
|
||||
|
||||
Args:
|
||||
arguments: Tool arguments dict (must contain ``filepath``; may
|
||||
contain ``output_path``).
|
||||
suffix: Default output filename suffix when ``output_path`` is
|
||||
not provided (e.g. ``"_modified"``, ``"_flash_fixed"``).
|
||||
|
||||
Returns:
|
||||
``(filepath, output_path, modifier)`` tuple ready for the
|
||||
handler's domain-specific operation.
|
||||
"""
|
||||
filepath, output_path = _resolve_io_paths(arguments, suffix)
|
||||
modifier = FCPXMLModifier(filepath)
|
||||
return filepath, output_path, modifier
|
||||
|
||||
def _setup_generator(
|
||||
arguments: dict,
|
||||
suffix: str = "_roughcut",
|
||||
) -> tuple[str, str, "RoughCutGenerator"]:
|
||||
"""Common setup for generation handlers: validate paths and create generator.
|
||||
|
||||
Args:
|
||||
arguments: Tool arguments dict (must contain ``filepath`` and
|
||||
``output_path``).
|
||||
suffix: Default output filename suffix.
|
||||
|
||||
Returns:
|
||||
``(filepath, output_path, generator)`` tuple.
|
||||
"""
|
||||
filepath, output_path = _resolve_io_paths(arguments, suffix)
|
||||
generator = RoughCutGenerator(filepath)
|
||||
return filepath, output_path, generator
|
||||
Reference in New Issue
Block a user