yt-stash 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.
Files changed (60) hide show
  1. yt_stash-1.0.0/.gitignore +18 -0
  2. yt_stash-1.0.0/CHANGELOG.md +40 -0
  3. yt_stash-1.0.0/CONTRIBUTING.md +174 -0
  4. yt_stash-1.0.0/LICENSE +21 -0
  5. yt_stash-1.0.0/PKG-INFO +177 -0
  6. yt_stash-1.0.0/README.md +137 -0
  7. yt_stash-1.0.0/docs/ARCHITECTURE.md +147 -0
  8. yt_stash-1.0.0/docs/RELEASING.md +71 -0
  9. yt_stash-1.0.0/docs/authentication.md +63 -0
  10. yt_stash-1.0.0/docs/installation.md +212 -0
  11. yt_stash-1.0.0/docs/translating.md +41 -0
  12. yt_stash-1.0.0/docs/troubleshooting.md +35 -0
  13. yt_stash-1.0.0/docs/usage.md +242 -0
  14. yt_stash-1.0.0/pyproject.toml +82 -0
  15. yt_stash-1.0.0/src/yt_stash/__init__.py +3 -0
  16. yt_stash-1.0.0/src/yt_stash/__main__.py +7 -0
  17. yt_stash-1.0.0/src/yt_stash/app.py +453 -0
  18. yt_stash-1.0.0/src/yt_stash/auth.py +199 -0
  19. yt_stash-1.0.0/src/yt_stash/browse.py +63 -0
  20. yt_stash-1.0.0/src/yt_stash/cli.py +295 -0
  21. yt_stash-1.0.0/src/yt_stash/commandline.py +59 -0
  22. yt_stash-1.0.0/src/yt_stash/concurrency.py +51 -0
  23. yt_stash-1.0.0/src/yt_stash/downloader.py +161 -0
  24. yt_stash-1.0.0/src/yt_stash/environment.py +48 -0
  25. yt_stash-1.0.0/src/yt_stash/errors.py +150 -0
  26. yt_stash-1.0.0/src/yt_stash/formats.py +102 -0
  27. yt_stash-1.0.0/src/yt_stash/gateway.py +248 -0
  28. yt_stash-1.0.0/src/yt_stash/i18n/__init__.py +104 -0
  29. yt_stash-1.0.0/src/yt_stash/i18n/en.py +318 -0
  30. yt_stash-1.0.0/src/yt_stash/i18n/tr.py +326 -0
  31. yt_stash-1.0.0/src/yt_stash/models.py +150 -0
  32. yt_stash-1.0.0/src/yt_stash/options.py +120 -0
  33. yt_stash-1.0.0/src/yt_stash/paths.py +71 -0
  34. yt_stash-1.0.0/src/yt_stash/probe.py +141 -0
  35. yt_stash-1.0.0/src/yt_stash/progress.py +154 -0
  36. yt_stash-1.0.0/src/yt_stash/prompts.py +813 -0
  37. yt_stash-1.0.0/src/yt_stash/retry.py +58 -0
  38. yt_stash-1.0.0/src/yt_stash/session.py +195 -0
  39. yt_stash-1.0.0/src/yt_stash/settings.py +60 -0
  40. yt_stash-1.0.0/src/yt_stash/urls.py +147 -0
  41. yt_stash-1.0.0/src/yt_stash/viewer.py +145 -0
  42. yt_stash-1.0.0/tests/conftest.py +225 -0
  43. yt_stash-1.0.0/tests/test_app.py +625 -0
  44. yt_stash-1.0.0/tests/test_auth.py +116 -0
  45. yt_stash-1.0.0/tests/test_browse.py +54 -0
  46. yt_stash-1.0.0/tests/test_cli.py +221 -0
  47. yt_stash-1.0.0/tests/test_commandline.py +92 -0
  48. yt_stash-1.0.0/tests/test_downloader.py +215 -0
  49. yt_stash-1.0.0/tests/test_errors.py +74 -0
  50. yt_stash-1.0.0/tests/test_formats.py +99 -0
  51. yt_stash-1.0.0/tests/test_gateway.py +236 -0
  52. yt_stash-1.0.0/tests/test_i18n.py +145 -0
  53. yt_stash-1.0.0/tests/test_network.py +23 -0
  54. yt_stash-1.0.0/tests/test_options.py +94 -0
  55. yt_stash-1.0.0/tests/test_paths_and_environment.py +94 -0
  56. yt_stash-1.0.0/tests/test_probe.py +115 -0
  57. yt_stash-1.0.0/tests/test_session.py +314 -0
  58. yt_stash-1.0.0/tests/test_settings.py +56 -0
  59. yt_stash-1.0.0/tests/test_ui.py +458 -0
  60. yt_stash-1.0.0/tests/test_urls.py +102 -0
@@ -0,0 +1,18 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ venv/
5
+ build/
6
+ dist/
7
+ *.egg-info/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ htmlcov/
12
+ .DS_Store
13
+ # Never commit exported cookies
14
+ *cookies*.txt
15
+ *cookies*.json
16
+ *.cookies
17
+ # Local Claude Code settings
18
+ .claude/
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ All notable changes to yt-stash are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
6
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). For a command-line tool, the
7
+ public interface that SemVer applies to is: command names, flags and their meaning, exit codes, and
8
+ the environment variables and settings file described in the documentation.
9
+
10
+ ## [Unreleased]
11
+
12
+ ## [1.0.0] - 2026-10-08
13
+
14
+ First public release.
15
+
16
+ ### Added
17
+
18
+ - Interactive main menu (`yt-stash` without arguments) with arrow-key navigation, a description
19
+ under every entry, Esc to go back, and a built-in setup check.
20
+ - `video` mode for one or more videos and `playlist` mode for whole playlists, with links read
21
+ from arguments or from a text file (`--from-file`).
22
+ - Quality selection across a whole batch: every available resolution from 144p to 8K is
23
+ detected, the default is 1080p (or the highest available), and `-q` accepts `2160`, `720p`,
24
+ `best` and `worst`.
25
+ - Audio-only downloads (`-a`: m4a, mp3, opus) and the video container choice (`--container`).
26
+ - Subtitles: download, auto-generated captions and embedding (`--subs`, `--auto-subs`,
27
+ `--embed-subs`).
28
+ - Members-only, private and age-restricted videos through a browser's signed-in session
29
+ (`--cookies-from-browser`), a `cookies.txt` file (`--cookies`), or cookies pasted for one run
30
+ (`--paste-cookies`); an interactive "sign in and retry" recovery.
31
+ - Parallel downloads (`-j`), resume of interrupted downloads, skipping of files that already exist
32
+ (`--overwrite` to override), and automatic retries with back-off for network errors and HTTP 429.
33
+ - Scripting support: `--yes`, automatic non-interactive mode without a terminal, a command that
34
+ repeats an interactive run, and the exit codes 0, 1, 2 and 130.
35
+ - English and Turkish interface (`--lang`, `YT_STASH_LANG`, saved choice, system language).
36
+ - Packaging for PyPI, an MIT license, a code of conduct, a security policy, contribution guidelines,
37
+ issue forms, and installation guides for macOS, Windows and Linux.
38
+
39
+ [Unreleased]: https://github.com/ilkerkeklik01/yt-stash/compare/v1.0.0...HEAD
40
+ [1.0.0]: https://github.com/ilkerkeklik01/yt-stash/releases/tag/v1.0.0
@@ -0,0 +1,174 @@
1
+ # Contributing to yt-stash
2
+
3
+ Thank you for taking the time to contribute! yt-stash is a small project maintained by a volunteer, and
4
+ every bug report, documentation fix, translation and pull request makes it better. This guide explains
5
+ how to take part. By participating you agree to the [Code of Conduct](CODE_OF_CONDUCT.md).
6
+
7
+ ## Ways to contribute
8
+
9
+ You don't need to write code to help:
10
+
11
+ - **Report a bug** with the [bug report form](https://github.com/ilkerkeklik01/yt-stash/issues/new/choose).
12
+ Include `yt-stash --version`, your operating system, the exact command and the output of `-v`.
13
+ Remove cookies and private links first.
14
+ - **Suggest a feature** with the feature request form. Describe the problem you want to solve before the
15
+ solution; it helps to find the best fit.
16
+ - **Ask a question or share an idea** in [Discussions](https://github.com/ilkerkeklik01/yt-stash/discussions).
17
+ - **Improve the documentation**: typos, unclear steps and missing examples are all welcome fixes.
18
+ - **Translate**: see [docs/translating.md](docs/translating.md).
19
+ - **Triage**: reproduce reported bugs and add details to them.
20
+ - **Write code**: pick an issue labelled
21
+ [`good first issue`](https://github.com/ilkerkeklik01/yt-stash/labels/good%20first%20issue) or
22
+ [`help wanted`](https://github.com/ilkerkeklik01/yt-stash/labels/help%20wanted) and say that you are
23
+ working on it, so nobody duplicates the effort.
24
+
25
+ For anything bigger than a small fix, **open an issue or discussion first**. It avoids the
26
+ disappointment of a large pull request that doesn't fit the project's direction.
27
+
28
+ ## Scope
29
+
30
+ yt-stash is a workflow and UX layer over yt-dlp. These guide what fits:
31
+
32
+ - Behavior that yt-dlp already provides is used, not reimplemented. Bugs in extraction or downloading
33
+ itself belong to [yt-dlp](https://github.com/yt-dlp/yt-dlp).
34
+ - Features should help most users and work on Linux, macOS and Windows.
35
+ - yt-stash does not bypass DRM or paywalls, and it will not store credentials. Sign-in works through
36
+ browser cookies the user already has.
37
+ - Fewer options are better than many; a feature that needs a long explanation may belong in a script.
38
+
39
+ A pull request that doesn't fit will be closed with an explanation and thanks. That's never personal.
40
+
41
+ ## Set up your environment
42
+
43
+ You need Python 3.10 or newer and git.
44
+
45
+ ```bash
46
+ git clone https://github.com/ilkerkeklik01/yt-stash.git
47
+ cd yt-stash
48
+ python -m venv .venv
49
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
50
+ pip install -e ".[dev]"
51
+ ```
52
+
53
+ Without an activated virtual environment, call `.venv/bin/pytest`, `.venv/bin/ruff` and
54
+ `.venv/bin/yt-stash` directly.
55
+
56
+ Running `yt-stash` by hand reads and writes your real settings file. When experimenting, point
57
+ `HOME` (and `XDG_CONFIG_HOME` / `APPDATA`) at a temporary folder.
58
+
59
+ ## Checks to run
60
+
61
+ CI runs the same checks on Linux, macOS and Windows with Python 3.10 and 3.13:
62
+
63
+ ```bash
64
+ pytest # fast, offline test suite
65
+ pytest -m network # real YouTube download (needs internet; optional)
66
+ pytest --cov --cov-report=term-missing # coverage, as CI runs it
67
+ ruff check . && ruff format --check . # lint and format (line length 110)
68
+ ruff format . # apply formatting
69
+ ```
70
+
71
+ ## Making a change
72
+
73
+ `main` is protected. Nothing is pushed to it directly: every change goes through a short-lived branch and
74
+ a pull request. If you are not a maintainer, **fork** the repository first and open the pull request from
75
+ your fork.
76
+
77
+ 1. **Start from an up-to-date `main`.**
78
+
79
+ ```bash
80
+ git switch main && git pull --ff-only
81
+ ```
82
+
83
+ 2. **Create a branch** named `<type>/<short-kebab-description>`:
84
+
85
+ | Prefix | Use for |
86
+ |-------------|-------------------------------------------|
87
+ | `feature/` | New behavior or options |
88
+ | `fix/` | Bug fixes |
89
+ | `docs/` | Documentation only |
90
+ | `chore/` | Tooling, CI, dependencies, refactoring |
91
+
92
+ ```bash
93
+ git switch -c fix/playlist-numbering
94
+ ```
95
+
96
+ 3. **Commit in small steps.** Write a short, imperative subject line ("Fix playlist numbering"); add a
97
+ body that explains *why* when it isn't obvious.
98
+
99
+ 4. **Check locally** (see above), then push and open a pull request against `main`:
100
+
101
+ ```bash
102
+ git push -u origin HEAD
103
+ gh pr create --fill # or use the GitHub website
104
+ ```
105
+
106
+ 5. **Wait for CI** and fix whatever it reports by pushing more commits to the same branch. Reviews
107
+ are discussions: ask questions, push back politely, and expect the same.
108
+
109
+ 6. **Merging.** A maintainer merges the pull request with a merge commit after CI passes. The branch is
110
+ deleted automatically.
111
+
112
+ Keep one branch to one concern, and keep branches short-lived so they don't drift from `main`.
113
+
114
+ ### Pull request checklist
115
+
116
+ - Tests added or updated. **No default test may touch the network**; mark real-network tests with
117
+ `@pytest.mark.network`.
118
+ - Code stays compatible with **Python 3.10 and Windows** (no PEP 701 f-string nesting of the same
119
+ quote style; use `os.sep`/`pathlib`).
120
+ - [README](README.md) and [docs/](docs/) updated for user-facing changes;
121
+ [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) updated when behavior or module responsibilities change.
122
+ - A line in [CHANGELOG.md](CHANGELOG.md) under **Unreleased** (see below).
123
+ - New user-visible text has keys in both `i18n/en.py` and `i18n/tr.py`. Don't know Turkish? Add the
124
+ English text to both and say so in the pull request; a maintainer will help.
125
+
126
+ See [CLAUDE.md](CLAUDE.md) for the invariants that span several files, such as "only `gateway.py`
127
+ calls the yt-dlp API", and [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the design.
128
+
129
+ ## The changelog and versions
130
+
131
+ yt-stash follows [Semantic Versioning](https://semver.org/) and keeps a
132
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) file. Add one bullet per user-visible change
133
+ under `## [Unreleased]`, in the section that fits:
134
+
135
+ | Section | Use for | Version bump |
136
+ |---|---|---|
137
+ | Added | new features, flags, languages | minor |
138
+ | Changed | behavior changes of existing features | minor, or **major** if scripts can break |
139
+ | Deprecated / Removed | features going away or gone | minor / **major** |
140
+ | Fixed | bug fixes | patch |
141
+ | Security | vulnerability fixes | patch |
142
+
143
+ The public interface is the command names, flags, exit codes, environment variables and settings file.
144
+ Maintainers cut releases as described in [docs/RELEASING.md](docs/RELEASING.md).
145
+
146
+ ## How decisions get made
147
+
148
+ yt-stash currently has a single maintainer, who decides what is merged and tries to explain every
149
+ decision in the open (in the issue or pull request). Regular contributors who show good judgment will be
150
+ invited to become maintainers. Questions and decisions stay in public issues and discussions so that
151
+ everyone can follow them.
152
+
153
+ ## What protects `main`
154
+
155
+ These rules are enforced by GitHub, for administrators too:
156
+
157
+ - Changes must arrive through a pull request; direct pushes are rejected.
158
+ - All CI checks must pass: `lint` and `test` on Ubuntu, macOS and Windows with Python 3.10 and 3.13,
159
+ and the `package` build check.
160
+ - The branch must be up to date with `main` before it merges. If `main` moved, merge it into your branch
161
+ (`git merge origin/main`), push, and let CI run again.
162
+ - Review conversations must be resolved.
163
+ - Force-pushes to `main` and deleting `main` are blocked.
164
+
165
+ (Maintainers: if the job list in `.github/workflows/ci.yml` changes, update the required checks in the
166
+ branch protection settings too, otherwise pull requests wait forever for a missing check.)
167
+
168
+ ## Reporting security problems
169
+
170
+ Please don't use public issues for vulnerabilities; follow [SECURITY.md](SECURITY.md).
171
+
172
+ ## License
173
+
174
+ By contributing you agree that your contribution is licensed under the project's [MIT License](LICENSE).
yt_stash-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 İlker Keklik
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,177 @@
1
+ Metadata-Version: 2.5
2
+ Name: yt-stash
3
+ Version: 1.0.0
4
+ Summary: Download YouTube videos and playlists from the terminal: pick any quality, run downloads in parallel, and save members-only videos.
5
+ Project-URL: Homepage, https://github.com/ilkerkeklik01/yt-stash
6
+ Project-URL: Documentation, https://github.com/ilkerkeklik01/yt-stash/tree/main/docs
7
+ Project-URL: Changelog, https://github.com/ilkerkeklik01/yt-stash/blob/main/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/ilkerkeklik01/yt-stash/issues
9
+ Project-URL: Source, https://github.com/ilkerkeklik01/yt-stash
10
+ Author-email: Ilker Keklik <ilkerkeklik50@gmail.com>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: audio,cli,downloader,playlist,subtitles,video,youtube,yt-dlp
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: End Users/Desktop
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: Microsoft :: Windows
19
+ Classifier: Operating System :: POSIX :: Linux
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Multimedia :: Sound/Audio
27
+ Classifier: Topic :: Multimedia :: Video
28
+ Classifier: Topic :: Utilities
29
+ Requires-Python: >=3.10
30
+ Requires-Dist: questionary>=2.1
31
+ Requires-Dist: rich>=15.0.0
32
+ Requires-Dist: yt-dlp[default]>=2026.8.19
33
+ Provides-Extra: dev
34
+ Requires-Dist: build>=1.2; extra == 'dev'
35
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
36
+ Requires-Dist: pytest>=8; extra == 'dev'
37
+ Requires-Dist: ruff>=0.6; extra == 'dev'
38
+ Requires-Dist: twine>=5; extra == 'dev'
39
+ Description-Content-Type: text/markdown
40
+
41
+ <div align="center">
42
+
43
+ # yt-stash
44
+
45
+ **Download YouTube videos and playlists from your terminal.**
46
+ Any quality, parallel downloads, members-only videos, subtitles, and a friendly arrow-key menu.
47
+
48
+ [![CI](https://github.com/ilkerkeklik01/yt-stash/actions/workflows/ci.yml/badge.svg)](https://github.com/ilkerkeklik01/yt-stash/actions/workflows/ci.yml)
49
+ [![PyPI](https://img.shields.io/pypi/v/yt-stash)](https://pypi.org/project/yt-stash/)
50
+ [![Python](https://img.shields.io/pypi/pyversions/yt-stash)](https://pypi.org/project/yt-stash/)
51
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ilkerkeklik01/yt-stash/blob/main/LICENSE)
52
+
53
+ </div>
54
+
55
+ yt-stash is a cross-platform (Linux, macOS, Windows) command-line downloader for single videos, several
56
+ videos and whole playlists, including **members-only and private videos**. It is a thin, heavily tested
57
+ workflow layer on top of [yt-dlp](https://github.com/yt-dlp/yt-dlp), the best-maintained YouTube
58
+ extraction library, so it keeps working when YouTube changes.
59
+
60
+ ## Features
61
+
62
+ - **Every quality**: detects all resolutions (144p … 8K, high frame rate, HDR) and lets you choose once
63
+ for a whole batch. Defaults to **1080p**, or the highest available.
64
+ - **Videos and playlists**: one or many links, a text file of links, or every video of a playlist.
65
+ - **Parallel downloads**: several videos at once, plus parallel fragments per video.
66
+ - **Members-only, private and age-restricted videos** through your browser's signed-in session, a
67
+ `cookies.txt` file, or cookies pasted for one run (never saved).
68
+ - **Audio only** (m4a, mp3, opus) and **subtitles** (save or embed, any language, auto-generated too).
69
+ - **Resume and skip**: interrupted downloads continue; files you already have are skipped; transient
70
+ errors and rate limits are retried automatically.
71
+ - **Interactive or scriptable**: arrow-key menus with an explanation under every entry, or
72
+ `--yes` plus flags for cron and CI, with documented exit codes.
73
+ - **English and Turkish** interface.
74
+
75
+ ## Quickstart
76
+
77
+ ```bash
78
+ # 1. Install (details for every system: docs/installation.md)
79
+ pipx install yt-stash
80
+
81
+ # 2. Open the interactive menu
82
+ yt-stash
83
+
84
+ # 3. Or download straight away
85
+ yt-stash video https://youtu.be/dQw4w9WgXcQ # asks for quality and folder
86
+ yt-stash video URL -q 720 -o ~/Videos # no questions
87
+ yt-stash video URL1 URL2 URL3 -j 3 # three at once
88
+ yt-stash playlist "https://www.youtube.com/playlist?list=PL..." # a whole playlist
89
+ yt-stash video URL -a mp3 # audio only
90
+ yt-stash video URL --subs en,tr --embed-subs # with subtitles
91
+ yt-stash video URL --cookies-from-browser firefox # members-only video
92
+ ```
93
+
94
+ ```text
95
+ $ yt-stash
96
+ yt-stash 1.0.0 Download YouTube videos and playlists
97
+
98
+ ▶ What do you want to do? (↑↓ to move, Enter to choose)
99
+ ❯ Download videos
100
+ Download a playlist
101
+ Download links from a text file
102
+ Show available qualities
103
+
104
+ Sign-in (off)
105
+ Language (English)
106
+ Check setup
107
+ Command-line options
108
+ Quit
109
+ Description: Paste one or more video links.
110
+ ```
111
+
112
+ ## Installation
113
+
114
+ yt-stash needs Python 3.10+; install **ffmpeg** and **deno** too for full quality.
115
+
116
+ | System | Install |
117
+ |---|---|
118
+ | **macOS** | `brew install python pipx ffmpeg deno && pipx ensurepath`, then `pipx install yt-stash` |
119
+ | **Windows** (PowerShell) | `winget install Python.Python.3.13`, `winget install Gyan.FFmpeg`, `winget install DenoLand.Deno`, reopen PowerShell, `py -m pip install --user pipx`, `py -m pipx ensurepath`, reopen, then `pipx install yt-stash` |
120
+ | **Debian / Ubuntu** | `sudo apt install python3 pipx ffmpeg && pipx ensurepath`, install [deno](https://deno.com), then `pipx install yt-stash` |
121
+ | **Fedora / Arch / openSUSE / uv / pip / source** | see the [installation guide](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/installation.md) |
122
+
123
+ Check it: `yt-stash --version`. **If downloads suddenly fail, update first:** `pipx upgrade yt-stash`.
124
+
125
+ ## Documentation
126
+
127
+ | Guide | What is in it |
128
+ |---|---|
129
+ | [Installation](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/installation.md) | Step by step for macOS, Windows and Linux; updating and uninstalling |
130
+ | [Using yt-stash](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/usage.md) | Every feature: menus, videos, playlists, quality, audio, subtitles, resume, language, scripting, all options, recipes |
131
+ | [Members-only videos](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/authentication.md) | Sign-in with browser cookies, a cookies file or pasted cookies |
132
+ | [Troubleshooting](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/troubleshooting.md) | Common problems and fixes |
133
+ | [Translating](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/translating.md) | Add or improve a language |
134
+ | [Architecture](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/ARCHITECTURE.md) | How the code is organised and why |
135
+ | [Changelog](https://github.com/ilkerkeklik01/yt-stash/blob/main/CHANGELOG.md) | What changed in each release |
136
+
137
+ Quick reference: `yt-stash --help`, `yt-stash video --help`, `yt-stash playlist --help`.
138
+
139
+ **Exit codes:** `0` everything downloaded or already present · `1` at least one video failed ·
140
+ `2` invalid usage · `130` interrupted with Ctrl+C.
141
+
142
+ ## Getting help
143
+
144
+ - **Question or idea?** Open a [Discussion](https://github.com/ilkerkeklik01/yt-stash/discussions).
145
+ - **Found a bug?** Open an [issue](https://github.com/ilkerkeklik01/yt-stash/issues/new/choose); the form
146
+ asks for the details that make it fixable.
147
+ - **Security problem?** Please don't open an issue; follow the
148
+ [security policy](https://github.com/ilkerkeklik01/yt-stash/blob/main/SECURITY.md).
149
+
150
+ yt-stash is maintained by one volunteer in their spare time. Replies may take a few days; thank you
151
+ for your patience.
152
+
153
+ ## Contributing
154
+
155
+ Contributions of every size are welcome: bug reports, documentation fixes, translations and code. Read
156
+ [CONTRIBUTING.md](https://github.com/ilkerkeklik01/yt-stash/blob/main/CONTRIBUTING.md) first; issues
157
+ labelled [`good first issue`](https://github.com/ilkerkeklik01/yt-stash/labels/good%20first%20issue) are
158
+ a good place to start. By taking part you agree to the
159
+ [Code of Conduct](https://github.com/ilkerkeklik01/yt-stash/blob/main/CODE_OF_CONDUCT.md).
160
+
161
+ ```bash
162
+ git clone https://github.com/ilkerkeklik01/yt-stash.git && cd yt-stash
163
+ python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
164
+ pip install -e ".[dev]"
165
+ pytest && ruff check . && ruff format --check .
166
+ ```
167
+
168
+ ## Legal
169
+
170
+ yt-stash is released under the [MIT License](https://github.com/ilkerkeklik01/yt-stash/blob/main/LICENSE).
171
+ It is an independent project, not affiliated with or endorsed by YouTube or Google. Only download
172
+ content you have the right to download, and respect YouTube's Terms of Service and the creators'
173
+ rights. You are responsible for how you use this tool.
174
+
175
+ yt-stash builds on [yt-dlp](https://github.com/yt-dlp/yt-dlp) (Unlicense), [rich](https://github.com/Textualize/rich)
176
+ (MIT), [questionary](https://github.com/tmbo/questionary) (MIT) and
177
+ [prompt_toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) (BSD-3-Clause). Thank you to their authors.
@@ -0,0 +1,137 @@
1
+ <div align="center">
2
+
3
+ # yt-stash
4
+
5
+ **Download YouTube videos and playlists from your terminal.**
6
+ Any quality, parallel downloads, members-only videos, subtitles, and a friendly arrow-key menu.
7
+
8
+ [![CI](https://github.com/ilkerkeklik01/yt-stash/actions/workflows/ci.yml/badge.svg)](https://github.com/ilkerkeklik01/yt-stash/actions/workflows/ci.yml)
9
+ [![PyPI](https://img.shields.io/pypi/v/yt-stash)](https://pypi.org/project/yt-stash/)
10
+ [![Python](https://img.shields.io/pypi/pyversions/yt-stash)](https://pypi.org/project/yt-stash/)
11
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ilkerkeklik01/yt-stash/blob/main/LICENSE)
12
+
13
+ </div>
14
+
15
+ yt-stash is a cross-platform (Linux, macOS, Windows) command-line downloader for single videos, several
16
+ videos and whole playlists, including **members-only and private videos**. It is a thin, heavily tested
17
+ workflow layer on top of [yt-dlp](https://github.com/yt-dlp/yt-dlp), the best-maintained YouTube
18
+ extraction library, so it keeps working when YouTube changes.
19
+
20
+ ## Features
21
+
22
+ - **Every quality**: detects all resolutions (144p … 8K, high frame rate, HDR) and lets you choose once
23
+ for a whole batch. Defaults to **1080p**, or the highest available.
24
+ - **Videos and playlists**: one or many links, a text file of links, or every video of a playlist.
25
+ - **Parallel downloads**: several videos at once, plus parallel fragments per video.
26
+ - **Members-only, private and age-restricted videos** through your browser's signed-in session, a
27
+ `cookies.txt` file, or cookies pasted for one run (never saved).
28
+ - **Audio only** (m4a, mp3, opus) and **subtitles** (save or embed, any language, auto-generated too).
29
+ - **Resume and skip**: interrupted downloads continue; files you already have are skipped; transient
30
+ errors and rate limits are retried automatically.
31
+ - **Interactive or scriptable**: arrow-key menus with an explanation under every entry, or
32
+ `--yes` plus flags for cron and CI, with documented exit codes.
33
+ - **English and Turkish** interface.
34
+
35
+ ## Quickstart
36
+
37
+ ```bash
38
+ # 1. Install (details for every system: docs/installation.md)
39
+ pipx install yt-stash
40
+
41
+ # 2. Open the interactive menu
42
+ yt-stash
43
+
44
+ # 3. Or download straight away
45
+ yt-stash video https://youtu.be/dQw4w9WgXcQ # asks for quality and folder
46
+ yt-stash video URL -q 720 -o ~/Videos # no questions
47
+ yt-stash video URL1 URL2 URL3 -j 3 # three at once
48
+ yt-stash playlist "https://www.youtube.com/playlist?list=PL..." # a whole playlist
49
+ yt-stash video URL -a mp3 # audio only
50
+ yt-stash video URL --subs en,tr --embed-subs # with subtitles
51
+ yt-stash video URL --cookies-from-browser firefox # members-only video
52
+ ```
53
+
54
+ ```text
55
+ $ yt-stash
56
+ yt-stash 1.0.0 Download YouTube videos and playlists
57
+
58
+ ▶ What do you want to do? (↑↓ to move, Enter to choose)
59
+ ❯ Download videos
60
+ Download a playlist
61
+ Download links from a text file
62
+ Show available qualities
63
+
64
+ Sign-in (off)
65
+ Language (English)
66
+ Check setup
67
+ Command-line options
68
+ Quit
69
+ Description: Paste one or more video links.
70
+ ```
71
+
72
+ ## Installation
73
+
74
+ yt-stash needs Python 3.10+; install **ffmpeg** and **deno** too for full quality.
75
+
76
+ | System | Install |
77
+ |---|---|
78
+ | **macOS** | `brew install python pipx ffmpeg deno && pipx ensurepath`, then `pipx install yt-stash` |
79
+ | **Windows** (PowerShell) | `winget install Python.Python.3.13`, `winget install Gyan.FFmpeg`, `winget install DenoLand.Deno`, reopen PowerShell, `py -m pip install --user pipx`, `py -m pipx ensurepath`, reopen, then `pipx install yt-stash` |
80
+ | **Debian / Ubuntu** | `sudo apt install python3 pipx ffmpeg && pipx ensurepath`, install [deno](https://deno.com), then `pipx install yt-stash` |
81
+ | **Fedora / Arch / openSUSE / uv / pip / source** | see the [installation guide](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/installation.md) |
82
+
83
+ Check it: `yt-stash --version`. **If downloads suddenly fail, update first:** `pipx upgrade yt-stash`.
84
+
85
+ ## Documentation
86
+
87
+ | Guide | What is in it |
88
+ |---|---|
89
+ | [Installation](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/installation.md) | Step by step for macOS, Windows and Linux; updating and uninstalling |
90
+ | [Using yt-stash](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/usage.md) | Every feature: menus, videos, playlists, quality, audio, subtitles, resume, language, scripting, all options, recipes |
91
+ | [Members-only videos](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/authentication.md) | Sign-in with browser cookies, a cookies file or pasted cookies |
92
+ | [Troubleshooting](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/troubleshooting.md) | Common problems and fixes |
93
+ | [Translating](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/translating.md) | Add or improve a language |
94
+ | [Architecture](https://github.com/ilkerkeklik01/yt-stash/blob/main/docs/ARCHITECTURE.md) | How the code is organised and why |
95
+ | [Changelog](https://github.com/ilkerkeklik01/yt-stash/blob/main/CHANGELOG.md) | What changed in each release |
96
+
97
+ Quick reference: `yt-stash --help`, `yt-stash video --help`, `yt-stash playlist --help`.
98
+
99
+ **Exit codes:** `0` everything downloaded or already present · `1` at least one video failed ·
100
+ `2` invalid usage · `130` interrupted with Ctrl+C.
101
+
102
+ ## Getting help
103
+
104
+ - **Question or idea?** Open a [Discussion](https://github.com/ilkerkeklik01/yt-stash/discussions).
105
+ - **Found a bug?** Open an [issue](https://github.com/ilkerkeklik01/yt-stash/issues/new/choose); the form
106
+ asks for the details that make it fixable.
107
+ - **Security problem?** Please don't open an issue; follow the
108
+ [security policy](https://github.com/ilkerkeklik01/yt-stash/blob/main/SECURITY.md).
109
+
110
+ yt-stash is maintained by one volunteer in their spare time. Replies may take a few days; thank you
111
+ for your patience.
112
+
113
+ ## Contributing
114
+
115
+ Contributions of every size are welcome: bug reports, documentation fixes, translations and code. Read
116
+ [CONTRIBUTING.md](https://github.com/ilkerkeklik01/yt-stash/blob/main/CONTRIBUTING.md) first; issues
117
+ labelled [`good first issue`](https://github.com/ilkerkeklik01/yt-stash/labels/good%20first%20issue) are
118
+ a good place to start. By taking part you agree to the
119
+ [Code of Conduct](https://github.com/ilkerkeklik01/yt-stash/blob/main/CODE_OF_CONDUCT.md).
120
+
121
+ ```bash
122
+ git clone https://github.com/ilkerkeklik01/yt-stash.git && cd yt-stash
123
+ python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
124
+ pip install -e ".[dev]"
125
+ pytest && ruff check . && ruff format --check .
126
+ ```
127
+
128
+ ## Legal
129
+
130
+ yt-stash is released under the [MIT License](https://github.com/ilkerkeklik01/yt-stash/blob/main/LICENSE).
131
+ It is an independent project, not affiliated with or endorsed by YouTube or Google. Only download
132
+ content you have the right to download, and respect YouTube's Terms of Service and the creators'
133
+ rights. You are responsible for how you use this tool.
134
+
135
+ yt-stash builds on [yt-dlp](https://github.com/yt-dlp/yt-dlp) (Unlicense), [rich](https://github.com/Textualize/rich)
136
+ (MIT), [questionary](https://github.com/tmbo/questionary) (MIT) and
137
+ [prompt_toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) (BSD-3-Clause). Thank you to their authors.