mirror of
https://github.com/THIS-IS-NOT-A-BACKUP/zspotify.git
synced 2025-12-27 19:10:28 +00:00
resolved merge conficts
This commit is contained in:
4
zspotify/__main__.py
Normal file
4
zspotify/__main__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from app import client
|
||||
|
||||
if __name__ == '__main__':
|
||||
client()
|
||||
@@ -37,7 +37,13 @@ def get_artist_albums(artist_id):
|
||||
""" Returns artist's albums """
|
||||
resp = ZSpotify.invoke_url(f'{ARTIST_URL}/{artist_id}/albums')
|
||||
# Return a list each album's id
|
||||
return [resp[ITEMS][i][ID] for i in range(len(resp[ITEMS]))]
|
||||
album_ids = [resp[ITEMS][i][ID] for i in range(len(resp[ITEMS]))]
|
||||
# Recursive requests to get all albums including singles an EPs
|
||||
while resp['next'] is not None:
|
||||
resp = ZSpotify.invoke_url(resp['next'])
|
||||
album_ids.extend([resp[ITEMS][i][ID] for i in range(len(resp[ITEMS]))])
|
||||
|
||||
return album_ids
|
||||
|
||||
|
||||
def download_album(album):
|
||||
|
||||
@@ -162,6 +162,3 @@ def perform_action(tracks: list, albums: list, playlists: list, artists: list,
|
||||
else:
|
||||
download_playlist(playlists, position - total_tracks - total_albums - total_artists)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
client()
|
||||
|
||||
@@ -55,6 +55,8 @@ ERROR = 'error'
|
||||
|
||||
EXPLICIT = 'explicit'
|
||||
|
||||
PLAYLIST = 'playlist'
|
||||
|
||||
PLAYLISTS = 'playlists'
|
||||
|
||||
OWNER = 'owner'
|
||||
@@ -109,4 +111,15 @@ ALBUM_ID = 'AlbumID'
|
||||
|
||||
TRACK_ID = 'TrackID'
|
||||
|
||||
S_NO = 'S.NO'
|
||||
S_NO = 'S.NO'
|
||||
CONFIG_DEFAULT_SETTINGS = {
|
||||
'ROOT_PATH': '../ZSpotify Music/',
|
||||
'ROOT_PODCAST_PATH': '../ZSpotify Podcasts/',
|
||||
'SKIP_EXISTING_FILES': True,
|
||||
'DOWNLOAD_FORMAT': 'mp3',
|
||||
'FORCE_PREMIUM': False,
|
||||
'ANTI_BAN_WAIT_TIME': 1,
|
||||
'OVERRIDE_AUTO_WAIT': False,
|
||||
'CHUNK_SIZE': 50000,
|
||||
'SPLIT_ALBUM_DISCS': False
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
from typing import Optional
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from librespot.metadata import EpisodeId
|
||||
from tqdm import tqdm
|
||||
@@ -12,7 +12,7 @@ EPISODE_INFO_URL = 'https://api.spotify.com/v1/episodes'
|
||||
SHOWS_URL = 'https://api.spotify.com/v1/shows'
|
||||
|
||||
|
||||
def get_episode_info(episode_id) -> tuple[Optional[str], Optional[str]]:
|
||||
def get_episode_info(episode_id) -> Tuple[Optional[str], Optional[str]]:
|
||||
info = ZSpotify.invoke_url(f'{EPISODE_INFO_URL}/{episode_id}')
|
||||
if ERROR in info:
|
||||
return None, None
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import math
|
||||
import os
|
||||
import time
|
||||
from typing import Any
|
||||
from typing import Any, Tuple, List
|
||||
|
||||
from librespot.audio.decoders import AudioQuality
|
||||
from librespot.metadata import TrackId
|
||||
@@ -23,7 +23,8 @@ def get_saved_tracks() -> list:
|
||||
limit = 50
|
||||
|
||||
while True:
|
||||
resp = ZSpotify.invoke_url_with_params(SAVED_TRACKS_URL, limit=limit, offset=offset)
|
||||
resp = ZSpotify.invoke_url_with_params(
|
||||
SAVED_TRACKS_URL, limit=limit, offset=offset)
|
||||
offset += limit
|
||||
songs.extend(resp[ITEMS])
|
||||
if len(resp[ITEMS]) < limit:
|
||||
@@ -32,15 +33,15 @@ def get_saved_tracks() -> list:
|
||||
return songs
|
||||
|
||||
|
||||
def get_song_info(song_id) -> tuple[list[str], str, str, Any, Any, Any, Any, Any, Any, Any]:
|
||||
def get_song_info(song_id) -> Tuple[List[str], str, str, Any, Any, Any, Any, Any, Any, Any]:
|
||||
""" Retrieves metadata for downloaded songs """
|
||||
info = ZSpotify.invoke_url(f'{TRACKS_URL}?ids={song_id}&market=from_token')
|
||||
|
||||
artists = []
|
||||
for data in info[TRACKS][0][ARTISTS]:
|
||||
artists.append(data[NAME])
|
||||
album_name = info[TRACKS][0][ALBUM][NAME]
|
||||
name = info[TRACKS][0][NAME]
|
||||
artists.append(sanitize_data(data[NAME]))
|
||||
album_name = sanitize_data(info[TRACKS][0][ALBUM][NAME])
|
||||
name = sanitize_data(info[TRACKS][0][NAME])
|
||||
image_url = info[TRACKS][0][ALBUM][IMAGES][0][URL]
|
||||
release_year = info[TRACKS][0][ALBUM][RELEASE_DATE].split('-')[0]
|
||||
disc_number = info[TRACKS][0][DISC_NUMBER]
|
||||
@@ -84,18 +85,23 @@ def process_track_metadata(artists: list, name: str, disc_number: Any, extra_pat
|
||||
create_m3u_file: bool):
|
||||
m3u_filename = None
|
||||
|
||||
song_name = sanitize_data(artists[0]) + ' - ' + sanitize_data(name)
|
||||
if create_m3u_file:
|
||||
download_directory = os.path.join(os.path.dirname(
|
||||
__file__), ZSpotify.get_config(ROOT_PATH), extra_paths, extra_paths[:-1])
|
||||
m3u_filename = f'{download_directory}.m3u'
|
||||
if ZSpotify.get_config(SPLIT_ALBUM_DISCS):
|
||||
download_directory = os.path.join(os.path.dirname(
|
||||
__file__), ZSpotify.get_config(ROOT_PATH), extra_paths, f'Disc {disc_number}')
|
||||
else:
|
||||
download_directory = os.path.join(os.path.dirname(
|
||||
__file__), ZSpotify.get_config(ROOT_PATH), extra_paths)
|
||||
song_name = artists[0] + ' - ' + name
|
||||
if prefix:
|
||||
song_name = f'{prefix_value.zfill(2)} - {song_name}' if prefix_value.isdigit(
|
||||
) else f'{prefix_value} - {song_name}'
|
||||
if create_m3u_file:
|
||||
m3u_filename = f'{os.path.join(ZSpotify.get_config(ROOT_PATH), extra_paths, extra_paths)[:-1]}.m3u'
|
||||
if ZSpotify.get_config(SPLIT_ALBUM_DISCS):
|
||||
filename = os.path.join(ZSpotify.get_config(ROOT_PATH), extra_paths, 'Disc ' + str(
|
||||
disc_number) + '/' + song_name + '.' + ZSpotify.get_config(DOWNLOAD_FORMAT))
|
||||
else:
|
||||
filename = os.path.join(ZSpotify.get_config(ROOT_PATH), extra_paths,
|
||||
song_name + '.' + ZSpotify.get_config(DOWNLOAD_FORMAT))
|
||||
|
||||
filename = os.path.join(
|
||||
download_directory, f'{song_name}.{ZSpotify.get_config(DOWNLOAD_FORMAT)}')
|
||||
return song_name, filename, m3u_filename
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import platform
|
||||
import re
|
||||
import time
|
||||
from enum import Enum
|
||||
from typing import Match
|
||||
from typing import List, Tuple, Match
|
||||
|
||||
import music_tag
|
||||
import requests
|
||||
@@ -28,7 +28,7 @@ def wait(seconds: int = 3) -> None:
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def split_input(selection) -> list[str]:
|
||||
def split_input(selection) -> List[str]:
|
||||
""" Returns a list of inputted strings """
|
||||
inputs = []
|
||||
if '-' in selection:
|
||||
@@ -92,7 +92,7 @@ def set_music_thumbnail(filename, image_url) -> None:
|
||||
tags.save()
|
||||
|
||||
|
||||
def regex_input_for_urls(search_input) -> tuple[str, str, str, str, str, str]:
|
||||
def regex_input_for_urls(search_input) -> Tuple[str, str, str, str, str, str]:
|
||||
""" Since many kinds of search may be passed at the command line, process them all here. """
|
||||
track_uri_search = re.search(
|
||||
r'^spotify:track:(?P<TrackID>[0-9a-zA-Z]{22})$', search_input)
|
||||
|
||||
@@ -18,7 +18,7 @@ from librespot.core import Session
|
||||
|
||||
from const import CREDENTIALS_JSON, TYPE, \
|
||||
PREMIUM, USER_READ_EMAIL, AUTHORIZATION, OFFSET, LIMIT, CONFIG_FILE_PATH, FORCE_PREMIUM, \
|
||||
PLAYLIST_READ_PRIVATE
|
||||
PLAYLIST_READ_PRIVATE, CONFIG_DEFAULT_SETTINGS
|
||||
from utils import MusicFormat
|
||||
|
||||
|
||||
@@ -55,8 +55,14 @@ class ZSpotify:
|
||||
@classmethod
|
||||
def load_config(cls) -> None:
|
||||
app_dir = os.path.dirname(__file__)
|
||||
with open(os.path.join(app_dir, CONFIG_FILE_PATH), encoding='utf-8') as config_file:
|
||||
cls.CONFIG = json.load(config_file)
|
||||
true_config_file_path = os.path.join(app_dir, CONFIG_FILE_PATH)
|
||||
if not os.path.exists(true_config_file_path):
|
||||
with open(true_config_file_path, 'w', encoding='utf-8') as config_file:
|
||||
json.dump(CONFIG_DEFAULT_SETTINGS, config_file, indent=4)
|
||||
cls.CONFIG = CONFIG_DEFAULT_SETTINGS
|
||||
else:
|
||||
with open(true_config_file_path, encoding='utf-8') as config_file:
|
||||
cls.CONFIG = json.load(config_file)
|
||||
|
||||
@classmethod
|
||||
def get_config(cls, key) -> Any:
|
||||
|
||||
Reference in New Issue
Block a user