Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
geigerzaehler committed Nov 16, 2024
2 parents ef97a96 + 389179e commit 551bfad
Show file tree
Hide file tree
Showing 8 changed files with 323 additions and 308 deletions.
16 changes: 9 additions & 7 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ jobs:
matrix:
os: ["ubuntu-latest"]
python-version:
- "3.8" # minimum required
- "3.12" # latest
- "3.13-dev" # next
- "3.10" # minimum required
- "3.13" # latest
include:
- python-version: 3.8
- python-version: "3.10"
os: windows-2022
- python-version: "3.10"
os: macos-12

runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.python-version == '3.13-dev' }}
# Fails because of https://github.com/beetbox/mediafile/pull/75
continue-on-error: ${{ matrix.python-version == '3.13' }}

steps:
- uses: actions/checkout@v4
Expand All @@ -39,7 +41,7 @@ jobs:
- uses: coverallsapp/github-action@v2
if: >
(github.event_name == 'pull_request' || github.ref_name == 'main') &&
matrix.python-version == '3.8' &&
matrix.python-version == '3.10' &&
matrix.os == 'ubuntu-latest'
with:
# Ignore .coverage, which has limited support from coveralls
Expand All @@ -58,7 +60,7 @@ jobs:
- run: pip install poetry
- uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: "3.10"
cache: poetry
- run: poetry env use $(which python)
- run: poetry install
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Change Log
* Consistently use Unicode paths to alternative items. This may result and
collection updates and orphaned files in alternatives. It may also improve
usability on non-standard file systems (see [#74]).
* Require Python >= 3.10

[#74]: https://github.com/geigerzaehler/beets-alternatives/issues/74

Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ documentation](./DEVELOPING.md).
Getting Started
---------------

Install the plugin and make sure you using at least version 1.6.0 of beets and
Python 3.8.
Install the plugin and make sure you using at least version 1.6.1 of beets and
Python 3.10.

```bash
pip install --upgrade beets>=1.6.0 beets-alternatives
Expand Down Expand Up @@ -257,6 +257,12 @@ following settings.

By default no transcoding is done.

* **`albumart_maxwidth`** Downscale the embedded album art to a width
of maximum `albumart_maxwidth` pixels. The aspect ratio of the image
will be preserved. This is comparable to the setting with the same
name of the [convert plugin][convert plugin].


* **`removable`** If this is `true` (the default) and `directory` does
not exist, the `update` command will ask you to confirm the creation
of the external collection. (optional)
Expand Down
32 changes: 21 additions & 11 deletions beetsplug/alternatives.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
import os.path
import shutil
import threading
from collections.abc import Callable, Iterable, Iterator, Sequence
from concurrent import futures
from enum import Enum
from pathlib import Path
from typing import Callable, Iterable, Iterator, Optional, Sequence, Set, Tuple

import beets
import confuse
Expand Down Expand Up @@ -181,6 +181,7 @@ def parse_config(self, config: confuse.ConfigView):
self.query, _ = parse_query_string(query, Item)

self.removable = config.get(dict).get("removable", True) # type: ignore
self.album_art_maxwidth = config.get(dict).get("album_art_maxwidth", None) # type: ignore

if "directory" in config:
dir = config["directory"].as_path()
Expand Down Expand Up @@ -229,7 +230,7 @@ def _matched_item_action(self, item: Item) -> Sequence[Action]:
else:
return [Action.ADD]

def _items_actions(self) -> Iterator[Tuple[Item, Sequence[Action]]]:
def _items_actions(self) -> Iterator[tuple[Item, Sequence[Action]]]:
matched_ids = set()
for album in self.lib.albums():
if self.query.match(album):
Expand All @@ -242,7 +243,7 @@ def _items_actions(self) -> Iterator[Tuple[Item, Sequence[Action]]]:
elif self._get_stored_path(item):
yield (item, [Action.REMOVE])

def ask_create(self, create: Optional[bool] = None) -> bool:
def ask_create(self, create: bool | None = None) -> bool:
if not self.removable:
return True
if create is not None:
Expand All @@ -255,7 +256,7 @@ def ask_create(self, create: Optional[bool] = None) -> bool:
)
return input_yn(msg, require=True)

def update(self, create: Optional[bool] = None):
def update(self, create: bool | None = None):
if not self.directory.is_dir() and not self.ask_create(create):
print_(f"Skipping creation of {self.directory}")
return
Expand All @@ -270,7 +271,8 @@ def update(self, create: Optional[bool] = None):
print_(f">{path} -> {dest}")
dest.parent.mkdir(parents=True, exist_ok=True)
path.rename(dest)
util.prune_dirs(str(path.parent), root=str(self.directory))
# beets types are confusing
util.prune_dirs(str(path.parent), root=str(self.directory)) # pyright: ignore
self._set_stored_path(item, dest)
item.store()
path = dest
Expand Down Expand Up @@ -307,7 +309,7 @@ def destination(self, item: Item) -> Path:
def _set_stored_path(self, item: Item, path: Path):
item[self.path_key] = str(path)

def _get_stored_path(self, item: Item) -> Optional[Path]:
def _get_stored_path(self, item: Item) -> Path | None:
try:
path = item[self.path_key]
except KeyError:
Expand All @@ -323,7 +325,8 @@ def _remove_file(self, item: Item):
path = self._get_stored_path(item)
if path:
path.unlink(missing_ok=True)
util.prune_dirs(str(path), root=str(self.directory))
# beets types are confusing
util.prune_dirs(str(path), root=str(self.directory)) # pyright: ignore
del item[self.path_key]

def _converter(self) -> "Worker":
Expand All @@ -340,7 +343,14 @@ def _sync_art(self, item: Item, path: Path):
album = item.get_album()
if album and album.artpath and Path(str(album.artpath, "utf8")).is_file():
self._log.debug(f"Embedding art from {album.artpath} into {path}")
art.embed_item(self._log, item, album.artpath, itempath=bytes(path))

art.embed_item(
self._log,
item,
album.artpath,
maxwidth=self.album_art_maxwidth,
itempath=bytes(path),
)


class ExternalConvert(External):
Expand Down Expand Up @@ -433,7 +443,7 @@ def item_change_actions(
return [Action.MOVE]

@override
def update(self, create: Optional[bool] = None):
def update(self, create: bool | None = None):
for item, actions in self._items_actions():
dest = self.destination(item)
path = self._get_stored_path(item)
Expand Down Expand Up @@ -474,10 +484,10 @@ def _sync_art(self, item: Item, path: Path):

class Worker(futures.ThreadPoolExecutor):
def __init__(
self, fn: Callable[[Item], Tuple[Item, Path]], max_workers: Optional[int]
self, fn: Callable[[Item], tuple[Item, Path]], max_workers: int | None
):
super().__init__(max_workers)
self._tasks: Set[futures.Future[Tuple[Item, Path]]] = set()
self._tasks: set[futures.Future[tuple[Item, Path]]] = set()
self._fn = fn

def run(self, item: Item):
Expand Down
Loading

0 comments on commit 551bfad

Please sign in to comment.