subs-down-n-sync 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,195 @@
1
+ Metadata-Version: 2.4
2
+ Name: subs-down-n-sync
3
+ Version: 1.0.0
4
+ Summary: CLI to download and sync subtitles for video files using semantic embeddings + DTW
5
+ Author-email: Airton Soares <airtonnsoares@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/subs-down-n-sync/
8
+ Project-URL: Repository, https://github.com/airton-soares/subs_down_n_sync
9
+ Project-URL: Bug Tracker, https://github.com/airton-soares/subs_down_n_sync/issues
10
+ Keywords: subtitles,subtitle-sync,opensubtitles,nlp,cli,video,sentence-transformers,dtw
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Environment :: Console
14
+ Classifier: Topic :: Multimedia :: Video
15
+ Classifier: Topic :: Utilities
16
+ Classifier: Natural Language :: Portuguese (Brazilian)
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Requires-Python: >=3.12
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: subliminal>=2.2
22
+ Requires-Dist: sentence-transformers>=3.0
23
+ Requires-Dist: scipy>=1.13
24
+ Requires-Dist: setuptools<81
25
+ Requires-Dist: rich>=13
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.0; extra == "dev"
28
+ Requires-Dist: pytest-mock>=3.12; extra == "dev"
29
+ Requires-Dist: pytest-cov>=6.0; extra == "dev"
30
+ Requires-Dist: ruff>=0.9; extra == "dev"
31
+
32
+ # subs_down_n_sync
33
+
34
+ ![CI](https://github.com/airton-soares/subs_down_n_sync/actions/workflows/ci.yml/badge.svg)
35
+ [![PyPI version](https://img.shields.io/pypi/v/subs-down-n-sync)](https://pypi.org/project/subs-down-n-sync/)
36
+ [![Python versions](https://img.shields.io/pypi/pyversions/subs-down-n-sync)](https://pypi.org/project/subs-down-n-sync/)
37
+ [![License](https://img.shields.io/github/license/airton-soares/subs_down_n_sync)](LICENSE)
38
+
39
+ CLI Python para baixar e sincronizar legendas para arquivos de vídeo. Idioma padrão: **pt-BR**, configurável via flag `--lang` (qualquer tag BCP 47).
40
+
41
+ A sincronização usa embeddings semânticos multilíngues ([sentence-transformers](https://www.sbert.net/), modelo `paraphrase-multilingual-MiniLM-L12-v2`) combinados com DTW: baixa uma legenda EN de referência e alinha os cues da legenda alvo aos timestamps da referência por similaridade semântica. Legendas com match exato (hash ou release group) são usadas sem sincronização.
42
+
43
+ ## Instalação
44
+
45
+ ```bash
46
+ pip install subs-down-n-sync
47
+ ```
48
+
49
+ Instale também o `ffmpeg`:
50
+
51
+ ```bash
52
+ sudo apt install ffmpeg # Debian/Ubuntu
53
+ brew install ffmpeg # macOS
54
+ winget install Gyan.FFmpeg # Windows
55
+ ```
56
+
57
+ Configure as credenciais do OpenSubtitles:
58
+
59
+ ```bash
60
+ export OPENSUBTITLES_USERNAME="seu_usuario"
61
+ export OPENSUBTITLES_PASSWORD="sua_senha"
62
+ ```
63
+
64
+ > Para desenvolvimento, veja [Setup](#setup).
65
+
66
+ ## Setup
67
+
68
+ Linux/macOS:
69
+
70
+ ```bash
71
+ python -m venv .venv
72
+ source .venv/bin/activate
73
+ pip install -e ".[dev]"
74
+ ```
75
+
76
+ Windows (PowerShell):
77
+
78
+ ```powershell
79
+ python -m venv .venv
80
+ .\.venv\Scripts\Activate.ps1
81
+ pip install -e ".[dev]"
82
+ ```
83
+
84
+ Windows (cmd.exe):
85
+
86
+ ```cmd
87
+ python -m venv .venv
88
+ .venv\Scripts\activate.bat
89
+ pip install -e ".[dev]"
90
+ ```
91
+
92
+ Instale também o `ffmpeg` no sistema:
93
+
94
+ ```bash
95
+ sudo apt install ffmpeg # Debian/Ubuntu
96
+ brew install ffmpeg # macOS
97
+ ```
98
+
99
+ ```powershell
100
+ winget install Gyan.FFmpeg # Windows (winget)
101
+ choco install ffmpeg # Windows (Chocolatey)
102
+ scoop install ffmpeg # Windows (Scoop)
103
+ ```
104
+
105
+ Confirme que `ffmpeg` está no `PATH` rodando `ffmpeg -version` em novo terminal.
106
+
107
+ ## Configuração (uma única vez)
108
+
109
+ Linux/macOS:
110
+
111
+ ```bash
112
+ export OPENSUBTITLES_USERNAME="seu_usuario"
113
+ export OPENSUBTITLES_PASSWORD="sua_senha"
114
+ ```
115
+
116
+ Windows (PowerShell, sessão atual):
117
+
118
+ ```powershell
119
+ $env:OPENSUBTITLES_USERNAME = "seu_usuario"
120
+ $env:OPENSUBTITLES_PASSWORD = "sua_senha"
121
+ ```
122
+
123
+ Windows (persistente, próximas sessões):
124
+
125
+ ```powershell
126
+ setx OPENSUBTITLES_USERNAME "seu_usuario"
127
+ setx OPENSUBTITLES_PASSWORD "sua_senha"
128
+ ```
129
+
130
+ ## Uso
131
+
132
+ ```bash
133
+ # Default: pt-BR
134
+ subs-down-n-sync /caminho/para/filme.mkv
135
+
136
+ # Outro idioma (BCP 47: 'en', 'pt-BR', 'en-US', 'es', 'ja', ...)
137
+ subs-down-n-sync /caminho/para/filme.mkv --lang en
138
+ subs-down-n-sync /caminho/para/filme.mkv -l es
139
+
140
+ # Processar diretório inteiro (busca vídeos recursivamente)
141
+ subs-down-n-sync /caminho/para/pasta/
142
+ subs-down-n-sync /caminho/para/pasta/ --lang en
143
+ subs-down-n-sync /caminho/para/pasta/ --overwrite # sobrescreve legendas existentes
144
+ subs-down-n-sync /caminho/para/pasta/ --parallel # processa até 2 vídeos simultâneos
145
+
146
+ # Ou via módulo Python
147
+ python -m subs_down_n_sync /caminho/para/filme.mkv
148
+ ```
149
+
150
+ Ao passar um diretório, vídeos que já têm legenda (`<video>.<lang>.srt`) são pulados por padrão. Use `--overwrite` / `-o` para reprocessar. Use `--parallel` / `-p` para processar até 2 vídeos em paralelo.
151
+
152
+ Saída: `/caminho/para/filme.<lang>.srt` (ex.: `filme.pt-BR.srt`, `filme.en.srt`). Isso permite manter legendas do mesmo vídeo em idiomas diferentes sem sobrescrever.
153
+
154
+ ## Desenvolvimento
155
+
156
+ ```bash
157
+ pip install -e ".[dev]"
158
+ pytest
159
+ ```
160
+
161
+ Os testes unitários rodam com gate de cobertura de 90% (configurado em `pyproject.toml`). O CI falha se a cobertura cair abaixo disso.
162
+
163
+ Para rodar sem o gate (útil ao explorar com `-k` ou `--collect-only`):
164
+
165
+ ```bash
166
+ pytest --no-cov
167
+ ```
168
+
169
+ ## Lint e formatação
170
+
171
+ O projeto usa [Ruff](https://docs.astral.sh/ruff/) para formatação e lint.
172
+
173
+ ```bash
174
+ ruff format . # aplica formatação
175
+ ruff format --check . # verifica sem escrever (usado no CI)
176
+ ruff check . # roda lint
177
+ ruff check --fix . # aplica fixes automáticos
178
+ ```
179
+
180
+ O CI falha se `ruff format --check` ou `ruff check` encontrarem problemas.
181
+
182
+ ## Testes de integração
183
+
184
+ O projeto tem duas camadas de testes:
185
+
186
+ - **Testes unitários** (padrão, `pytest`) — rápidos, mockam `subliminal` e `sentence_transformers`. Não precisam de rede nem de binários externos além do Python.
187
+ - **Testes de integração** (`pytest -m integration`) — exercitam o pipeline real de alinhamento semântico (download do modelo `sentence-transformers` + DTW) sobre legendas reais. Requer acesso à internet no primeiro run para baixar o modelo (~120 MB), cacheado pelo Hugging Face em `~/.cache/huggingface/`.
188
+
189
+ Como rodar cada camada:
190
+
191
+ ```bash
192
+ pytest # só unit (rápido)
193
+ pytest -m integration # só integração (baixa modelo de embeddings, roda DTW real)
194
+ pytest -m "" # tudo (unit + integração)
195
+ ```
@@ -0,0 +1,164 @@
1
+ # subs_down_n_sync
2
+
3
+ ![CI](https://github.com/airton-soares/subs_down_n_sync/actions/workflows/ci.yml/badge.svg)
4
+ [![PyPI version](https://img.shields.io/pypi/v/subs-down-n-sync)](https://pypi.org/project/subs-down-n-sync/)
5
+ [![Python versions](https://img.shields.io/pypi/pyversions/subs-down-n-sync)](https://pypi.org/project/subs-down-n-sync/)
6
+ [![License](https://img.shields.io/github/license/airton-soares/subs_down_n_sync)](LICENSE)
7
+
8
+ CLI Python para baixar e sincronizar legendas para arquivos de vídeo. Idioma padrão: **pt-BR**, configurável via flag `--lang` (qualquer tag BCP 47).
9
+
10
+ A sincronização usa embeddings semânticos multilíngues ([sentence-transformers](https://www.sbert.net/), modelo `paraphrase-multilingual-MiniLM-L12-v2`) combinados com DTW: baixa uma legenda EN de referência e alinha os cues da legenda alvo aos timestamps da referência por similaridade semântica. Legendas com match exato (hash ou release group) são usadas sem sincronização.
11
+
12
+ ## Instalação
13
+
14
+ ```bash
15
+ pip install subs-down-n-sync
16
+ ```
17
+
18
+ Instale também o `ffmpeg`:
19
+
20
+ ```bash
21
+ sudo apt install ffmpeg # Debian/Ubuntu
22
+ brew install ffmpeg # macOS
23
+ winget install Gyan.FFmpeg # Windows
24
+ ```
25
+
26
+ Configure as credenciais do OpenSubtitles:
27
+
28
+ ```bash
29
+ export OPENSUBTITLES_USERNAME="seu_usuario"
30
+ export OPENSUBTITLES_PASSWORD="sua_senha"
31
+ ```
32
+
33
+ > Para desenvolvimento, veja [Setup](#setup).
34
+
35
+ ## Setup
36
+
37
+ Linux/macOS:
38
+
39
+ ```bash
40
+ python -m venv .venv
41
+ source .venv/bin/activate
42
+ pip install -e ".[dev]"
43
+ ```
44
+
45
+ Windows (PowerShell):
46
+
47
+ ```powershell
48
+ python -m venv .venv
49
+ .\.venv\Scripts\Activate.ps1
50
+ pip install -e ".[dev]"
51
+ ```
52
+
53
+ Windows (cmd.exe):
54
+
55
+ ```cmd
56
+ python -m venv .venv
57
+ .venv\Scripts\activate.bat
58
+ pip install -e ".[dev]"
59
+ ```
60
+
61
+ Instale também o `ffmpeg` no sistema:
62
+
63
+ ```bash
64
+ sudo apt install ffmpeg # Debian/Ubuntu
65
+ brew install ffmpeg # macOS
66
+ ```
67
+
68
+ ```powershell
69
+ winget install Gyan.FFmpeg # Windows (winget)
70
+ choco install ffmpeg # Windows (Chocolatey)
71
+ scoop install ffmpeg # Windows (Scoop)
72
+ ```
73
+
74
+ Confirme que `ffmpeg` está no `PATH` rodando `ffmpeg -version` em novo terminal.
75
+
76
+ ## Configuração (uma única vez)
77
+
78
+ Linux/macOS:
79
+
80
+ ```bash
81
+ export OPENSUBTITLES_USERNAME="seu_usuario"
82
+ export OPENSUBTITLES_PASSWORD="sua_senha"
83
+ ```
84
+
85
+ Windows (PowerShell, sessão atual):
86
+
87
+ ```powershell
88
+ $env:OPENSUBTITLES_USERNAME = "seu_usuario"
89
+ $env:OPENSUBTITLES_PASSWORD = "sua_senha"
90
+ ```
91
+
92
+ Windows (persistente, próximas sessões):
93
+
94
+ ```powershell
95
+ setx OPENSUBTITLES_USERNAME "seu_usuario"
96
+ setx OPENSUBTITLES_PASSWORD "sua_senha"
97
+ ```
98
+
99
+ ## Uso
100
+
101
+ ```bash
102
+ # Default: pt-BR
103
+ subs-down-n-sync /caminho/para/filme.mkv
104
+
105
+ # Outro idioma (BCP 47: 'en', 'pt-BR', 'en-US', 'es', 'ja', ...)
106
+ subs-down-n-sync /caminho/para/filme.mkv --lang en
107
+ subs-down-n-sync /caminho/para/filme.mkv -l es
108
+
109
+ # Processar diretório inteiro (busca vídeos recursivamente)
110
+ subs-down-n-sync /caminho/para/pasta/
111
+ subs-down-n-sync /caminho/para/pasta/ --lang en
112
+ subs-down-n-sync /caminho/para/pasta/ --overwrite # sobrescreve legendas existentes
113
+ subs-down-n-sync /caminho/para/pasta/ --parallel # processa até 2 vídeos simultâneos
114
+
115
+ # Ou via módulo Python
116
+ python -m subs_down_n_sync /caminho/para/filme.mkv
117
+ ```
118
+
119
+ Ao passar um diretório, vídeos que já têm legenda (`<video>.<lang>.srt`) são pulados por padrão. Use `--overwrite` / `-o` para reprocessar. Use `--parallel` / `-p` para processar até 2 vídeos em paralelo.
120
+
121
+ Saída: `/caminho/para/filme.<lang>.srt` (ex.: `filme.pt-BR.srt`, `filme.en.srt`). Isso permite manter legendas do mesmo vídeo em idiomas diferentes sem sobrescrever.
122
+
123
+ ## Desenvolvimento
124
+
125
+ ```bash
126
+ pip install -e ".[dev]"
127
+ pytest
128
+ ```
129
+
130
+ Os testes unitários rodam com gate de cobertura de 90% (configurado em `pyproject.toml`). O CI falha se a cobertura cair abaixo disso.
131
+
132
+ Para rodar sem o gate (útil ao explorar com `-k` ou `--collect-only`):
133
+
134
+ ```bash
135
+ pytest --no-cov
136
+ ```
137
+
138
+ ## Lint e formatação
139
+
140
+ O projeto usa [Ruff](https://docs.astral.sh/ruff/) para formatação e lint.
141
+
142
+ ```bash
143
+ ruff format . # aplica formatação
144
+ ruff format --check . # verifica sem escrever (usado no CI)
145
+ ruff check . # roda lint
146
+ ruff check --fix . # aplica fixes automáticos
147
+ ```
148
+
149
+ O CI falha se `ruff format --check` ou `ruff check` encontrarem problemas.
150
+
151
+ ## Testes de integração
152
+
153
+ O projeto tem duas camadas de testes:
154
+
155
+ - **Testes unitários** (padrão, `pytest`) — rápidos, mockam `subliminal` e `sentence_transformers`. Não precisam de rede nem de binários externos além do Python.
156
+ - **Testes de integração** (`pytest -m integration`) — exercitam o pipeline real de alinhamento semântico (download do modelo `sentence-transformers` + DTW) sobre legendas reais. Requer acesso à internet no primeiro run para baixar o modelo (~120 MB), cacheado pelo Hugging Face em `~/.cache/huggingface/`.
157
+
158
+ Como rodar cada camada:
159
+
160
+ ```bash
161
+ pytest # só unit (rápido)
162
+ pytest -m integration # só integração (baixa modelo de embeddings, roda DTW real)
163
+ pytest -m "" # tudo (unit + integração)
164
+ ```
@@ -0,0 +1,76 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "subs-down-n-sync"
7
+ version = "1.0.0"
8
+ description = "CLI to download and sync subtitles for video files using semantic embeddings + DTW"
9
+ requires-python = ">=3.12"
10
+ authors = [{name = "Airton Soares", email = "airtonnsoares@gmail.com"}]
11
+ license = {text = "MIT"}
12
+ readme = "README.md"
13
+ keywords = ["subtitles", "subtitle-sync", "opensubtitles", "nlp", "cli", "video", "sentence-transformers", "dtw"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Environment :: Console",
18
+ "Topic :: Multimedia :: Video",
19
+ "Topic :: Utilities",
20
+ "Natural Language :: Portuguese (Brazilian)",
21
+ "Operating System :: OS Independent",
22
+ "License :: OSI Approved :: MIT License",
23
+ ]
24
+ dependencies = [
25
+ "subliminal>=2.2",
26
+ "sentence-transformers>=3.0",
27
+ "scipy>=1.13",
28
+ "setuptools<81",
29
+ "rich>=13",
30
+ ]
31
+
32
+ [project.scripts]
33
+ subs-down-n-sync = "subs_down_n_sync.cli:main"
34
+
35
+ [project.urls]
36
+ Homepage = "https://pypi.org/project/subs-down-n-sync/"
37
+ Repository = "https://github.com/airton-soares/subs_down_n_sync"
38
+ "Bug Tracker" = "https://github.com/airton-soares/subs_down_n_sync/issues"
39
+
40
+ [project.optional-dependencies]
41
+ dev = [
42
+ "pytest>=8.0",
43
+ "pytest-mock>=3.12",
44
+ "pytest-cov>=6.0",
45
+ "ruff>=0.9",
46
+ ]
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.pytest.ini_options]
52
+ markers = ["integration: testes que dependem de ffmpeg, stable-ts e rede"]
53
+ addopts = "-m 'not integration' --cov=src/subs_down_n_sync --cov-report=term-missing --cov-fail-under=90"
54
+
55
+ [tool.ruff]
56
+ target-version = "py312"
57
+ line-length = 100
58
+
59
+ [tool.ruff.lint]
60
+ select = ["E", "F", "W", "I", "UP", "B", "SIM"]
61
+
62
+ [tool.ruff.format]
63
+ quote-style = "double"
64
+
65
+ [tool.coverage.run]
66
+ source = ["src/subs_down_n_sync"]
67
+
68
+ [tool.coverage.report]
69
+ fail_under = 90
70
+
71
+ [tool.semantic_release]
72
+ version_toml = ["pyproject.toml:project.version"]
73
+ version_variables = ["src/subs_down_n_sync/__init__.py:__version__"]
74
+ branch = "main"
75
+ build_command = "pip install build && python -m build"
76
+ commit_message = "chore(release): {version} [skip ci]"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ __version__ = "1.0.0"
2
+
3
+ from subs_down_n_sync.core import run
4
+
5
+ __all__ = ["run", "__version__"]
@@ -0,0 +1,3 @@
1
+ from subs_down_n_sync.cli import main
2
+
3
+ main()