lumenfetch 2.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.
- lumenfetch-2.0.0/.github/workflows/tests.yml +35 -0
- lumenfetch-2.0.0/.gitignore +13 -0
- lumenfetch-2.0.0/CONTRIBUTING.md +67 -0
- lumenfetch-2.0.0/LICENSE +21 -0
- lumenfetch-2.0.0/PKG-INFO +387 -0
- lumenfetch-2.0.0/README.md +354 -0
- lumenfetch-2.0.0/core/__init__.py +6 -0
- lumenfetch-2.0.0/core/constants.py +99 -0
- lumenfetch-2.0.0/core/detector.py +167 -0
- lumenfetch-2.0.0/core/downloader.py +323 -0
- lumenfetch-2.0.0/core/errors.py +118 -0
- lumenfetch-2.0.0/core/ffmpeg.py +74 -0
- lumenfetch-2.0.0/core/log.py +75 -0
- lumenfetch-2.0.0/core/options.py +292 -0
- lumenfetch-2.0.0/core/update_checker.py +63 -0
- lumenfetch-2.0.0/core/utils.py +631 -0
- lumenfetch-2.0.0/downloads/.gitkeep +0 -0
- lumenfetch-2.0.0/main.py +557 -0
- lumenfetch-2.0.0/pyproject.toml +62 -0
- lumenfetch-2.0.0/requirements-dev.txt +3 -0
- lumenfetch-2.0.0/requirements.txt +16 -0
- lumenfetch-2.0.0/tests/__init__.py +0 -0
- lumenfetch-2.0.0/tests/conftest.py +24 -0
- lumenfetch-2.0.0/tests/test_detector.py +243 -0
- lumenfetch-2.0.0/tests/test_downloader.py +353 -0
- lumenfetch-2.0.0/tests/test_features.py +354 -0
- lumenfetch-2.0.0/tests/test_main.py +211 -0
- lumenfetch-2.0.0/tests/test_options.py +200 -0
- lumenfetch-2.0.0/tests/test_utils.py +631 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repo
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Setup Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Install ffmpeg
|
|
26
|
+
run: sudo apt-get update && sudo apt-get install -y ffmpeg
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: pip install -r requirements-dev.txt
|
|
30
|
+
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: pytest tests/ -v
|
|
33
|
+
|
|
34
|
+
- name: Lint with ruff
|
|
35
|
+
run: ruff check .
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Kontribusi ke Lumenfetch
|
|
2
|
+
|
|
3
|
+
Makasih udah mau bantu kembangin Lumenfetch. Panduan ini biar kontribusi kamu gampang diproses.
|
|
4
|
+
|
|
5
|
+
## π Setup Development
|
|
6
|
+
|
|
7
|
+
1. Fork & clone repo ini
|
|
8
|
+
2. Install dependency (termasuk tools testing & lint):
|
|
9
|
+
```bash
|
|
10
|
+
pip install -r requirements-dev.txt
|
|
11
|
+
```
|
|
12
|
+
3. Pastikan `ffmpeg` sudah terinstall di sistem kamu (lihat bagian Requirements di README)
|
|
13
|
+
|
|
14
|
+
## π Struktur & Prinsip Modul
|
|
15
|
+
|
|
16
|
+
Lumenfetch sengaja dipisah per tanggung jawab, tolong dijaga konsistensinya kalau nambah/ubah kode:
|
|
17
|
+
|
|
18
|
+
| File | Tanggung jawab | Tidak boleh |
|
|
19
|
+
|------|-----------------|-------------|
|
|
20
|
+
| `core/constants.py` | Nilai shared (versi, format, batas) | Logic bisnis |
|
|
21
|
+
| `core/errors.py` | Klasifikasi error + pesan ramah terpusat | Logic download/deteksi |
|
|
22
|
+
| `core/ffmpeg.py` | Deteksi ffmpeg sistem dulu, bundled fallback | Download/deteksi |
|
|
23
|
+
| `core/log.py` | Logging file terpusat | Tampilan rich/menu |
|
|
24
|
+
| `core/detector.py` | Deteksi info video YouTube via yt-dlp | Mendownload apa pun |
|
|
25
|
+
| `core/downloader.py` | Proses download, progress hook, retry | Menampilkan menu/prompt |
|
|
26
|
+
| `core/options.py` | Semua interaksi & tampilan menu (rich) | Logic download |
|
|
27
|
+
| `core/utils.py` | Helper murni: sanitasi, format, config.json | Bergantung ke CLI atau jaringan |
|
|
28
|
+
| `main.py` | Menyatukan semua modul lewat satu loop | Logic bisnis baru |
|
|
29
|
+
|
|
30
|
+
Kalau nambah fitur, coba taruh di modul yang paling sesuai dulu sebelum bikin file baru.
|
|
31
|
+
|
|
32
|
+
## β
Sebelum Bikin Pull Request
|
|
33
|
+
|
|
34
|
+
Jalankan ini dulu di root project:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pytest tests/ -v
|
|
38
|
+
ruff check .
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Pastikan semua test lulus dan tidak ada warning lint baru. GitHub Actions juga bakal jalanin ini otomatis di setiap PR.
|
|
42
|
+
|
|
43
|
+
## π Commit Message
|
|
44
|
+
|
|
45
|
+
Pakai prefix singkat biar history gampang dibaca:
|
|
46
|
+
|
|
47
|
+
- `feat:` β fitur baru
|
|
48
|
+
- `fix:` β perbaikan bug
|
|
49
|
+
- `docs:` β perubahan dokumentasi (README, CONTRIBUTING, dll)
|
|
50
|
+
- `refactor:` β perubahan struktur kode tanpa mengubah perilaku
|
|
51
|
+
- `test:` β nambah/ubah test
|
|
52
|
+
|
|
53
|
+
Contoh: `fix: handle carousel gambar dengan 1 gambar saja`
|
|
54
|
+
|
|
55
|
+
## π Lapor Bug / Request Fitur
|
|
56
|
+
|
|
57
|
+
Buka [Issues](../../issues) baru, sertakan:
|
|
58
|
+
- Platform/link yang bermasalah (kalau ada, hapus info pribadi)
|
|
59
|
+
- Pesan error yang muncul di terminal
|
|
60
|
+
- Langkah buat reproduce masalahnya
|
|
61
|
+
|
|
62
|
+
## π€ Pull Request
|
|
63
|
+
|
|
64
|
+
1. Buat branch baru dari `main`, kasih nama yang jelas (misal `fix/carousel-single-image`)
|
|
65
|
+
2. Pastikan `pytest` dan `ruff check .` lulus
|
|
66
|
+
3. Jelasin di deskripsi PR apa yang diubah dan kenapa
|
|
67
|
+
4. Tunggu review β mungkin ada request perubahan kecil sebelum di-merge
|
lumenfetch-2.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nicolas Dwi Dharma
|
|
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,387 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: lumenfetch
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: YouTube downloader buat terminal - MP4 & MP3.
|
|
5
|
+
Project-URL: Homepage, https://github.com/nekonaru/lumenfetch
|
|
6
|
+
Author: Nicolas Dwi Dharma
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: cli,downloader,mp3,mp4,youtube,yt-dlp
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Multimedia :: Video
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Requires-Dist: curl-cffi
|
|
24
|
+
Requires-Dist: pyperclip
|
|
25
|
+
Requires-Dist: rich
|
|
26
|
+
Requires-Dist: static-ffmpeg
|
|
27
|
+
Requires-Dist: yt-dlp
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pyinstaller; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
<div align="center">
|
|
35
|
+
|
|
36
|
+
### π₯ Lumenfetch
|
|
37
|
+
**YouTube downloader buat terminal - MP4 & MP3. Paste link, pilih quality, beres.**
|
|
38
|
+
|
|
39
|
+
<br>
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+

|
|
43
|
+

|
|
44
|
+

|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
## β¨ Tentang Project
|
|
50
|
+
|
|
51
|
+
**Lumenfetch** adalah CLI Python buat download video YouTube jadi **MP4** atau ekstrak audionya jadi **MP3** - cukup paste link, dia otomatis deteksi judul, durasi, dan estimasi ukuran, lalu kasih kamu opsi quality yang relevan. Didukung [yt-dlp](https://github.com/yt-dlp/yt-dlp) di belakang layar, plus `curl_cffi` buat lolos bot-check YouTube.
|
|
52
|
+
|
|
53
|
+
> _"Satu command, langsung MP4/MP3."_
|
|
54
|
+
|
|
55
|
+
## π― Fitur
|
|
56
|
+
|
|
57
|
+
| Fitur | Keterangan |
|
|
58
|
+
|-------|------------|
|
|
59
|
+
| π **Auto-detect** | Judul, durasi, dan estimasi ukuran terdeteksi otomatis |
|
|
60
|
+
| π **Opsi dinamis** | Menu quality menyesuaikan (video / audio saja) |
|
|
61
|
+
| π **Video MP4** | Pilihan quality Best/1080p/720p/480p/360p/Worst, thumbnail otomatis ter-embed |
|
|
62
|
+
| π΅ **Audio MP3** | Pilihan bitrate Best/320kbps/192kbps/128kbps |
|
|
63
|
+
| π **Playlist** | Default video pertama saja; `--playlist all` untuk semua sekaligus |
|
|
64
|
+
| π¬ **Subtitle & metadata** | Download subtitle (SRT) + embed ke MP4, opsional via flag/CLI |
|
|
65
|
+
| π **Auto-paste clipboard** | Kalau ada link valid di clipboard, langsung ditawarkan tanpa perlu paste manual - tidak akan nanya ulang isi clipboard yang sama berkali-kali |
|
|
66
|
+
| π **Progress bar real-time** | Kecepatan, ukuran, dan estimasi waktu tersisa lewat `rich` |
|
|
67
|
+
| π **Estimasi ukuran & waktu** | Muncul di menu pilih quality (video/audio), dihitung dari data yt-dlp + kecepatan rata-rata download kamu sebelumnya |
|
|
68
|
+
| π **Auto-retry** | Error koneksi dicoba ulang otomatis (default 3x), error fatal (private/invalid) langsung dilaporkan |
|
|
69
|
+
| π **Riwayat download** | 20 entri terakhir tersimpan, bisa dilihat kapan saja lewat command `history` |
|
|
70
|
+
| βοΈ **Pengaturan persisten** | Folder download (default: folder Downloads OS, ganti kapan saja), max retry, auto-paste, dan naming template diingat lewat `config.json` |
|
|
71
|
+
| πͺ **Cookies browser/file** | Opsional, buat video age-restricted/private - dari Chrome/Firefox/Edge/dll atau file `cookies.txt` |
|
|
72
|
+
| π§Ό **Nama file aman** | Karakter ilegal disanitasi, duplikat otomatis dikasih suffix `(1)`, `(2)`, dst |
|
|
73
|
+
| π **Auto-check update yt-dlp** | Tiap dibuka, dicek ke PyPI apakah ada versi yt-dlp lebih baru - gagal cek (mis. offline) diam-diam diabaikan |
|
|
74
|
+
|
|
75
|
+
## π¦ Requirements
|
|
76
|
+
|
|
77
|
+
- **Python** 3.9 atau lebih baru
|
|
78
|
+
- **Koneksi internet**
|
|
79
|
+
|
|
80
|
+
> ffmpeg **tidak perlu diinstall manual** - Lumenfetch otomatis mengunduh dan memakai versi bundled-nya sendiri (lewat `static-ffmpeg`) begitu pertama kali dijalankan, persis seperti cara kerja `ffmpeg-static` di project Node.js.
|
|
81
|
+
|
|
82
|
+
### Belum pernah pakai terminal? Ikuti ini dulu
|
|
83
|
+
|
|
84
|
+
<details>
|
|
85
|
+
<summary><b>πͺ Cara buka terminal di Windows</b></summary>
|
|
86
|
+
|
|
87
|
+
1. Tekan tombol **Windows**, ketik `PowerShell`, lalu tekan **Enter**
|
|
88
|
+
2. Jendela hitam/biru akan terbuka. Itu tempat kamu mengetik perintah
|
|
89
|
+
3. Semua perintah `python ...` atau `pip ...` di panduan ini diketik di jendela itu, lalu tekan **Enter**
|
|
90
|
+
|
|
91
|
+
</details>
|
|
92
|
+
|
|
93
|
+
<details>
|
|
94
|
+
<summary><b>π Cara buka terminal di macOS</b></summary>
|
|
95
|
+
|
|
96
|
+
1. Tekan **Cmd + Spasi**, ketik `Terminal`, lalu tekan **Enter**
|
|
97
|
+
2. Ketik perintah-perintah di panduan ini di situ, lalu tekan **Enter**
|
|
98
|
+
|
|
99
|
+
</details>
|
|
100
|
+
|
|
101
|
+
<details>
|
|
102
|
+
<summary><b>π§ Cara buka terminal di Linux</b></summary>
|
|
103
|
+
|
|
104
|
+
Tekan **Ctrl + Alt + T**, atau cari aplikasi "Terminal" di menu aplikasi.
|
|
105
|
+
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
### Belum punya Python?
|
|
109
|
+
|
|
110
|
+
1. Buka [python.org/downloads](https://www.python.org/downloads/) dan unduh versi terbaru
|
|
111
|
+
2. **Khusus Windows**: saat instalasi, centang dulu kotak **"Add Python to PATH"** di layar pertama sebelum klik Install
|
|
112
|
+
3. Setelah selesai install, cek dengan:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python --version
|
|
116
|
+
# atau
|
|
117
|
+
python3 --version
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## π Instalasi
|
|
121
|
+
|
|
122
|
+
**1. Ambil kode project ini**
|
|
123
|
+
|
|
124
|
+
<details>
|
|
125
|
+
<summary><b>Punya Git terinstall</b></summary>
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
git clone https://github.com/nekonaru/lumenfetch.git
|
|
129
|
+
cd lumenfetch
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
</details>
|
|
133
|
+
|
|
134
|
+
<details>
|
|
135
|
+
<summary><b>Tidak punya Git</b></summary>
|
|
136
|
+
|
|
137
|
+
1. Buka halaman repository di GitHub
|
|
138
|
+
2. Klik tombol hijau **`Code`** β pilih **`Download ZIP`**
|
|
139
|
+
3. Ekstrak file ZIP yang terunduh ke folder pilihanmu
|
|
140
|
+
4. Di terminal, masuk ke folder hasil ekstrak
|
|
141
|
+
|
|
142
|
+
</details>
|
|
143
|
+
|
|
144
|
+
**2. Install dependency**
|
|
145
|
+
```bash
|
|
146
|
+
pip install -r requirements.txt
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
> Kalau muncul error `externally-managed-environment` (biasanya di Linux):
|
|
150
|
+
> ```bash
|
|
151
|
+
> pip install -r requirements.txt --break-system-packages
|
|
152
|
+
> ```
|
|
153
|
+
|
|
154
|
+
**3. (Opsional) Install sebagai command `lumenfetch`**
|
|
155
|
+
```bash
|
|
156
|
+
pip install -e .
|
|
157
|
+
lumenfetch --version
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## π₯οΈ Cara Pakai
|
|
161
|
+
|
|
162
|
+
**Jalankan:**
|
|
163
|
+
```bash
|
|
164
|
+
python main.py
|
|
165
|
+
# atau non-interaktif:
|
|
166
|
+
python main.py "https://youtube.com/watch?v=..." -t video -f mp4 -q 720p -y
|
|
167
|
+
python main.py --batch daftar.txt --jobs 2
|
|
168
|
+
python main.py --history
|
|
169
|
+
python main.py --help
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Flag CLI:**
|
|
173
|
+
```
|
|
174
|
+
-t/--type {video,audio} -f/--format {mp4,mp3} -q/--quality
|
|
175
|
+
-o/--output --cookies --cookies-file --max-retry --playlist {single,all}
|
|
176
|
+
--subs --sub-langs en,id --embed-subs --embed-metadata
|
|
177
|
+
--batch file.txt --jobs 1-4 --no-clipboard -y/--yes -v/--verbose
|
|
178
|
+
--history --version
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Masukkan URL saat diminta:**
|
|
182
|
+
```
|
|
183
|
+
Masukkan URL (q: keluar, history, settings, help): https://youtube.com/watch?v=...
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Kalau ada link valid di clipboard, Lumenfetch akan menawarkannya duluan - tinggal jawab `y` kalau mau pakai itu.
|
|
187
|
+
|
|
188
|
+
**Link YouTube otomatis terdeteksi, lalu menu menyesuaikan:**
|
|
189
|
+
|
|
190
|
+
- **Video** β pilih output Video (MP4) / Audio (MP3) β pilih quality
|
|
191
|
+
- **Stream audio** β langsung pilih bitrate MP3
|
|
192
|
+
- **Playlist** β default video pertama; `--playlist all` untuk semua
|
|
193
|
+
|
|
194
|
+
**Konfirmasi nama file, lalu proses download berjalan** dengan progress bar real-time (kecepatan, ukuran, ETA). Tekan `Ctrl+C` kapan saja untuk membatalkan dengan aman.
|
|
195
|
+
|
|
196
|
+
## β¨οΈ Command
|
|
197
|
+
|
|
198
|
+
Diketik langsung di prompt utama, menggantikan URL:
|
|
199
|
+
|
|
200
|
+
| Command | Fungsi |
|
|
201
|
+
|---------|--------|
|
|
202
|
+
| `history` | Lihat 20 riwayat download terakhir (tanggal, judul, format, ukuran, status) |
|
|
203
|
+
| `settings` | Ganti folder default, max retry, auto-paste clipboard, naming template, atau cookies |
|
|
204
|
+
| `help` | Tampilkan panduan singkat di dalam aplikasi |
|
|
205
|
+
| `q` / `quit` | Keluar dari aplikasi |
|
|
206
|
+
| `Ctrl+C` | Batalkan download yang sedang berjalan |
|
|
207
|
+
|
|
208
|
+
## πͺ Cookies (Opsional)
|
|
209
|
+
|
|
210
|
+
Video age-restricted atau private butuh login. Kalau ketemu error semacam itu, aktifkan salah satu:
|
|
211
|
+
|
|
212
|
+
**A. Cookies dari browser:**
|
|
213
|
+
1. Buka Lumenfetch, ketik `settings`
|
|
214
|
+
2. Pilih `[5] Pakai cookies dari browser/file`
|
|
215
|
+
3. Pilih browser di mana kamu sudah login YouTube (Chrome/Firefox/Edge/Brave/Opera/Vivaldi/Safari)
|
|
216
|
+
|
|
217
|
+
Setelah aktif, Lumenfetch akan meminjam cookies dari browser itu setiap kali mendeteksi atau mendownload konten, seolah request-nya datang dari sesi browser kamu yang sudah login. Cukup pilih `[1] Nonaktifkan` di menu yang sama kalau mau matikan lagi.
|
|
218
|
+
|
|
219
|
+
> **Penting:** browser yang dipilih harus **benar-benar tertutup total** saat download (file cookies dikunci selama browser terbuka - errornya `Could not copy ... cookie database`). Cek Task Manager dan matikan semua proses browser tersebut (Edge/Chrome sering masih jalan di background).
|
|
220
|
+
|
|
221
|
+
> **Alternatif paling reliable (disarankan kalau error cookies terus muncul):** pakai **file cookies** yang works walau browser terbuka:
|
|
222
|
+
> 1. Install extension **"Get cookies.txt LOCALLY"** (Chrome/Edge/Firefox) di browser
|
|
223
|
+
> 2. Buka youtube.com (pastikan sudah login), klik extension β **Export** β simpan mis. `D:\cookies.txt`
|
|
224
|
+
> 3. Di Lumenfetch: `settings` β `[5]` β `[1] Nonaktifkan` β isi path file cookies tadi
|
|
225
|
+
> 4. Atau via CLI: `python main.py <URL> --cookies-file D:\cookies.txt`
|
|
226
|
+
|
|
227
|
+
## π Estimasi Ukuran & Waktu Download
|
|
228
|
+
|
|
229
|
+
Pas milih quality buat video atau audio, Lumenfetch nampilin perkiraan ukuran file dan waktu download di sebelah tiap opsi:
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
Pilih Quality:
|
|
233
|
+
[1] Best (default) (~147.8 MB, ~31 detik)
|
|
234
|
+
[2] 1080p (~147.8 MB, ~31 detik)
|
|
235
|
+
[3] 720p (~81.1 MB, ~17 detik)
|
|
236
|
+
[4] 480p (~42.9 MB, ~9 detik)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Cara kerjanya:
|
|
240
|
+
|
|
241
|
+
- **Ukuran** dihitung dari data yang yt-dlp udah dapat pas proses "Mendeteksi konten..." (gak ada request tambahan ke platform, jadi gak bikin lambat)
|
|
242
|
+
- **Waktu** dihitung dari kecepatan rata-rata beberapa download terakhir kamu yang sukses (bukan angka tebakan generik) - makin sering pakai Lumenfetch, makin akurat estimasinya
|
|
243
|
+
- Kalau datanya gak cukup buat ngasih estimasi yang jujur (mis. platform gak expose ukuran file sama sekali, quality tier yang diminta gak tersedia buat konten itu, atau ini baru pertama kali pakai aplikasi jadi belum ada riwayat kecepatan) - estimasinya gak ditampilin sama sekali, daripada nampilin angka ngasal
|
|
244
|
+
|
|
245
|
+
## π Auto-check Update yt-dlp
|
|
246
|
+
|
|
247
|
+
YouTube sering ubah sistemnya - jadi `yt-dlp` juga perlu sering di-update biar tetap kompatibel. Ini bukan "sekali fix, selesai selamanya", tapi proses berkelanjutan (mirip antivirus yang perlu update rutin).
|
|
248
|
+
|
|
249
|
+
Buat bantu itu, tiap kali Lumenfetch dibuka, otomatis dicek ke PyPI apakah ada versi `yt-dlp` yang lebih baru dari yang terinstall. Kalau ada, muncul notice kayak gini:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
π Update yt-dlp tersedia
|
|
253
|
+
yt-dlp kamu versi 2026.1.1, versi terbaru 2026.8.19 sudah tersedia.
|
|
254
|
+
pip install --upgrade yt-dlp
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Tinggal jalankan command yang ditampilkan. Kalau lagi offline atau PyPI nggak bisa diakses, pengecekan ini gagal diam-diam dan **tidak** menghalangi kamu pakai aplikasinya.
|
|
258
|
+
|
|
259
|
+
## π Naming & Konfigurasi
|
|
260
|
+
|
|
261
|
+
Nama file mengikuti template di `config.json` (default: `%(platform)s_%(title)s_%(year)s`), contoh hasil:
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
YouTube_Lofi-Hip-Hop-Radio_2026.mp4
|
|
265
|
+
YouTube_Lofi-Hip-Hop-Radio_2026.mp3
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Preferensi kamu (folder simpan, max retry, auto-paste, naming template, cookies browser, dan riwayat) otomatis tersimpan di config user
|
|
269
|
+
(`%APPDATA%/lumenfetch/config.json` di Windows, `~/.config/lumenfetch/config.json` di Linux, `~/Library/Application Support/lumenfetch/` di macOS)
|
|
270
|
+
- dibuat otomatis dengan nilai default saat pertama kali dijalankan. Config lama di `config.json` project root dimigrasi otomatis sekali.
|
|
271
|
+
Log detail tersimpan di `lumenfetch.log` sefolder config (pakai `-v/--verbose` untuk level debug).
|
|
272
|
+
|
|
273
|
+
**Folder download default** otomatis mengikuti folder **Downloads** asli sistem operasi kamu (`~/Downloads` di macOS/Linux, `C:\Users\<nama-kamu>\Downloads` di Windows) - persis seperti kebiasaan browser lain (Chrome, Firefox, Edge, dll), bukan folder relatif di dalam project. Mau ganti ke folder lain? Tinggal:
|
|
274
|
+
|
|
275
|
+
1. Ketik `settings` di prompt utama
|
|
276
|
+
2. Pilih `[1] Ganti folder download default`
|
|
277
|
+
3. Ketik path folder yang diinginkan (boleh pakai `~` buat home folder, mis. `~/Documents/Video`, atau path absolut penuh)
|
|
278
|
+
|
|
279
|
+
> **Catatan:** config tersimpan di folder data user (lihat atas), bukan relatif ke folder project - jadi aman dijalankan dari mana saja.
|
|
280
|
+
|
|
281
|
+
## β οΈ Troubleshooting
|
|
282
|
+
|
|
283
|
+
| Masalah | Solusi |
|
|
284
|
+
|---------|--------|
|
|
285
|
+
| `ModuleNotFoundError: No module named 'yt_dlp'` / `'rich'` / `'curl_cffi'` / `'pyperclip'` / `'static_ffmpeg'` | Jalankan ulang `pip install -r requirements.txt` |
|
|
286
|
+
| `HTTP Error 403: Forbidden` | Update yt-dlp ke versi terbaru: `pip install --upgrade yt-dlp` |
|
|
287
|
+
| `Sign in to confirm you're not a bot` | Aktifkan fitur **Cookies** di atas (browser atau file) |
|
|
288
|
+
| `β Konten ini private / tidak bisa diakses` | Video private/age-restricted - aktifkan **Cookies** di atas |
|
|
289
|
+
| `β Format tidak tersedia untuk konten ini` | Coba quality lain |
|
|
290
|
+
| `β Koneksi internet bermasalah` terus muncul | Cek koneksi, atau naikkan `max_retry` lewat command `settings` |
|
|
291
|
+
| Video berhasil download tapi tidak ada suara | Jarang terjadi karena ffmpeg sudah bundled otomatis, tapi kalau muncul, jalankan ulang aplikasinya (ffmpeg diunduh ulang otomatis kalau file sebelumnya rusak) |
|
|
292
|
+
| Ganti naming template di `settings` ditolak | Template cuma boleh pakai `%(platform)s`, `%(title)s`, `%(year)s` - ditolak otomatis kalau ada placeholder salah ketik, biar tidak bikin nama file error saat download |
|
|
293
|
+
| `β οΈ URL ini playlist berisi N video` | Default cuma video pertama. Gunakan `--playlist all` untuk download semua sebagai file ber-index |
|
|
294
|
+
| Batch download | Buat file teks (satu URL per baris, `#` = komentar), lalu `python main.py --batch daftar.txt --jobs 2` |
|
|
295
|
+
| Resume download | Didukung via `continuedl` yt-dlp + retry backoff eksponensial (2s, 4s, 8s... max 30s). File parsial `.part` dilanjutkan, bukan diulang dari 0 |
|
|
296
|
+
| `ffmpeg tidak ditemukan` | Install ffmpeg sistem dulu (lebih ringan), fallback bundled otomatis. Cek dengan `ffmpeg -version` |
|
|
297
|
+
|
|
298
|
+
## ποΈ Struktur Project
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
lumenfetch/
|
|
302
|
+
βββ main.py # Entry point, CLI args, batch, loop utama
|
|
303
|
+
βββ core/
|
|
304
|
+
β βββ constants.py # Single source of truth (versi, format, batas)
|
|
305
|
+
β βββ errors.py # Taxonomy error terpusat (klasifikasi + pesan ramah)
|
|
306
|
+
β βββ ffmpeg.py # Deteksi ffmpeg sistem dulu, bundled fallback
|
|
307
|
+
β βββ log.py # Logging file terpusat
|
|
308
|
+
β βββ downloader.py # Download MP4 / ekstrak MP3 + resume + retry backoff
|
|
309
|
+
β βββ detector.py # Deteksi info video YouTube
|
|
310
|
+
β βββ options.py # Menu & prompt interaktif (rich)
|
|
311
|
+
β βββ update_checker.py # Auto-check versi terbaru yt-dlp di PyPI
|
|
312
|
+
β βββ utils.py # Sanitasi nama file, format size, config user
|
|
313
|
+
βββ tests/
|
|
314
|
+
β βββ conftest.py # Fixture global (no-sleep) + SAMPLE_VIDEO_FORMATS
|
|
315
|
+
β βββ test_utils.py
|
|
316
|
+
β βββ test_detector.py
|
|
317
|
+
β βββ test_downloader.py
|
|
318
|
+
β βββ test_options.py
|
|
319
|
+
β βββ test_main.py
|
|
320
|
+
β βββ test_features.py # Fitur (CLI, backoff, batch, ffmpeg, cookies, log)
|
|
321
|
+
βββ .github/
|
|
322
|
+
β βββ workflows/
|
|
323
|
+
β βββ tests.yml # CI: test & lint otomatis
|
|
324
|
+
βββ downloads/ # Folder placeholder (bukan lokasi download aktual - lihat "Naming & Konfigurasi")
|
|
325
|
+
βββ requirements.txt
|
|
326
|
+
βββ requirements-dev.txt # Dependency tambahan untuk development (pytest, ruff)
|
|
327
|
+
βββ pyproject.toml # Metadata project + entry point + konfigurasi ruff
|
|
328
|
+
βββ CONTRIBUTING.md
|
|
329
|
+
βββ LICENSE
|
|
330
|
+
βββ README.md
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Prinsip pemisahan modul:**
|
|
334
|
+
- `constants.py` - nilai shared (versi, format, batas) biar tidak drift antar modul
|
|
335
|
+
- `errors.py` - klasifikasi error terpusat, dipakai detector & downloader bersama
|
|
336
|
+
- `detector.py` - murni deteksi info video YouTube, tidak mendownload apa pun
|
|
337
|
+
- `downloader.py` - murni proses download MP4/MP3 & progress, tidak menampilkan menu
|
|
338
|
+
- `options.py` - semua interaksi & tampilan menu, tidak ada logic download
|
|
339
|
+
- `utils.py` - helper murni (sanitasi, format, baca/tulis config), tidak tahu soal CLI atau jaringan
|
|
340
|
+
- `main.py` - menyatukan semuanya lewat CLI + loop utama
|
|
341
|
+
|
|
342
|
+
## πΊοΈ Roadmap
|
|
343
|
+
|
|
344
|
+
- [x] **Phase 1 - Core**: struktur project, integrasi yt-dlp dasar, progress bar, config user
|
|
345
|
+
- [x] **Phase 2 - Smart Detection**: auto-detect video YouTube, auto-paste clipboard, preview nama file
|
|
346
|
+
- [x] **Phase 3 - Reliability**: resume, retry backoff eksponensial, playlist, cancel graceful
|
|
347
|
+
- [x] **Phase 4 - Polish**: menu history, settings, help, naming template, subtitle & metadata
|
|
348
|
+
- [x] **Phase 5 - Fokus YouTube**: scope MP4/MP3 saja (v2.0.0) - hapus jalur multi-platform & dep berat
|
|
349
|
+
|
|
350
|
+
## π§ͺ Testing
|
|
351
|
+
|
|
352
|
+
Ada unit test per modul (sanitasi nama file, naming template, resolve duplikat, format ukuran/durasi, config, validasi URL YouTube, opts yt-dlp, CLI, dll).
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
pip install -r requirements-dev.txt
|
|
356
|
+
pytest tests/ -v
|
|
357
|
+
ruff check .
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
CI (`.github/workflows/tests.yml`) otomatis menjalankan ini di setiap push & pull request ke `main`, di Python 3.9-3.12.
|
|
361
|
+
|
|
362
|
+
## π€ Kontribusi
|
|
363
|
+
|
|
364
|
+
Mau bantu kembangin Lumenfetch? Baca [`CONTRIBUTING.md`](CONTRIBUTING.md) untuk struktur project dan alur kontribusi.
|
|
365
|
+
|
|
366
|
+
## π€ Author
|
|
367
|
+
|
|
368
|
+
<div align="center">
|
|
369
|
+
|
|
370
|
+
| [](https://github.com/nekonaru) |
|
|
371
|
+
|:---:|
|
|
372
|
+
| **Nicolas Dwi Dharma** |
|
|
373
|
+
| [github.com/nekonaru](https://github.com/nekonaru) |
|
|
374
|
+
|
|
375
|
+
</div>
|
|
376
|
+
|
|
377
|
+
## π License
|
|
378
|
+
|
|
379
|
+
Distributed under the **MIT License**. See [`LICENSE`](LICENSE) for more information.
|
|
380
|
+
|
|
381
|
+
<div align="center">
|
|
382
|
+
|
|
383
|
+
Made with π₯ by **Nicolas Dwi Dharma**
|
|
384
|
+
|
|
385
|
+
*Star β repo ini kalau project ini membantumu!*
|
|
386
|
+
|
|
387
|
+
</div>
|