-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Centralize conversions from DTO to model instances
Refs: #143
- Loading branch information
Showing
14 changed files
with
158 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from collections import defaultdict | ||
from typing import Callable, Dict, List, Mapping, Optional, Sequence | ||
|
||
from argos.dto import ArtistDTO, TlTrackDTO, TrackDTO | ||
from argos.model import TracklistTrackModel, TrackModel | ||
|
||
|
||
class ModelHelper: | ||
"""Help convert DTOs to model instances. | ||
Some conversions can be tracked through visitors. | ||
""" | ||
|
||
def convert_track(self, track_dto: TrackDTO) -> TrackModel: | ||
track = TrackModel( | ||
uri=track_dto.uri, | ||
name=track_dto.name, | ||
track_no=track_dto.track_no if track_dto.track_no is not None else -1, | ||
disc_no=track_dto.disc_no if track_dto.disc_no is not None else 1, | ||
length=track_dto.length if track_dto.length is not None else -1, | ||
artist_name=track_dto.artists[0].name if len(track_dto.artists) > 0 else "", | ||
album_name=track_dto.album.name if track_dto.album is not None else "", | ||
last_modified=track_dto.last_modified | ||
if track_dto.last_modified is not None | ||
else -1, | ||
) | ||
return track | ||
|
||
def convert_tl_track(self, tl_track_dto: TlTrackDTO) -> TracklistTrackModel: | ||
track = self.convert_track(tl_track_dto.track) | ||
tl_track = TracklistTrackModel(tlid=tl_track_dto.tlid, track=track) | ||
return tl_track | ||
|
||
def parse_tracks( | ||
self, | ||
tracks_dto: Mapping[str, Sequence[TrackDTO]], | ||
*, | ||
visitors: Optional[Sequence[Callable[[str, TrackDTO], None]]] = None, | ||
) -> Dict[str, List[TrackModel]]: | ||
"""Parse a track list. | ||
Keys in ``track_dto`` can be album URIs or track URIs (when fetching | ||
details of playlist tracks). | ||
Args: | ||
tracks_dto: Track data transfer objects to parse. | ||
visitors: An optional list of callable to be called on each | ||
visited track. | ||
Returns: | ||
Dict of list of ``TrackModel``. | ||
""" | ||
parsed_tracks: Dict[str, List[TrackModel]] = defaultdict(list) | ||
for uri in tracks_dto: | ||
for track_dto in tracks_dto[uri]: | ||
if visitors is not None: | ||
for visitor in visitors: | ||
visitor(uri, track_dto) | ||
|
||
parsed_tracks[uri].append(self.convert_track(track_dto)) | ||
|
||
return parsed_tracks |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import json | ||
import pathlib | ||
import unittest | ||
from unittest.mock import Mock, call | ||
|
||
from argos.controllers.helper import ModelHelper | ||
from argos.dto import TrackDTO | ||
from argos.model.track import TrackModel | ||
|
||
|
||
def load_json_data(filename: str): | ||
path = pathlib.Path(__file__).parent.parent / "data" / filename | ||
with open(path) as fh: | ||
data = json.load(fh) | ||
return data | ||
|
||
|
||
class TestModelHelper(unittest.TestCase): | ||
def test_parse_tracks(self): | ||
track_dto = TrackDTO.factory(load_json_data("track.json")) | ||
tracks_dto = {"local:album:md5:ff5c5b8f60a44e4c7d6f1bb53474e17b": [track_dto]} | ||
tracks = ModelHelper().parse_tracks(tracks_dto) | ||
self.assertListEqual([k for k in tracks_dto.keys()], [k for k in tracks.keys()]) | ||
self.assertIsInstance( | ||
tracks["local:album:md5:ff5c5b8f60a44e4c7d6f1bb53474e17b"][0], TrackModel | ||
) | ||
|
||
def test_parse_tracks_with_visitor(self): | ||
track_dto = TrackDTO.factory(load_json_data("track.json")) | ||
tracks_dto = {"local:album:md5:ff5c5b8f60a44e4c7d6f1bb53474e17b": [track_dto]} | ||
visitor = Mock() | ||
ModelHelper().parse_tracks(tracks_dto, visitors=[visitor]) | ||
visitor.assert_called_once_with( | ||
"local:album:md5:ff5c5b8f60a44e4c7d6f1bb53474e17b", track_dto | ||
) |
Oops, something went wrong.