plexdo 1.1.29__tar.gz → 2.0.3__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 (152) hide show
  1. {plexdo-1.1.29 → plexdo-2.0.3}/.github/workflows/ci.yml +18 -1
  2. {plexdo-1.1.29 → plexdo-2.0.3}/.github/workflows/publish.yml +34 -10
  3. {plexdo-1.1.29 → plexdo-2.0.3}/.github/workflows/wiki.yml +8 -2
  4. plexdo-2.0.3/.markdownlint-cli2.yaml +26 -0
  5. plexdo-2.0.3/.nvmrc +1 -0
  6. plexdo-2.0.3/.yamllint.yaml +21 -0
  7. plexdo-2.0.3/AI.policy.txt +6 -0
  8. plexdo-1.1.29/AI.prompt.md → plexdo-2.0.3/AI.prompt.txt +546 -134
  9. {plexdo-1.1.29 → plexdo-2.0.3}/CHANGELOG.md +190 -11
  10. {plexdo-1.1.29 → plexdo-2.0.3}/CONTRIBUTING.md +34 -10
  11. plexdo-2.0.3/LICENSE +674 -0
  12. plexdo-2.0.3/LICENSES/GPL-3.0-or-later.txt +674 -0
  13. plexdo-2.0.3/MANIFEST.in +20 -0
  14. {plexdo-1.1.29 → plexdo-2.0.3}/Makefile +27 -12
  15. {plexdo-1.1.29/src/plexdo.egg-info → plexdo-2.0.3}/PKG-INFO +129 -118
  16. {plexdo-1.1.29 → plexdo-2.0.3}/README.md +125 -116
  17. plexdo-2.0.3/REUSE.toml +28 -0
  18. plexdo-2.0.3/SECURITY.md +50 -0
  19. {plexdo-1.1.29/src/plexdo/data → plexdo-2.0.3/completions}/_plexdo +12 -1
  20. {plexdo-1.1.29 → plexdo-2.0.3}/completions/plexdo.bash +54 -38
  21. {plexdo-1.1.29/src/plexdo/data → plexdo-2.0.3/completions}/plexdo.fish +10 -3
  22. {plexdo-1.1.29/src/plexdo/data → plexdo-2.0.3/completions}/plexdo.ps1 +8 -2
  23. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-append-playlist.1.scd +3 -0
  24. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-build-chronological.1.scd +3 -0
  25. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-build-concatenated.1.scd +3 -0
  26. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-build-interleaved.1.scd +3 -0
  27. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-build-randomize.1.scd +3 -0
  28. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-clean-playlist.1.scd +3 -0
  29. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-conventions.7.scd +63 -33
  30. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-copy-playlist-all-users.1.scd +3 -0
  31. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-copy-playlist-to-user.1.scd +3 -0
  32. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-copy-watched.1.scd +3 -0
  33. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-export-playlist.1.scd +3 -0
  34. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-export-titles.1.scd +3 -0
  35. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-find-missing.1.scd +3 -0
  36. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-list-libraries.1.scd +3 -0
  37. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-list-playlist.1.scd +3 -0
  38. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-list-playlists.1.scd +3 -0
  39. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-list-show.1.scd +3 -0
  40. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-list-titles.1.scd +3 -0
  41. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-list-users.1.scd +3 -0
  42. plexdo-2.0.3/man/plexdo-login.1.scd +160 -0
  43. plexdo-2.0.3/man/plexdo-logout.1.scd +150 -0
  44. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-player-remote-play.1.scd +27 -25
  45. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-read.1.scd +3 -0
  46. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-remove-playlist.1.scd +3 -0
  47. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-rescan.1.scd +3 -0
  48. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-search.1.scd +3 -0
  49. plexdo-2.0.3/man/plexdo-set-pin.1.scd +120 -0
  50. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-show-metadata.1.scd +3 -0
  51. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-status.1.scd +3 -0
  52. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-wait.1.scd +3 -0
  53. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo-write-config-example.1.scd +28 -20
  54. {plexdo-1.1.29 → plexdo-2.0.3}/man/plexdo.1 +124 -73
  55. plexdo-2.0.3/package-lock.json +1420 -0
  56. plexdo-2.0.3/package.json +12 -0
  57. {plexdo-1.1.29 → plexdo-2.0.3}/pyproject.toml +36 -2
  58. {plexdo-1.1.29 → plexdo-2.0.3}/requirements.txt +6 -0
  59. plexdo-2.0.3/sbom.spdx.json +263 -0
  60. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/__init__.py +30 -3
  61. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/__main__.py +4 -2
  62. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/accounts.py +73 -65
  63. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/airdates.py +27 -18
  64. plexdo-2.0.3/src/plexdo/arguments.py +83 -0
  65. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/cache.py +7 -5
  66. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/cli.py +49 -19
  67. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/__init__.py +24 -7
  68. plexdo-2.0.3/src/plexdo/commands/auth.py +458 -0
  69. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/build.py +85 -72
  70. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/copy.py +50 -22
  71. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/libraries.py +62 -35
  72. plexdo-2.0.3/src/plexdo/commands/metadata.py +149 -0
  73. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/missing.py +57 -26
  74. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/playlists.py +101 -39
  75. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/remote.py +201 -120
  76. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/rescan.py +54 -21
  77. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/search.py +47 -29
  78. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/status.py +69 -40
  79. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/stream.py +11 -8
  80. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/users.py +8 -2
  81. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/wait.py +216 -108
  82. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/commands/watched.py +71 -38
  83. plexdo-2.0.3/src/plexdo/config.py +237 -0
  84. plexdo-2.0.3/src/plexdo/connection.py +46 -0
  85. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/console.py +69 -32
  86. plexdo-2.0.3/src/plexdo/constants.py +280 -0
  87. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/convert.py +4 -3
  88. {plexdo-1.1.29/completions → plexdo-2.0.3/src/plexdo/data}/_plexdo +12 -1
  89. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/data/plexdo.1 +124 -73
  90. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/data/plexdo.bash +54 -38
  91. {plexdo-1.1.29/completions → plexdo-2.0.3/src/plexdo/data}/plexdo.fish +10 -3
  92. {plexdo-1.1.29/completions → plexdo-2.0.3/src/plexdo/data}/plexdo.ps1 +8 -2
  93. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/fanout.py +35 -20
  94. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/formats.py +22 -14
  95. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/gallery.py +54 -31
  96. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/identify.py +12 -5
  97. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/logs.py +2 -0
  98. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/m3u.py +4 -3
  99. plexdo-2.0.3/src/plexdo/migrate.py +192 -0
  100. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/paths.py +16 -9
  101. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/photos.py +10 -9
  102. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/playback.py +69 -37
  103. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/playlists.py +21 -17
  104. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/records.py +35 -27
  105. plexdo-2.0.3/src/plexdo/secret_store.py +241 -0
  106. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/sections.py +15 -6
  107. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/security.py +6 -4
  108. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/sorting.py +7 -6
  109. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/throttle.py +8 -3
  110. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/titles.py +8 -4
  111. plexdo-2.0.3/src/plexdo/tokens.py +113 -0
  112. {plexdo-1.1.29 → plexdo-2.0.3/src/plexdo.egg-info}/PKG-INFO +129 -118
  113. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo.egg-info/SOURCES.txt +17 -1
  114. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo.egg-info/requires.txt +3 -1
  115. {plexdo-1.1.29 → plexdo-2.0.3}/tests/conftest.py +67 -13
  116. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_airdates_misc.py +52 -24
  117. plexdo-2.0.3/tests/test_cli_and_config.py +416 -0
  118. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_console.py +48 -21
  119. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_fanout.py +30 -8
  120. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_fixes.py +45 -17
  121. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_formats.py +3 -1
  122. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_identify.py +5 -1
  123. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_logout.py +53 -35
  124. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_logs.py +10 -4
  125. plexdo-2.0.3/tests/test_paths_tokens.py +131 -0
  126. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_playback.py +92 -37
  127. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_playlists.py +26 -9
  128. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_records_missing.py +77 -34
  129. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_remote_play.py +269 -148
  130. plexdo-2.0.3/tests/test_secret_store.py +330 -0
  131. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_throttle.py +9 -2
  132. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_wait.py +148 -53
  133. {plexdo-1.1.29 → plexdo-2.0.3}/tests/test_watched.py +9 -5
  134. plexdo-2.0.3/tools/derive.py +262 -0
  135. {plexdo-1.1.29 → plexdo-2.0.3}/tools/wiki-pages.sh +3 -0
  136. plexdo-1.1.29/LICENSE +0 -232
  137. plexdo-1.1.29/MANIFEST.in +0 -12
  138. plexdo-1.1.29/SECURITY.md +0 -35
  139. plexdo-1.1.29/man/plexdo-login.1.scd +0 -146
  140. plexdo-1.1.29/man/plexdo-logout.1.scd +0 -144
  141. plexdo-1.1.29/src/plexdo/commands/auth.py +0 -334
  142. plexdo-1.1.29/src/plexdo/commands/metadata.py +0 -135
  143. plexdo-1.1.29/src/plexdo/config.py +0 -153
  144. plexdo-1.1.29/src/plexdo/constants.py +0 -118
  145. plexdo-1.1.29/src/plexdo/tokens.py +0 -106
  146. plexdo-1.1.29/tests/test_cli_and_config.py +0 -248
  147. plexdo-1.1.29/tests/test_paths_tokens.py +0 -103
  148. {plexdo-1.1.29 → plexdo-2.0.3}/setup.cfg +0 -0
  149. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo/py.typed +0 -0
  150. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo.egg-info/dependency_links.txt +0 -0
  151. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo.egg-info/entry_points.txt +0 -0
  152. {plexdo-1.1.29 → plexdo-2.0.3}/src/plexdo.egg-info/top_level.txt +0 -0
@@ -1,3 +1,8 @@
1
+ # SPDX-FileCopyrightText: 2026 SidusNare
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+ # SPDX-FileContributor: Claude Opus 5.5 (AI-generated)
4
+
5
+ ---
1
6
  name: CI
2
7
 
3
8
  on:
@@ -26,10 +31,22 @@ jobs:
26
31
  with:
27
32
  python-version: ${{ matrix.python-version }}
28
33
 
34
+ # markdownlint-cli2 needs Node 22 or newer; .nvmrc names the version.
35
+ - uses: actions/setup-node@v7
36
+ with:
37
+ node-version-file: .nvmrc
38
+
39
+ # make check lints with every tool the project requires: ShellCheck
40
+ # and yamllint from apt, reuse from PyPI (apt's is too old to read
41
+ # REUSE.toml), and markdownlint-cli2 at the version package.json pins.
42
+ # publish.yml installs the same, since it runs the same make check.
29
43
  - name: Install
30
44
  run: |
31
45
  python -m pip install --upgrade pip
32
- pip install -e ".[dev]"
46
+ pip install -e ".[dev]" reuse
47
+ sudo apt-get update
48
+ sudo apt-get install -y shellcheck yamllint
49
+ npm ci
33
50
 
34
51
  - name: Full check
35
52
  run: make check
@@ -1,3 +1,8 @@
1
+ # SPDX-FileCopyrightText: 2026 SidusNare
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+ # SPDX-FileContributor: Claude Opus 5.5 (AI-generated)
4
+
5
+ ---
1
6
  name: Publish
2
7
 
3
8
  # Publishes to PyPI through Trusted Publishing (OIDC), so no API token is
@@ -40,13 +45,25 @@ jobs:
40
45
  with:
41
46
  python-version: "3.12"
42
47
 
48
+ # markdownlint-cli2 needs Node 22 or newer; .nvmrc names the version.
49
+ - uses: actions/setup-node@v7
50
+ with:
51
+ node-version-file: .nvmrc
52
+
53
+ # make check lints with every tool the project requires: ShellCheck
54
+ # and yamllint from apt, reuse from PyPI (apt's is too old to read
55
+ # REUSE.toml), and markdownlint-cli2 at the version package.json pins.
56
+ # ci.yml installs the same, since it runs the same make check.
43
57
  - name: Install
44
58
  run: |
45
59
  python -m pip install --upgrade pip
46
- pip install -e ".[dev]"
60
+ pip install -e ".[dev]" reuse
61
+ sudo apt-get update
62
+ sudo apt-get install -y shellcheck yamllint
63
+ npm ci
47
64
 
48
65
  # Everything that gates a normal pull request also gates a release:
49
- # version consistency across the three places it appears, packaged
66
+ # the man page and SBOM matching pyproject's version, packaged
50
67
  # assets matching their sources, the smoke test, the suite, pylint,
51
68
  # the build itself, and twine's metadata check.
52
69
  - name: Full check
@@ -55,17 +72,24 @@ jobs:
55
72
  # A release tagged v1.2.3 must contain version 1.2.3. Without this the
56
73
  # wheel would upload under whatever version the source happened to
57
74
  # carry, and PyPI would accept it: uploads are immutable, so the
58
- # mistake could not be taken back.
75
+ # mistake could not be taken back. Compared as versions, not text: a
76
+ # tag is SemVer, v2.0.0-rc.1, and pyproject's PEP 440, 2.0.0rc1.
59
77
  - name: Tag matches package version
60
78
  if: github.event_name == 'release'
79
+ shell: python
61
80
  run: |
62
- tag="${GITHUB_REF_NAME#v}"
63
- version="$(python -c 'import plexdo; print(plexdo.__version__)')"
64
- if [ "$tag" != "$version" ]; then
65
- echo "::error::tag $GITHUB_REF_NAME does not match version $version"
66
- exit 1
67
- fi
68
- echo "tag $GITHUB_REF_NAME matches version $version"
81
+ import os
82
+ import sys
83
+
84
+ from packaging.version import Version
85
+
86
+ import plexdo
87
+
88
+ tag = os.environ["GITHUB_REF_NAME"]
89
+ if Version(tag.removeprefix("v")) != Version(plexdo.__version__):
90
+ print(f"::error::tag {tag} does not match {plexdo.__version__}")
91
+ sys.exit(1)
92
+ print(f"tag {tag} matches version {plexdo.__version__}")
69
93
 
70
94
  # Exactly one job may upload a given artifact name: since v4 they are
71
95
  # immutable, so a second upload of "dist" would fail rather than merge.
@@ -1,3 +1,8 @@
1
+ # SPDX-FileCopyrightText: 2026 SidusNare
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+ # SPDX-FileContributor: Claude Opus 5.5 (AI-generated)
4
+
5
+ ---
1
6
  name: Wiki
2
7
 
3
8
  # Publishes one GitHub wiki page per man/*.scd page: tools/wiki-pages.sh
@@ -121,8 +126,9 @@ jobs:
121
126
  fi
122
127
  git diff --cached --stat
123
128
 
124
- git config user.name "github-actions[bot]"
125
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
129
+ bot="github-actions[bot]"
130
+ git config user.name "$bot"
131
+ git config user.email "41898282+$bot@users.noreply.github.com"
126
132
  git commit --quiet \
127
133
  -m "Update manual pages from ${GITHUB_SHA::7}" \
128
134
  -m "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}"
@@ -0,0 +1,26 @@
1
+ # SPDX-FileCopyrightText: 2026 SidusNare
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+ # SPDX-FileContributor: Claude Opus 5.5 (AI-generated)
4
+ #
5
+ #
6
+ # markdownlint-cli2 configuration, following Google's Markdown style guide.
7
+ ---
8
+ config:
9
+ # Each CHANGELOG release repeats the same Added/Changed/Fixed headings, so
10
+ # only headings that are siblings under one parent must differ.
11
+ MD024:
12
+ siblings_only: true
13
+ # Google's guide: 80 columns, except where a line cannot be broken, as in
14
+ # a code block or a table row.
15
+ MD013:
16
+ line_length: 80
17
+ code_blocks: false
18
+ tables: false
19
+ globs:
20
+ - "**/*.md"
21
+ ignores:
22
+ - "node_modules/**"
23
+ - "build/**"
24
+ - "dist/**"
25
+ # pytest writes a README of its own here while the tests run.
26
+ - ".pytest_cache/**"
plexdo-2.0.3/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 24
@@ -0,0 +1,21 @@
1
+ # SPDX-FileCopyrightText: 2026 SidusNare
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+ # SPDX-FileContributor: Claude Opus 5.5 (AI-generated)
4
+ #
5
+ #
6
+ # yamllint configuration: the default rules, at Google's 80 columns.
7
+ ---
8
+ extends: default
9
+
10
+ ignore: |
11
+ node_modules/
12
+ build/
13
+ dist/
14
+
15
+ rules:
16
+ line-length:
17
+ max: 80
18
+ # GitHub Actions requires the key "on", which YAML 1.1 reads as a
19
+ # boolean; keys are exempt, values are still checked.
20
+ truthy:
21
+ check-keys: false
@@ -0,0 +1,6 @@
1
+
2
+ AI has been trained almost exclusively on open source. Ethically, all rights, AI generated code should be automatically encumbered by the licenses of the code that generated it. While I can't make any corporation, AI platform, or government adopt such a policy, I can commit to a personal policy pertaining to what I generate with AI.
3
+
4
+ All AI projects will be released GPL-3.
5
+ All AI projects will be released with all available platform and prompt information to aid in reproducing, modifying, and collaborating development in the spirit of the open source community that started this in the first place.
6
+