diff --git a/data/interfaces/default/config.html b/data/interfaces/default/config.html index 216e4eb6..3dfa2420 100644 --- a/data/interfaces/default/config.html +++ b/data/interfaces/default/config.html @@ -342,10 +342,15 @@ m<%inherit file="base.html"/>
- + e.g. /Users/name/Music/iTunes or /Volumes/share/music
+
+ + + Set this if you have a separate directory for lossless music +
@@ -379,8 +384,14 @@ m<%inherit file="base.html"/>
+
-
+
+
+
+ +
+ <% if config['encoder'] == 'lame': lameselect = 'selected="selected"' diff --git a/headphones/__init__.py b/headphones/__init__.py index e61cb103..2b938e02 100644 --- a/headphones/__init__.py +++ b/headphones/__init__.py @@ -84,6 +84,7 @@ CHECK_GITHUB_INTERVAL = None MUSIC_DIR = None DESTINATION_DIR = None +LOSSLESS_DESTINATION_DIR = None FOLDER_FORMAT = None FILE_FORMAT = None PATH_TO_XML = None @@ -165,6 +166,7 @@ ENCODEROUTPUTFORMAT = None ENCODERQUALITY = None ENCODERVBRCBR = None ENCODERLOSSLESS = False +DELETE_LOSSLESS_FILES = False PROWL_ENABLED = True PROWL_PRIORITY = 1 PROWL_KEYS = None @@ -238,7 +240,8 @@ def initialize(): global __INITIALIZED__, FULL_PATH, PROG_DIR, VERBOSE, DAEMON, DATA_DIR, CONFIG_FILE, CFG, CONFIG_VERSION, LOG_DIR, CACHE_DIR, \ HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTP_PROXY, LAUNCH_BROWSER, API_ENABLED, API_KEY, GIT_PATH, \ - CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, MUSIC_DIR, DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, \ + CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, MUSIC_DIR, DESTINATION_DIR, \ + LOSSLESS_DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, \ ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, \ ADD_ALBUM_ART, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \ TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, DOWNLOAD_TORRENT_DIR, \ @@ -246,7 +249,7 @@ def initialize(): NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS,\ NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, \ ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, \ - ENCODERLOSSLESS, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, MIRRORLIST, MIRROR, CUSTOMHOST, CUSTOMPORT, \ + ENCODERLOSSLESS, DELETE_LOSSLESS_FILES, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, MIRRORLIST, MIRROR, CUSTOMHOST, CUSTOMPORT, \ CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, XBMC_NOTIFY, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY, SYNOINDEX_ENABLED, \ ALBUM_COMPLETION_PCT @@ -295,6 +298,7 @@ def initialize(): MUSIC_DIR = check_setting_str(CFG, 'General', 'music_dir', '') DESTINATION_DIR = check_setting_str(CFG, 'General', 'destination_dir', '') + LOSSLESS_DESTINATION_DIR = check_setting_str(CFG, 'General', 'lossless_destination_dir', '') PREFERRED_QUALITY = check_setting_int(CFG, 'General', 'preferred_quality', 0) PREFERRED_BITRATE = check_setting_int(CFG, 'General', 'preferred_bitrate', '') DETECT_BITRATE = bool(check_setting_int(CFG, 'General', 'detect_bitrate', 0)) @@ -373,6 +377,7 @@ def initialize(): ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2) ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr', 'cbr') ENCODERLOSSLESS = bool(check_setting_int(CFG, 'General', 'encoderlossless', 1)) + DELETE_LOSSLESS_FILES = bool(check_setting_int(CFG, 'General', 'delete_lossless_files', 1)) PROWL_ENABLED = bool(check_setting_int(CFG, 'Prowl', 'prowl_enabled', 0)) PROWL_KEYS = check_setting_str(CFG, 'Prowl', 'prowl_keys', '') @@ -570,6 +575,7 @@ def config_write(): new_config['General']['music_dir'] = MUSIC_DIR new_config['General']['destination_dir'] = DESTINATION_DIR + new_config['General']['lossless_destination_dir'] = LOSSLESS_DESTINATION_DIR new_config['General']['preferred_quality'] = PREFERRED_QUALITY new_config['General']['preferred_bitrate'] = PREFERRED_BITRATE new_config['General']['detect_bitrate'] = int(DETECT_BITRATE) @@ -677,7 +683,8 @@ def config_write(): new_config['General']['encoderoutputformat'] = ENCODEROUTPUTFORMAT new_config['General']['encoderquality'] = ENCODERQUALITY new_config['General']['encodervbrcbr'] = ENCODERVBRCBR - new_config['General']['encoderlossless'] = ENCODERLOSSLESS + new_config['General']['encoderlossless'] = int(ENCODERLOSSLESS) + new_config['General']['delete_lossless_files'] = int(DELETE_LOSSLESS_FILES) new_config['General']['mirror'] = MIRROR new_config['General']['customhost'] = CUSTOMHOST diff --git a/headphones/helpers.py b/headphones/helpers.py index 1dbfbcda..7f5cbab9 100644 --- a/headphones/helpers.py +++ b/headphones/helpers.py @@ -13,10 +13,10 @@ # You should have received a copy of the GNU General Public License # along with Headphones. If not, see . -import time +import os, time from operator import itemgetter import datetime -import re +import re, shutil import headphones @@ -218,3 +218,35 @@ def extract_song_data(s): else: logger.info("Couldn't parse " + s + " into a valid Newbin format") return (name, album, year) + +def smartMove(src, dest, delete=True): + + source_dir = os.path.dirname(src) + filename = os.path.basename(src) + + if os.path.isfile(os.path.join(dest, filename)): + logger.info('Destination file exists: %s' % os.path.join(dest, filename).decode(headphones.SYS_ENCODING)) + title = os.path.splitext(filename)[0] + ext = os.path.splitext(filename)[1] + i = 1 + while True: + newfile = title + '(' + str(i) + ')' + ext + if os.path.isfile(os.path.join(dest, newfile)): + i += 1 + else: + logger.info('Renaming to %s' % newfile) + try: + os.rename(src, os.path.join(source_dir, newfile)) + filename = newfile + except Exception, e: + logger.warn('Error renaming %s: %s' % (src.decode(headphones.SYS_ENCODING), e)) + break + + try: + if delete: + shutil.move(os.path.join(source_dir, filename), os.path.join(dest, filename)) + else: + shutil.copy(os.path.join(source_dir, filename), os.path.join(dest, filename)) + return True + except Exception, e: + logger.warn('Error moving file %s: %s' % (filename.decode(headphones.SYS_ENCODING), e)) diff --git a/headphones/music_encoder.py b/headphones/music_encoder.py index 51864aa4..71da9ba5 100644 --- a/headphones/music_encoder.py +++ b/headphones/music_encoder.py @@ -138,7 +138,8 @@ def command(encoder,musicSource,musicDest,albumPath): time.sleep(10) return_code = call(cmd, shell=True) if (return_code==0) and (os.path.exists(musicDest)): - os.remove(musicSource) + if headphones.DELETE_LOSSLESS_FILES: + os.remove(musicSource) shutil.move(musicDest,albumPath) logger.info('Music "%s" encoded in %s' % (musicSource,getTimeEncode(startMusicTime))) diff --git a/headphones/postprocessor.py b/headphones/postprocessor.py index cd7fcadc..7959dd64 100644 --- a/headphones/postprocessor.py +++ b/headphones/postprocessor.py @@ -263,7 +263,7 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) renameFiles(albumpath, downloaded_track_list, release) if headphones.MOVE_FILES and headphones.DESTINATION_DIR: - albumpath = moveFiles(albumpath, release, tracks) + albumpaths = moveFiles(albumpath, release, tracks) if headphones.MOVE_FILES and not headphones.DESTINATION_DIR: logger.error('No DESTINATION_DIR has been set. Set "Destination Directory" to the parent directory you want to move the files to') @@ -273,8 +273,9 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) myDB.action('UPDATE albums SET status = "Downloaded" WHERE AlbumID=?', [albumid]) myDB.action('UPDATE snatched SET status = "Processed" WHERE AlbumID=?', [albumid]) - # Update the have tracks - librarysync.libraryScan(dir=albumpath, append=True, ArtistID=release['ArtistID'], ArtistName=release['ArtistName']) + # Update the have tracks for all created dirs: + for albumpath in albumpaths: + librarysync.libraryScan(dir=albumpath, append=True, ArtistID=release['ArtistID'], ArtistName=release['ArtistName']) logger.info('Post-processing for %s - %s complete' % (release['ArtistName'], release['AlbumTitle'])) @@ -297,7 +298,8 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) if headphones.SYNOINDEX_ENABLED: syno = notifiers.Synoindex() - syno.notify(albumpath) + for albumpath in albumpaths: + syno.notify(albumpath) def embedAlbumArt(artwork, downloaded_track_list): logger.info('Embedding album art') @@ -375,71 +377,138 @@ def moveFiles(albumpath, release, tracks): if folder.startswith('.'): folder = folder.replace(0, '_') + + # Grab our list of files early on so we can determine if we need to create + # the lossy_dest_dir, lossless_dest_dir, or both + files_to_move = [] + lossy_media = False + lossless_media = False - destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING) - - last_folder = headphones.FOLDER_FORMAT.split('/')[-1] - - # Only rename the folder if they use the album name, otherwise merge into existing folder - if os.path.exists(destination_path) and 'album' in last_folder.lower(): - i = 1 - while True: - newfolder = folder + '[%i]' % i - destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING) - if os.path.exists(destination_path): - i += 1 - else: - folder = newfolder - break - - logger.info('Moving files from %s to %s' % (unicode(albumpath, headphones.SYS_ENCODING, errors="replace"), unicode(destination_path, headphones.SYS_ENCODING, errors="replace"))) - - # Basically check if generic/non-album folders already exist, since we're going to merge - if not os.path.exists(destination_path): - try: - os.makedirs(destination_path) - except Exception, e: - logger.error('Could not create folder for %s. Not moving: %s' % (release['AlbumTitle'], e)) - return albumpath - - # Move files to the destination folder, renaming them if they already exist for r,d,f in os.walk(albumpath): for files in f: - if os.path.isfile(os.path.join(destination_path, files)): - logger.info('Destination file exists: %s' % os.path.join(destination_path, files)) - title = os.path.splitext(files)[0] - ext = os.path.splitext(files)[1] - i = 1 - while True: - newfile = title + '(' + str(i) + ')' + ext - if os.path.isfile(os.path.join(destination_path, newfile)): - i += 1 - else: - logger.info('Renaming to %s' % newfile) - try: - os.rename(os.path.join(r, files), os.path.join(r, newfile)) - files = newfile - except Exception, e: - logger.warn('Error renaming %s: %s' % (files, e)) - break + files_to_move.append(os.path.join(r, files)) + if any(files.lower.endswith(x) for x in headphones.LOSSY_MEDIA_FORMATS): + lossy_media = True + if any(files.lower.endswith(x) for x in headphones.LOSSLESS_MEDIA_FORMATS): + lossless_media = True + # Do some sanity checking to see what directories we need to create: + make_lossy_folder = False + make_lossless_folder = False + + lossy_destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING) + lossless_destination_path = os.path.normpath(os.path.join(headphones.LOSSLESS_DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING) + + # If they set a destination dir for lossless media, only create the lossy folder if there is lossy media + if headphones.LOSSLESS_DESTINATION_DIR: + if lossy_media: + make_lossy_folder = True + if lossless_media: + make_lossless_folder = True + # If they haven't set a lossless dest_dir, just create the "lossy" folder + else: + make_lossy_folder = True + + last_folder = headphones.FOLDER_FORMAT.split('/')[-1] + + if make_lossless_folder: + # Only rename the folder if they use the album name, otherwise merge into existing folder + if os.path.exists(lossless_destination_path) and 'album' in last_folder.lower(): + i = 1 + while True: + newfolder = folder + '[%i]' % i + lossless_destination_path = os.path.normpath(os.path.join(headphones.LOSSLESS_DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING) + if os.path.exists(destination_path): + i += 1 + else: + folder = newfolder + break + + if not os.path.exists(lossless_destination_path): try: - shutil.move(os.path.join(r, files), os.path.join(destination_path, files)) + os.makedirs(lossless_destination_path) except Exception, e: - logger.warn('Error moving file %s: %s' % (files, e)) + logger.error('Could not create lossless folder for %s. (Error: %s)' % (release['AlbumTitle'], e)) + if not make_lossy_folder: + return albumpath + if make_lossy_folder: + if os.path.exists(lossy_destination_path) and 'album' in last_folder.lower(): + i = 1 + while True: + newfolder = folder + '[%i]' % i + lossy_destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING) + if os.path.exists(lossy_destination_path): + i += 1 + else: + folder = newfolder + break + + if not os.path.exists(lossy_destination_path): + try: + os.makedirs(lossy_destination_path) + except Exception, e: + logger.error('Could not create folder for %s. Not moving: %s' % (release['AlbumTitle'], e)) + return albumpath + + logger.info('Checking which files we need to move.....') + + # Move files to the destination folder, renaming them if they already exist + # If we have two desination_dirs, move non-music files to both + if make_lossy_folder and make_lossless_folder: + + for file_to_move in files_to_move: + + if any(file_to_move.lower.endswith(x) for x in headphones.LOSSY_MEDIA_FORMATS): + helpers.smartMove(file_to_move, lossy_destination_path) + + elif any(files.lower.endswith(x) for x in headphones.LOSSLESS_MEDIA_FORMATS): + helpers.smartMove(file_to_move, lossless_destination_path) + + # If it's a non-music file, move it to both dirs + else: + + moved_to_lossy_folder = helpers.smartMove(file_to_move, lossy_destination_path, delete=False) + moved_to_lossless_folder = helpers.smartMove(file_to_move, lossless_destination_path, delete=False) + + if moved_to_lossy_folder or moved_to_lossless_folder: + try: + os.remove(file_to_move) + except Exception, e: + logger.error("Error deleting file '" + file_to_move.decode(headphones.SYS_ENCODING) + "' from source directory") + else: + logger.error("Error copying '" + file_to_move.decode(headphones.SYS_ENCODING) + "'. Not deleting from download directory") + + elif make_lossless_folder and not make_lossy_folder: + + for file_to_move in files_to_move: + helpers.smartMove(file_to_move, lossless_destination_path) + + else: + + for file_to_move in files_to_move: + helpers.smartMove(file_to_move, lossy_destination_path) + # Chmod the directories using the folder_format (script courtesy of premiso!) folder_list = folder.split('/') - temp_f = headphones.DESTINATION_DIR - - for f in folder_list: - - temp_f = os.path.join(temp_f, f) - - try: - os.chmod(os.path.normpath(temp_f).encode(headphones.SYS_ENCODING), int(headphones.FOLDER_PERMISSIONS, 8)) - except Exception, e: - logger.error("Error trying to change permissions on folder: %s" % temp_f) + temp_fs = [] + + if make_lossless_folder: + temp_fs.append(headphones.LOSSLESS_DESTINATION_DIR) + + if make_lossy_folder: + temp_fs.append(headphones.DESTINATION_DIR) + + for temp_f in temp_fs: + + for f in folder_list: + + temp_f = os.path.join(temp_f, f) + + try: + os.chmod(os.path.normpath(temp_f).encode(headphones.SYS_ENCODING), int(headphones.FOLDER_PERMISSIONS, 8)) + except Exception, e: + logger.error("Error trying to change permissions on folder: %s" % temp_f) # If we failed to move all the files out of the directory, this will fail too try: @@ -447,42 +516,68 @@ def moveFiles(albumpath, release, tracks): except Exception, e: logger.error('Could not remove directory: %s. %s' % (albumpath, e)) - return destination_path + destination_paths = [] + + if make_lossy_folder: + destination_paths.append(lossy_destination_path) + if make_lossless_folder: + destination_paths.append(lossless_destination_path) + + return destination_paths def correctMetadata(albumid, release, downloaded_track_list): - logger.info('Writing metadata') - items = [] + logger.info('Preparing to write metadata to tracks....') + lossy_items = [] + lossless_items = [] + + # Process lossless & lossy media formats separately for downloaded_track in downloaded_track_list: + + try: - try: - items.append(beets.library.Item.from_path(downloaded_track)) + if any(downloaded_track.lower().endswith('.' + x.lower()) for x in headphones.LOSSLESS_MEDIA_FORMATS): + lossless_items.append(beets.library.Item.from_path(downloaded_track)) + elif any(downloaded_track.lower().endswith('.' + x.lower()) for x in headphones.LOSSY_MEDIA_FORMATS): + lossy_items.append(beets.library.Item.from_path(downloaded_track)) + else: + logger.warn("Skipping: " + downloaded_track.decode(headphones.SYS_ENCODING) + " because it is not a mutagen friendly file format") except Exception, e: - logger.error("Beets couldn't create an Item from: " + downloaded_track + " - not a media file?" + str(e)) - - try: - cur_artist, cur_album, candidates, rec = autotag.tag_album(items, search_artist=helpers.latinToAscii(release['ArtistName']), search_album=helpers.latinToAscii(release['AlbumTitle'])) - except Exception, e: - logger.error('Error getting recommendation: %s. Not writing metadata' % e) - return - if rec == 'RECOMMEND_NONE': - logger.warn('No accurate album match found for %s, %s - not writing metadata' % (release['ArtistName'], release['AlbumTitle'])) - return - - dist, info, mapping, extra_items, extra_tracks = candidates[0] - logger.debug('Beets recommendation: %s' % rec) - autotag.apply_metadata(info, mapping) - - if len(items) != len(downloaded_track_list): - logger.warn("Mismatch between number of tracks downloaded and the metadata items, but I'll try to write it anyway") - - i = 1 - for item in items: + + logger.error("Beets couldn't create an Item from: " + downloaded_track.decode(headphones.SYS_ENCODING) + " - not a media file?" + str(e)) + + for items in [lossy_items, lossless_items]: + + if not items: + continue + try: - item.write() + cur_artist, cur_album, candidates, rec = autotag.tag_album(items, search_artist=helpers.latinToAscii(release['ArtistName']), search_album=helpers.latinToAscii(release['AlbumTitle'])) except Exception, e: - logger.warn('Error writing metadata to track %i: %s' % (i,e)) - i += 1 + logger.error('Error getting recommendation: %s. Not writing metadata' % e) + return + if rec == 'RECOMMEND_NONE': + logger.warn('No accurate album match found for %s, %s - not writing metadata' % (release['ArtistName'], release['AlbumTitle'])) + return + + if candidates: + dist, info, mapping, extra_items, extra_tracks = candidates[0] + else: + logger.warn('No accurate album match found for %s, %s - not writing metadata' % (release['ArtistName'], release['AlbumTitle'])) + return + + logger.info('Beets recommendation for tagging items: %s' % rec) + + # TODO: Handle extra_items & extra_tracks + + autotag.apply_metadata(info, mapping) + + for item in items: + try: + item.write() + logger.info("Successfully applied metadata to: " + item.path.decode(headphones.SYS_ENCODING)) + except Exception, e: + logger.warn("Error writing metadata to " + item.path.decode(headphones.SYS_ENCODING) + ": " + str(e)) def embedLyrics(downloaded_track_list): logger.info('Adding lyrics') diff --git a/headphones/webserve.py b/headphones/webserve.py index 2f88c041..d00c1f86 100644 --- a/headphones/webserve.py +++ b/headphones/webserve.py @@ -429,6 +429,7 @@ class WebInterface(object): "embed_album_art" : checked(headphones.EMBED_ALBUM_ART), "embed_lyrics" : checked(headphones.EMBED_LYRICS), "dest_dir" : headphones.DESTINATION_DIR, + "lossless_dest_dir" : headphones.LOSSLESS_DESTINATION_DIR, "folder_format" : headphones.FOLDER_FORMAT, "file_format" : headphones.FILE_FORMAT, "include_extras" : checked(headphones.INCLUDE_EXTRAS), @@ -446,6 +447,7 @@ class WebInterface(object): "encodervbrcbr": headphones.ENCODERVBRCBR, "encoderquality": headphones.ENCODERQUALITY, "encoderlossless": checked(headphones.ENCODERLOSSLESS), + "delete_lossless_files": checked(headphones.DELETE_LOSSLESS_FILES), "prowl_enabled": checked(headphones.PROWL_ENABLED), "prowl_onsnatch": checked(headphones.PROWL_ONSNATCH), "prowl_keys": headphones.PROWL_KEYS, @@ -477,8 +479,8 @@ class WebInterface(object): usenet_retention=None, nzbmatrix=0, nzbmatrix_username=None, nzbmatrix_apikey=None, newznab=0, newznab_host=None, newznab_apikey=None, newznab_enabled=0, nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, newzbin=0, newzbin_uid=None, newzbin_password=None, preferred_quality=0, preferred_bitrate=None, detect_bitrate=0, move_files=0, torrentblackhole_dir=None, download_torrent_dir=None, numberofseeders=10, use_isohunt=0, use_kat=0, use_mininova=0, waffles=0, waffles_uid=None, waffles_passkey=None, - rename_files=0, correct_metadata=0, cleanup_files=0, add_album_art=0, embed_album_art=0, embed_lyrics=0, destination_dir=None, folder_format=None, file_format=None, include_extras=0, autowant_upcoming=False, autowant_all=False, interface=None, log_dir=None, - music_encoder=0, encoder=None, bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0, + rename_files=0, correct_metadata=0, cleanup_files=0, add_album_art=0, embed_album_art=0, embed_lyrics=0, destination_dir=None, lossless_destination_dir=None, folder_format=None, file_format=None, include_extras=0, autowant_upcoming=False, autowant_all=False, interface=None, log_dir=None, + music_encoder=0, encoder=None, bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0, delete_lossless_files=0, prowl_enabled=0, prowl_onsnatch=0, prowl_keys=None, prowl_priority=0, xbmc_enabled=0, xbmc_host=None, xbmc_username=None, xbmc_password=None, xbmc_update=0, xbmc_notify=0, nma_enabled=False, nma_apikey=None, nma_priority=0, synoindex_enabled=False, mirror=None, customhost=None, customport=None, customsleep=None, hpuser=None, hppass=None, **kwargs): @@ -534,6 +536,7 @@ class WebInterface(object): headphones.EMBED_ALBUM_ART = embed_album_art headphones.EMBED_LYRICS = embed_lyrics headphones.DESTINATION_DIR = destination_dir + headphones.LOSSLESS_DESTINATION_DIR = lossless_destination_dir headphones.FOLDER_FORMAT = folder_format headphones.FILE_FORMAT = file_format headphones.INCLUDE_EXTRAS = include_extras @@ -550,7 +553,8 @@ class WebInterface(object): headphones.ENCODEROUTPUTFORMAT = encoderoutputformat headphones.ENCODERVBRCBR = encodervbrcbr headphones.ENCODERQUALITY = int(encoderquality) - headphones.ENCODERLOSSLESS = encoderlossless + headphones.ENCODERLOSSLESS = int(encoderlossless) + headphones.DELETE_LOSSLESS_FILES = int(delete_lossless_files) headphones.PROWL_ENABLED = prowl_enabled headphones.PROWL_ONSNATCH = prowl_onsnatch headphones.PROWL_KEYS = prowl_keys