luniebox/application/spotifydl.py

115 lines
4.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__name__ = "SpotifyDL"
import subprocess
from configparser import ConfigParser
import os.path
import logging
from enum import Enum
defaultCredentialsLocation = '../config/zspotify.credentials'
class SpotifyDLStatus(Enum):
NONE = "none"
RUNNING = "running"
FINISHED = "finished"
ERROR = "error"
DISABLED = "disabled"
class SpotifyDL():
def __init__(self, luniebox, credentialsLocation=defaultCredentialsLocation):
if not luniebox.zspotify_path:
raise ValueError("No zspotify path provivded!")
else:
self.zspotify_path = luniebox.zspotify_path
if credentialsLocation:
self.credentialsLocation = credentialsLocation
else:
raise ValueError("No credentialsLocation provivded!")
username = luniebox.spotify.get_setting("username")
if not username:
raise ValueError("No username provided!")
password = luniebox.spotify.get_setting("password")
if not password:
raise ValueError("No password provided!")
root = luniebox.get_setting('mpd', 'library_path')
if root:
if not root.endswith("/"):
root = root + "/"
self.root = root
else:
raise ValueError("No root provided!")
if not os.path.isfile(self.credentialsLocation):
logging.getLogger('luniebox').info("initialize zspotify")
p = subprocess.Popen([self.zspotify_path + 'venv/bin/python', self.zspotify_path + 'zspotify/__main__.py', '-s',
'--credentials-location', self.credentialsLocation], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, shell=False, group="pi", user="pi")
input = username + '\n' + password + '\n'
out, err = p.communicate(input=input.encode())
logging.getLogger('luniebox').info(out)
logging.getLogger('luniebox').warn(err)
self.downloads = {}
def download(self, uri):
status = self.downloadStatus(uri)
if status == SpotifyDLStatus.NONE or status == SpotifyDLStatus.ERROR:
logging.getLogger('luniebox').info(
"start download of '" + uri + "'")
trackprefix = ""
if uri.startswith('spotify:album:'):
trackprefix = "{album_num}. "
elif uri.startswith('spotify:playlist:'):
trackprefix = "{playlist_num}. "
p = subprocess.Popen([self.zspotify_path + 'venv/bin/python', self.zspotify_path + 'zspotify/__main__.py', "--root-path", self.root,
'--credentials-location', self.credentialsLocation, "--download-real-time", "True", "--chunk-size", "50000", "--skip-existing-files", "True", "--skip-previously-downloaded", "True", "--output", uri + "/" + trackprefix + "{artist} - {song_name}.{ext}", uri], stdin=None,
stdout=None, stderr=None, close_fds=True, shell=False, group="pi", user="pi")
self.downloads[uri] = p
return SpotifyDLStatus.RUNNING
elif status == SpotifyDLStatus.RUNNING:
logging.getLogger('luniebox').debug(
"download for '" + uri + "' still running")
elif status == SpotifyDLStatus.FINISHED:
logging.getLogger('luniebox').debug(
"alreaded downloaded '" + uri + "'")
return status
def downloadStatus(self, uri):
doneFiledPath = self.root + uri + '/.spotifydl'
if uri in self.downloads:
if self.downloads[uri]:
poll = self.downloads[uri].poll()
if poll != None:
self.downloads.pop(uri)
if poll == 0:
p = subprocess.Popen(["touch", doneFiledPath], stdin=None,
stdout=None, stderr=None, close_fds=True, shell=False, group="pi", user="pi")
p.communicate()
return SpotifyDLStatus.FINISHED
logging.getLogger('luniebox').warn(
"download of '" + uri + "' exited with: " + str(poll))
return SpotifyDLStatus.ERROR
return SpotifyDLStatus.RUNNING
if os.path.exists(doneFiledPath):
return SpotifyDLStatus.FINISHED
return SpotifyDLStatus.NONE
def getDownloads(self):
downloads = {}
for uri in self.downloads.keys():
downloads[uri] = str(self.downloadStatus(uri))
return downloads