emby-cli 0.3.0__tar.gz → 0.4.1__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 (53) hide show
  1. {emby_cli-0.3.0 → emby_cli-0.4.1}/CHANGELOG.md +11 -0
  2. emby_cli-0.4.1/PKG-INFO +242 -0
  3. emby_cli-0.4.1/README.md +208 -0
  4. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/_version.py +2 -2
  5. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/cli.py +63 -10
  6. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/client.py +9 -5
  7. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/download.py +20 -15
  8. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/help.py +1 -0
  9. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/search.py +17 -11
  10. emby_cli-0.4.1/src/emby_cli/commands/show.py +273 -0
  11. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/constants.py +11 -0
  12. emby_cli-0.4.1/src/emby_cli/mode_args.py +31 -0
  13. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_client.py +13 -7
  14. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_parser.py +79 -17
  15. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_search.py +7 -7
  16. emby_cli-0.4.1/tests/test_show.py +142 -0
  17. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_validate_args.py +58 -19
  18. emby_cli-0.3.0/PKG-INFO +0 -129
  19. emby_cli-0.3.0/README.md +0 -95
  20. {emby_cli-0.3.0 → emby_cli-0.4.1}/.env.example +0 -0
  21. {emby_cli-0.3.0 → emby_cli-0.4.1}/.github/workflows/ci.yml +0 -0
  22. {emby_cli-0.3.0 → emby_cli-0.4.1}/.github/workflows/publish.yml +0 -0
  23. {emby_cli-0.3.0 → emby_cli-0.4.1}/.gitignore +0 -0
  24. {emby_cli-0.3.0 → emby_cli-0.4.1}/LICENSE +0 -0
  25. {emby_cli-0.3.0 → emby_cli-0.4.1}/pyproject.toml +0 -0
  26. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/__init__.py +0 -0
  27. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/__main__.py +0 -0
  28. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/auth_cache.py +0 -0
  29. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/__init__.py +0 -0
  30. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/config.py +0 -0
  31. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/info.py +0 -0
  32. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/login.py +0 -0
  33. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/logout.py +0 -0
  34. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/play.py +0 -0
  35. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/commands/version.py +0 -0
  36. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/credentials.py +0 -0
  37. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/download_ops.py +0 -0
  38. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/output.py +0 -0
  39. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/resolve.py +0 -0
  40. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/util.py +0 -0
  41. {emby_cli-0.3.0 → emby_cli-0.4.1}/src/emby_cli/version.py +0 -0
  42. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_auth_cache.py +0 -0
  43. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_config.py +0 -0
  44. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_credentials.py +0 -0
  45. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_download_ops.py +0 -0
  46. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_info.py +0 -0
  47. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_logout.py +0 -0
  48. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_output.py +0 -0
  49. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_resolve.py +0 -0
  50. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_resolve_table.py +0 -0
  51. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_session_auth.py +0 -0
  52. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_util.py +0 -0
  53. {emby_cli-0.3.0 → emby_cli-0.4.1}/tests/test_version.py +0 -0
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.4.1
6
+
7
+ - README rewritten for end users (quick start, everyday workflows, responsible-use disclaimer).
8
+
9
+ ## 0.4.0
10
+
11
+ Added:
12
+
13
+ - `show`: detail view for `--item` / `--library` (QUERY or `--id`); multiple matches print a disambiguation table with IDs. Libraries include total item count and the last 10 added (`DateCreated`), limited to Movie/Episode/Audio (no Studio, etc.).
14
+ - `search` / `download`: `--item QUERY` / `--library QUERY` (query on the mode flag); `--media-item` is an alias of `--item`. `--search` still works as an alternative selector.
15
+
5
16
  ## 0.3.0
6
17
 
7
18
  Breaking:
@@ -0,0 +1,242 @@
1
+ Metadata-Version: 2.4
2
+ Name: emby-cli
3
+ Version: 0.4.1
4
+ Summary: CLI to list, search, play, and download/backup original media from an Emby server via its REST API.
5
+ Project-URL: Homepage, https://github.com/soukron/emby-cli
6
+ Project-URL: Repository, https://github.com/soukron/emby-cli
7
+ Project-URL: Issues, https://github.com/soukron/emby-cli/issues
8
+ Author-email: Sergio Garcia <soukron@gmbros.net>
9
+ Maintainer-email: Sergio Garcia <soukron@gmbros.net>
10
+ License-Expression: CC-BY-NC-4.0
11
+ License-File: LICENSE
12
+ Keywords: backup,cli,download,emby,media
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: License :: Free for non-commercial use
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Multimedia :: Video
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: m3u8>=4.0
26
+ Requires-Dist: requests>=2.31
27
+ Requires-Dist: static-ffmpeg>=3.0
28
+ Requires-Dist: tqdm>=4.66
29
+ Provides-Extra: dev
30
+ Requires-Dist: build>=1.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Requires-Dist: twine>=5.0; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # emby-cli
36
+
37
+ [PyPI](https://pypi.org/project/emby-cli/)
38
+ · [License: CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)
39
+
40
+ Search, browse, play, and download media from your [Emby](https://emby.media/) server — from the terminal. Only HTTP access to the server is needed (typically port 8096). No SSH, no shared folders, no rsync.
41
+
42
+ ```bash
43
+ pip install emby-cli
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Quick start
49
+
50
+ **1. Log in once** (username + password, or an API key):
51
+
52
+ ```bash
53
+ emby-cli login --server http://emby:8096 --username you
54
+ # prompted for password if not set
55
+ ```
56
+
57
+ Your session is saved locally. Later commands reuse it, so you usually do not need to pass `--server` again.
58
+
59
+ **2. Check the connection:**
60
+
61
+ ```bash
62
+ emby-cli info
63
+ ```
64
+
65
+ **3. Search and download:**
66
+
67
+ ```bash
68
+ emby-cli search --item "matrix"
69
+ emby-cli download --item "matrix" --pick-best-item
70
+ ```
71
+
72
+ Use `emby-cli help` for the command list, and `emby-cli <command> -h` for options.
73
+
74
+ ---
75
+
76
+ ## Everyday use
77
+
78
+ ### Server info
79
+
80
+ ```bash
81
+ emby-cli version # CLI version (and Emby version when connected)
82
+ emby-cli info # user, server, library count, content totals
83
+ ```
84
+
85
+ ### Search
86
+
87
+ Find movies, episodes, and other media — or list libraries:
88
+
89
+ ```bash
90
+ emby-cli search --item "fast and furious"
91
+ emby-cli search --item "fast and furious" --count 50
92
+ emby-cli search --item --id 123456
93
+ emby-cli search --library "peliculas"
94
+ emby-cli search --library --all
95
+ ```
96
+
97
+ `--item` and `--library` accept the search text directly. You can also pass `--id` when you already know the Emby ID.
98
+
99
+ ### Show details
100
+
101
+ Inspect one title or one library (counts, metadata, recently added):
102
+
103
+ ```bash
104
+ emby-cli show --item "matrix"
105
+ emby-cli show --item --id 123456
106
+ emby-cli show --library "peliculas"
107
+ ```
108
+
109
+ If several titles match, `show` lists them with IDs so you can pick one:
110
+
111
+ ```bash
112
+ emby-cli show --item --id 123456
113
+ ```
114
+
115
+ ### Play
116
+
117
+ Open a title in an external player (VLC, mpv, IINA, …):
118
+
119
+ ```bash
120
+ emby-cli play --search "Pelicula (1980)" --pick-best-item
121
+ emby-cli play --id 123456
122
+ emby-cli play --id 123456 --player vlc --wait
123
+ ```
124
+
125
+ Set `EMBY_PLAYER` if the player is not found automatically.
126
+
127
+ ### Download
128
+
129
+ Download a single title, a whole library, or a list of titles from a file:
130
+
131
+ ```bash
132
+ emby-cli download --item --id 123456
133
+ emby-cli download --item "californication S01E01" --pick-best-item
134
+ emby-cli download --library "PELICULAS 4K"
135
+ emby-cli download --from-file titles.txt
136
+ ```
137
+
138
+ Useful options:
139
+
140
+ | Option | Meaning |
141
+ |--------|---------|
142
+ | `-n` / `--dry-run` | Resolve titles only — do not write files |
143
+ | `-o` / `--output` | Output folder (default `./downloads`) |
144
+ | `-f` / `--force` | Re-download even if a matching local file exists |
145
+ | `--pick-best-item` | When several versions match, pick the best ≤1080p |
146
+ | `-m download\|stream\|hls` | How to fetch the file (see below) |
147
+
148
+ **Title lines** in `--item` / `--from-file` can look like:
149
+
150
+ - `Movie (2010)`
151
+ - `Show S01E05`
152
+ - `Show S01` — whole season (with `--item` or `--from-file`)
153
+
154
+ By default, matching is **strict**: a wrong year or several ambiguous results stops with a table of candidates. Add `--pick-best-item` to choose automatically (best quality up to 1080p).
155
+
156
+ Library downloads match the library **name** (case-insensitive, unique match required).
157
+
158
+ ---
159
+
160
+ ## Logging in and switching servers
161
+
162
+ | Approach | When to use |
163
+ |----------|-------------|
164
+ | `emby-cli login` | Recommended — saves a session and remembers the server |
165
+ | API key | `--api-key` / `EMBY_API_KEY` (keys are not stored by `login`) |
166
+ | Flags / env | `--server`, `--username`, `--password` or `EMBY_*` for one-off use |
167
+
168
+ Manage saved servers:
169
+
170
+ ```bash
171
+ emby-cli config get-servers
172
+ emby-cli config current-server
173
+ emby-cli config use-server 'you@http://emby:8096'
174
+ emby-cli config view # tokens redacted
175
+ emby-cli logout # revoke and forget the current session
176
+ ```
177
+
178
+ Sessions live under `~/.cache/emby-cli/auth.json` (override with `EMBY_CACHE_DIR`). Set `EMBY_NO_AUTH_CACHE=1` to never read or write the cache.
179
+
180
+ ---
181
+
182
+ ## Download methods
183
+
184
+ Choose with `-m` / `EMBY_METHOD`:
185
+
186
+ | Method | Best for |
187
+ |--------|----------|
188
+ | `download` (default) | Normal file download from Emby |
189
+ | `stream` | Direct stream URL (similar to Emby Web) |
190
+ | `hls` | HLS remux to `.mkv` |
191
+
192
+ ---
193
+
194
+ ## Configuration reference
195
+
196
+ Flags override environment variables. Optional template: `.env.example` (export the vars yourself — the CLI does not load `.env` files).
197
+
198
+ | Variable | Description |
199
+ |----------|-------------|
200
+ | `EMBY_SERVER` | Server URL |
201
+ | `EMBY_API_KEY` | API key |
202
+ | `EMBY_USERNAME` / `EMBY_PASSWORD` | Username / password |
203
+ | `EMBY_OUTPUT` | Download directory (default `./downloads`) |
204
+ | `EMBY_METHOD` | `download`, `stream`, or `hls` |
205
+ | `EMBY_PLAYER` | External player command or path |
206
+ | `EMBY_ITEM_ID` | Default `--id` for item download / play |
207
+ | `EMBY_CACHE_DIR` | Credentials directory (default `~/.cache/emby-cli`) |
208
+ | `EMBY_NO_AUTH_CACHE` | `1` = disable session cache |
209
+
210
+ ---
211
+
212
+ ## Tips
213
+
214
+ - Prefer **search → show → download** when you are unsure of the exact title.
215
+ - Prefer **IDs** (`--id`) when you already have them — no ambiguity.
216
+ - Use **`--dry-run`** before a large library or file-list download.
217
+ - Content totals in `info` can count multiple versions of the same title separately.
218
+
219
+ ---
220
+
221
+ ## Responsible use
222
+
223
+ This tool talks to Emby over its normal HTTP API. Whether download or playback is allowed depends on **how that server is configured** and on **the terms set by whoever runs it**.
224
+
225
+ Use `emby-cli` only on servers you are authorized to access, and only in ways that comply with that server’s terms of use, policies, and applicable law. The authors provide the software as-is and are **not responsible** for misuse, for downloads from servers that disallow them, or for any consequences of using the tool.
226
+
227
+ ---
228
+
229
+ ## For contributors
230
+
231
+ ```bash
232
+ python3 -m venv .venv && source .venv/bin/activate
233
+ pip install -e ".[dev]"
234
+ pytest -q
235
+ python -m build && twine check dist/*
236
+ ```
237
+
238
+ Releases: tag `vX.Y.Z` and push (or create a GitHub Release). CI publishes to PyPI via Trusted Publisher.
239
+
240
+ ## License
241
+
242
+ [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/) — free for non-commercial use.
@@ -0,0 +1,208 @@
1
+ # emby-cli
2
+
3
+ [PyPI](https://pypi.org/project/emby-cli/)
4
+ · [License: CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)
5
+
6
+ Search, browse, play, and download media from your [Emby](https://emby.media/) server — from the terminal. Only HTTP access to the server is needed (typically port 8096). No SSH, no shared folders, no rsync.
7
+
8
+ ```bash
9
+ pip install emby-cli
10
+ ```
11
+
12
+ ---
13
+
14
+ ## Quick start
15
+
16
+ **1. Log in once** (username + password, or an API key):
17
+
18
+ ```bash
19
+ emby-cli login --server http://emby:8096 --username you
20
+ # prompted for password if not set
21
+ ```
22
+
23
+ Your session is saved locally. Later commands reuse it, so you usually do not need to pass `--server` again.
24
+
25
+ **2. Check the connection:**
26
+
27
+ ```bash
28
+ emby-cli info
29
+ ```
30
+
31
+ **3. Search and download:**
32
+
33
+ ```bash
34
+ emby-cli search --item "matrix"
35
+ emby-cli download --item "matrix" --pick-best-item
36
+ ```
37
+
38
+ Use `emby-cli help` for the command list, and `emby-cli <command> -h` for options.
39
+
40
+ ---
41
+
42
+ ## Everyday use
43
+
44
+ ### Server info
45
+
46
+ ```bash
47
+ emby-cli version # CLI version (and Emby version when connected)
48
+ emby-cli info # user, server, library count, content totals
49
+ ```
50
+
51
+ ### Search
52
+
53
+ Find movies, episodes, and other media — or list libraries:
54
+
55
+ ```bash
56
+ emby-cli search --item "fast and furious"
57
+ emby-cli search --item "fast and furious" --count 50
58
+ emby-cli search --item --id 123456
59
+ emby-cli search --library "peliculas"
60
+ emby-cli search --library --all
61
+ ```
62
+
63
+ `--item` and `--library` accept the search text directly. You can also pass `--id` when you already know the Emby ID.
64
+
65
+ ### Show details
66
+
67
+ Inspect one title or one library (counts, metadata, recently added):
68
+
69
+ ```bash
70
+ emby-cli show --item "matrix"
71
+ emby-cli show --item --id 123456
72
+ emby-cli show --library "peliculas"
73
+ ```
74
+
75
+ If several titles match, `show` lists them with IDs so you can pick one:
76
+
77
+ ```bash
78
+ emby-cli show --item --id 123456
79
+ ```
80
+
81
+ ### Play
82
+
83
+ Open a title in an external player (VLC, mpv, IINA, …):
84
+
85
+ ```bash
86
+ emby-cli play --search "Pelicula (1980)" --pick-best-item
87
+ emby-cli play --id 123456
88
+ emby-cli play --id 123456 --player vlc --wait
89
+ ```
90
+
91
+ Set `EMBY_PLAYER` if the player is not found automatically.
92
+
93
+ ### Download
94
+
95
+ Download a single title, a whole library, or a list of titles from a file:
96
+
97
+ ```bash
98
+ emby-cli download --item --id 123456
99
+ emby-cli download --item "californication S01E01" --pick-best-item
100
+ emby-cli download --library "PELICULAS 4K"
101
+ emby-cli download --from-file titles.txt
102
+ ```
103
+
104
+ Useful options:
105
+
106
+ | Option | Meaning |
107
+ |--------|---------|
108
+ | `-n` / `--dry-run` | Resolve titles only — do not write files |
109
+ | `-o` / `--output` | Output folder (default `./downloads`) |
110
+ | `-f` / `--force` | Re-download even if a matching local file exists |
111
+ | `--pick-best-item` | When several versions match, pick the best ≤1080p |
112
+ | `-m download\|stream\|hls` | How to fetch the file (see below) |
113
+
114
+ **Title lines** in `--item` / `--from-file` can look like:
115
+
116
+ - `Movie (2010)`
117
+ - `Show S01E05`
118
+ - `Show S01` — whole season (with `--item` or `--from-file`)
119
+
120
+ By default, matching is **strict**: a wrong year or several ambiguous results stops with a table of candidates. Add `--pick-best-item` to choose automatically (best quality up to 1080p).
121
+
122
+ Library downloads match the library **name** (case-insensitive, unique match required).
123
+
124
+ ---
125
+
126
+ ## Logging in and switching servers
127
+
128
+ | Approach | When to use |
129
+ |----------|-------------|
130
+ | `emby-cli login` | Recommended — saves a session and remembers the server |
131
+ | API key | `--api-key` / `EMBY_API_KEY` (keys are not stored by `login`) |
132
+ | Flags / env | `--server`, `--username`, `--password` or `EMBY_*` for one-off use |
133
+
134
+ Manage saved servers:
135
+
136
+ ```bash
137
+ emby-cli config get-servers
138
+ emby-cli config current-server
139
+ emby-cli config use-server 'you@http://emby:8096'
140
+ emby-cli config view # tokens redacted
141
+ emby-cli logout # revoke and forget the current session
142
+ ```
143
+
144
+ Sessions live under `~/.cache/emby-cli/auth.json` (override with `EMBY_CACHE_DIR`). Set `EMBY_NO_AUTH_CACHE=1` to never read or write the cache.
145
+
146
+ ---
147
+
148
+ ## Download methods
149
+
150
+ Choose with `-m` / `EMBY_METHOD`:
151
+
152
+ | Method | Best for |
153
+ |--------|----------|
154
+ | `download` (default) | Normal file download from Emby |
155
+ | `stream` | Direct stream URL (similar to Emby Web) |
156
+ | `hls` | HLS remux to `.mkv` |
157
+
158
+ ---
159
+
160
+ ## Configuration reference
161
+
162
+ Flags override environment variables. Optional template: `.env.example` (export the vars yourself — the CLI does not load `.env` files).
163
+
164
+ | Variable | Description |
165
+ |----------|-------------|
166
+ | `EMBY_SERVER` | Server URL |
167
+ | `EMBY_API_KEY` | API key |
168
+ | `EMBY_USERNAME` / `EMBY_PASSWORD` | Username / password |
169
+ | `EMBY_OUTPUT` | Download directory (default `./downloads`) |
170
+ | `EMBY_METHOD` | `download`, `stream`, or `hls` |
171
+ | `EMBY_PLAYER` | External player command or path |
172
+ | `EMBY_ITEM_ID` | Default `--id` for item download / play |
173
+ | `EMBY_CACHE_DIR` | Credentials directory (default `~/.cache/emby-cli`) |
174
+ | `EMBY_NO_AUTH_CACHE` | `1` = disable session cache |
175
+
176
+ ---
177
+
178
+ ## Tips
179
+
180
+ - Prefer **search → show → download** when you are unsure of the exact title.
181
+ - Prefer **IDs** (`--id`) when you already have them — no ambiguity.
182
+ - Use **`--dry-run`** before a large library or file-list download.
183
+ - Content totals in `info` can count multiple versions of the same title separately.
184
+
185
+ ---
186
+
187
+ ## Responsible use
188
+
189
+ This tool talks to Emby over its normal HTTP API. Whether download or playback is allowed depends on **how that server is configured** and on **the terms set by whoever runs it**.
190
+
191
+ Use `emby-cli` only on servers you are authorized to access, and only in ways that comply with that server’s terms of use, policies, and applicable law. The authors provide the software as-is and are **not responsible** for misuse, for downloads from servers that disallow them, or for any consequences of using the tool.
192
+
193
+ ---
194
+
195
+ ## For contributors
196
+
197
+ ```bash
198
+ python3 -m venv .venv && source .venv/bin/activate
199
+ pip install -e ".[dev]"
200
+ pytest -q
201
+ python -m build && twine check dist/*
202
+ ```
203
+
204
+ Releases: tag `vX.Y.Z` and push (or create a GitHub Release). CI publishes to PyPI via Trusted Publisher.
205
+
206
+ ## License
207
+
208
+ [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/) — free for non-commercial use.
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.3.0'
22
- __version_tuple__ = version_tuple = (0, 3, 0)
21
+ __version__ = version = '0.4.1'
22
+ __version_tuple__ = version_tuple = (0, 4, 1)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -21,6 +21,7 @@ from emby_cli.commands.login import cmd_login
21
21
  from emby_cli.commands.logout import cmd_logout
22
22
  from emby_cli.commands.play import cmd_play, validate_play_args
23
23
  from emby_cli.commands.search import cmd_search, validate_search_args
24
+ from emby_cli.commands.show import cmd_show, validate_show_args
24
25
  from emby_cli.commands.version import cmd_version
25
26
  from emby_cli.constants import DEFAULT_OUTPUT, SEARCH_COUNT_DEFAULT
26
27
  from emby_cli.credentials import (
@@ -82,14 +83,23 @@ def build_parser() -> argparse.ArgumentParser:
82
83
  )
83
84
  mode = dl.add_mutually_exclusive_group(required=True)
84
85
  mode.add_argument(
86
+ "--item",
85
87
  "--media-item",
86
- action="store_true",
87
- help="Download media items; use with --id or --search",
88
+ nargs="?",
89
+ const="",
90
+ default=None,
91
+ metavar="QUERY",
92
+ dest="item",
93
+ help="Download media items; optional QUERY, or use with --id "
94
+ "(--media-item is an alias)",
88
95
  )
89
96
  mode.add_argument(
90
97
  "--library",
91
- action="store_true",
92
- help="Download a library; use with --id or --search",
98
+ nargs="?",
99
+ const="",
100
+ default=None,
101
+ metavar="QUERY",
102
+ help="Download a library; optional QUERY, or use with --id",
93
103
  )
94
104
  mode.add_argument(
95
105
  "--from-file",
@@ -105,7 +115,7 @@ def build_parser() -> argparse.ArgumentParser:
105
115
  )
106
116
  dl.add_argument(
107
117
  "--search",
108
- help="Search query for media item or library",
118
+ help="Search query (alternative to QUERY on --item / --library)",
109
119
  )
110
120
  dl.add_argument(
111
121
  "--dry-run",
@@ -146,14 +156,23 @@ def build_parser() -> argparse.ArgumentParser:
146
156
  sr = sub.add_parser("search", help=_help_by_name["search"])
147
157
  sr_mode = sr.add_mutually_exclusive_group(required=True)
148
158
  sr_mode.add_argument(
159
+ "--item",
149
160
  "--media-item",
150
- action="store_true",
151
- help="Search media items; use with --id, --search, or --all",
161
+ nargs="?",
162
+ const="",
163
+ default=None,
164
+ metavar="QUERY",
165
+ dest="item",
166
+ help="Search media items; optional QUERY, or use with --id / --all "
167
+ "(--media-item is an alias)",
152
168
  )
153
169
  sr_mode.add_argument(
154
170
  "--library",
155
- action="store_true",
156
- help="Search libraries; use with --id, --search, or --all",
171
+ nargs="?",
172
+ const="",
173
+ default=None,
174
+ metavar="QUERY",
175
+ help="Search libraries; optional QUERY, or use with --id / --all",
157
176
  )
158
177
  sr.add_argument(
159
178
  "--id",
@@ -162,7 +181,7 @@ def build_parser() -> argparse.ArgumentParser:
162
181
  )
163
182
  sr.add_argument(
164
183
  "--search",
165
- help="Search query for media item or library",
184
+ help="Search query (alternative to QUERY on --item / --library)",
166
185
  )
167
186
  sr.add_argument(
168
187
  "--all",
@@ -206,6 +225,37 @@ def build_parser() -> argparse.ArgumentParser:
206
225
  "(default: list matches and fail)",
207
226
  )
208
227
 
228
+ sh = sub.add_parser("show", help=_help_by_name["show"])
229
+ sh_mode = sh.add_mutually_exclusive_group(required=True)
230
+ sh_mode.add_argument(
231
+ "--item",
232
+ "--media-item",
233
+ nargs="?",
234
+ const="",
235
+ default=None,
236
+ metavar="QUERY",
237
+ dest="item",
238
+ help="Show a media item; optional QUERY, or use with --id "
239
+ "(--media-item is an alias)",
240
+ )
241
+ sh_mode.add_argument(
242
+ "--library",
243
+ nargs="?",
244
+ const="",
245
+ default=None,
246
+ metavar="QUERY",
247
+ help="Show a library; optional QUERY, or use with --id",
248
+ )
249
+ sh.add_argument(
250
+ "--id",
251
+ default=None,
252
+ help="Media item or library ID",
253
+ )
254
+ sh.add_argument(
255
+ "--search",
256
+ help="Search query (alternative to QUERY on --item / --library)",
257
+ )
258
+
209
259
  sub.add_parser("version", help=_help_by_name["version"])
210
260
  sub.add_parser("info", help=_help_by_name["info"])
211
261
 
@@ -249,6 +299,8 @@ def _validate_command_args(command: str, args: argparse.Namespace) -> str | None
249
299
  return validate_download_args(args)
250
300
  if command == "play":
251
301
  return validate_play_args(args)
302
+ if command == "show":
303
+ return validate_show_args(args)
252
304
  return None
253
305
 
254
306
 
@@ -293,6 +345,7 @@ def main() -> None:
293
345
  "download": cmd_download,
294
346
  "search": cmd_search,
295
347
  "play": cmd_play,
348
+ "show": cmd_show,
296
349
  }
297
350
  commands[args.command](client, args)
298
351
 
@@ -458,15 +458,19 @@ class EmbyClient:
458
458
  recursive: bool = True,
459
459
  start: int = 0,
460
460
  limit: int = 200,
461
+ *,
462
+ sort_by: str = "SortName",
463
+ sort_order: str = "Ascending",
464
+ fields: str | None = None,
461
465
  ) -> dict:
462
466
  uid = self.resolve_user_id()
463
467
  params: dict = {
464
468
  "StartIndex": start,
465
469
  "Limit": limit,
466
470
  "Recursive": str(recursive).lower(),
467
- "Fields": ITEM_FIELDS,
468
- "SortBy": "SortName",
469
- "SortOrder": "Ascending",
471
+ "Fields": fields or ITEM_FIELDS,
472
+ "SortBy": sort_by,
473
+ "SortOrder": sort_order,
470
474
  }
471
475
  if parent_id:
472
476
  params["ParentId"] = parent_id
@@ -493,11 +497,11 @@ class EmbyClient:
493
497
  break
494
498
  return items
495
499
 
496
- def get_item_info(self, item_id: str) -> dict:
500
+ def get_item_info(self, item_id: str, *, fields: str | None = None) -> dict:
497
501
  uid = self.resolve_user_id()
498
502
  resp = self._get(
499
503
  f"/Users/{uid}/Items/{item_id}",
500
- params={"Fields": ITEM_FIELDS},
504
+ params={"Fields": fields or ITEM_FIELDS},
501
505
  )
502
506
  return resp.json()
503
507