From c4c62ea0037f4532e32f32d608ac36288675d286 Mon Sep 17 00:00:00 2001 From: cosven Date: Sun, 14 Apr 2024 18:19:44 +0800 Subject: [PATCH] introduce Collection dataclass --- feeluown/collection.py | 13 +++------ feeluown/gui/pages/homepage.py | 4 +-- feeluown/library/__init__.py | 1 + feeluown/library/collection.py | 38 +++++++++++++++++++++++++++ feeluown/library/provider_protocol.py | 5 ++-- feeluown/player/lyric.py | 10 ++++--- 6 files changed, 54 insertions(+), 17 deletions(-) create mode 100644 feeluown/library/collection.py diff --git a/feeluown/collection.py b/feeluown/collection.py index 3bd7cb1d90..d6fe10ff12 100644 --- a/feeluown/collection.py +++ b/feeluown/collection.py @@ -3,7 +3,6 @@ import logging import os from datetime import datetime -from enum import Enum from pathlib import Path from typing import Dict, Iterable, List @@ -12,7 +11,7 @@ from feeluown.consts import COLLECTIONS_DIR from feeluown.utils.dispatch import Signal from feeluown.library import resolve, reverse, ResolverNotFound, \ - ResolveFailed, ModelState + ResolveFailed, ModelState, CollectionType from feeluown.utils.utils import elfhash logger = logging.getLogger(__name__) @@ -33,14 +32,10 @@ class CollectionAlreadyExists(Exception): pass -class CollectionType(Enum): - sys_library = 16 - sys_pool = 13 - - mixed = 8 - - class Collection: + """ + TODO: This collection should be moved into local provider. + """ def __init__(self, fpath): # TODO: 以后考虑添加 identifier 字段,identifier diff --git a/feeluown/gui/pages/homepage.py b/feeluown/gui/pages/homepage.py index a2e65089b6..44a66ca6a3 100644 --- a/feeluown/gui/pages/homepage.py +++ b/feeluown/gui/pages/homepage.py @@ -3,7 +3,7 @@ from PyQt5.QtWidgets import QWidget, QVBoxLayout -from feeluown.library import SupportsRecListDailyPlaylists, SupportsRecACollection +from feeluown.library import SupportsRecListDailyPlaylists, SupportsRecACollectionOfSongs from feeluown.utils.reader import create_reader from feeluown.utils.aio import run_fn, as_completed from feeluown.gui.widgets.header import LargeHeader @@ -111,7 +111,7 @@ async def _get_rec_songs(self): songs = [] for coro in as_completed([ run_fn(provider.rec_a_collection) for provider in providers - if isinstance(provider, SupportsRecACollection) + if isinstance(provider, SupportsRecACollectionOfSongs) ]): try: title, songs_ = await coro diff --git a/feeluown/library/__init__.py b/feeluown/library/__init__.py index ef6fd09aaf..23d440e097 100644 --- a/feeluown/library/__init__.py +++ b/feeluown/library/__init__.py @@ -28,3 +28,4 @@ Resolver, reverse, resolve, ResolverNotFound, ResolveFailed, parse_line, NS_TYPE_MAP, ) +from .collection import Collection, CollectionType diff --git a/feeluown/library/collection.py b/feeluown/library/collection.py new file mode 100644 index 0000000000..b7342abdb7 --- /dev/null +++ b/feeluown/library/collection.py @@ -0,0 +1,38 @@ +from enum import Enum +from dataclasses import dataclass +from typing import List + +from .models import BaseModel + + +class CollectionType(Enum): + """Collection type enumeration""" + + # These two values are only used in local collection. + sys_library = 16 + sys_pool = 13 + + only_songs = 1 + only_artists = 2 + only_albums = 3 + only_playlists = 4 + only_lyrics = 5 + only_videos = 6 + + only_users = 17 + only_comments = 18 + + mixed = 32 + + +@dataclass +class Collection: + """ + Differences between a collection and a playlist + - A collection has no identifier in general. + - A collection may have songs, albums and artists. + """ + name: str + type_: CollectionType + models: List[BaseModel] + description: str = '' diff --git a/feeluown/library/provider_protocol.py b/feeluown/library/provider_protocol.py index 9a474807d6..8dbc236fc5 100644 --- a/feeluown/library/provider_protocol.py +++ b/feeluown/library/provider_protocol.py @@ -7,6 +7,7 @@ PlaylistModel, UserModel, ModelType, BriefArtistModel, BriefSongModel, LyricModel, BriefVideoModel, ) +from .collection import Collection from .flags import Flags as PF @@ -385,9 +386,9 @@ def rec_list_daily_songs(self) -> List[SongModel]: @runtime_checkable -class SupportsRecACollection(Protocol): +class SupportsRecACollectionOfSongs(Protocol): @abstractmethod - def rec_a_collection(self) -> Tuple[str, List[BriefSongModel]]: + def rec_a_collection_of_songs(self) -> Collection: """ For example, providers may provider a list of songs, and the title looks like “大家都在听” / “红心歌曲”. diff --git a/feeluown/player/lyric.py b/feeluown/player/lyric.py index 8732c6e9c5..fefba885f8 100644 --- a/feeluown/player/lyric.py +++ b/feeluown/player/lyric.py @@ -49,10 +49,12 @@ def parse_lyric_text(content: str) -> Dict[int, str]: """ Reference: https://github.com/osdlyrics/osdlyrics/blob/master/python/lrc.py - >>> parse_lyric_text("[00:00.00] 作曲 : 周杰伦\\n[00:01.00] 作词 : 周杰伦\\n") - OrderedDict([(0, ' 作曲 : 周杰伦'), (1000, ' 作词 : 周杰伦')]) - >>> parse_lyric_text("[01:30][00:01:10][01:00]再等直至再吻到你") - OrderedDict([(60000, '再等直至再吻到你'), (70000, '再等直至再吻到你'), (90000, '再等直至再吻到你')]) + >>> r = parse_lyric_text("[00:00.00] 作曲 : 周杰伦\\n[00:01.00] 作词 : 周杰伦\\n") + >>> list(r.items())[0] + (0, ' 作曲 : 周杰伦') + >>> r = parse_lyric_text("[01:30][00:01:10][01:00]再等直至再吻到你") + >>> list(r.items())[-1] + (90000, '再等直至再吻到你') """ def to_mileseconds(time_str): mileseconds = 0