Skip to content

Commit

Permalink
sort imports + tweaks to write local tags logic
Browse files Browse the repository at this point in the history
  • Loading branch information
geo-martino committed Jan 16, 2024
1 parent 0508f51 commit ab6a684
Show file tree
Hide file tree
Showing 15 changed files with 43 additions and 40 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ python -m pip install musify
## Currently Supported
- **Music Streaming Services**: `Spotify`
- **Audio filetypes**: `.wma` `.flac` `.mp3` `.m4a`
- **Audio filetypes**: `.wma` `.flac` `.m4a` `.mp3`
- **Local playlist filetypes**: `.m3u` `.xautopf`
- **Local Libraries**: `MusicBee`
Expand Down
3 changes: 2 additions & 1 deletion musify/local/collection.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from __future__ import annotations

import logging
import sys
from abc import ABCMeta, abstractmethod
from collections.abc import Mapping, Collection, Iterable, Container
from datetime import datetime
from glob import glob
from os.path import splitext, join, basename, exists, isdir
from typing import Any

import sys

from musify.local.base import LocalItem
from musify.local.exception import LocalCollectionError
from musify.local.track import LocalTrack, SyncResultTrack, load_track, TRACK_FILETYPES
Expand Down
10 changes: 9 additions & 1 deletion musify/local/track/base/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def save(self, tags: UnitIterable[Tags] = Tags.ALL, replace: bool = False, dry_r
return SyncResultTrack(saved=save, updated=updated)

@abstractmethod
def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -> bool:
def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -> bool | None:
"""
Generic method for updating a tag value in the file.
Expand All @@ -243,6 +243,14 @@ def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -
:param dry_run: Run function, but do not modify file at all.
:return: True if the file was updated or would have been when dry_run is True, False otherwise.
"""
if tag_id is None:
return False

if tag_value is None:
remove = not dry_run and tag_id in self.file and self.file[tag_id]
if remove:
del self.file[tag_id]
return remove

def _write_title(self, dry_run: bool = True) -> bool:
"""
Expand Down
12 changes: 5 additions & 7 deletions musify/local/track/flac.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,16 @@ def _check_for_images(self) -> bool:
return len(self._file.pictures) > 0

def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -> bool:
if tag_value is None:
remove = not dry_run and tag_id in self.file and self.file[tag_id]
if remove:
del self.file[tag_id]
return remove
result = super()._write_tag(tag_id=tag_id, tag_value=tag_value, dry_run=dry_run)
if result is not None:
return result

if not dry_run and tag_id is not None:
if not dry_run:
if isinstance(tag_value, (list, set, tuple)):
self._file[tag_id] = list(map(str, tag_value))
else:
self._file[tag_id] = str(tag_value)
return tag_id is not None
return True

def _write_images(self, dry_run: bool = True) -> bool:
updated = False
Expand Down
12 changes: 5 additions & 7 deletions musify/local/track/m4a.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,11 @@ def _read_images(self) -> list[Image.Image] | None:
return [Image.open(BytesIO(bytes(value))) for value in values] if values is not None else None

def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -> bool:
if tag_value is None:
remove = not dry_run and tag_id in self.file and self.file[tag_id]
if remove:
del self.file[tag_id]
return remove
result = super()._write_tag(tag_id=tag_id, tag_value=tag_value, dry_run=dry_run)
if result is not None:
return result

if not dry_run and tag_id is not None:
if not dry_run:
if tag_id.startswith("----:com.apple.iTunes"):
self._file[tag_id] = [
mutagen.mp4.MP4FreeForm(str(v).encode("utf-8"), 1) for v in to_collection(tag_value)
Expand All @@ -95,7 +93,7 @@ def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -
self._file[tag_id] = [tag_value]
else:
self._file[tag_id] = to_collection(tag_value, list)
return tag_id is not None
return True

def _write_track(self, dry_run: bool = True) -> bool:
tag_id = next(iter(self.tag_map.track_number), None)
Expand Down
12 changes: 5 additions & 7 deletions musify/local/track/mp3.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,13 @@ def _read_images(self) -> list[Image.Image] | None:
return [Image.open(BytesIO(value.data)) for value in values] if values is not None else None

def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -> bool:
if tag_value is None:
remove = not dry_run and tag_id in self.file and self.file[tag_id]
if remove:
del self.file[tag_id]
return remove
result = super()._write_tag(tag_id=tag_id, tag_value=tag_value, dry_run=dry_run)
if result is not None:
return result

if not dry_run and tag_id is not None:
if not dry_run:
self._file[tag_id] = getattr(mutagen.id3, tag_id)(3, text=str(tag_value))
return tag_id is not None
return True

def _write_genres(self, dry_run: bool = True) -> bool:
values = ";".join(self.genres or [])
Expand Down
12 changes: 5 additions & 7 deletions musify/local/track/wma.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,19 @@ def _read_images(self) -> list[Image.Image] | None:
return images

def _write_tag(self, tag_id: str | None, tag_value: Any, dry_run: bool = True) -> bool:
if tag_value is None:
remove = not dry_run and tag_id in self.file and self.file[tag_id]
if remove:
del self.file[tag_id]
return remove
result = super()._write_tag(tag_id=tag_id, tag_value=tag_value, dry_run=dry_run)
if result is not None:
return result

if not dry_run and tag_id is not None:
if not dry_run:
if isinstance(tag_value, (list, set, tuple)):
if all(isinstance(v, mutagen.asf.ASFByteArrayAttribute) for v in tag_value):
self._file[tag_id] = tag_value
else:
self._file[tag_id] = [mutagen.asf.ASFUnicodeAttribute(str(v)) for v in tag_value]
else:
self._file[tag_id] = mutagen.asf.ASFUnicodeAttribute(str(tag_value))
return tag_id is not None
return True

def _write_images(self, dry_run: bool = True) -> bool:
tag_id = next(iter(self.tag_map.images), None)
Expand Down
2 changes: 1 addition & 1 deletion musify/shared/api/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
from datetime import datetime as dt
from datetime import timedelta
from http import HTTPStatus
from time import sleep
from typing import Any

from requests import Response, Session
from requests_cache import CachedSession
from time import sleep

from musify.shared.api.authorise import APIAuthoriser
from musify.shared.api.exception import APIError
Expand Down
2 changes: 1 addition & 1 deletion musify/shared/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import os
import re
import shutil
import sys
from collections.abc import Iterable
from datetime import datetime
from glob import glob
from os.path import join, dirname, splitext, split, basename, isfile, sep, isdir
from typing import Any

import sys
from tqdm.auto import tqdm

from musify import PROGRAM_NAME
Expand Down
5 changes: 3 additions & 2 deletions musify/spotify/api/item.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import re
from abc import ABCMeta
from collections.abc import Collection, Mapping, MutableMapping
from itertools import batched
from typing import Any
from urllib.parse import parse_qs, urlparse

from itertools import batched

from musify.shared.api.exception import APIError
from musify.shared.remote.api import APIMethodInputType
from musify.shared.remote.enum import RemoteObjectType, RemoteIDType
Expand Down Expand Up @@ -54,7 +55,7 @@ def _get_items_multi(
kind = self._get_unit(key=key, kind=kind)

bar = self.logger.get_progress_bar(
iterable=id_list, desc=f"Getting {kind}", unit=kind, disable=len(id_list) < self._bar_threshold * 10
iterable=id_list, desc=f"Getting {kind}", unit=kind, disable=len(id_list) < self._bar_threshold
)

results: list[dict[str, Any]] = []
Expand Down
3 changes: 2 additions & 1 deletion musify/spotify/api/playlist.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from abc import ABCMeta
from collections.abc import Collection, Mapping
from itertools import batched
from typing import Any

from itertools import batched

from musify import PROGRAM_NAME, PROGRAM_URL
from musify.shared.remote.enum import RemoteIDType, RemoteObjectType
from musify.shared.remote.exception import RemoteIDTypeError
Expand Down
2 changes: 1 addition & 1 deletion tests/processors/test_sort.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from collections.abc import Callable
from itertools import groupby
from random import choice, randrange

import pytest
import xmltodict
from itertools import groupby

from musify.local.track import LocalTrack
from musify.local.track.field import LocalTrackField
Expand Down
2 changes: 1 addition & 1 deletion tests/shared/remote/processors/check.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import re
from abc import ABC, abstractmethod
from itertools import batched
from random import randrange, choice

import pytest
from itertools import batched
from pytest_mock import MockerFixture

from musify.local.track import LocalTrack
Expand Down
2 changes: 1 addition & 1 deletion tests/shared/test_logger.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import logging
import os
import string
import sys
from copy import copy, deepcopy
from datetime import datetime, timedelta
from glob import glob
from os.path import join, basename, splitext
from random import choice

import pytest
import sys

from musify.shared.logger import MusifyLogger, INFO_EXTRA, REPORT, STAT, LOGGING_DT_FORMAT
from musify.shared.logger import format_full_func_name, LogFileFilter, CurrentTimeRotatingFileHandler
Expand Down
2 changes: 1 addition & 1 deletion tests/spotify/api/test_spotify_api_item.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from collections.abc import Collection
from copy import deepcopy
from itertools import batched
from random import sample, choice
from typing import Any
from urllib.parse import parse_qs

import pytest
from itertools import batched
# noinspection PyProtectedMember,PyUnresolvedReferences
from requests_mock.request import _RequestObjectProxy as Request

Expand Down

0 comments on commit ab6a684

Please sign in to comment.