Compare commits
No commits in common. "2f70c6f7fa1ff16a8a79f6f977785ba37c296870" and "35703de26116bdcf4ffd0f5c34e32be1939e8012" have entirely different histories.
2f70c6f7fa
...
35703de261
12 changed files with 27 additions and 89 deletions
25
pdm.lock
generated
25
pdm.lock
generated
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
def extract_docs_from_cls_obj(cls: type) -> dict[str, list[str]]: ...
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue