mirror of
https://github.com/Footsiefat/zspotify
synced 2021-12-21 22:06:14 +01:00
Move loader to own python file and added cmd flag to suppress its output
This commit is contained in:
parent
d37ab43880
commit
a15d966d93
@ -29,6 +29,7 @@ PRINT_API_ERRORS = 'PRINT_API_ERRORS'
|
||||
TEMP_DOWNLOAD_DIR = 'TEMP_DOWNLOAD_DIR'
|
||||
MD_ALLGENRES = 'MD_ALLGENRES'
|
||||
MD_GENREDELIMITER = 'MD_GENREDELIMITER'
|
||||
PRINT_PROGRESS_INFO = 'PRINT_PROGRESS_INFO'
|
||||
|
||||
CONFIG_VALUES = {
|
||||
ROOT_PATH: { 'default': '../ZSpotify Music/', 'type': str, 'arg': '--root-path' },
|
||||
@ -53,6 +54,7 @@ CONFIG_VALUES = {
|
||||
PRINT_ERRORS: { 'default': 'True', 'type': bool, 'arg': '--print-errors' },
|
||||
PRINT_DOWNLOADS: { 'default': 'False', 'type': bool, 'arg': '--print-downloads' },
|
||||
PRINT_API_ERRORS: { 'default': 'False', 'type': bool, 'arg': '--print-api-errors' },
|
||||
PRINT_PROGRESS_INFO: { 'default': 'True', 'type': bool, 'arg': '--print-progress-info' },
|
||||
MD_ALLGENRES: { 'default': 'False', 'type': bool, 'arg': '--md-allgenres' },
|
||||
MD_GENREDELIMITER: { 'default': ';', 'type': str, 'arg': '--md-genredelimiter' },
|
||||
TEMP_DOWNLOAD_DIR: { 'default': '', 'type': str, 'arg': '--temp-download-dir' }
|
||||
|
72
zspotify/loader.py
Normal file
72
zspotify/loader.py
Normal file
@ -0,0 +1,72 @@
|
||||
# load symbol from:
|
||||
# https://stackoverflow.com/questions/22029562/python-how-to-make-simple-animated-loading-while-process-is-running
|
||||
|
||||
# imports
|
||||
from itertools import cycle
|
||||
from shutil import get_terminal_size
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
|
||||
from termoutput import Printer
|
||||
|
||||
|
||||
class Loader:
|
||||
"""Busy symbol.
|
||||
|
||||
Can be called inside a context:
|
||||
|
||||
with Loader("This take some Time..."):
|
||||
# do something
|
||||
pass
|
||||
"""
|
||||
def __init__(self, chan, desc="Loading...", end='', timeout=0.1, mode='std1'):
|
||||
"""
|
||||
A loader-like context manager
|
||||
|
||||
Args:
|
||||
desc (str, optional): The loader's description. Defaults to "Loading...".
|
||||
end (str, optional): Final print. Defaults to "".
|
||||
timeout (float, optional): Sleep time between prints. Defaults to 0.1.
|
||||
"""
|
||||
self.desc = desc
|
||||
self.end = end
|
||||
self.timeout = timeout
|
||||
self.channel = chan
|
||||
|
||||
self._thread = Thread(target=self._animate, daemon=True)
|
||||
if mode == 'std1':
|
||||
self.steps = ["⢿", "⣻", "⣽", "⣾", "⣷", "⣯", "⣟", "⡿"]
|
||||
elif mode == 'std2':
|
||||
self.steps = ["◜","◝","◞","◟"]
|
||||
elif mode == 'std3':
|
||||
self.steps = ["😐 ","😐 ","😮 ","😮 ","😦 ","😦 ","😧 ","😧 ","🤯 ","💥 ","✨ ","\u3000 ","\u3000 ","\u3000 "]
|
||||
elif mode == 'prog':
|
||||
self.steps = ["[∙∙∙]","[●∙∙]","[∙●∙]","[∙∙●]","[∙∙∙]"]
|
||||
|
||||
self.done = False
|
||||
|
||||
def start(self):
|
||||
self._thread.start()
|
||||
return self
|
||||
|
||||
def _animate(self):
|
||||
for c in cycle(self.steps):
|
||||
if self.done:
|
||||
break
|
||||
Printer.print_loader(self.channel, f"\r\t{c} {self.desc} ")
|
||||
sleep(self.timeout)
|
||||
|
||||
def __enter__(self):
|
||||
self.start()
|
||||
|
||||
def stop(self):
|
||||
self.done = True
|
||||
cols = get_terminal_size((80, 20)).columns
|
||||
Printer.print_loader(self.channel, "\r" + " " * cols)
|
||||
|
||||
if self.end != "":
|
||||
Printer.print_loader(self.channel, f"\r{self.end}")
|
||||
|
||||
def __exit__(self, exc_type, exc_value, tb):
|
||||
# handle exceptions with those variables ^
|
||||
self.stop()
|
@ -1,7 +1,7 @@
|
||||
from enum import Enum
|
||||
from tqdm import tqdm
|
||||
|
||||
from config import PRINT_SPLASH, PRINT_SKIPS, PRINT_DOWNLOAD_PROGRESS, PRINT_ERRORS, PRINT_DOWNLOADS, PRINT_API_ERRORS
|
||||
from config import *
|
||||
from zspotify import ZSpotify
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ class PrintChannel(Enum):
|
||||
ERRORS = PRINT_ERRORS
|
||||
DOWNLOADS = PRINT_DOWNLOADS
|
||||
API_ERRORS = PRINT_API_ERRORS
|
||||
PROGRESS_INFO = PRINT_PROGRESS_INFO
|
||||
|
||||
|
||||
class Printer:
|
||||
@ -20,6 +21,11 @@ class Printer:
|
||||
if ZSpotify.CONFIG.get(channel.value):
|
||||
print(msg)
|
||||
|
||||
@staticmethod
|
||||
def print_loader(channel: PrintChannel, msg: str) -> None:
|
||||
if ZSpotify.CONFIG.get(channel.value):
|
||||
print(msg, flush=True, end="")
|
||||
|
||||
@staticmethod
|
||||
def progress(iterable=None, desc=None, total=None, unit='it', disable=False, unit_scale=False, unit_divisor=1000):
|
||||
if not ZSpotify.CONFIG.get(PrintChannel.DOWNLOAD_PROGRESS.value):
|
||||
|
@ -17,7 +17,7 @@ from utils import fix_filename, set_audio_tags, set_music_thumbnail, create_down
|
||||
from zspotify import ZSpotify
|
||||
import traceback
|
||||
|
||||
from utils import Loader
|
||||
from loader import Loader
|
||||
|
||||
def get_saved_tracks() -> list:
|
||||
""" Returns user's saved tracks """
|
||||
@ -38,7 +38,7 @@ def get_saved_tracks() -> list:
|
||||
|
||||
def get_song_info(song_id) -> Tuple[List[str], List[str], str, str, Any, Any, Any, Any, Any, Any, int]:
|
||||
""" Retrieves metadata for downloaded songs """
|
||||
with Loader("Fetching track information..."):
|
||||
with Loader(PrintChannel.PROGRESS_INFO, "Fetching track information..."):
|
||||
(raw, info) = ZSpotify.invoke_url(f'{TRACKS_URL}?ids={song_id}&market=from_token')
|
||||
|
||||
if not TRACKS in info:
|
||||
@ -50,7 +50,7 @@ def get_song_info(song_id) -> Tuple[List[str], List[str], str, str, Any, Any, An
|
||||
for data in info[TRACKS][0][ARTISTS]:
|
||||
artists.append(data[NAME])
|
||||
# query artist genres via href, which will be the api url
|
||||
with Loader("Fetching artist information..."):
|
||||
with Loader(PrintChannel.PROGRESS_INFO, "Fetching artist information..."):
|
||||
(raw, artistInfo) = ZSpotify.invoke_url(f'{data["href"]}')
|
||||
if ZSpotify.CONFIG.get_allGenres() and len(artistInfo[GENRES]) > 0:
|
||||
for genre in artistInfo[GENRES]:
|
||||
@ -103,7 +103,7 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=
|
||||
(artists, genres, album_name, name, image_url, release_year, disc_number,
|
||||
track_number, scraped_song_id, is_playable, duration_ms) = get_song_info(track_id)
|
||||
|
||||
prepareDownloadLoader = Loader("Preparing download...");
|
||||
prepareDownloadLoader = Loader(PrintChannel.PROGRESS_INFO, "Preparing download...");
|
||||
prepareDownloadLoader.start()
|
||||
|
||||
song_name = fix_filename(artists[0]) + ' - ' + fix_filename(name)
|
||||
@ -251,7 +251,7 @@ def convert_audio_format(filename) -> None:
|
||||
outputs={filename: output_params}
|
||||
)
|
||||
|
||||
with Loader("Converting file..."):
|
||||
with Loader(PrintChannel.PROGRESS_INFO, "Converting file..."):
|
||||
ff_m.run()
|
||||
|
||||
if os.path.exists(temp_filename):
|
||||
|
@ -280,84 +280,3 @@ def fmt_seconds(secs: float) -> str:
|
||||
return f'{m}'.zfill(2) + ':' + f'{s}'.zfill(2)
|
||||
else:
|
||||
return f'{h}'.zfill(2) + ':' + f'{m}'.zfill(2) + ':' + f'{s}'.zfill(2)
|
||||
|
||||
|
||||
# load symbol from:
|
||||
# https://stackoverflow.com/questions/22029562/python-how-to-make-simple-animated-loading-while-process-is-running
|
||||
|
||||
# imports
|
||||
from itertools import cycle
|
||||
from shutil import get_terminal_size
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
|
||||
class Loader:
|
||||
"""Busy symbol.
|
||||
|
||||
Can be called inside a context:
|
||||
|
||||
with Loader("This take some Time..."):
|
||||
# do something
|
||||
pass
|
||||
"""
|
||||
def __init__(self, desc="Loading...", end='', timeout=0.1, mode='std1'):
|
||||
"""
|
||||
A loader-like context manager
|
||||
|
||||
Args:
|
||||
desc (str, optional): The loader's description. Defaults to "Loading...".
|
||||
end (str, optional): Final print. Defaults to "".
|
||||
timeout (float, optional): Sleep time between prints. Defaults to 0.1.
|
||||
"""
|
||||
self.desc = desc
|
||||
self.end = end
|
||||
self.timeout = timeout
|
||||
|
||||
self._thread = Thread(target=self._animate, daemon=True)
|
||||
if mode == 'std1':
|
||||
self.steps = ["⢿", "⣻", "⣽", "⣾", "⣷", "⣯", "⣟", "⡿"]
|
||||
elif mode == 'std2':
|
||||
self.steps = ["◜","◝","◞","◟"]
|
||||
elif mode == 'std3':
|
||||
self.steps = ["😐 ","😐 ","😮 ","😮 ","😦 ","😦 ","😧 ","😧 ","🤯 ","💥 ","✨ ","\u3000 ","\u3000 ","\u3000 "]
|
||||
elif mode == 'prog':
|
||||
self.steps = ["[∙∙∙]","[●∙∙]","[∙●∙]","[∙∙●]","[∙∙∙]"]
|
||||
|
||||
self.done = False
|
||||
|
||||
def start(self):
|
||||
self._thread.start()
|
||||
return self
|
||||
|
||||
def _animate(self):
|
||||
for c in cycle(self.steps):
|
||||
if self.done:
|
||||
break
|
||||
print(f"\r\t{c} {self.desc} ", flush=True, end="")
|
||||
sleep(self.timeout)
|
||||
|
||||
def __enter__(self):
|
||||
self.start()
|
||||
|
||||
def stop(self):
|
||||
self.done = True
|
||||
cols = get_terminal_size((80, 20)).columns
|
||||
print("\r" + " " * cols, end="", flush=True)
|
||||
|
||||
if self.end != "":
|
||||
print(f"\r{self.end}", flush=True)
|
||||
|
||||
def __exit__(self, exc_type, exc_value, tb):
|
||||
# handle exceptions with those variables ^
|
||||
self.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with Loader("Loading with context manager..."):
|
||||
for i in range(10):
|
||||
sleep(0.25)
|
||||
|
||||
loader = Loader("Loading with object...", "That was fast!", 0.05).start()
|
||||
for i in range(10):
|
||||
sleep(0.25)
|
||||
loader.stop()
|
||||
|
Loading…
Reference in New Issue
Block a user