|  |  |  | @ -2,9 +2,8 @@ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | from argparse import ArgumentParser | 
		
	
		
			
				|  |  |  |  | from datetime import date, datetime, timedelta | 
		
	
		
			
				|  |  |  |  | from typing import Dict, Iterable | 
		
	
		
			
				|  |  |  |  | from typing import Iterable | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | from spotify_model import SimplifiedAlbum | 
		
	
		
			
				|  |  |  |  | from spotipy import Spotify | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | from spotify_actions.album import ( | 
		
	
	
		
			
				
					
					|  |  |  | @ -39,43 +38,38 @@ def label_playlist(client: Spotify, label_name: str, playlist_id: str) -> None: | 
		
	
		
			
				|  |  |  |  |     playlist_replace(client, playlist_id, tracks) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | def label_recent(client: Spotify, playlist_id: str, released_after: date) -> Iterable[SimplifiedAlbum]: | 
		
	
		
			
				|  |  |  |  |     # Get all albums in a playlist released after the provided date | 
		
	
		
			
				|  |  |  |  |     tracks = playlist_tracks(client, [playlist_id]) | 
		
	
		
			
				|  |  |  |  |     albums = track_unique_albums(tracks) | 
		
	
		
			
				|  |  |  |  | def label_recent(client: Spotify, label_playlist_ids: Iterable[str], playlist_id: str, released_after: date) -> None: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Because the playlists were created in descending release date order, | 
		
	
		
			
				|  |  |  |  |     # `is_sorted=True` is enabled to reduce the number of API queries needed | 
		
	
		
			
				|  |  |  |  |     return album_filter_release(albums, released_after, is_sorted=True) | 
		
	
		
			
				|  |  |  |  |     album_iterables = [] | 
		
	
		
			
				|  |  |  |  |     for label_playlist_id in label_playlist_ids: | 
		
	
		
			
				|  |  |  |  |         # Get all albums in a playlist released after the provided date | 
		
	
		
			
				|  |  |  |  |         tracks = playlist_tracks(client, [label_playlist_id]) | 
		
	
		
			
				|  |  |  |  |         album_ids = track_unique_albums(tracks) | 
		
	
		
			
				|  |  |  |  |         albums = album_from_ids(client, album_ids) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | def run(client: Spotify, recent_releases_id: str, label_ids: Dict[str, str], released_after: date) -> None: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Create the individual label playlists | 
		
	
		
			
				|  |  |  |  |     for label_name, playlist_id in label_ids.items(): | 
		
	
		
			
				|  |  |  |  |         label_playlist(client, label_name, playlist_id) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Get albums from the playlists we just created | 
		
	
		
			
				|  |  |  |  |     album_iterables = [label_recent(client, playlist_id, released_after) for _, playlist_id in label_ids.items()] | 
		
	
		
			
				|  |  |  |  |         # Because the playlists were created in descending release date order, | 
		
	
		
			
				|  |  |  |  |         # `is_sorted=True` is enabled to reduce the number of API queries needed | 
		
	
		
			
				|  |  |  |  |         album_iterables.append(album_filter_release(albums, released_after, is_sorted=True)) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Merge all the albums from each label playlist | 
		
	
		
			
				|  |  |  |  |     recent_albums = combinator_join(*album_iterables) | 
		
	
		
			
				|  |  |  |  |     recent_tracks = album_to_tracks(client, recent_albums) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Create the recent releases playlist | 
		
	
		
			
				|  |  |  |  |     playlist_replace(client, recent_releases_id, recent_tracks) | 
		
	
		
			
				|  |  |  |  |     playlist_replace(client, playlist_id, recent_tracks) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | def main() -> None: | 
		
	
		
			
				|  |  |  |  |     one_week_ago = (datetime.now().date() - timedelta(days=7)).strftime("%Y-%m-%d") | 
		
	
		
			
				|  |  |  |  |     # Intentionally 6 days - if running on a Friday, we don't want to include last Friday's releases | 
		
	
		
			
				|  |  |  |  |     one_week_ago = (datetime.now().date() - timedelta(days=6)).strftime("%Y-%m-%d") | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     parser = ArgumentParser() | 
		
	
		
			
				|  |  |  |  |     parser.add_argument("-c", "--credentials", required=True) | 
		
	
		
			
				|  |  |  |  |     parser.add_argument("-r", "--redirect-uri", required=True) | 
		
	
		
			
				|  |  |  |  |     parser.add_argument("--recent-release", help='Name of the "recent releases" playlist constructed from all labels.') | 
		
	
		
			
				|  |  |  |  |     parser.add_argument( | 
		
	
		
			
				|  |  |  |  |         "-d", "--released-after", help="YYYY-MM-DD date that albums must be released after", default=one_week_ago | 
		
	
		
			
				|  |  |  |  |         "--released-after", help="YYYY-MM-DD date that albums must be released after", default=one_week_ago | 
		
	
		
			
				|  |  |  |  |     ) | 
		
	
		
			
				|  |  |  |  |     parser.add_argument("recent_release", help='Name of the "recent releases" playlist constructed from all labels') | 
		
	
		
			
				|  |  |  |  |     parser.add_argument("label", nargs="+") | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     cmdline = parser.parse_args() | 
		
	
	
		
			
				
					
					|  |  |  | @ -86,8 +80,6 @@ def main() -> None: | 
		
	
		
			
				|  |  |  |  |         scopes=["playlist-read-private", "playlist-modify-private", "playlist-modify-public"], | 
		
	
		
			
				|  |  |  |  |     ) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     released_after = datetime.strptime(cmdline.released_after, "%Y-%m-%d") | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     # Get all user playlists; we'll be iterating over this a couple times | 
		
	
		
			
				|  |  |  |  |     user_playlists = list(playlist_current_user_all(client)) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @ -97,10 +89,15 @@ def main() -> None: | 
		
	
		
			
				|  |  |  |  |         # The `str()` wrapper is technically unnecessary, but keeps mypy happy | 
		
	
		
			
				|  |  |  |  |         return str(list(assured)[0].spotify_id) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     recent_releases = _locate_playlist(cmdline.recent_release) | 
		
	
		
			
				|  |  |  |  |     label_playlists = {label: _locate_playlist(label) for label in cmdline.label} | 
		
	
		
			
				|  |  |  |  |     label_ids = {name: _locate_playlist(name) for name in cmdline.label} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     run(client, recent_releases, label_playlists, released_after) | 
		
	
		
			
				|  |  |  |  |     for label_name, playlist_id in label_ids.items(): | 
		
	
		
			
				|  |  |  |  |         label_playlist(client, label_name, playlist_id) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if cmdline.recent_release: | 
		
	
		
			
				|  |  |  |  |         recent_release = _locate_playlist(cmdline.recent_release) | 
		
	
		
			
				|  |  |  |  |         released_after = datetime.strptime(cmdline.released_after, "%Y-%m-%d").date() | 
		
	
		
			
				|  |  |  |  |         label_recent(client, label_ids.values(), recent_release, released_after) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | if __name__ == "__main__": | 
		
	
	
		
			
				
					
					|  |  |  | 
 |