Major bug fixes

dev
Michael K. Steinberg 2023-01-14 18:48:46 +02:00
rodzic 3706a095a9
commit d6ded68b16
6 zmienionych plików z 84 dodań i 26 usunięć

Wyświetl plik

@ -2,6 +2,7 @@ class Settings:
DEFAULT_DOWNLOAD_DIRECTORY = 'E:\\Spotify\\'
ARTIST_IMAGES_SUB_DIR = '_Artists'
PLAYLIST_METADATA_SUB_DIR = '_Playlists'
CATEGORY_METADATA_SUB_DIR = '_Categories'
GLOBALS_SAVE_FILE = '_downloaded_store.json'
FULL_DOWNLOAD_RECURISVE_LIMIT = 0x4000
FULL_DOWNLOAD_THREAD_LIMIT = 50

Wyświetl plik

@ -150,24 +150,36 @@ def full_download(download_dir: str, identifier: str, recursive_artist: bool=Fal
console.error(f'Full download exception: {ex}')
def download_all_categories_playlists(download_meta_data_only=True):
def download_category_playlists(category_id, category_index, category_ids, download_meta_data_only):
playlist_ids = scraper.get_category_playlist_ids(category_id)
random.shuffle(playlist_ids)
for playlist_index, playlist_id in enumerate(playlist_ids):
console.log(f'Scraping playlist data from playlist {playlist_id} ({playlist_index + 1}/{len(playlist_ids)}) from category {category_id} ({category_index + 1}/{len(category_ids)})')
try:
playlist = scraper.get_playlist(playlist_id)
playlist.export_to_file()
if not download_meta_data_only:
full_download(f'{settings.DEFAULT_DOWNLOAD_DIRECTORY}', identifier=playlist.href, thread_count=15)
except Exception as ex:
console.error(f'Scraping categories exception: {ex}')
def download_all_categories_playlists(download_meta_data_only=True, query:str=''):
client.refresh_tokens()
os.makedirs(f'{settings.DEFAULT_DOWNLOAD_DIRECTORY}/{settings.PLAYLIST_METADATA_SUB_DIR}/', exist_ok=True)
console.log(f'Scraping playlists from all categories')
category_ids = scraper.get_categories_ids()
random.shuffle(category_ids)
for category_index, category_id in enumerate(category_ids):
console.log(f'Scraping playlists from category {category_id} ({category_index + 1}/{len(category_ids)})')
console.log(f'Scraping playlists from "{query}" categories')
categories = scraper.get_categories_full(query=query)
threads = []
random.shuffle(categories)
for category_index, category in enumerate(categories):
console.log(f'Scraping playlists from category {category.name} ({category_index + 1}/{len(categories)})')
#category.download_metadata(scraper=scraper)
try:
playlist_ids = scraper.get_category_playlist_ids(category_id)
for playlist_index, playlist_id in enumerate(playlist_ids):
console.log(f'Scraping playlist data from playlist {playlist_id} ({playlist_index + 1}/{len(playlist_ids)}) from category {category_id} ({category_index + 1}/{len(category_ids)})')
try:
playlist = scraper.get_playlist(playlist_id)
playlist.export_to_file()
if not download_meta_data_only:
full_download(f'{settings.DEFAULT_DOWNLOAD_DIRECTORY}', identifier=playlist.href, thread_count=15)
except Exception as ex:
console.error(f'Scraping categories exception: {ex}')
thread = Thread(target=download_category_playlists, args=(category.spotify_id, category_index, categories, download_meta_data_only))
thread.start()
threads.append(thread)
#download_category_playlists(category_id, category_index=category_index, category_ids=category_ids, download_meta_data_only=download_meta_data_only)
except Exception as ex:
console.error(f'Scraping categories exception: {ex}')
[x.join() for x in threads]

Wyświetl plik

@ -155,17 +155,21 @@ class SpotifyScraper:
return playlist_ids
def get_category_playlists(self, category_id: str, limit:int=50, offset:int=0) -> str:
return self.get(f'https://api.spotify.com/v1/browse/categories/{category_id}/playlists/?limit={limit}&offset={offset}').json()
data = self.get(f'https://api.spotify.com/v1/browse/categories/{category_id}/playlists/?limit={limit}&offset={offset}').json()
return data
def get_categories(self, limit=50) -> str:
return self.get(f'https://api.spotify.com/v1/browse/categories/?limit={limit}').json()
return self.get(f'https://api.spotify.com/v1/browse/categories/?limit={limit}&country=IL').json()
def get_categories_ids(self, limit=50) -> str:
def get_categories_full(self, limit=50, query:str='') -> list[SpotifyCategory]:
categories = self.get_categories()
ids = []
for category in categories['categories']['items']:
ids.append(category['id'])
return ids
categories_data = []
os.makedirs(f'{settings.DEFAULT_DOWNLOAD_DIRECTORY}/{settings.CATEGORY_METADATA_SUB_DIR}/', exist_ok=True)
for category_json in categories['categories']['items']:
if not query or query.lower() in category_json['name'].lower():
category = SpotifyCategory(category_json)
categories_data.append(category)
return categories_data
def get_playlist_data(self, playlist_id: str) -> str:
return self.get(f'https://api.spotify.com/v1/playlists/{playlist_id}').json()

Wyświetl plik

@ -3,6 +3,40 @@ import base64
from config import *
class SpotifyCategory:
name = ''
spotify_id = ''
playlist_ids = ''
thumbnail_href = ''
def __init__(self, category_data=None):
self.name = category_data['name']
self.spotify_id = category_data['id']
if len(category_data['icons']) > 0:
self.thumbnail_href = category_data['icons'][0]['url']
def download_metadata(self, scraper):
thumbail_b64 = ''
if self.thumbnail_href:
thumbail_b64 = base64.b64encode( requests.get(self.thumbnail_href).content ).decode()
try:
self.playlist_ids = scraper.get_category_playlist_ids(category_id=self.spotify_id)
except:
self.playlist_ids = []
data = {
'name': self.name,
'spotify_id': self.spotify_id,
'thumbnail_b64': thumbail_b64,
'playlist_ids': self.playlist_ids,
}
with open(f'{settings.DEFAULT_DOWNLOAD_DIRECTORY}/{settings.CATEGORY_METADATA_SUB_DIR}/{self.spotify_id}.category', 'w') as f:
f.write(json.dumps(data))
class SpotifyAlbum:
title = ''
thumbnail_href = ''

Wyświetl plik

@ -54,9 +54,13 @@
<div class="single-line"><label>Thread Limit: </label><input type="number" name="thread-count" value="5"></div>
</div></div>
</form>
<form id="category-download-form" action="/actions/download/categories" method="POST" target="dummy-frame">
<input type="text" id="query" name="query" placeholder="Category query (e.g. 'pop')" style="width:30em;">
<input type="submit" value="Download"/><br>
</form>
</div>
<div>
<div style="display:inline-flex;align-items:baseline;"><label>Show settings: </label><input id="autoscroll" type="checkbox" checked onchange="toggle_settings_visibility();"></div>
<div style="display:inline-flex;align-items:baseline;"><label>Show settings: </label><input type="checkbox" checked onchange="toggle_settings_visibility();"></div>
<div id="settings-container" style="display:block;" name="Settings">
<form action="/settings/" method="POST" target="dummy-frame" style="width:100%;">
<input name="download-dir" placeholder="Download directory" value="{{settings.DEFAULT_DOWNLOAD_DIRECTORY}}">

Wyświetl plik

@ -30,9 +30,12 @@ def actions_download():
return str(ex)
@app.route('/actions/download/categories')
@app.route('/actions/download/categories', methods=['POST'])
def actions_download_categories():
download_all_categories_playlists(download_meta_data_only=False)
query = request.form.get('query')
if not query:
query = ''
download_all_categories_playlists(download_meta_data_only=False, query=query)
@app.route('/info/console/')