def qbittorrent_add_file(self, data): host = headphones.CONFIG.QBITTORRENT_HOST if not host.startswith('http'): host = 'http://' + host if host.endswith('/'): host = host[:-1] if host.endswith('/gui'): host = host[:-4] base_url = host # self.session.auth = HTTPDigestAuth(headphones.CONFIG.QBITTORRENT_USERNAME, headphones.CONFIG.QBITTORRENT_PASSWORD) url = base_url + '/login' try: self.session.post(url, data={'username': headphones.CONFIG.QBITTORRENT_USERNAME, 'password': headphones.CONFIG.QBITTORRENT_PASSWORD}) except Exception as e: logger.exception('Error adding file to qbittorrent %s', e) return url = base_url + '/command/upload' args = {'savepath': headphones.CONFIG.DOWNLOAD_TORRENT_DIR} if headphones.CONFIG.QBITTORRENT_LABEL: args['category'] = headphones.CONFIG.QBITTORRENT_LABEL torrent_files = {'torrents': data} try: self.session.post(url, data=args, files=torrent_files) except Exception as e: logger.exception('Error adding file to qbittorrent %s', e)
def utorrent_add_file(self, data): host = headphones.CONFIG.UTORRENT_HOST if not host.startswith('http'): host = 'http://' + host if host.endswith('/'): host = host[:-1] if host.endswith('/gui'): host = host[:-4] base_url = host url = base_url + '/gui/' self.session.auth = (headphones.CONFIG.UTORRENT_USERNAME, headphones.CONFIG.UTORRENT_PASSWORD) try: r = self.session.get(url + 'token.html') except Exception as e: logger.error('Error getting token: %s', e) return if r.status_code == 401: logger.debug('Error reaching utorrent') return regex = re.search(r'.+>([^<]+)</div></html>', r.text) if regex is None: logger.debug('Error reading token') return self.session.params = {'token': regex.group(1)} files = {'torrent_file': ("", data)} try: self.session.post(url, params={'action': 'add-file'}, files=files) except Exception as e: logger.exception('Error adding file to utorrent %s', e)
def encode(albumPath): # Return if xld details not found if XLD: global xldProfile (xldProfile, xldFormat, xldBitrate) = getXldProfile.getXldProfile(headphones.XLDPROFILE) if not xldFormat: logger.error('Details for xld profile \'%s\' not found, files will not be re-encoded', xldProfile) return None tempDirEncode=os.path.join(albumPath,"temp") musicFiles=[] musicFinalFiles=[] musicTempFiles=[] encoder = "" # Create temporary directory, but remove the old one first. try: if os.path.exists(tempDirEncode): shutil.rmtree(tempDirEncode) time.sleep(1) os.mkdir(tempDirEncode) except Exception, e: logger.exception("Unable to create temporary directory") return None
def encode(albumPath): # Return if xld details not found if XLD: global xldProfile (xldProfile, xldFormat, xldBitrate) = getXldProfile.getXldProfile(headphones.XLDPROFILE) if not xldFormat: logger.error( 'Details for xld profile \'%s\' not found, files will not be re-encoded', xldProfile) return None tempDirEncode = os.path.join(albumPath, "temp") musicFiles = [] musicFinalFiles = [] musicTempFiles = [] encoder = "" # Create temporary directory, but remove the old one first. try: if os.path.exists(tempDirEncode): shutil.rmtree(tempDirEncode) time.sleep(1) os.mkdir(tempDirEncode) except Exception, e: logger.exception("Unable to create temporary directory") return None
def realdebrid_add_file(self, data): host = "https://api.real-debrid.com/rest/1.0" apikey = headphones.CONFIG.REALDEBRID_APIKEY url = host + "/torrents/addTorrent?auth_token=" + apikey try: self.session.post(url, data) except Exception as e: logger.exception('Error adding file to utorrent %s', e)
def command_map(args): """ This method is used for the multiprocessing.map() method as a wrapper. """ try: return command(*args) except Exception, e: logger.exception("Encoder exception, will return failed") return False
def command_map(args): """ Wrapper for the '[multiprocessing.]map()' method, to unpack the arguments and wrap exceptions. """ # Initialize multiprocessing logger if multiprocessing.current_process().name != "MainProcess": logger.initMultiprocessing() # Start encoding try: return command(*args) except Exception: logger.exception("Encoder raised an exception.") return False
def utorrent_add_file(self, filename): host = headphones.UTORRENT_HOST if not host.startswith('http'): host = 'http://' + host if host.endswith('/'): host = host[:-1] if host.endswith('/gui'): host = host[:-4] base_url = host username = headphones.UTORRENT_USERNAME password = headphones.UTORRENT_PASSWORD session = requests.Session() url = base_url + '/gui/' session.auth = (username, password) try: r = session.get(url + 'token.html') except Exception: logger.exception('Error getting token') return if r.status_code == '401': logger.debug('Error reaching utorrent') return regex = re.search(r'.+>([^<]+)</div></html>', r.text) if regex is None: logger.debug('Error reading token') return session.params = {'token': regex.group(1)} with open(filename, 'rb') as f: try: session.post(url, params={'action': 'add-file'}, files={'torrent_file': f}) except Exception: logger.exception('Error adding file to utorrent') return
def initialize(config_file): with INIT_LOCK: global CONFIG global SOFT_CHROOT global _INITIALIZED global CURRENT_VERSION global LATEST_VERSION global UMASK CONFIG = headphones.config.Config(config_file) assert CONFIG is not None if _INITIALIZED: return False if CONFIG.HTTP_PORT < 21 or CONFIG.HTTP_PORT > 65535: headphones.logger.warn( 'HTTP_PORT out of bounds: 21 < %s < 65535', CONFIG.HTTP_PORT) CONFIG.HTTP_PORT = 8181 if CONFIG.HTTPS_CERT == '': CONFIG.HTTPS_CERT = os.path.join(DATA_DIR, 'server.crt') if CONFIG.HTTPS_KEY == '': CONFIG.HTTPS_KEY = os.path.join(DATA_DIR, 'server.key') if not CONFIG.LOG_DIR: CONFIG.LOG_DIR = os.path.join(DATA_DIR, 'logs') if not os.path.exists(CONFIG.LOG_DIR): try: os.makedirs(CONFIG.LOG_DIR) except OSError: CONFIG.LOG_DIR = None if not QUIET: sys.stderr.write("Unable to create the log directory. " "Logging to screen only.\n") # Start the logger, disable console if needed logger.initLogger(console=not QUIET, log_dir=CONFIG.LOG_DIR, verbose=VERBOSE) try: SOFT_CHROOT = SoftChroot(str(CONFIG.SOFT_CHROOT)) if SOFT_CHROOT.isEnabled(): logger.info("Soft-chroot enabled for dir: %s", str(CONFIG.SOFT_CHROOT)) except headphones.exceptions.SoftChrootError as e: logger.error("SoftChroot error: %s", e) raise e if not CONFIG.CACHE_DIR: # Put the cache dir in the data dir for now CONFIG.CACHE_DIR = os.path.join(DATA_DIR, 'cache') if not os.path.exists(CONFIG.CACHE_DIR): try: os.makedirs(CONFIG.CACHE_DIR) except OSError as e: logger.error("Could not create cache dir '%s': %s", DATA_DIR, e) # Sanity check for search interval. Set it to at least 6 hours if CONFIG.SEARCH_INTERVAL and CONFIG.SEARCH_INTERVAL < 360: logger.info("Search interval too low. Resetting to 6 hour minimum.") CONFIG.SEARCH_INTERVAL = 360 # Initialize the database logger.info('Checking to see if the database has all tables....') try: dbcheck() except Exception as e: logger.error("Can't connect to the database: %s", e) # Get the currently installed version. Returns None, 'win32' or the git # hash. CURRENT_VERSION, CONFIG.GIT_BRANCH = versioncheck.getVersion() # Write current version to a file, so we know which version did work. # This allowes one to restore to that version. The idea is that if we # arrive here, most parts of Headphones seem to work. if CURRENT_VERSION: version_lock_file = os.path.join(DATA_DIR, "version.lock") try: with open(version_lock_file, "w") as fp: fp.write(CURRENT_VERSION) except IOError as e: logger.error("Unable to write current version to file '%s': %s", version_lock_file, e) # Check for new versions if CONFIG.CHECK_GITHUB and CONFIG.CHECK_GITHUB_ON_STARTUP: try: LATEST_VERSION = versioncheck.checkGithub() except: logger.exception("Unhandled exception") LATEST_VERSION = CURRENT_VERSION else: LATEST_VERSION = CURRENT_VERSION # Store the original umask UMASK = os.umask(0) os.umask(UMASK) _INITIALIZED = True return True
def encode(albumPath): use_xld = headphones.CONFIG.ENCODER == 'xld' # Return if xld details not found if use_xld: (xldProfile, xldFormat, xldBitrate) = getXldProfile.getXldProfile( headphones.CONFIG.XLDPROFILE) if not xldFormat: logger.error('Details for xld profile \'%s\' not found, files will not be re-encoded', xldProfile) return None else: xldProfile = None tempDirEncode = os.path.join(albumPath, "temp") musicFiles = [] musicFinalFiles = [] musicTempFiles = [] encoder = "" # Create temporary directory, but remove the old one first. try: if os.path.exists(tempDirEncode): shutil.rmtree(tempDirEncode) time.sleep(1) os.mkdir(tempDirEncode) except Exception as e: logger.exception("Unable to create temporary directory") return None for r, d, f in os.walk(albumPath): for music in f: if any(music.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS): if not use_xld: encoderFormat = headphones.CONFIG.ENCODEROUTPUTFORMAT.encode( headphones.SYS_ENCODING) else: xldMusicFile = os.path.join(r, music) xldInfoMusic = MediaFile(xldMusicFile) encoderFormat = xldFormat if headphones.CONFIG.ENCODERLOSSLESS: ext = os.path.normpath(os.path.splitext(music)[1].lstrip(".")).lower() if not use_xld and ext == 'flac' or use_xld and ( ext != xldFormat and (xldInfoMusic.bitrate / 1000 > 400)): musicFiles.append(os.path.join(r, music)) musicTemp = os.path.normpath( os.path.splitext(music)[0] + '.' + encoderFormat) musicTempFiles.append(os.path.join(tempDirEncode, musicTemp)) else: logger.debug('%s is already encoded', music) else: musicFiles.append(os.path.join(r, music)) musicTemp = os.path.normpath(os.path.splitext(music)[0] + '.' + encoderFormat) musicTempFiles.append(os.path.join(tempDirEncode, musicTemp)) if headphones.CONFIG.ENCODER_PATH: encoder = headphones.CONFIG.ENCODER_PATH.encode(headphones.SYS_ENCODING) else: if use_xld: encoder = os.path.join('/Applications', 'xld') elif headphones.CONFIG.ENCODER == 'lame': if headphones.SYS_PLATFORM == "win32": # NEED THE DEFAULT LAME INSTALL ON WIN! encoder = "C:/Program Files/lame/lame.exe" else: encoder = "lame" elif headphones.CONFIG.ENCODER == 'ffmpeg': if headphones.SYS_PLATFORM == "win32": encoder = "C:/Program Files/ffmpeg/bin/ffmpeg.exe" else: encoder = "ffmpeg" elif headphones.CONFIG.ENCODER == 'libav': if headphones.SYS_PLATFORM == "win32": encoder = "C:/Program Files/libav/bin/avconv.exe" else: encoder = "avconv" i = 0 encoder_failed = False jobs = [] for music in musicFiles: infoMusic = MediaFile(music) encode = False if use_xld: if xldBitrate and (infoMusic.bitrate / 1000 <= xldBitrate): logger.info('%s has bitrate <= %skb, will not be re-encoded', music.decode(headphones.SYS_ENCODING, 'replace'), xldBitrate) else: encode = True elif headphones.CONFIG.ENCODER == 'lame': if not any( music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.' + x) for x in ["mp3", "wav"]): logger.warn('Lame cannot encode %s format for %s, use ffmpeg', os.path.splitext(music)[1], music) else: if music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.mp3') and ( int(infoMusic.bitrate / 1000) <= headphones.CONFIG.BITRATE): logger.info('%s has bitrate <= %skb, will not be re-encoded', music, headphones.CONFIG.BITRATE) else: encode = True else: if headphones.CONFIG.ENCODEROUTPUTFORMAT == 'ogg': if music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.ogg'): logger.warn('Cannot re-encode .ogg %s', music.decode(headphones.SYS_ENCODING, 'replace')) else: encode = True else: if music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.' + headphones.CONFIG.ENCODEROUTPUTFORMAT) and (int(infoMusic.bitrate / 1000) <= headphones.CONFIG.BITRATE): logger.info('%s has bitrate <= %skb, will not be re-encoded', music, headphones.CONFIG.BITRATE) else: encode = True # encode if encode: job = (encoder, music, musicTempFiles[i], albumPath, xldProfile) jobs.append(job) else: musicFiles[i] = None musicTempFiles[i] = None i = i + 1 # Encode music files if len(jobs) > 0: processes = 1 # Use multicore if enabled if headphones.CONFIG.ENCODER_MULTICORE: if headphones.CONFIG.ENCODER_MULTICORE_COUNT == 0: processes = multiprocessing.cpu_count() else: processes = headphones.CONFIG.ENCODER_MULTICORE_COUNT logger.debug("Multi-core encoding enabled, spawning %d processes", processes) # Use multiprocessing only if it's worth the overhead. and if it is # enabled. If not, then use the old fashioned way. if processes > 1: with logger.listener(): pool = multiprocessing.Pool(processes=processes) results = pool.map_async(command_map, jobs) # No new processes will be created, so close it and wait for all # processes to finish pool.close() pool.join() # Retrieve the results results = results.get() else: results = map(command_map, jobs) # The results are either True or False, so determine if one is False encoder_failed = not all(results) musicFiles = filter(None, musicFiles) musicTempFiles = filter(None, musicTempFiles) # check all files to be encoded now exist in temp directory if not encoder_failed and musicTempFiles: for dest in musicTempFiles: if not os.path.exists(dest): encoder_failed = True logger.error("Encoded file '%s' does not exist in the destination temp directory", dest) # No errors, move from temp to parent if not encoder_failed and musicTempFiles: i = 0 for dest in musicTempFiles: if os.path.exists(dest): source = musicFiles[i] if headphones.CONFIG.DELETE_LOSSLESS_FILES: os.remove(source) check_dest = os.path.join(albumPath, os.path.split(dest)[1]) if os.path.exists(check_dest): os.remove(check_dest) try: shutil.move(dest, albumPath) except Exception as e: logger.error('Could not move %s to %s: %s', dest, albumPath, e) encoder_failed = True break i += 1 # remove temp directory shutil.rmtree(tempDirEncode) # Return with error if any encoding errors if encoder_failed: logger.error( "One or more files failed to encode. Ensure you have the latest version of %s installed.", headphones.CONFIG.ENCODER) return None time.sleep(1) for r, d, f in os.walk(albumPath): for music in f: if any(music.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS): musicFinalFiles.append(os.path.join(r, music)) if not musicTempFiles: logger.info('Encoding for folder \'%s\' is not required', albumPath) return musicFinalFiles
def initialize(config_file): with INIT_LOCK: global CONFIG global SOFT_CHROOT global _INITIALIZED global CURRENT_VERSION global LATEST_VERSION global UMASK CONFIG = headphones.config.Config(config_file) assert CONFIG is not None if _INITIALIZED: return False if CONFIG.HTTP_PORT < 21 or CONFIG.HTTP_PORT > 65535: headphones.logger.warn('HTTP_PORT out of bounds: 21 < %s < 65535', CONFIG.HTTP_PORT) CONFIG.HTTP_PORT = 8181 if CONFIG.HTTPS_CERT == '': CONFIG.HTTPS_CERT = os.path.join(DATA_DIR, 'server.crt') if CONFIG.HTTPS_KEY == '': CONFIG.HTTPS_KEY = os.path.join(DATA_DIR, 'server.key') if not CONFIG.LOG_DIR: CONFIG.LOG_DIR = os.path.join(DATA_DIR, 'logs') if not os.path.exists(CONFIG.LOG_DIR): try: os.makedirs(CONFIG.LOG_DIR) except OSError: CONFIG.LOG_DIR = None if not QUIET: sys.stderr.write("Unable to create the log directory. " "Logging to screen only.\n") # Start the logger, disable console if needed logger.initLogger(console=not QUIET, log_dir=CONFIG.LOG_DIR, verbose=VERBOSE) try: SOFT_CHROOT = SoftChroot(str(CONFIG.SOFT_CHROOT)) if SOFT_CHROOT.isEnabled(): logger.info("Soft-chroot enabled for dir: %s", str(CONFIG.SOFT_CHROOT)) except headphones.exceptions.SoftChrootError as e: logger.error("SoftChroot error: %s", e) raise e if not CONFIG.CACHE_DIR: # Put the cache dir in the data dir for now CONFIG.CACHE_DIR = os.path.join(DATA_DIR, 'cache') if not os.path.exists(CONFIG.CACHE_DIR): try: os.makedirs(CONFIG.CACHE_DIR) except OSError as e: logger.error("Could not create cache dir '%s': %s", DATA_DIR, e) # Sanity check for search interval. Set it to at least 6 hours if CONFIG.SEARCH_INTERVAL and CONFIG.SEARCH_INTERVAL < 360: logger.info( "Search interval too low. Resetting to 6 hour minimum.") CONFIG.SEARCH_INTERVAL = 360 # Initialize the database logger.info('Checking to see if the database has all tables....') try: dbcheck() except Exception as e: logger.error("Can't connect to the database: %s", e) # Get the currently installed version. Returns None, 'win32' or the git # hash. CURRENT_VERSION, CONFIG.GIT_BRANCH = versioncheck.getVersion() # Write current version to a file, so we know which version did work. # This allowes one to restore to that version. The idea is that if we # arrive here, most parts of Headphones seem to work. if CURRENT_VERSION: version_lock_file = os.path.join(DATA_DIR, "version.lock") try: with open(version_lock_file, "w") as fp: fp.write(CURRENT_VERSION) except IOError as e: logger.error( "Unable to write current version to file '%s': %s", version_lock_file, e) # Check for new versions if CONFIG.CHECK_GITHUB and CONFIG.CHECK_GITHUB_ON_STARTUP: try: LATEST_VERSION = versioncheck.checkGithub() except: logger.exception("Unhandled exception") LATEST_VERSION = CURRENT_VERSION else: LATEST_VERSION = CURRENT_VERSION # Store the original umask UMASK = os.umask(0) os.umask(UMASK) _INITIALIZED = True return True
def encode(albumPath): use_xld = headphones.CONFIG.ENCODER == 'xld' # Return if xld details not found if use_xld: (xldProfile, xldFormat, xldBitrate) = getXldProfile.getXldProfile(headphones.CONFIG.XLDPROFILE) if not xldFormat: logger.error('Details for xld profile \'%s\' not found, files will not be re-encoded', xldProfile) return None else: xldProfile = None tempDirEncode = os.path.join(albumPath, "temp") musicFiles = [] musicFinalFiles = [] musicTempFiles = [] encoder = "" # Create temporary directory, but remove the old one first. try: if os.path.exists(tempDirEncode): shutil.rmtree(tempDirEncode) time.sleep(1) os.mkdir(tempDirEncode) except Exception as e: logger.exception("Unable to create temporary directory") return None for r, d, f in os.walk(albumPath): for music in f: if any(music.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS): if not use_xld: encoderFormat = headphones.CONFIG.ENCODEROUTPUTFORMAT.encode(headphones.SYS_ENCODING) else: xldMusicFile = os.path.join(r, music) xldInfoMusic = MediaFile(xldMusicFile) encoderFormat = xldFormat if headphones.CONFIG.ENCODERLOSSLESS: ext = os.path.normpath(os.path.splitext(music)[1].lstrip(".")).lower() if not use_xld and ext == 'flac' or use_xld and (ext != xldFormat and (xldInfoMusic.bitrate / 1000 > 400)): musicFiles.append(os.path.join(r, music)) musicTemp = os.path.normpath(os.path.splitext(music)[0] + '.' + encoderFormat) musicTempFiles.append(os.path.join(tempDirEncode, musicTemp)) else: logger.debug('%s is already encoded', music) else: musicFiles.append(os.path.join(r, music)) musicTemp = os.path.normpath(os.path.splitext(music)[0] + '.' + encoderFormat) musicTempFiles.append(os.path.join(tempDirEncode, musicTemp)) if headphones.CONFIG.ENCODER_PATH: encoder = headphones.CONFIG.ENCODER_PATH.encode(headphones.SYS_ENCODING) else: if use_xld: encoder = os.path.join('/Applications', 'xld') elif headphones.CONFIG.ENCODER == 'lame': if headphones.SYS_PLATFORM == "win32": ## NEED THE DEFAULT LAME INSTALL ON WIN! encoder = "C:/Program Files/lame/lame.exe" else: encoder = "lame" elif headphones.CONFIG.ENCODER == 'ffmpeg': if headphones.SYS_PLATFORM == "win32": encoder = "C:/Program Files/ffmpeg/bin/ffmpeg.exe" else: encoder = "ffmpeg" elif headphones.CONFIG.ENCODER == 'libav': if headphones.SYS_PLATFORM == "win32": encoder = "C:/Program Files/libav/bin/avconv.exe" else: encoder = "avconv" i = 0 encoder_failed = False jobs = [] for music in musicFiles: infoMusic = MediaFile(music) encode = False if use_xld: if xldBitrate and (infoMusic.bitrate / 1000 <= xldBitrate): logger.info('%s has bitrate <= %skb, will not be re-encoded', music.decode(headphones.SYS_ENCODING, 'replace'), xldBitrate) else: encode = True elif headphones.CONFIG.ENCODER == 'lame': if not any(music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.' + x) for x in ["mp3", "wav"]): logger.warn('Lame cannot encode %s format for %s, use ffmpeg', os.path.splitext(music)[1], music) else: if music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.mp3') and (int(infoMusic.bitrate / 1000) <= headphones.CONFIG.BITRATE): logger.info('%s has bitrate <= %skb, will not be re-encoded', music, headphones.CONFIG.BITRATE) else: encode = True else: if headphones.CONFIG.ENCODEROUTPUTFORMAT == 'ogg': if music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.ogg'): logger.warn('Cannot re-encode .ogg %s', music.decode(headphones.SYS_ENCODING, 'replace')) else: encode = True elif headphones.CONFIG.ENCODEROUTPUTFORMAT == 'mp3' or headphones.CONFIG.ENCODEROUTPUTFORMAT == 'm4a': if music.decode(headphones.SYS_ENCODING, 'replace').lower().endswith('.' + headphones.CONFIG.ENCODEROUTPUTFORMAT) and (int(infoMusic.bitrate / 1000) <= headphones.CONFIG.BITRATE): logger.info('%s has bitrate <= %skb, will not be re-encoded', music, headphones.CONFIG.BITRATE) else: encode = True # encode if encode: job = (encoder, music, musicTempFiles[i], albumPath, xldProfile) jobs.append(job) else: musicFiles[i] = None musicTempFiles[i] = None i = i + 1 # Encode music files if len(jobs) > 0: processes = 1 # Use multicore if enabled if headphones.CONFIG.ENCODER_MULTICORE: if headphones.CONFIG.ENCODER_MULTICORE_COUNT == 0: processes = multiprocessing.cpu_count() else: processes = headphones.CONFIG.ENCODER_MULTICORE_COUNT logger.debug("Multi-core encoding enabled, spawning %d processes", processes) # Use multiprocessing only if it's worth the overhead. and if it is # enabled. If not, then use the old fashioned way. if processes > 1: with logger.listener(): pool = multiprocessing.Pool(processes=processes) results = pool.map_async(command_map, jobs) # No new processes will be created, so close it and wait for all # processes to finish pool.close() pool.join() # Retrieve the results results = results.get() else: results = map(command_map, jobs) # The results are either True or False, so determine if one is False encoder_failed = not all(results) musicFiles = filter(None, musicFiles) musicTempFiles = filter(None, musicTempFiles) # check all files to be encoded now exist in temp directory if not encoder_failed and musicTempFiles: for dest in musicTempFiles: if not os.path.exists(dest): encoder_failed = True logger.error("Encoded file '%s' does not exist in the destination temp directory", dest) # No errors, move from temp to parent if not encoder_failed and musicTempFiles: i = 0 for dest in musicTempFiles: if os.path.exists(dest): source = musicFiles[i] if headphones.CONFIG.DELETE_LOSSLESS_FILES: os.remove(source) check_dest = os.path.join(albumPath, os.path.split(dest)[1]) if os.path.exists(check_dest): os.remove(check_dest) try: shutil.move(dest, albumPath) except Exception as e: logger.error('Could not move %s to %s: %s', dest, albumPath, e) encoder_failed = True break i += 1 # remove temp directory shutil.rmtree(tempDirEncode) # Return with error if any encoding errors if encoder_failed: logger.error("One or more files failed to encode. Ensure you have the latest version of %s installed.", headphones.CONFIG.ENCODER) return None time.sleep(1) for r, d, f in os.walk(albumPath): for music in f: if any(music.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS): musicFinalFiles.append(os.path.join(r, music)) if not musicTempFiles: logger.info('Encoding for folder \'%s\' is not required', albumPath) return musicFinalFiles