Files
gart/code/fcpxml/writer/modifier.py
João HenriqueandClaude Opus 5 4f5cf94443 refactor: writer.py vira pacote, um módulo por assunto
O writer tinha 4.199 linhas, das quais 3.300 numa única classe com dezoito
assuntos dentro. Achar o trecho de zoom exigia rolar por marcadores,
velocidade e legendas.

Agora é o pacote fcpxml/writer/, com um arquivo por assunto e o
FCPXMLModifier montado por composição de mixins. Mixins, e não objetos
separados, porque todas essas operações mexem no mesmo documento e nos
mesmos índices — separá-las em objetos independentes transformaria toda
chamada interna em travessia de fronteira sem nada em troca. A divisão que
importa aqui é de leitura, não de estado.

Nenhuma mudança de comportamento e nenhuma alteração nos ~50 pontos que
importam do writer: o __init__ re-exporta tudo, inclusive os nomes com
underscore que a suíte já usava.

    core      723   carga, índices, navegação na spine, save
    titles    600   títulos e legendas dinâmicas
    cut       333   dividir, cortar faixas, apagar
    speed     297   velocidade e zoom
    (+ 20 módulos menores)

Único ajuste de chamada: quatro testes faziam patch em
fcpxml.writer.subprocess, que agora mora em writer.document (ver
Engine/docs/05_EXPERIENCIAS.md #23).

Lint zerado, 1441 testes passando.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 21:38:49 -04:00

65 lines
2.2 KiB
Python

"""FCPXMLModifier — a edição de FCPXML montada a partir de um mixin por assunto.
A classe era um bloco de 3.300 linhas com dezoito assuntos dentro. Ela continua
sendo uma classe só para quem chama — `modifier.add_marker(...)` não mudou — mas
cada assunto agora mora no seu próprio arquivo e pode ser lido inteiro sem rolar
por marcadores, velocidade e legendas até achar o trecho procurado.
Mixins em vez de objetos separados por uma razão concreta: todas essas operações
mexem no *mesmo* documento e dependem dos mesmos índices e da mesma navegação na
spine (`_require_clip`, `_iter_spine_clips`, `_ripple_after_clip`). Separá-las em
objetos independentes obrigaria cada um a carregar uma referência de volta ao
documento e transformaria toda chamada interna em travessia de fronteira, sem
nada em troca — a divisão que importa aqui é de *leitura*, não de estado.
A ordem abaixo é irrelevante para o comportamento: nenhum mixin sobrescreve
método de outro; cada um contribui com um conjunto disjunto de operações.
"""
from .audio import AudioMixin
from .compound import CompoundMixin
from .connected import ConnectedMixin
from .core import ModifierCore
from .cut import CutMixin
from .insert import InsertMixin
from .markers import MarkersMixin
from .rapid import RapidMixin
from .reformat import ReformatMixin
from .relink import RelinkMixin
from .reorder import ReorderMixin
from .roles import RolesMixin
from .selection import SelectionMixin
from .silence import SilenceMixin
from .speed import SpeedMixin
from .titles import TitlesMixin
from .transitions import TransitionsMixin
from .trim import TrimMixin
class FCPXMLModifier(
RelinkMixin,
MarkersMixin,
TrimMixin,
ReorderMixin,
TransitionsMixin,
SpeedMixin,
CutMixin,
RapidMixin,
SelectionMixin,
InsertMixin,
ConnectedMixin,
TitlesMixin,
AudioMixin,
CompoundMixin,
RolesMixin,
ReformatMixin,
SilenceMixin,
ModifierCore,
):
"""Carrega um FCPXML, aplica edições cirúrgicas e salva.
Interface de escrita usada por todos os handlers do servidor MCP. A
documentação de cada operação está no mixin correspondente; o
carregamento, os índices e o `save` estão em `core.ModifierCore`.
"""