Skip to content
This repository was archived by the owner on Oct 26, 2025. It is now read-only.

Commit 795cf28

Browse files
authored
Modernize 2025-09-14 (#59)
* modernize with ruff * Remove deprecated ownerid * Switch from poetry to uv. Bump a bunch of versions. Remove unused modules. * Better exception handling * Tweak gh workflow syntax
1 parent d3ab129 commit 795cf28

11 files changed

Lines changed: 411 additions & 1034 deletions

File tree

.dockerignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
.mypy_cache
1515
.requirements*
1616
.tox
17+
.venv
1718
.vscode
1819
Pipfile.lock
1920
__pycache__
2021
dev.env
2122
env
2223
pip-wheel-metadata
23-
poetry.lock
24+
venv

.flake8

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/workflows/create-release-from-tag.yaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@ jobs:
1414
- name: Checkout code
1515
uses: actions/checkout@v4
1616

17-
- name: Install Poetry
18-
run: curl -sSL https://install.python-poetry.org/ | python -
17+
# https://docs.astral.sh/uv/guides/integration/github/
18+
- name: Install uv
19+
uses: astral-sh/setup-uv@v5
1920

2021
- name: Build packages
21-
run: poetry build -f wheel
22+
run: uv build
2223

2324
- name: Create Release
2425
id: create_release
25-
uses: softprops/action-gh-release@v1
26+
uses: softprops/action-gh-release@v2
2627
with:
2728
files: dist/*.whl

.github/workflows/pre-commit-action.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: pre-commit
22

3-
on: [push, pull_request]
3+
on:
4+
pull_request:
45

56
jobs:
67
pre-commit:

.pre-commit-config.yaml

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,23 @@
11
---
22
exclude: "(venv|.vscode)" # regex
33
repos:
4-
- repo: https://github.com/pre-commit/pygrep-hooks
5-
rev: v1.10.0
6-
hooks:
7-
- id: python-check-blanket-noqa
8-
- id: python-check-blanket-type-ignore
9-
- id: text-unicode-replacement-char
10-
- repo: https://github.com/pre-commit/mirrors-prettier
11-
rev: "v3.1.0"
12-
hooks:
13-
- id: prettier
14-
args: ["--print-width=135"]
15-
- repo: https://github.com/asottile/pyupgrade
16-
rev: v3.20.0
17-
hooks:
18-
- id: pyupgrade
19-
args: ["--py38-plus"]
20-
- repo: https://github.com/pycqa/isort
21-
rev: 6.0.1
22-
hooks:
23-
- id: isort
24-
name: isort (python)
25-
- repo: https://github.com/psf/black
26-
rev: 25.1.0
27-
hooks:
28-
- id: black
294
- repo: https://github.com/astral-sh/ruff-pre-commit
30-
rev: "v0.12.7"
5+
rev: "v0.13.0"
316
hooks:
327
- id: ruff-check
33-
args: ["--fix", "--exit-non-zero-on-fix"]
8+
args:
9+
- "--fix"
10+
- "--exit-non-zero-on-fix"
11+
- "--unsafe-fixes"
12+
- id: ruff-format
3413
- repo: https://github.com/PyCQA/bandit
3514
rev: 1.8.6
3615
hooks:
3716
- id: bandit
3817
args: ["-s", "B101"]
39-
- repo: https://github.com/PyCQA/pydocstyle
40-
rev: 6.3.0
41-
hooks:
42-
- id: pydocstyle
43-
- repo: https://github.com/PyCQA/flake8
44-
rev: 7.3.0
45-
hooks:
46-
- id: flake8
4718
- repo: https://github.com/pre-commit/pre-commit-hooks
48-
rev: v5.0.0
19+
rev: v6.0.0
4920
hooks:
50-
- id: check-byte-order-marker
5121
- id: check-case-conflict
5222
- id: check-executables-have-shebangs
5323
- id: check-docstring-first
@@ -65,7 +35,6 @@ repos:
6535
- id: mixed-line-ending
6636
args: ["--fix=lf"]
6737
- id: pretty-format-json
68-
- id: requirements-txt-fixer
6938
- id: sort-simple-yaml
7039
- id: trailing-whitespace
7140
- repo: https://github.com/adrienverge/yamllint.git

Makefile

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,39 +37,24 @@ docker-push: ## Push built Docker container to Docker Hub
3737

3838
.PHONY: clean
3939
clean: ## Delete build artifacts
40-
rm -f .requirements-dev .requirements || true
41-
find . -name '*.pyc' -delete
42-
find . -name '__pycache__' -delete
43-
rm -rf dist
40+
-rm -rf .venv
41+
-find . -name '*.pyc' -delete
42+
-find . -name '__pycache__' -delete
43+
-rm -rf dist
4444

45-
.PHONY: poetry-clean
46-
poetry-clean: ## Delete poetry virtualenv
47-
poetry env list 2>/dev/null | awk '{print $$1}' | xargs -n1 poetry env remove || true
48-
rm -fv .requirements
49-
50-
.PHONY: wheel
51-
wheel: ## Build a wheel
52-
poetry build -f wheel
45+
.PHONY: build
46+
build: ## Build a wheel
47+
uv build
5348

5449
.PHONY: test
5550
test: ## Run tests
56-
tox
57-
58-
.PHONY: requirements-dev
59-
requirements-dev: .requirements-dev ## Install dev requirements
60-
.requirements-dev:
61-
pip3 install --user --upgrade poetry
62-
poetry run pip install --quiet --upgrade pip setuptools wheel
63-
poetry install
64-
touch .requirements-dev .requirements
51+
uv run pytest tests
6552

66-
.PHONY: requirements
67-
requirements: .requirements ## Install requirements
68-
.requirements:
69-
pip3 install --user --upgrade poetry
70-
poetry run pip install --quiet --upgrade pip setuptools wheel
71-
poetry install --no-dev
72-
touch .requirements
53+
.PHONY: venv
54+
venv: .venv ## Install dev requirements
55+
.venv:
56+
uv venv --seed
57+
uv sync
7358

7459
.PHONY: generate-setup.py
7560
generate-setup.py: wheel ## Generate the setup.py file from pyproject.toml

plexdl/cli.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""plexdl CLI."""
22

33
import datetime
4-
import logging
54
import sys
65

76
import humanize
@@ -15,24 +14,17 @@
1514

1615
from plexdl.plexdl import Client
1716

18-
19-
def get_logger(ctx, param, value):
20-
"""Get logger and return verbosity value."""
21-
logging.basicConfig(format="%(message)s")
22-
log = logging.getLogger("plexdl")
23-
if value > 0:
24-
log.setLevel("DEBUG") # https://docs.python.org/3.9/library/logging.html#logging-levels
25-
return value
26-
27-
28-
app = typer.Typer(help=__doc__, context_settings={"max_content_width": 9999})
17+
app = typer.Typer(
18+
context_settings={"max_content_width": 9999},
19+
help=__doc__,
20+
pretty_exceptions_enable=False,
21+
)
2922

3023

3124
@app.command()
3225
def get_server_info(
3326
username: str = typer.Argument(None, envvar="PLEXDL_USERNAME"),
3427
password: str = typer.Argument(None, envvar="PLEXDL_PASSWORD"),
35-
debug: bool = typer.Argument(False, envvar="PLEXDL_DEBUG"),
3628
):
3729
"""Show info about servers available to your account."""
3830
p = MyPlexAccount(
@@ -63,7 +55,6 @@ def get_server_info(
6355
print(f" httpsRequired: {server.httpsRequired}")
6456
print(f" name: {server.name}")
6557
print(f" owned: {server.owned}")
66-
print(f" ownerid: {server.ownerid}")
6758
print(f" platform: {server.platform}")
6859
print(f" platformVersion: {server.platformVersion}")
6960
print(f" presence: {server.presence}")
@@ -73,7 +64,7 @@ def get_server_info(
7364
print(f" publicAddressMatches: {server.publicAddressMatches}")
7465
print(f" sourceTitle: {server.sourceTitle}")
7566
print(f" synced: {server.synced}")
76-
print("")
67+
print()
7768

7869

7970
@app.command()
@@ -86,7 +77,6 @@ def search(
8677
show_ratings: bool = typer.Option(False, "--show-ratings", help="Show ratings for each result"),
8778
show_metadata: bool = typer.Option(False, "--show-metadata", help="Show file and codec metadata for each file in each result"),
8879
include_relays: bool = typer.Option(False, "--include-relays", help="Output relay servers along with direct servers"),
89-
verbose: bool = typer.Option(False, "--verbose", "-v"),
9080
debug: bool = typer.Option(False, "--debug"),
9181
):
9282
"""Search for media in servers that are available to your account."""

plexdl/plexdl.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import locale
44
import logging
5-
from typing import List
5+
from typing import ClassVar
66

77
import humanfriendly
88
import requests
9+
from plexapi.exceptions import Unauthorized
910
from plexapi.myplex import MyPlexAccount
1011
from plexapi.server import PlexServer
1112

@@ -29,7 +30,7 @@ def __init__(self, **kwargs):
2930
self.username = kwargs["username"]
3031
self.account = MyPlexAccount(self.username, self.password)
3132

32-
available_servers: List[PlexServer] = []
33+
available_servers: ClassVar[list[PlexServer]] = []
3334

3435
@staticmethod
3536
def print_item_info(self, item, access_token):
@@ -60,7 +61,7 @@ def print_item_info(self, item, access_token):
6061
except ValueError:
6162
pass
6263
if media_info:
63-
print(f'({", ".join(media_info)})')
64+
print(f"({', '.join(media_info)})")
6465
print(f' {self.item_prefix} "{download_filename}" "{download_url}"')
6566

6667
@staticmethod
@@ -110,8 +111,7 @@ def main(self):
110111
if self.relay is False:
111112
log.debug(f"Skipping {this_server_connection.friendlyName} relay")
112113
continue
113-
else:
114-
relay_status = " (relay)"
114+
relay_status = " (relay)"
115115
print("\n")
116116
print("=" * 79)
117117
print(f'Server: "{this_server_connection.friendlyName}"{relay_status}')
@@ -122,7 +122,7 @@ def main(self):
122122
for item in this_server_connection.search(self.title):
123123
self.print_all_items_for_server(self, item, this_server.accessToken)
124124

125-
except (requests.exceptions.ConnectionError, requests.exceptions.ReadTimeout) as e:
125+
except (requests.exceptions.ConnectionError, requests.exceptions.ReadTimeout, Unauthorized) as e:
126126
print(f'ERROR: connection to "{this_server.name} {connection.address}" failed.')
127127
log.debug(e)
128128
continue

0 commit comments

Comments
 (0)