toolost-uploader 0.1.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.
- toolost_uploader-0.1.0/LICENSE +21 -0
- toolost_uploader-0.1.0/MANIFEST.in +11 -0
- toolost_uploader-0.1.0/PKG-INFO +248 -0
- toolost_uploader-0.1.0/README.md +221 -0
- toolost_uploader-0.1.0/docs/schemas/manifest-v1.schema.json +62 -0
- toolost_uploader-0.1.0/docs/schemas/validate-result-v1.schema.json +23 -0
- toolost_uploader-0.1.0/pyproject.toml +45 -0
- toolost_uploader-0.1.0/setup.cfg +4 -0
- toolost_uploader-0.1.0/tests/test_approval.py +110 -0
- toolost_uploader-0.1.0/tests/test_browser.py +114 -0
- toolost_uploader-0.1.0/tests/test_cli.py +197 -0
- toolost_uploader-0.1.0/tests/test_fake_flow.py +105 -0
- toolost_uploader-0.1.0/tests/test_fake_ui.py +186 -0
- toolost_uploader-0.1.0/tests/test_fake_upload.py +172 -0
- toolost_uploader-0.1.0/tests/test_fake_workflow.py +155 -0
- toolost_uploader-0.1.0/tests/test_gated_upload.py +116 -0
- toolost_uploader-0.1.0/tests/test_gather.py +50 -0
- toolost_uploader-0.1.0/tests/test_journal.py +197 -0
- toolost_uploader-0.1.0/tests/test_live_draft.py +289 -0
- toolost_uploader-0.1.0/tests/test_live_recovery.py +452 -0
- toolost_uploader-0.1.0/tests/test_packaging.py +81 -0
- toolost_uploader-0.1.0/tests/test_read_only.py +86 -0
- toolost_uploader-0.1.0/tests/test_storage.py +321 -0
- toolost_uploader-0.1.0/tests/test_validate.py +220 -0
- toolost_uploader-0.1.0/toolost_uploader/__init__.py +3 -0
- toolost_uploader-0.1.0/toolost_uploader/__main__.py +3 -0
- toolost_uploader-0.1.0/toolost_uploader/approval.py +116 -0
- toolost_uploader-0.1.0/toolost_uploader/browser.py +253 -0
- toolost_uploader-0.1.0/toolost_uploader/cli.py +333 -0
- toolost_uploader-0.1.0/toolost_uploader/fake_flow.py +63 -0
- toolost_uploader-0.1.0/toolost_uploader/fake_ui.py +166 -0
- toolost_uploader-0.1.0/toolost_uploader/fake_upload.py +146 -0
- toolost_uploader-0.1.0/toolost_uploader/fake_workflow.py +160 -0
- toolost_uploader-0.1.0/toolost_uploader/journal.py +171 -0
- toolost_uploader-0.1.0/toolost_uploader/live_draft.py +468 -0
- toolost_uploader-0.1.0/toolost_uploader/live_journal.py +129 -0
- toolost_uploader-0.1.0/toolost_uploader/read_only.py +126 -0
- toolost_uploader-0.1.0/toolost_uploader/storage.py +282 -0
- toolost_uploader-0.1.0/toolost_uploader/validation.py +241 -0
- toolost_uploader-0.1.0/toolost_uploader.egg-info/PKG-INFO +248 -0
- toolost_uploader-0.1.0/toolost_uploader.egg-info/SOURCES.txt +43 -0
- toolost_uploader-0.1.0/toolost_uploader.egg-info/dependency_links.txt +1 -0
- toolost_uploader-0.1.0/toolost_uploader.egg-info/entry_points.txt +2 -0
- toolost_uploader-0.1.0/toolost_uploader.egg-info/requires.txt +6 -0
- toolost_uploader-0.1.0/toolost_uploader.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gunamaya / KiriminAja
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: toolost-uploader
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI and Playwright automation tool for Too Lost music release manifests
|
|
5
|
+
Author-email: Gunamaya <developer@kiriminaja.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/gunamaya/toolost-uploader
|
|
8
|
+
Project-URL: Repository, https://github.com/gunamaya/toolost-uploader
|
|
9
|
+
Project-URL: Issues, https://github.com/gunamaya/toolost-uploader/issues
|
|
10
|
+
Keywords: too-lost,music-distribution,uploader,playwright,automation
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: playwright<2,>=1.40.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: build<2,>=1.2.2; extra == "dev"
|
|
24
|
+
Requires-Dist: twine<6,>=5.0.0; extra == "dev"
|
|
25
|
+
Requires-Dist: jsonschema<5,>=4.26; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# Toolost Uploader
|
|
29
|
+
|
|
30
|
+
CLI & Playwright Automation Tool untuk manajemen dan upload draft rilis [Too Lost](https://toolost.com) berbasis manifest JSON.
|
|
31
|
+
|
|
32
|
+
[](https://pypi.org/project/toolost-uploader/)
|
|
33
|
+
[](https://www.python.org/)
|
|
34
|
+
[](LICENSE)
|
|
35
|
+
[](#pengujian--pengembangan)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Fitur Utama
|
|
40
|
+
|
|
41
|
+
- **Validasi Manifest Offline**: Memvalidasi metadata rilis (Single & Album), resolusi artwork (3000×3000px), format audio (MP3/WAV/FLAC), dan kecocokan hash integritas berkas (SHA-256) tanpa membuka jaringan atau browser.
|
|
42
|
+
- **Sesi Browser Mandiri & Aman**: Membuka Google Chrome biasa di profil lokal terisolasi (`.local/profiles/<alias>`) agar operator dapat login manual dengan aman tanpa menyimpan password/cookie mentah di kode repo.
|
|
43
|
+
- **Auto-Bootup & Readiness Check**: Diagnosa otomatis ketersediaan binary Chrome, status lock profil, port CDP (Chrome DevTools Protocol loopback), dan verifikasi sesi login aktif Too Lost terhadap `--expected-account`.
|
|
44
|
+
- **Eksekutor Playwright Single & Multi-Track Album**: Mengotomatisasi pemilihan tipe rilis, pengisian judul, upload & encoding artwork, multi-track audio, penataan urutan track, pengisian metadata AI per-track, hingga eksekusi simpan perubahan (*Save Changes*).
|
|
45
|
+
- **Safety First (Draft-Only Guard)**: Eksekusi dibatasi secara ketat hanya sampai penyimpanan draft (`--draft-only`). Tool ini **tidak pernah** menekan tombol Publish atau memicu distribusi rilis.
|
|
46
|
+
- **Desain Integrasi Subprocess**: Format keluaran stdout JSON murni yang deterministik dan aliran log progres real-time ke stderr, sangat ramah untuk integrasi aplikasi induk seperti [yt-to-flowmusic](docs/INTEGRATION-PLAN.md).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Instalasi
|
|
51
|
+
|
|
52
|
+
### Dari PyPI (Rekomendasi)
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
pip install toolost-uploader
|
|
56
|
+
playwright install chromium
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Dari Source / Git
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
git clone https://github.com/gunamaya/toolost-uploader.git
|
|
63
|
+
cd toolost-uploader
|
|
64
|
+
python3 -m venv .venv
|
|
65
|
+
source .venv/bin/activate
|
|
66
|
+
pip install -e .
|
|
67
|
+
playwright install chromium
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Panduan Penggunaan Cepat
|
|
73
|
+
|
|
74
|
+
Alur kerja umum terdiri dari 4 langkah berurutan:
|
|
75
|
+
|
|
76
|
+
```mermaid
|
|
77
|
+
flowchart LR
|
|
78
|
+
A["1. Validasi Manifest<br/>(toolost validate)"] --> B["2. Setup Browser Login<br/>(toolost setup)"]
|
|
79
|
+
B --> C["3. Cek Kesiapan<br/>(toolost check)"]
|
|
80
|
+
C --> D["4. Upload Simpan Draft<br/>(toolost upload --draft-only)"]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 1. Validasi Manifest Rilis (Offline)
|
|
84
|
+
|
|
85
|
+
Periksa integritas manifest JSON dan kecocokan hash SHA-256 berkas lokal:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
toolost validate path/to/manifest.json --json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 2. Setup Sesi Browser (Login Manual Operator)
|
|
92
|
+
|
|
93
|
+
Buka browser Chrome lokal untuk login manual ke portal Too Lost. Sesi login akan disimpan secara privat di folder profil lokal:
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
toolost setup --profile production
|
|
97
|
+
```
|
|
98
|
+
*Tutup jendela Chrome setelah selesai login.*
|
|
99
|
+
|
|
100
|
+
### 3. Diagnosa Kesiapan Lingkungan (Readiness Check)
|
|
101
|
+
|
|
102
|
+
Pastikan Google Chrome, port CDP, dan sesi akun siap:
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
toolost check --profile production --expected-account 422512 --auto-bootup --json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Contoh keluaran JSON (`exit code 0`):
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"status": "ready",
|
|
112
|
+
"chrome_binary": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
113
|
+
"profile_dir": "/path/to/.local/profiles/production",
|
|
114
|
+
"cdp_url": "http://127.0.0.1:9437",
|
|
115
|
+
"auth": {
|
|
116
|
+
"status": "authenticated",
|
|
117
|
+
"account_id": "422512"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 4. Unggah & Simpan Draft Rilis
|
|
123
|
+
|
|
124
|
+
Jalankan otomatisasi upload Playwright. Port CDP akan otomatis di-bootup bila belum aktif:
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
toolost upload path/to/manifest.json \
|
|
128
|
+
--draft-only \
|
|
129
|
+
--profile production \
|
|
130
|
+
--expected-account 422512 \
|
|
131
|
+
--approve-draft \
|
|
132
|
+
--accept-ui-date \
|
|
133
|
+
--verbose \
|
|
134
|
+
--json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Contoh keluaran JSON sukses:
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"status": "draft_saved_subset",
|
|
141
|
+
"run_id": "20261026-154000-album-test",
|
|
142
|
+
"draft_id": "2004317",
|
|
143
|
+
"warnings": [
|
|
144
|
+
"Tanggal UI diwarisi; bukan release_date manifest terverifikasi.",
|
|
145
|
+
"Remote track identity dan rights/services belum diverifikasi; bukan siap distribusi."
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Spesifikasi Manifest JSON (Schema v1)
|
|
153
|
+
|
|
154
|
+
Contoh manifest untuk rilis Album multi-track:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"schema_version": 1,
|
|
159
|
+
"release_id": "album-project-001",
|
|
160
|
+
"release_type": "album",
|
|
161
|
+
"title": "Album Eksperimental FlowMusic",
|
|
162
|
+
"release_date": "2026-11-01",
|
|
163
|
+
"artwork": {
|
|
164
|
+
"path": "/path/to/artwork-3000x3000.png",
|
|
165
|
+
"sha256": "338ca5ab7fb090dfa5b6cdc8fd6c68f2f8afa939266e412d85ee35187b275de6"
|
|
166
|
+
},
|
|
167
|
+
"tracks": [
|
|
168
|
+
{
|
|
169
|
+
"track_id": "track-01",
|
|
170
|
+
"title": "Terangnya Belum Pulang",
|
|
171
|
+
"audio": {
|
|
172
|
+
"path": "/path/to/track-01.mp3",
|
|
173
|
+
"sha256": "53431441811b965acc69664ec4e2dcf47d5765c2ddc483f4daf49ded30a7214d"
|
|
174
|
+
},
|
|
175
|
+
"ai_assisted": true
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"track_id": "track-02",
|
|
179
|
+
"title": "Sungai Teh Susu",
|
|
180
|
+
"audio": {
|
|
181
|
+
"path": "/path/to/track-02.mp3",
|
|
182
|
+
"sha256": "4278102d0dcc1ba4e1886ba518552c1a974a8f88679536a021b3896eaecf61f1"
|
|
183
|
+
},
|
|
184
|
+
"ai_assisted": true
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Referensi Kode Keluar (Exit Codes)
|
|
193
|
+
|
|
194
|
+
| Exit Code | Status JSON | Makna & Tindakan Penanganan |
|
|
195
|
+
|---|---|---|
|
|
196
|
+
| **`0`** | `valid`, `ready`, `draft_saved_subset` | Eksekusi sukses. Payload JSON memuat informasi rilis / kesiapan. |
|
|
197
|
+
| **`2`** | `invalid_input`, `login_required`, `account_mismatch` | Argumen salah, hash aset tidak cocok, atau sesi login perlu diperbarui melalui `toolost setup`. |
|
|
198
|
+
| **`4`** | `reconciliation_required` | Operasi dihentikan aman (*fail-stop*). Periksa status browser atau koneksi. Hindari melakukan *retry* buta. |
|
|
199
|
+
| **`5`** | Error I/O / OS | File tidak ditemukan atau binary Chrome gagal diluncurkan. |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Pengujian & Pengembangan
|
|
204
|
+
|
|
205
|
+
Menjalankan seluruh rangkaian tes unit offline (stdlib, tanpa memerlukan login atau koneksi eksternal):
|
|
206
|
+
|
|
207
|
+
```sh
|
|
208
|
+
python3 -m unittest discover -s tests -v
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Uji sanitasi paket wheel dan instalasi lingkungan terisolasi:
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
pip install -e '.[dev]'
|
|
215
|
+
uv build
|
|
216
|
+
TOOLOST_TEST_DIST_DIR=dist python3 -m unittest tests/test_packaging.py -v
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Pemeriksaan gaya kode dan whitespace git:
|
|
220
|
+
|
|
221
|
+
```sh
|
|
222
|
+
git diff --check
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Dokumentasi Arsitektur & Riset
|
|
228
|
+
|
|
229
|
+
- [Rencana Integrasi ke yt-to-flowmusic](docs/INTEGRATION-PLAN.md) — Arsitektur adapter subprocess async & Textual UI.
|
|
230
|
+
- [Rencana Packaging & Distribusi PyPI](docs/PACKAGING-PLAN.md) — Roadmap dan checklist packaging.
|
|
231
|
+
- [Antrean Pekerjaan Utama & Backlog](docs/ANTRIAN-PEKERJAAN-UTAMA.md) — Pelacakan status task engineering, klaim, dan acceptance.
|
|
232
|
+
- [Riwayat Checkpoint Rekayasa](docs/backlog/CHECKPOINT-HISTORY.md) — Bukti eksekusi dan log verifikasi.
|
|
233
|
+
- [Review CLI & Analisis Kontrak](docs/CLI-REVIEW.md) — Pemetaan fitur yang diimplementasikan vs proposed.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Kebijakan Keamanan & Privasi
|
|
238
|
+
|
|
239
|
+
1. **Penyimpanan Sesi Lokal**: Folder `.local/` berisi session cookie Chrome privat dan attempt journal tidak pernah di-commit atau dimasukkan ke dalam paket distribusi sdist/wheel.
|
|
240
|
+
2. **Tanpa Otomasi Kredensial**: Tool ini tidak membaca password operator, tidak melakukan scraping cookie secara ilegal, dan tidak mencoba melewati CAPTCHA/2FA.
|
|
241
|
+
3. **Draft Only**: Operasi rilis dihentikan di level penyimpanan draft untuk ditinjau oleh operator manusia sebelum proses rilis aktual.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Lisensi
|
|
246
|
+
|
|
247
|
+
Proyek ini didistribusikan di bawah lisensi [MIT License](LICENSE).
|
|
248
|
+
Hak Cipta (c) 2026 Gunamaya / KiriminAja.
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Toolost Uploader
|
|
2
|
+
|
|
3
|
+
CLI & Playwright Automation Tool untuk manajemen dan upload draft rilis [Too Lost](https://toolost.com) berbasis manifest JSON.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/toolost-uploader/)
|
|
6
|
+
[](https://www.python.org/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](#pengujian--pengembangan)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Fitur Utama
|
|
13
|
+
|
|
14
|
+
- **Validasi Manifest Offline**: Memvalidasi metadata rilis (Single & Album), resolusi artwork (3000×3000px), format audio (MP3/WAV/FLAC), dan kecocokan hash integritas berkas (SHA-256) tanpa membuka jaringan atau browser.
|
|
15
|
+
- **Sesi Browser Mandiri & Aman**: Membuka Google Chrome biasa di profil lokal terisolasi (`.local/profiles/<alias>`) agar operator dapat login manual dengan aman tanpa menyimpan password/cookie mentah di kode repo.
|
|
16
|
+
- **Auto-Bootup & Readiness Check**: Diagnosa otomatis ketersediaan binary Chrome, status lock profil, port CDP (Chrome DevTools Protocol loopback), dan verifikasi sesi login aktif Too Lost terhadap `--expected-account`.
|
|
17
|
+
- **Eksekutor Playwright Single & Multi-Track Album**: Mengotomatisasi pemilihan tipe rilis, pengisian judul, upload & encoding artwork, multi-track audio, penataan urutan track, pengisian metadata AI per-track, hingga eksekusi simpan perubahan (*Save Changes*).
|
|
18
|
+
- **Safety First (Draft-Only Guard)**: Eksekusi dibatasi secara ketat hanya sampai penyimpanan draft (`--draft-only`). Tool ini **tidak pernah** menekan tombol Publish atau memicu distribusi rilis.
|
|
19
|
+
- **Desain Integrasi Subprocess**: Format keluaran stdout JSON murni yang deterministik dan aliran log progres real-time ke stderr, sangat ramah untuk integrasi aplikasi induk seperti [yt-to-flowmusic](docs/INTEGRATION-PLAN.md).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Instalasi
|
|
24
|
+
|
|
25
|
+
### Dari PyPI (Rekomendasi)
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pip install toolost-uploader
|
|
29
|
+
playwright install chromium
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Dari Source / Git
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
git clone https://github.com/gunamaya/toolost-uploader.git
|
|
36
|
+
cd toolost-uploader
|
|
37
|
+
python3 -m venv .venv
|
|
38
|
+
source .venv/bin/activate
|
|
39
|
+
pip install -e .
|
|
40
|
+
playwright install chromium
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Panduan Penggunaan Cepat
|
|
46
|
+
|
|
47
|
+
Alur kerja umum terdiri dari 4 langkah berurutan:
|
|
48
|
+
|
|
49
|
+
```mermaid
|
|
50
|
+
flowchart LR
|
|
51
|
+
A["1. Validasi Manifest<br/>(toolost validate)"] --> B["2. Setup Browser Login<br/>(toolost setup)"]
|
|
52
|
+
B --> C["3. Cek Kesiapan<br/>(toolost check)"]
|
|
53
|
+
C --> D["4. Upload Simpan Draft<br/>(toolost upload --draft-only)"]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 1. Validasi Manifest Rilis (Offline)
|
|
57
|
+
|
|
58
|
+
Periksa integritas manifest JSON dan kecocokan hash SHA-256 berkas lokal:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
toolost validate path/to/manifest.json --json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. Setup Sesi Browser (Login Manual Operator)
|
|
65
|
+
|
|
66
|
+
Buka browser Chrome lokal untuk login manual ke portal Too Lost. Sesi login akan disimpan secara privat di folder profil lokal:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
toolost setup --profile production
|
|
70
|
+
```
|
|
71
|
+
*Tutup jendela Chrome setelah selesai login.*
|
|
72
|
+
|
|
73
|
+
### 3. Diagnosa Kesiapan Lingkungan (Readiness Check)
|
|
74
|
+
|
|
75
|
+
Pastikan Google Chrome, port CDP, dan sesi akun siap:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
toolost check --profile production --expected-account 422512 --auto-bootup --json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Contoh keluaran JSON (`exit code 0`):
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"status": "ready",
|
|
85
|
+
"chrome_binary": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
86
|
+
"profile_dir": "/path/to/.local/profiles/production",
|
|
87
|
+
"cdp_url": "http://127.0.0.1:9437",
|
|
88
|
+
"auth": {
|
|
89
|
+
"status": "authenticated",
|
|
90
|
+
"account_id": "422512"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 4. Unggah & Simpan Draft Rilis
|
|
96
|
+
|
|
97
|
+
Jalankan otomatisasi upload Playwright. Port CDP akan otomatis di-bootup bila belum aktif:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
toolost upload path/to/manifest.json \
|
|
101
|
+
--draft-only \
|
|
102
|
+
--profile production \
|
|
103
|
+
--expected-account 422512 \
|
|
104
|
+
--approve-draft \
|
|
105
|
+
--accept-ui-date \
|
|
106
|
+
--verbose \
|
|
107
|
+
--json
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Contoh keluaran JSON sukses:
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"status": "draft_saved_subset",
|
|
114
|
+
"run_id": "20261026-154000-album-test",
|
|
115
|
+
"draft_id": "2004317",
|
|
116
|
+
"warnings": [
|
|
117
|
+
"Tanggal UI diwarisi; bukan release_date manifest terverifikasi.",
|
|
118
|
+
"Remote track identity dan rights/services belum diverifikasi; bukan siap distribusi."
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Spesifikasi Manifest JSON (Schema v1)
|
|
126
|
+
|
|
127
|
+
Contoh manifest untuk rilis Album multi-track:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"schema_version": 1,
|
|
132
|
+
"release_id": "album-project-001",
|
|
133
|
+
"release_type": "album",
|
|
134
|
+
"title": "Album Eksperimental FlowMusic",
|
|
135
|
+
"release_date": "2026-11-01",
|
|
136
|
+
"artwork": {
|
|
137
|
+
"path": "/path/to/artwork-3000x3000.png",
|
|
138
|
+
"sha256": "338ca5ab7fb090dfa5b6cdc8fd6c68f2f8afa939266e412d85ee35187b275de6"
|
|
139
|
+
},
|
|
140
|
+
"tracks": [
|
|
141
|
+
{
|
|
142
|
+
"track_id": "track-01",
|
|
143
|
+
"title": "Terangnya Belum Pulang",
|
|
144
|
+
"audio": {
|
|
145
|
+
"path": "/path/to/track-01.mp3",
|
|
146
|
+
"sha256": "53431441811b965acc69664ec4e2dcf47d5765c2ddc483f4daf49ded30a7214d"
|
|
147
|
+
},
|
|
148
|
+
"ai_assisted": true
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"track_id": "track-02",
|
|
152
|
+
"title": "Sungai Teh Susu",
|
|
153
|
+
"audio": {
|
|
154
|
+
"path": "/path/to/track-02.mp3",
|
|
155
|
+
"sha256": "4278102d0dcc1ba4e1886ba518552c1a974a8f88679536a021b3896eaecf61f1"
|
|
156
|
+
},
|
|
157
|
+
"ai_assisted": true
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Referensi Kode Keluar (Exit Codes)
|
|
166
|
+
|
|
167
|
+
| Exit Code | Status JSON | Makna & Tindakan Penanganan |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| **`0`** | `valid`, `ready`, `draft_saved_subset` | Eksekusi sukses. Payload JSON memuat informasi rilis / kesiapan. |
|
|
170
|
+
| **`2`** | `invalid_input`, `login_required`, `account_mismatch` | Argumen salah, hash aset tidak cocok, atau sesi login perlu diperbarui melalui `toolost setup`. |
|
|
171
|
+
| **`4`** | `reconciliation_required` | Operasi dihentikan aman (*fail-stop*). Periksa status browser atau koneksi. Hindari melakukan *retry* buta. |
|
|
172
|
+
| **`5`** | Error I/O / OS | File tidak ditemukan atau binary Chrome gagal diluncurkan. |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Pengujian & Pengembangan
|
|
177
|
+
|
|
178
|
+
Menjalankan seluruh rangkaian tes unit offline (stdlib, tanpa memerlukan login atau koneksi eksternal):
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
python3 -m unittest discover -s tests -v
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Uji sanitasi paket wheel dan instalasi lingkungan terisolasi:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
pip install -e '.[dev]'
|
|
188
|
+
uv build
|
|
189
|
+
TOOLOST_TEST_DIST_DIR=dist python3 -m unittest tests/test_packaging.py -v
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Pemeriksaan gaya kode dan whitespace git:
|
|
193
|
+
|
|
194
|
+
```sh
|
|
195
|
+
git diff --check
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Dokumentasi Arsitektur & Riset
|
|
201
|
+
|
|
202
|
+
- [Rencana Integrasi ke yt-to-flowmusic](docs/INTEGRATION-PLAN.md) — Arsitektur adapter subprocess async & Textual UI.
|
|
203
|
+
- [Rencana Packaging & Distribusi PyPI](docs/PACKAGING-PLAN.md) — Roadmap dan checklist packaging.
|
|
204
|
+
- [Antrean Pekerjaan Utama & Backlog](docs/ANTRIAN-PEKERJAAN-UTAMA.md) — Pelacakan status task engineering, klaim, dan acceptance.
|
|
205
|
+
- [Riwayat Checkpoint Rekayasa](docs/backlog/CHECKPOINT-HISTORY.md) — Bukti eksekusi dan log verifikasi.
|
|
206
|
+
- [Review CLI & Analisis Kontrak](docs/CLI-REVIEW.md) — Pemetaan fitur yang diimplementasikan vs proposed.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Kebijakan Keamanan & Privasi
|
|
211
|
+
|
|
212
|
+
1. **Penyimpanan Sesi Lokal**: Folder `.local/` berisi session cookie Chrome privat dan attempt journal tidak pernah di-commit atau dimasukkan ke dalam paket distribusi sdist/wheel.
|
|
213
|
+
2. **Tanpa Otomasi Kredensial**: Tool ini tidak membaca password operator, tidak melakukan scraping cookie secara ilegal, dan tidak mencoba melewati CAPTCHA/2FA.
|
|
214
|
+
3. **Draft Only**: Operasi rilis dihentikan di level penyimpanan draft untuk ditinjau oleh operator manusia sebelum proses rilis aktual.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Lisensi
|
|
219
|
+
|
|
220
|
+
Proyek ini didistribusikan di bawah lisensi [MIT License](LICENSE).
|
|
221
|
+
Hak Cipta (c) 2026 Gunamaya / KiriminAja.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Toolost offline manifest v1 (unreleased)",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"additionalProperties": false,
|
|
6
|
+
"required": ["schema_version", "release_id", "release_type", "title", "release_date", "artwork", "tracks"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schema_version": {"type": "integer", "const": 1},
|
|
9
|
+
"release_id": {"$ref": "#/$defs/id"},
|
|
10
|
+
"release_type": {"enum": ["album", "ep", "single", "compilation"]},
|
|
11
|
+
"title": {"$ref": "#/$defs/text"},
|
|
12
|
+
"release_date": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", "format": "date"},
|
|
13
|
+
"artwork": {"$ref": "#/$defs/file"},
|
|
14
|
+
"language": {"$ref": "#/$defs/text"},
|
|
15
|
+
"primary_genre": {"$ref": "#/$defs/text"},
|
|
16
|
+
"secondary_genre": {"$ref": "#/$defs/text"},
|
|
17
|
+
"label": {"$ref": "#/$defs/text"},
|
|
18
|
+
"upc": {"$ref": "#/$defs/text"},
|
|
19
|
+
"copyright": {
|
|
20
|
+
"type": "object", "additionalProperties": false, "minProperties": 1,
|
|
21
|
+
"properties": {
|
|
22
|
+
"c_year": {"type": "integer", "minimum": 1, "maximum": 9999},
|
|
23
|
+
"p_year": {"type": "integer", "minimum": 1, "maximum": 9999},
|
|
24
|
+
"c_owner": {"$ref": "#/$defs/text"},
|
|
25
|
+
"p_owner": {"$ref": "#/$defs/text"}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"tracks": {
|
|
29
|
+
"type": "array", "minItems": 1, "maxItems": 1000,
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "object", "additionalProperties": false,
|
|
32
|
+
"required": ["track_id", "title", "audio", "ai_assisted"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"track_id": {"$ref": "#/$defs/id"},
|
|
35
|
+
"title": {"$ref": "#/$defs/text"},
|
|
36
|
+
"audio": {"$ref": "#/$defs/file"},
|
|
37
|
+
"lyrics": {"$ref": "#/$defs/file"},
|
|
38
|
+
"ai_assisted": {"type": "boolean"},
|
|
39
|
+
"provenance_known_ai_generated": {"type": "boolean"},
|
|
40
|
+
"version_line": {"$ref": "#/$defs/text"},
|
|
41
|
+
"language": {"$ref": "#/$defs/text"},
|
|
42
|
+
"instrumental": {"type": "boolean"},
|
|
43
|
+
"explicit": {"type": "boolean"},
|
|
44
|
+
"clean_version": {"type": "boolean"},
|
|
45
|
+
"isrc": {"$ref": "#/$defs/text"},
|
|
46
|
+
"iswc": {"$ref": "#/$defs/text"}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"$defs": {
|
|
52
|
+
"text": {"type": "string", "pattern": "\\S"},
|
|
53
|
+
"id": {"type": "string", "pattern": "^[A-Za-z0-9_-]{1,128}$"},
|
|
54
|
+
"file": {
|
|
55
|
+
"type": "object", "additionalProperties": false, "required": ["path", "sha256"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"path": {"type": "string", "pattern": "\\S"},
|
|
58
|
+
"sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Toolost offline validate result v1 (unreleased)",
|
|
4
|
+
"type": "object", "additionalProperties": false,
|
|
5
|
+
"required": ["schema_version", "command", "run_id", "status", "profile", "release_id", "draft_id", "remote_verified", "issues", "warnings", "error"],
|
|
6
|
+
"properties": {
|
|
7
|
+
"schema_version": {"type": "integer", "const": 1},
|
|
8
|
+
"command": {"const": "validate"},
|
|
9
|
+
"run_id": {"type": "null"},
|
|
10
|
+
"status": {"enum": ["valid", "invalid_input"]},
|
|
11
|
+
"profile": {"type": "null"},
|
|
12
|
+
"release_id": {"type": ["string", "null"], "pattern": "^[A-Za-z0-9_-]{1,128}$"},
|
|
13
|
+
"draft_id": {"type": "null"},
|
|
14
|
+
"remote_verified": {"const": false},
|
|
15
|
+
"issues": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["code", "scope", "message"], "properties": {"code": {"type": "string"}, "scope": {"type": "string"}, "message": {"type": "string"}}}},
|
|
16
|
+
"warnings": {"type": "array", "items": {"type": "string"}},
|
|
17
|
+
"error": {"type": ["object", "null"], "additionalProperties": false, "required": ["code", "message", "retryable"], "properties": {"code": {"type": "string"}, "message": {"type": "string"}, "retryable": {"const": false}}}
|
|
18
|
+
},
|
|
19
|
+
"allOf": [
|
|
20
|
+
{"if": {"properties": {"status": {"const": "valid"}}}, "then": {"properties": {"release_id": {"type": "string"}, "issues": {"maxItems": 0}, "error": {"type": "null"}}}},
|
|
21
|
+
{"if": {"properties": {"status": {"const": "invalid_input"}}}, "then": {"properties": {"issues": {"minItems": 1}, "error": {"type": "object"}}}}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0.3"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "toolost-uploader"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "CLI and Playwright automation tool for Too Lost music release manifests"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Gunamaya", email = "developer@kiriminaja.com" }
|
|
14
|
+
]
|
|
15
|
+
keywords = ["too-lost", "music-distribution", "uploader", "playwright", "automation"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Topic :: Multimedia :: Sound/Audio",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"playwright>=1.40.0,<2",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = ["build>=1.2.2,<2", "twine>=5.0.0,<6", "jsonschema>=4.26,<5"]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/gunamaya/toolost-uploader"
|
|
34
|
+
Repository = "https://github.com/gunamaya/toolost-uploader"
|
|
35
|
+
Issues = "https://github.com/gunamaya/toolost-uploader/issues"
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
toolost = "toolost_uploader.cli:main"
|
|
39
|
+
|
|
40
|
+
[tool.setuptools]
|
|
41
|
+
packages = ["toolost_uploader"]
|
|
42
|
+
include-package-data = false
|
|
43
|
+
|
|
44
|
+
[tool.setuptools.dynamic]
|
|
45
|
+
version = {attr = "toolost_uploader.__version__"}
|