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.
- yt_stash-1.0.0/.gitignore +18 -0
- yt_stash-1.0.0/CHANGELOG.md +40 -0
- yt_stash-1.0.0/CONTRIBUTING.md +174 -0
- yt_stash-1.0.0/LICENSE +21 -0
- yt_stash-1.0.0/PKG-INFO +177 -0
- yt_stash-1.0.0/README.md +137 -0
- yt_stash-1.0.0/docs/ARCHITECTURE.md +147 -0
- yt_stash-1.0.0/docs/RELEASING.md +71 -0
- yt_stash-1.0.0/docs/authentication.md +63 -0
- yt_stash-1.0.0/docs/installation.md +212 -0
- yt_stash-1.0.0/docs/translating.md +41 -0
- yt_stash-1.0.0/docs/troubleshooting.md +35 -0
- yt_stash-1.0.0/docs/usage.md +242 -0
- yt_stash-1.0.0/pyproject.toml +82 -0
- yt_stash-1.0.0/src/yt_stash/__init__.py +3 -0
- yt_stash-1.0.0/src/yt_stash/__main__.py +7 -0
- yt_stash-1.0.0/src/yt_stash/app.py +453 -0
- yt_stash-1.0.0/src/yt_stash/auth.py +199 -0
- yt_stash-1.0.0/src/yt_stash/browse.py +63 -0
- yt_stash-1.0.0/src/yt_stash/cli.py +295 -0
- yt_stash-1.0.0/src/yt_stash/commandline.py +59 -0
- yt_stash-1.0.0/src/yt_stash/concurrency.py +51 -0
- yt_stash-1.0.0/src/yt_stash/downloader.py +161 -0
- yt_stash-1.0.0/src/yt_stash/environment.py +48 -0
- yt_stash-1.0.0/src/yt_stash/errors.py +150 -0
- yt_stash-1.0.0/src/yt_stash/formats.py +102 -0
- yt_stash-1.0.0/src/yt_stash/gateway.py +248 -0
- yt_stash-1.0.0/src/yt_stash/i18n/__init__.py +104 -0
- yt_stash-1.0.0/src/yt_stash/i18n/en.py +318 -0
- yt_stash-1.0.0/src/yt_stash/i18n/tr.py +326 -0
- yt_stash-1.0.0/src/yt_stash/models.py +150 -0
- yt_stash-1.0.0/src/yt_stash/options.py +120 -0
- yt_stash-1.0.0/src/yt_stash/paths.py +71 -0
- yt_stash-1.0.0/src/yt_stash/probe.py +141 -0
- yt_stash-1.0.0/src/yt_stash/progress.py +154 -0
- yt_stash-1.0.0/src/yt_stash/prompts.py +813 -0
- yt_stash-1.0.0/src/yt_stash/retry.py +58 -0
- yt_stash-1.0.0/src/yt_stash/session.py +195 -0
- yt_stash-1.0.0/src/yt_stash/settings.py +60 -0
- yt_stash-1.0.0/src/yt_stash/urls.py +147 -0
- yt_stash-1.0.0/src/yt_stash/viewer.py +145 -0
- yt_stash-1.0.0/tests/conftest.py +225 -0
- yt_stash-1.0.0/tests/test_app.py +625 -0
- yt_stash-1.0.0/tests/test_auth.py +116 -0
- yt_stash-1.0.0/tests/test_browse.py +54 -0
- yt_stash-1.0.0/tests/test_cli.py +221 -0
- yt_stash-1.0.0/tests/test_commandline.py +92 -0
- yt_stash-1.0.0/tests/test_downloader.py +215 -0
- yt_stash-1.0.0/tests/test_errors.py +74 -0
- yt_stash-1.0.0/tests/test_formats.py +99 -0
- yt_stash-1.0.0/tests/test_gateway.py +236 -0
- yt_stash-1.0.0/tests/test_i18n.py +145 -0
- yt_stash-1.0.0/tests/test_network.py +23 -0
- yt_stash-1.0.0/tests/test_options.py +94 -0
- yt_stash-1.0.0/tests/test_paths_and_environment.py +94 -0
- yt_stash-1.0.0/tests/test_probe.py +115 -0
- yt_stash-1.0.0/tests/test_session.py +314 -0
- yt_stash-1.0.0/tests/test_settings.py +56 -0
- yt_stash-1.0.0/tests/test_ui.py +458 -0
- 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.
|
yt_stash-1.0.0/PKG-INFO
ADDED
|
@@ -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
|
+
[](https://github.com/ilkerkeklik01/yt-stash/actions/workflows/ci.yml)
|
|
49
|
+
[](https://pypi.org/project/yt-stash/)
|
|
50
|
+
[](https://pypi.org/project/yt-stash/)
|
|
51
|
+
[](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.
|
yt_stash-1.0.0/README.md
ADDED
|
@@ -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
|
+
[](https://github.com/ilkerkeklik01/yt-stash/actions/workflows/ci.yml)
|
|
9
|
+
[](https://pypi.org/project/yt-stash/)
|
|
10
|
+
[](https://pypi.org/project/yt-stash/)
|
|
11
|
+
[](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.
|