- definido projeto com uma sequência e múltiplos arquivos de mídia - criada persistência de projeto com uma sequência e seleções de faixas e clipes - criada guia Projeto para selecionar sequência, faixas e clipes do Premiere - adicionada gravação das seleções da guia Projeto no SQLite Resumo: - 10 arquivos alterados - 4 novos - 6 modificados - 0 removidos 6 files changed, 71 insertions(+), 2 deletions(-) Arquivos: - .jhonny/analises.db - CONTEXT.md - code/cep-plugin/index.html - code/cep-plugin/main.js - code/engine/persistencia/__init__.py - code/engine/persistencia/esquema.py - code/cep-plugin/abas/ - code/engine/persistencia/repositorio_de_projetos.py - code/engine/registrar_projeto_de_edicao.py - code/engine/testes/test_repositorio_de_projetos.py
80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
"""Persistência dos projetos de edição e das seleções da guia Projeto."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
from dataclasses import dataclass
|
|
|
|
|
|
class ErroDeProjeto(ValueError):
|
|
"""Projeto inválido para persistência."""
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ProjetoDeEdicao:
|
|
"""Projeto associado a exatamente uma sequência do Premiere."""
|
|
|
|
nome: str
|
|
video_id: str
|
|
faixas: tuple[str, ...] = ()
|
|
clipes: tuple[str, ...] = ()
|
|
status: str = "aberto"
|
|
|
|
|
|
class RepositorioDeProjetos:
|
|
"""Grava e recupera projetos sem duplicar dados da timeline."""
|
|
|
|
def __init__(self, conexao: sqlite3.Connection) -> None:
|
|
"""Inicializa o repositório com uma conexão SQLite preparada."""
|
|
self.conexao = conexao
|
|
|
|
def registrar(self, projeto: ProjetoDeEdicao) -> int:
|
|
"""Cria um projeto e grava suas faixas e clipes selecionados."""
|
|
if not projeto.nome.strip():
|
|
raise ErroDeProjeto("O projeto precisa ter um nome.")
|
|
if not projeto.video_id.strip():
|
|
raise ErroDeProjeto("O projeto precisa ter uma sequência.")
|
|
with self.conexao:
|
|
cursor = self.conexao.execute(
|
|
"""INSERT INTO projetos_de_edicao (video_id, nome, status)
|
|
VALUES (?, ?, ?)""",
|
|
(projeto.video_id, projeto.nome, projeto.status),
|
|
)
|
|
projeto_id = int(cursor.lastrowid)
|
|
self.conexao.executemany(
|
|
"INSERT INTO faixas_do_projeto (projeto_id, faixa_id) VALUES (?, ?)",
|
|
[(projeto_id, faixa_id) for faixa_id in projeto.faixas],
|
|
)
|
|
self.conexao.executemany(
|
|
"INSERT INTO clipes_do_projeto (projeto_id, clipe_id) VALUES (?, ?)",
|
|
[(projeto_id, clipe_id) for clipe_id in projeto.clipes],
|
|
)
|
|
return projeto_id
|
|
|
|
def carregar(self, projeto_id: int) -> dict[str, object] | None:
|
|
"""Carrega um projeto com sua sequência, faixas e clipes selecionados."""
|
|
linha = self.conexao.execute(
|
|
"SELECT * FROM projetos_de_edicao WHERE id = ?", (projeto_id,),
|
|
).fetchone()
|
|
if linha is None:
|
|
return None
|
|
return {
|
|
"id": linha["id"], "nome": linha["nome"], "video_id": linha["video_id"],
|
|
"status": linha["status"], "faixas": [
|
|
r["faixa_id"] for r in self.conexao.execute(
|
|
"""SELECT faixa_id FROM faixas_do_projeto
|
|
WHERE projeto_id = ? AND selecionada = 1 ORDER BY rowid""",
|
|
(projeto_id,),
|
|
)
|
|
], "clipes": [
|
|
r["clipe_id"] for r in self.conexao.execute(
|
|
"""SELECT clipe_id FROM clipes_do_projeto
|
|
WHERE projeto_id = ? AND selecionado = 1 ORDER BY rowid""",
|
|
(projeto_id,),
|
|
)
|
|
],
|
|
}
|
|
|
|
|
|
__all__ = ["ErroDeProjeto", "ProjetoDeEdicao", "RepositorioDeProjetos"]
|