Compare commits

..

No commits in common. "2f70c6f7fa1ff16a8a79f6f977785ba37c296870" and "35703de26116bdcf4ffd0f5c34e32be1939e8012" have entirely different histories.

12 changed files with 27 additions and 89 deletions

View file

@ -5,7 +5,7 @@
groups = ["default", "all", "dev"] groups = ["default", "all", "dev"]
strategy = ["cross_platform"] strategy = ["cross_platform"]
lock_version = "4.4.1" lock_version = "4.4.1"
content_hash = "sha256:17fdf74bf4b2980c66c106cebcb936921e671e8adaeb2f2e95d95f255704aa38" content_hash = "sha256:828f8051de2c2a04cede8130abf86764edb38f0428cd1d52dd797bff43452afe"
[[package]] [[package]]
name = "aiocache" name = "aiocache"
@ -80,19 +80,6 @@ files = [
{file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
] ]
[[package]]
name = "class-doc"
version = "0.2.6"
requires_python = ">=3.6,<4.0"
summary = "Extract attributes docstrings defined in various ways"
dependencies = [
"more-itertools>=5.0.0",
]
files = [
{file = "class-doc-0.2.6.tar.gz", hash = "sha256:f5e036ed9b7f6de528affdd9f038851910b342d4c1c1252983a55ff080b530e0"},
{file = "class_doc-0.2.6-py3-none-any.whl", hash = "sha256:e6f2cea2dfbe93f76dee25de13d70dc0d2269698e8b849f751d98dc894c52ea5"},
]
[[package]] [[package]]
name = "idna" name = "idna"
version = "3.7" version = "3.7"
@ -103,16 +90,6 @@ files = [
{file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
] ]
[[package]]
name = "more-itertools"
version = "10.3.0"
requires_python = ">=3.8"
summary = "More routines for operating on iterables, beyond itertools"
files = [
{file = "more-itertools-10.3.0.tar.gz", hash = "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463"},
{file = "more_itertools-10.3.0-py3-none-any.whl", hash = "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320"},
]
[[package]] [[package]]
name = "multidict" name = "multidict"
version = "6.0.5" version = "6.0.5"

View file

@ -44,10 +44,30 @@ Issues = "https://git.00dani.me/00dani/mpd-now-playable/issues"
[project.scripts] [project.scripts]
mpd-now-playable = 'mpd_now_playable.cli:main' mpd-now-playable = 'mpd_now_playable.cli:main'
[tool.pdm.scripts]
start = {call = 'mpd_now_playable.cli:main'}
lint = 'ruff check src/mpd_now_playable'
typecheck = 'mypy -p mpd_now_playable'
check = {composite = ['lint', 'typecheck'], keep_going = true}
[tool.pdm.version]
source = "scm"
write_to = 'mpd_now_playable/__version__.py'
write_template = "__version__ = '{}'"
[build-system] [build-system]
requires = ["pdm-backend"] requires = ["pdm-backend"]
build-backend = "pdm.backend" build-backend = "pdm.backend"
[tool.pdm.build]
excludes = ["**/.mypy_cache"]
[tool.pdm.dev-dependencies]
dev = [
"mypy>=1.7.1",
"ruff>=0.1.6",
]
[tool.mypy] [tool.mypy]
mypy_path = 'stubs' mypy_path = 'stubs'
@ -81,26 +101,3 @@ mypy-init-return = true
[tool.ruff.format] [tool.ruff.format]
# I prefer tabs for accessibility reasons. # I prefer tabs for accessibility reasons.
indent-style = "tab" indent-style = "tab"
[tool.pdm.scripts]
start = {call = 'mpd_now_playable.cli:main'}
lint = 'ruff check src/mpd_now_playable'
typecheck = 'mypy -p mpd_now_playable'
check = {composite = ['lint', 'typecheck'], keep_going = true}
[tool.pdm.version]
source = "scm"
write_to = 'mpd_now_playable/__version__.py'
write_template = "__version__ = '{}'"
[tool.pdm.build]
excludes = ["**/.mypy_cache"]
[tool.pdm.dev-dependencies]
dev = [
"mypy>=1.7.1",
"ruff>=0.1.6",
"class-doc>=0.2.6",
]

View file

@ -35,9 +35,9 @@ from MediaPlayer import (
MPRemoteCommandHandlerStatusSuccess, MPRemoteCommandHandlerStatusSuccess,
) )
from ..async_tools import run_background_task
from ..player import Player from ..player import Player
from ..song import PlaybackState, Song from ..song import PlaybackState, Song
from ..tools.asyncio import run_background_task
from .persistent_id import song_to_persistent_id from .persistent_id import song_to_persistent_id

View file

@ -13,12 +13,7 @@
"$ref": "#/definitions/URL" "$ref": "#/definitions/URL"
}, },
"cache": { "cache": {
"allOf": [
{
"$ref": "#/definitions/URL" "$ref": "#/definitions/URL"
}
],
"description": "A URL describing a cache service for mpd-now-playable to use. Supported protocols are memory://, redis://, and memcached://."
}, },
"mpd": { "mpd": {
"additionalProperties": false, "additionalProperties": false,
@ -29,17 +24,14 @@
"properties": { "properties": {
"host": { "host": {
"default": "127.0.0.1", "default": "127.0.0.1",
"description": "The hostname or IP address of your MPD server. If you're running MPD on your local machine, you don't need to configure this.",
"format": "hostname", "format": "hostname",
"type": "string" "type": "string"
}, },
"password": { "password": {
"description": "The password required to connect to your MPD instance, if you need one.",
"type": "string" "type": "string"
}, },
"port": { "port": {
"default": 6600, "default": 6600,
"description": "The port on which to connect to MPD. Unless you're managing multiple MPD servers on one machine for some reason, you probably haven't changed this from the default port, 6600.",
"maximum": 65535, "maximum": 65535,
"minimum": 1, "minimum": 1,
"type": "integer" "type": "integer"

View file

@ -11,14 +11,8 @@ __all__ = ("MpdConfig", "Config")
@dataclass(frozen=True) @dataclass(frozen=True)
class MpdConfig: class MpdConfig:
#: The password required to connect to your MPD instance, if you need one.
password: Optional[str] = optional() password: Optional[str] = optional()
#: The hostname or IP address of your MPD server. If you're running MPD
#: on your local machine, you don't need to configure this.
host: Host = Host("127.0.0.1") host: Host = Host("127.0.0.1")
#: The port on which to connect to MPD. Unless you're managing multiple MPD
#: servers on one machine for some reason, you probably haven't changed this
#: from the default port, 6600.
port: Port = Port(6600) port: Port = Port(6600)
@ -28,8 +22,5 @@ class Config:
default=URL("https://cdn.00dani.me/m/schemata/mpd-now-playable/config-v1.json"), default=URL("https://cdn.00dani.me/m/schemata/mpd-now-playable/config-v1.json"),
metadata=alias("$schema"), metadata=alias("$schema"),
) )
#: A URL describing a cache service for mpd-now-playable to use. Supported
#: protocols are memory://, redis://, and memcached://.
cache: Optional[URL] = optional() cache: Optional[URL] = optional()
mpd: MpdConfig = field(default_factory=MpdConfig) mpd: MpdConfig = field(default_factory=MpdConfig)

View file

@ -1,33 +1,15 @@
from json import dump from json import dump
from pathlib import Path from pathlib import Path
from pprint import pp from pprint import pp
from shutil import get_terminal_size
from typing import Any, Mapping from typing import Any, Mapping
from apischema import schema, settings
from apischema.json_schema import JsonSchemaVersion, deserialization_schema from apischema.json_schema import JsonSchemaVersion, deserialization_schema
from apischema.schemas import Schema
from class_doc import extract_docs_from_cls_obj
from .model import Config from .model import Config
def field_base_schema(tp: type, name: str, alias: str) -> Schema | None:
desc_lines = extract_docs_from_cls_obj(tp).get(name, [])
if desc_lines:
print((tp, name, alias))
return schema(description=" ".join(desc_lines))
return None
settings.base_schema.field = field_base_schema
def generate() -> Mapping[str, Any]: def generate() -> Mapping[str, Any]:
return deserialization_schema( return deserialization_schema(Config, version=JsonSchemaVersion.DRAFT_7)
Config,
version=JsonSchemaVersion.DRAFT_7,
)
def write() -> None: def write() -> None:
@ -36,7 +18,7 @@ def write() -> None:
schema_file = Path(__file__).parent / Config.schema.name schema_file = Path(__file__).parent / Config.schema.name
print(f"Writing this schema to {schema_file}") print(f"Writing this schema to {schema_file}")
pp(schema, sort_dicts=True, width=get_terminal_size().columns) pp(schema)
with open(schema_file, "w") as fp: with open(schema_file, "w") as fp:
dump(schema, fp, indent="\t", sort_keys=True) dump(schema, fp, indent="\t", sort_keys=True)
fp.write("\n") fp.write("\n")

View file

@ -4,8 +4,8 @@ from typing import TypedDict
from yarl import URL from yarl import URL
from ..async_tools import run_background_task
from ..cache import Cache, make_cache from ..cache import Cache, make_cache
from ..tools.asyncio import run_background_task
from .types import CurrentSongResponse, MpdStateHandler from .types import CurrentSongResponse, MpdStateHandler
CACHE_TTL = 60 * 60 # seconds = 1 hour CACHE_TTL = 60 * 60 # seconds = 1 hour

View file

@ -9,7 +9,7 @@ from yarl import URL
from ..config.model import MpdConfig from ..config.model import MpdConfig
from ..player import Player from ..player import Player
from ..song import PlaybackState, Song, SongListener from ..song import PlaybackState, Song, SongListener
from ..tools.types import convert_if_exists from ..type_tools import convert_if_exists
from .artwork_cache import MpdArtworkCache from .artwork_cache import MpdArtworkCache
from .types import CurrentSongResponse, StatusResponse from .types import CurrentSongResponse, StatusResponse

View file

@ -1 +0,0 @@
def extract_docs_from_cls_obj(cls: type) -> dict[str, list[str]]: ...