Started reworking the library

This commit is contained in:
RemixDev 2020-08-14 20:31:37 +02:00
parent a991ad04ec
commit 8afdfc7042
8 changed files with 199 additions and 197 deletions

View File

@ -4,6 +4,12 @@ import click
import deemix.app.cli as app import deemix.app.cli as app
from deemix.app.settings import initSettings from deemix.app.settings import initSettings
from os.path import isfile from os.path import isfile
import random
import string
def randomString(stringLength=8):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
@click.command() @click.command()
@ -26,8 +32,5 @@ def download(bitrate, local, url):
if local: if local:
click.echo(settings['downloadLocation']) #folder name output click.echo(settings['downloadLocation']) #folder name output
def main():
download()
if __name__ == '__main__': if __name__ == '__main__':
main() download()

168
deemix/app/Settings.py Normal file
View File

@ -0,0 +1,168 @@
#!/usr/bin/env python3
import json
import os.path as path
from os import makedirs, listdir, remove
from deemix import __version__ as deemixVersion
import logging
import datetime
import platform
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('deemix')
import deemix.utils.localpaths as localpaths
class Settings:
def __init__(self, configFolder=None):
self.settings = {}
self.configFolder = configFolder
if not self.configFolder:
self.configFolder = localpaths.getConfigFolder()
self.defaultSettings = {
"downloadLocation": path.join(localpaths.getHomeFolder(), 'deemix Music'),
"tracknameTemplate": "%artist% - %title%",
"albumTracknameTemplate": "%tracknumber% - %title%",
"playlistTracknameTemplate": "%position% - %artist% - %title%",
"createPlaylistFolder": True,
"playlistNameTemplate": "%playlist%",
"createArtistFolder": False,
"artistNameTemplate": "%artist%",
"createAlbumFolder": True,
"albumNameTemplate": "%artist% - %album%",
"createCDFolder": True,
"createStructurePlaylist": False,
"createSingleFolder": False,
"padTracks": True,
"paddingSize": "0",
"illegalCharacterReplacer": "_",
"queueConcurrency": 3,
"maxBitrate": "3",
"fallbackBitrate": True,
"fallbackSearch": False,
"logErrors": True,
"logSearched": False,
"saveDownloadQueue": False,
"overwriteFile": "n",
"createM3U8File": False,
"playlistFilenameTemplate": "playlist",
"syncedLyrics": False,
"embeddedArtworkSize": 800,
"localArtworkSize": 1400,
"localArtworkFormat": "jpg",
"saveArtwork": True,
"coverImageTemplate": "cover",
"saveArtworkArtist": False,
"artistImageTemplate": "folder",
"jpegImageQuality": 80,
"dateFormat": "Y-M-D",
"albumVariousArtists": True,
"removeAlbumVersion": False,
"removeDuplicateArtists": False,
"featuredToTitle": "0",
"titleCasing": "nothing",
"artistCasing": "nothing",
"executeCommand": "",
"tags": {
"title": True,
"artist": True,
"album": True,
"cover": True,
"trackNumber": True,
"trackTotal": False,
"discNumber": True,
"discTotal": False,
"albumArtist": True,
"genre": True,
"year": True,
"date": True,
"explicit": False,
"isrc": True,
"length": True,
"barcode": True,
"bpm": True,
"replayGain": False,
"label": True,
"lyrics": False,
"copyright": False,
"composer": False,
"involvedPeople": False,
"savePlaylistAsCompilation": False,
"useNullSeparator": False,
"saveID3v1": True,
"multiArtistSeparator": "default",
"singleAlbumArtist": False
}
}
# Create config folder if it doesn't exsist
makedirs(self.configFolder, exist_ok=True)
# Create config file if it doesn't exsist
if not path.isfile(path.join(self.configFolder, 'config.json')):
with open(path.join(self.configFolder, 'config.json'), 'w') as f:
json.dump(self.defaultSettings, f, indent=2)
# Read config file
with open(path.join(self.configFolder, 'config.json'), 'r') as configFile:
self.settings = json.load(configFile)
self.settingsCheck()
# Make sure the download path exsits
makedirs(self.settings['downloadLocation'], exist_ok=True)
# LOGFILES
# Create logfile name and path
logspath = path.join(self.configFolder, 'logs')
now = datetime.datetime.now()
logfile = now.strftime("%Y-%m-%d_%H%M%S")+".log"
makedirs(logspath, exist_ok=True)
# Add handler for logging
fh = logging.FileHandler(path.join(logspath, logfile))
fh.setLevel(logging.DEBUG)
fh.setFormatter(logging.Formatter('%(asctime)s - [%(levelname)s] %(message)s'))
logger.addHandler(fh)
logger.info(f"{platform.platform(True, True)} - Python {platform.python_version()}, deemix {deemixVersion}")
# Only keep last 5 logfiles (to preserve disk space)
logslist = listdir(logspath)
logslist.sort()
if len(logslist)>5:
for i in range(len(logslist)-5):
remove(path.join(logspath, logslist[i]))
def getSettings(self):
return self.settings
def getDefaultSettings(self):
return self.defaultSettings
# Saves the settings
def saveSettings(self, newSettings=None):
if newSettings:
self.settings = newSettings
with open(path.join(self.configFolder, 'config.json'), 'w') as configFile:
json.dump(self.settings, configFile, indent=2)
# Checks if the default settings have changed
def settingsCheck(self):
changes = 0
for x in self.defaultSettings:
if not x in self.settings or type(self.settings[x]) != type(self.defaultSettings[x]):
self.settings[x] = self.defaultSettings[x]
changes += 1
for x in self.defaultSettings['tags']:
if not x in self.settings['tags'] or type(self.settings['tags'][x]) != type(self.defaultSettings['tags'][x]):
self.settings['tags'][x] = self.defaultSettings['tags'][x]
changes += 1
if self.settings['downloadLocation'] == "":
self.settings['downloadLocation'] = path.join(localpaths.getHomeFolder(), 'deemix Music')
changes += 1
for template in ['tracknameTemplate', 'albumTracknameTemplate', 'playlistTracknameTemplate', 'playlistNameTemplate', 'artistNameTemplate', 'albumNameTemplate', 'playlistFilenameTemplate', 'coverImageTemplate', 'artistImageTemplate']:
if self.settings[template] == "":
self.settings[template] = self.defaultSettings[template]
changes += 1
if changes > 0:
saveSettings()

View File

@ -1,2 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# Empty File # Empty File
class deemix:
def __init__(self):

View File

@ -1,75 +0,0 @@
{
"downloadLocation": "",
"tracknameTemplate": "%artist% - %title%",
"albumTracknameTemplate": "%tracknumber% - %title%",
"playlistTracknameTemplate": "%position% - %artist% - %title%",
"createPlaylistFolder": true,
"playlistNameTemplate": "%playlist%",
"createArtistFolder": false,
"artistNameTemplate": "%artist%",
"createAlbumFolder": true,
"albumNameTemplate": "%artist% - %album%",
"createCDFolder": true,
"createStructurePlaylist": false,
"createSingleFolder": false,
"padTracks": true,
"paddingSize": "0",
"illegalCharacterReplacer": "_",
"queueConcurrency": 3,
"maxBitrate": "3",
"fallbackBitrate": true,
"fallbackSearch": false,
"logErrors": true,
"logSearched": false,
"saveDownloadQueue": false,
"overwriteFile": "n",
"createM3U8File": false,
"playlistFilenameTemplate": "playlist",
"syncedLyrics": false,
"embeddedArtworkSize": 800,
"localArtworkSize": 1400,
"localArtworkFormat": "jpg",
"saveArtwork": true,
"coverImageTemplate": "cover",
"saveArtworkArtist": false,
"artistImageTemplate": "folder",
"jpegImageQuality": 80,
"dateFormat": "Y-M-D",
"albumVariousArtists": true,
"removeAlbumVersion": false,
"removeDuplicateArtists": false,
"featuredToTitle": "0",
"titleCasing": "nothing",
"artistCasing": "nothing",
"executeCommand": "",
"tags": {
"title": true,
"artist": true,
"album": true,
"cover": true,
"trackNumber": true,
"trackTotal": false,
"discNumber": true,
"discTotal": false,
"albumArtist": true,
"genre": true,
"year": true,
"date": true,
"explicit": false,
"isrc": true,
"length": true,
"barcode": true,
"bpm": true,
"replayGain": false,
"label": true,
"lyrics": false,
"copyright": false,
"composer": false,
"involvedPeople": false,
"savePlaylistAsCompilation": false,
"useNullSeparator": false,
"saveID3v1": true,
"multiArtistSeparator": "default",
"singleAlbumArtist": false
}
}

View File

@ -1,103 +0,0 @@
#!/usr/bin/env python3
import json
import os.path as path
from os import makedirs, listdir, remove
from deemix import __version__ as deemixVersion
import random
import string
import logging
import datetime
import platform
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('deemix')
import deemix.utils.localpaths as localpaths
settings = {}
defaultSettings = {}
configDir = ""
def initSettings(configFolder = None):
global settings
global defaultSettings
global configDir
currentFolder = path.abspath(path.dirname(__file__))
if not configFolder:
configFolder = localpaths.getConfigFolder()
configDir = configFolder
makedirs(configFolder, exist_ok=True)
with open(path.join(currentFolder, 'default.json'), 'r') as d:
defaultSettings = json.load(d)
defaultSettings['downloadLocation'] = path.join(localpaths.getHomeFolder(), 'deemix Music')
if not path.isfile(path.join(configFolder, 'config.json')):
with open(path.join(configFolder, 'config.json'), 'w') as f:
json.dump(defaultSettings, f, indent=2)
with open(path.join(configFolder, 'config.json'), 'r') as configFile:
settings = json.load(configFile)
settingsCheck()
if settings['downloadLocation'] == "":
settings['downloadLocation'] = path.join(localpaths.getHomeFolder(), 'deemix Music')
saveSettings(settings)
makedirs(settings['downloadLocation'], exist_ok=True)
# logfiles
# logfile name
logspath = path.join(configFolder, 'logs')
now = datetime.datetime.now()
logfile = now.strftime("%Y-%m-%d_%H%M%S")+".log"
makedirs(logspath, exist_ok=True)
# add handler for logfile
fh = logging.FileHandler(path.join(logspath, logfile))
fh.setLevel(logging.DEBUG)
fh.setFormatter(logging.Formatter('%(asctime)s - [%(levelname)s] %(message)s'))
logger.addHandler(fh)
logger.info(f"{platform.platform(True, True)} - Python {platform.python_version()}, deemix {deemixVersion}")
#delete old logfiles
logslist = listdir(logspath)
logslist.sort()
if len(logslist)>5:
for i in range(len(logslist)-5):
remove(path.join(logspath, logslist[i]))
return settings
def getSettings():
global settings
return settings
def getDefaultSettings():
global defaultSettings
return defaultSettings
def saveSettings(newSettings):
global settings
settings = newSettings
with open(path.join(configDir, 'config.json'), 'w') as configFile:
json.dump(settings, configFile, indent=2)
return True
def settingsCheck():
global settings
global defaultSettings
changes = 0
for x in defaultSettings:
if not x in settings or type(settings[x]) != type(defaultSettings[x]):
settings[x] = defaultSettings[x]
changes += 1
for x in defaultSettings['tags']:
if not x in settings['tags'] or type(settings['tags'][x]) != type(defaultSettings['tags'][x]):
settings['tags'][x] = defaultSettings['tags'][x]
changes += 1
if changes > 0:
saveSettings(settings)
def randomString(stringLength=8):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))

View File

@ -11,14 +11,12 @@ if getenv("APPDATA"):
elif sys.platform.startswith('darwin'): elif sys.platform.startswith('darwin'):
userdata = homedata + '/Library/Application Support/deemix/' userdata = homedata + '/Library/Application Support/deemix/'
elif getenv("XDG_CONFIG_HOME"): elif getenv("XDG_CONFIG_HOME"):
userdata = getenv("XDG_CONFIG_HOME") + '/deemix/'; userdata = getenv("XDG_CONFIG_HOME") + '/deemix/'
else: else:
userdata = homedata + '/.config/deemix/'; userdata = homedata + '/.config/deemix/'
def getHomeFolder(): def getHomeFolder():
return homedata return homedata
def getConfigFolder(): def getConfigFolder():
return userdata return userdata

View File

@ -94,12 +94,3 @@ def uniqueArray(arr):
if iPrinc!=iRest and namePrinc.lower() in nRest.lower(): if iPrinc!=iRest and namePrinc.lower() in nRest.lower():
del arr[iRest] del arr[iRest]
return arr return arr
def isValidLink(text):
if text.lower().startswith("http"):
if "deezer.com" in text.lower() or "open.spotify.com" in text.lower():
return True
elif text.lower().startswith("spotify:"):
return True
return False

View File

@ -3,8 +3,9 @@ from mutagen.flac import FLAC, Picture
from mutagen.id3 import ID3, ID3NoHeaderError, TXXX, TIT2, TPE1, TALB, TPE2, TRCK, TPOS, TCON, TYER, TDAT, TLEN, TBPM, \ from mutagen.id3 import ID3, ID3NoHeaderError, TXXX, TIT2, TPE1, TALB, TPE2, TRCK, TPOS, TCON, TYER, TDAT, TLEN, TBPM, \
TPUB, TSRC, USLT, APIC, IPLS, TCOM, TCOP, TCMP TPUB, TSRC, USLT, APIC, IPLS, TCOM, TCOP, TCMP
# Adds tags to a MP3 file
def tagID3(stream, track, save): def tagID3(stream, track, save):
# Delete exsisting tags
try: try:
tag = ID3(stream) tag = ID3(stream)
tag.delete() tag.delete()
@ -13,6 +14,7 @@ def tagID3(stream, track, save):
if save['title']: if save['title']:
tag.add(TIT2(text=track['title'])) tag.add(TIT2(text=track['title']))
if save['artist'] and len(track['artists']): if save['artist'] and len(track['artists']):
if save['multiArtistSeparator'] != "default": if save['multiArtistSeparator'] != "default":
if save['multiArtistSeparator'] == "nothing": if save['multiArtistSeparator'] == "nothing":
@ -22,13 +24,16 @@ def tagID3(stream, track, save):
tag.add(TXXX(desc="ARTISTS", text=track['artists'])) tag.add(TXXX(desc="ARTISTS", text=track['artists']))
else: else:
tag.add(TPE1(text=track['artists'])) tag.add(TPE1(text=track['artists']))
if save['album']: if save['album']:
tag.add(TALB(text=track['album']['title'])) tag.add(TALB(text=track['album']['title']))
if save['albumArtist'] and len(track['album']['artists']): if save['albumArtist'] and len(track['album']['artists']):
if save['singleAlbumArtist'] and track['album']['mainArtist']['save']: if save['singleAlbumArtist'] and track['album']['mainArtist']['save']:
tag.add(TPE2(text=track['album']['mainArtist']['name'])) tag.add(TPE2(text=track['album']['mainArtist']['name']))
else: else:
tag.add(TPE2(text=track['album']['artists'])) tag.add(TPE2(text=track['album']['artists']))
if save['trackNumber']: if save['trackNumber']:
tag.add(TRCK( tag.add(TRCK(
text=str(track['trackNumber']) + ("/" + str(track['album']['trackTotal']) if save['trackTotal'] else ""))) text=str(track['trackNumber']) + ("/" + str(track['album']['trackTotal']) if save['trackTotal'] else "")))
@ -57,6 +62,7 @@ def tagID3(stream, track, save):
tag.add(TXXX(desc="REPLAYGAIN_TRACK_GAIN", text=track['replayGain'])) tag.add(TXXX(desc="REPLAYGAIN_TRACK_GAIN", text=track['replayGain']))
if 'unsync' in track['lyrics'] and save['lyrics']: if 'unsync' in track['lyrics'] and save['lyrics']:
tag.add(USLT(text=track['lyrics']['unsync'])) tag.add(USLT(text=track['lyrics']['unsync']))
involved_people = [] involved_people = []
for role in track['contributors']: for role in track['contributors']:
if role in ['author', 'engineer', 'mixer', 'producer', 'writer']: if role in ['author', 'engineer', 'mixer', 'producer', 'writer']:
@ -66,10 +72,12 @@ def tagID3(stream, track, save):
tag.add(TCOM(text=track['contributors']['composer'])) tag.add(TCOM(text=track['contributors']['composer']))
if len(involved_people) > 0 and save['involvedPeople']: if len(involved_people) > 0 and save['involvedPeople']:
tag.add(IPLS(people=involved_people)) tag.add(IPLS(people=involved_people))
if save['copyright']: if save['copyright']:
tag.add(TCOP(text=track['copyright'])) tag.add(TCOP(text=track['copyright']))
if save['savePlaylistAsCompilation'] and "playlist" in track: if save['savePlaylistAsCompilation'] and "playlist" in track:
tag.add(TCMP(text="1")) tag.add(TCMP(text="1"))
if save['cover'] and track['album']['picPath']: if save['cover'] and track['album']['picPath']:
with open(track['album']['picPath'], 'rb') as f: with open(track['album']['picPath'], 'rb') as f:
tag.add( tag.add(
@ -78,13 +86,16 @@ def tagID3(stream, track, save):
tag.save(stream, v1=2 if save['saveID3v1'] else 0, v2_version=3, tag.save(stream, v1=2 if save['saveID3v1'] else 0, v2_version=3,
v23_sep=None if save['useNullSeparator'] else '/') v23_sep=None if save['useNullSeparator'] else '/')
# Adds tags to a FLAC file
def tagFLAC(stream, track, save): def tagFLAC(stream, track, save):
# Delete exsisting tags
tag = FLAC(stream) tag = FLAC(stream)
tag.delete() tag.delete()
tag.clear_pictures() tag.clear_pictures()
if save['title']: if save['title']:
tag["TITLE"] = track['title'] tag["TITLE"] = track['title']
if save['artist'] and len(track['artists']): if save['artist'] and len(track['artists']):
if save['multiArtistSeparator'] != "default": if save['multiArtistSeparator'] != "default":
if save['multiArtistSeparator'] == "nothing": if save['multiArtistSeparator'] == "nothing":
@ -94,13 +105,16 @@ def tagFLAC(stream, track, save):
tag["ARTISTS"] = track['artists'] tag["ARTISTS"] = track['artists']
else: else:
tag["ARTIST"] = track['artists'] tag["ARTIST"] = track['artists']
if save['album']: if save['album']:
tag["ALBUM"] = track['album']['title'] tag["ALBUM"] = track['album']['title']
if save['albumArtist'] and len(track['album']['artists']): if save['albumArtist'] and len(track['album']['artists']):
if save['singleAlbumArtist']: if save['singleAlbumArtist']:
tag["ALBUMARTIST"] = track['album']['mainArtist']['name'] tag["ALBUMARTIST"] = track['album']['mainArtist']['name']
else: else:
tag["ALBUMARTIST"] = track['album']['artists'] tag["ALBUMARTIST"] = track['album']['artists']
if save['trackNumber']: if save['trackNumber']:
tag["TRACKNUMBER"] = str(track['trackNumber']) tag["TRACKNUMBER"] = str(track['trackNumber'])
if save['trackTotal']: if save['trackTotal']:
@ -131,12 +145,14 @@ def tagFLAC(stream, track, save):
tag["REPLAYGAIN_TRACK_GAIN"] = track['replayGain'] tag["REPLAYGAIN_TRACK_GAIN"] = track['replayGain']
if 'unsync' in track['lyrics'] and save['lyrics']: if 'unsync' in track['lyrics'] and save['lyrics']:
tag["LYRICS"] = track['lyrics']['unsync'] tag["LYRICS"] = track['lyrics']['unsync']
for role in track['contributors']: for role in track['contributors']:
if role in ['author', 'engineer', 'mixer', 'producer', 'writer', 'composer']: if role in ['author', 'engineer', 'mixer', 'producer', 'writer', 'composer']:
if save['involvedPeople'] and role != 'composer' or role == 'composer' and save['composer']: if save['involvedPeople'] and role != 'composer' or role == 'composer' and save['composer']:
tag[role] = track['contributors'][role] tag[role] = track['contributors'][role]
elif role == 'musicpublisher' and save['involvedPeople']: elif role == 'musicpublisher' and save['involvedPeople']:
tag["ORGANIZATION"] = track['contributors']['musicpublisher'] tag["ORGANIZATION"] = track['contributors']['musicpublisher']
if save['copyright']: if save['copyright']:
tag["COPYRIGHT"] = track['copyright'] tag["COPYRIGHT"] = track['copyright']
if save['savePlaylistAsCompilation'] and "playlist" in track: if save['savePlaylistAsCompilation'] and "playlist" in track: