added filter framework, migrated to processor package
This commit is contained in:
parent
20090d14b5
commit
36e20d8ec3
@ -4,9 +4,9 @@ from spotframework.net.user import NetworkUser
|
||||
import spotframework.io.json as json
|
||||
import spotframework.util.monthstrings as monthstrings
|
||||
from spotframework.engine.playlistengine import PlaylistEngine
|
||||
from spotframework.engine.filter.shuffle import Shuffle
|
||||
from spotframework.engine.filter.sort import SortReleaseDate
|
||||
from spotframework.engine.filter.deduplicate import DeduplicateByID, DeduplicateByName
|
||||
from spotframework.engine.processor.shuffle import Shuffle
|
||||
from spotframework.engine.processor.sort import SortReleaseDate
|
||||
from spotframework.engine.processor.deduplicate import DeduplicateByID, DeduplicateByName
|
||||
|
||||
import os
|
||||
import datetime
|
||||
|
@ -1,47 +0,0 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List
|
||||
from spotframework.model.track import Track
|
||||
|
||||
|
||||
class AbstractProcessor(ABC):
|
||||
|
||||
def __init__(self, names: List[str] = None):
|
||||
self.playlist_names = names
|
||||
|
||||
def has_targets(self):
|
||||
if self.playlist_names:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@abstractmethod
|
||||
def process(self, tracks: List[Track]):
|
||||
pass
|
||||
|
||||
|
||||
class AbstractTestFilter(AbstractProcessor, ABC):
|
||||
|
||||
def __init__(self,
|
||||
names: List[str] = None,
|
||||
keep_failed: bool = True):
|
||||
super().__init__(names)
|
||||
self.keep_failed = keep_failed
|
||||
|
||||
@abstractmethod
|
||||
def logic_test(self, track: Track):
|
||||
pass
|
||||
|
||||
def process(self, tracks: List[Track]):
|
||||
|
||||
return_tracks = []
|
||||
malformed_tracks = []
|
||||
|
||||
for track in tracks:
|
||||
if self.logic_test(track):
|
||||
return_tracks.append(track)
|
||||
else:
|
||||
malformed_tracks.append(track)
|
||||
if self.keep_failed:
|
||||
return_tracks += malformed_tracks
|
||||
|
||||
return return_tracks
|
@ -1,47 +0,0 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from .abstract import AbstractProcessor
|
||||
import datetime
|
||||
from typing import List
|
||||
from spotframework.model.track import Track, PlaylistTrack
|
||||
|
||||
|
||||
class Added(AbstractProcessor, ABC):
|
||||
|
||||
def __init__(self,
|
||||
boundary: datetime.datetime,
|
||||
names: List[str] = None,
|
||||
keep_malformed_type: bool = True):
|
||||
super().__init__(names)
|
||||
self.boundary = boundary
|
||||
self.keep_malformed_type = keep_malformed_type
|
||||
|
||||
@abstractmethod
|
||||
def check_date(self, track: PlaylistTrack):
|
||||
pass
|
||||
|
||||
def process(self, tracks: List[Track]):
|
||||
|
||||
return_tracks = []
|
||||
malformed_tracks = []
|
||||
|
||||
for track in tracks:
|
||||
if isinstance(track, PlaylistTrack):
|
||||
if self.check_date(track):
|
||||
return_tracks.append(track)
|
||||
else:
|
||||
malformed_tracks.append(track)
|
||||
|
||||
if self.keep_malformed_type:
|
||||
return_tracks += malformed_tracks
|
||||
|
||||
return return_tracks
|
||||
|
||||
|
||||
class AddedBefore(Added):
|
||||
def check_date(self, track: PlaylistTrack):
|
||||
return track.added_at < self.boundary
|
||||
|
||||
|
||||
class AddedSince(Added):
|
||||
def check_date(self, track: PlaylistTrack):
|
||||
return track.added_at > self.boundary
|
@ -1,45 +0,0 @@
|
||||
from spotframework.engine.filter.abstract import AbstractProcessor
|
||||
from typing import List
|
||||
from spotframework.model.track import Track, SpotifyTrack
|
||||
|
||||
|
||||
class DeduplicateByID(AbstractProcessor):
|
||||
|
||||
def __init__(self,
|
||||
names: List[str] = None,
|
||||
keep_malformed_type: bool = True):
|
||||
super().__init__(names)
|
||||
self.keep_malformed_type = keep_malformed_type
|
||||
|
||||
def process(self, tracks: List[Track]):
|
||||
return_tracks = []
|
||||
malformed_tracks = []
|
||||
|
||||
for track in tracks:
|
||||
if isinstance(track, SpotifyTrack):
|
||||
if track.uri not in [i.uri for i in return_tracks]:
|
||||
return_tracks.append(track)
|
||||
else:
|
||||
malformed_tracks.append(track)
|
||||
|
||||
if self.keep_malformed_type:
|
||||
return_tracks += malformed_tracks
|
||||
|
||||
return return_tracks
|
||||
|
||||
|
||||
class DeduplicateByName(AbstractProcessor):
|
||||
|
||||
def process(self, tracks: List[Track]):
|
||||
return_tracks = []
|
||||
|
||||
for to_check in tracks:
|
||||
|
||||
for cache_track in return_tracks:
|
||||
if to_check.name.lower() == cache_track.name.lower():
|
||||
if to_check.artists[0].name.lower() == cache_track.artists[0].name.lower():
|
||||
break
|
||||
else:
|
||||
return_tracks.append(to_check)
|
||||
|
||||
return return_tracks
|
@ -1,38 +0,0 @@
|
||||
from spotframework.engine.filter.abstract import AbstractProcessor
|
||||
from typing import List
|
||||
from spotframework.model.track import Track, SpotifyTrack
|
||||
|
||||
|
||||
class SortPopularity(AbstractProcessor):
|
||||
|
||||
def __init__(self,
|
||||
names: List[str] = None,
|
||||
keep_malformed_type: bool = True):
|
||||
super().__init__(names)
|
||||
self.keep_malformed_type = keep_malformed_type
|
||||
|
||||
def sort(self, tracks: List[SpotifyTrack]):
|
||||
tracks.sort(key=lambda x: x.popularity, reverse=True)
|
||||
|
||||
def process(self, tracks: List[Track]):
|
||||
return_tracks = []
|
||||
malformed_tracks = []
|
||||
|
||||
for track in tracks:
|
||||
if isinstance(track, SpotifyTrack):
|
||||
return_tracks.append(track)
|
||||
else:
|
||||
malformed_tracks.append(track)
|
||||
|
||||
self.sort(return_tracks)
|
||||
|
||||
if self.keep_malformed_type:
|
||||
return_tracks += malformed_tracks
|
||||
|
||||
return return_tracks
|
||||
|
||||
|
||||
class SortReversePopularity(SortPopularity):
|
||||
|
||||
def sort(self, tracks: List[SpotifyTrack]):
|
||||
tracks.sort(key=lambda x: x.popularity, reverse=False)
|
@ -3,13 +3,13 @@ import os
|
||||
import logging
|
||||
|
||||
import spotframework.util.monthstrings as monthstrings
|
||||
from spotframework.engine.filter.added import AddedSince
|
||||
from spotframework.engine.processor.added import AddedSince
|
||||
|
||||
from typing import List
|
||||
from spotframework.model.track import SpotifyTrack
|
||||
from spotframework.model.playlist import SpotifyPlaylist
|
||||
from spotframework.net.network import Network
|
||||
from spotframework.engine.filter.abstract import AbstractProcessor
|
||||
from spotframework.engine.processor.abstract import AbstractProcessor
|
||||
from datetime import datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
71
spotframework/engine/processor/abstract.py
Normal file
71
spotframework/engine/processor/abstract.py
Normal file
@ -0,0 +1,71 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List
|
||||
from spotframework.model.track import Track
|
||||
|
||||
|
||||
class AbstractProcessor(ABC):
|
||||
|
||||
def __init__(self, names: List[str] = None):
|
||||
self.playlist_names = names
|
||||
|
||||
def has_targets(self):
|
||||
if self.playlist_names:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@abstractmethod
|
||||
def process(self, tracks: List[Track]):
|
||||
pass
|
||||
|
||||
|
||||
class BatchSingleProcessor(AbstractProcessor, ABC):
|
||||
|
||||
@staticmethod
|
||||
def process_single(track: Track):
|
||||
return track
|
||||
|
||||
def process_batch(self, tracks: List[Track]):
|
||||
processed = []
|
||||
|
||||
for track in tracks:
|
||||
processed_track = self.process_single(track)
|
||||
processed.append(processed_track)
|
||||
|
||||
return processed
|
||||
|
||||
def process(self, tracks: List[Track]):
|
||||
return [i for i in self.process_batch(tracks) if i]
|
||||
|
||||
|
||||
class BatchSingleTypeAwareProcessor(BatchSingleProcessor, ABC):
|
||||
|
||||
def __init__(self,
|
||||
names: List[str] = None,
|
||||
instance_check=None,
|
||||
append_malformed: bool = True):
|
||||
super().__init__(names)
|
||||
self.instance_check = instance_check
|
||||
self.append_malformed = append_malformed
|
||||
|
||||
def process(self, tracks: List[Track]):
|
||||
|
||||
if self.instance_check:
|
||||
return_tracks = []
|
||||
malformed_tracks = []
|
||||
|
||||
for track in tracks:
|
||||
|
||||
if isinstance(track, self.instance_check):
|
||||
return_tracks.append(track)
|
||||
else:
|
||||
malformed_tracks.append(track)
|
||||
|
||||
return_tracks = super().process(return_tracks)
|
||||
|
||||
if self.append_malformed:
|
||||
return_tracks += malformed_tracks
|
||||
|
||||
return return_tracks
|
||||
else:
|
||||
return tracks
|
28
spotframework/engine/processor/added.py
Normal file
28
spotframework/engine/processor/added.py
Normal file
@ -0,0 +1,28 @@
|
||||
from .abstract import BatchSingleTypeAwareProcessor
|
||||
import datetime
|
||||
from typing import List
|
||||
from spotframework.model.track import PlaylistTrack
|
||||
|
||||
|
||||
class Added(BatchSingleTypeAwareProcessor):
|
||||
|
||||
def __init__(self,
|
||||
boundary: datetime.datetime,
|
||||
names: List[str] = None,
|
||||
append_malformed: bool = True):
|
||||
super().__init__(names,
|
||||
instance_check=PlaylistTrack,
|
||||
append_malformed=append_malformed)
|
||||
self.boundary = boundary
|
||||
|
||||
|
||||
class AddedBefore(Added):
|
||||
def process_single(self, track: PlaylistTrack):
|
||||
if track.added_at < self.boundary:
|
||||
return track
|
||||
|
||||
|
||||
class AddedSince(Added):
|
||||
def process_single(self, track: PlaylistTrack):
|
||||
if track.added_at > self.boundary:
|
||||
return track
|
39
spotframework/engine/processor/deduplicate.py
Normal file
39
spotframework/engine/processor/deduplicate.py
Normal file
@ -0,0 +1,39 @@
|
||||
from spotframework.engine.processor.abstract import BatchSingleProcessor, BatchSingleTypeAwareProcessor
|
||||
from typing import List
|
||||
from spotframework.model.track import Track, SpotifyTrack
|
||||
|
||||
|
||||
class DeduplicateByID(BatchSingleTypeAwareProcessor):
|
||||
|
||||
def __init__(self,
|
||||
names: List[str] = None,
|
||||
append_malformed: bool = True):
|
||||
super().__init__(names,
|
||||
instance_check=SpotifyTrack,
|
||||
append_malformed=append_malformed)
|
||||
|
||||
def process_batch(self, tracks: List[SpotifyTrack]):
|
||||
return_tracks = []
|
||||
|
||||
for track in tracks:
|
||||
if track.uri not in [i.uri for i in return_tracks]:
|
||||
return_tracks.append(track)
|
||||
|
||||
return return_tracks
|
||||
|
||||
|
||||
class DeduplicateByName(BatchSingleProcessor):
|
||||
|
||||
def process_batch(self, tracks: List[Track]):
|
||||
return_tracks = []
|
||||
|
||||
for to_check in tracks:
|
||||
|
||||
for cache_track in return_tracks:
|
||||
if to_check.name.lower() == cache_track.name.lower():
|
||||
if to_check.artists[0].name.lower() == cache_track.artists[0].name.lower():
|
||||
break
|
||||
else:
|
||||
return_tracks.append(to_check)
|
||||
|
||||
return return_tracks
|
19
spotframework/engine/processor/popularity.py
Normal file
19
spotframework/engine/processor/popularity.py
Normal file
@ -0,0 +1,19 @@
|
||||
from spotframework.engine.processor.abstract import BatchSingleTypeAwareProcessor
|
||||
from typing import List
|
||||
from spotframework.model.track import SpotifyTrack
|
||||
|
||||
|
||||
class SortPopularity(BatchSingleTypeAwareProcessor):
|
||||
|
||||
def __init__(self,
|
||||
names: List[str] = None,
|
||||
append_malformed: bool = True,
|
||||
reverse: bool = False):
|
||||
super().__init__(names,
|
||||
instance_check=SpotifyTrack,
|
||||
append_malformed=append_malformed)
|
||||
self.reverse = reverse
|
||||
|
||||
def process_batch(self, tracks: List[SpotifyTrack]):
|
||||
tracks.sort(key=lambda x: x.popularity, reverse=self.reverse)
|
||||
return tracks
|
Loading…
Reference in New Issue
Block a user