def remove_read_only(path): if not os.path.isdir(path): return for dirpath, dirnames, filenames in os.walk(path): for filename in filenames: logger.debug("Removing Read Only Flag for: %s" % (filename)) os.chmod(os.path.join(dirpath, filename), stat.S_IWRITE)
def extract_subs(file, newfilePath, bitbucket): video_details = getVideoDetails(file) if not video_details: return subStreams = [item for item in video_details["streams"] if item["codec_type"] == "subtitle"] if nzbtomedia.SUBSDIR: subdir = nzbtomedia.SUBSDIR else: subdir = os.path.split(newfilePath)[0] name = os.path.splitext(os.path.split(newfilePath)[1])[0] for n in range(len(subStreams)): sub = subStreams[n] lan = sub["tags"]["language"] outputFile = os.path.join(subdir, "%s(%s).srt" %(name, lan)) if os.path.isfile(outputFile): outputFile = os.path.join(subdir, "%s(%s)%s.srt" %(name, n, lan)) command = [nzbtomedia.FFMPEG, '-loglevel', 'warning', '-i', sub, '-vn', '-an', '-codec:s:' + str(n), 'srt', outputFile] if platform.system() != 'Windows': command = ['nice', '-%d' % nzbtomedia.NICENESS] + command logger.info("Extracting %s Subtitle from: %s" % (lan, file)) cmd = "" for item in command: cmd = cmd + " " + item logger.debug("calling command:%s" % (cmd)) result = 1 # set result to failed in case call fails. try: result = call(command, stdout=bitbucket, stderr=bitbucket) except: logger.error("Extracting subtitles has failed") if result == 0: logger.info("Extracting %s Subtitle from %s has succeeded" % (lan, file)) else: logger.error("Extracting subtitles has failed")
def find_download(clientAgent, download_id): logger.debug("Searching for Download on %s ..." % (clientAgent)) if clientAgent == 'utorrent': torrents = nzbtomedia.TORRENT_CLASS.list()[1]['torrents'] for torrent in torrents: if download_id in torrent: return True if clientAgent == 'transmission': torrents = nzbtomedia.TORRENT_CLASS.get_torrents() for torrent in torrents: hash = torrent.hashString if hash == download_id: return True if clientAgent == 'deluge': return False if clientAgent == 'sabnzbd': baseURL = "http://%s:%s/api" % (nzbtomedia.SABNZBDHOST, nzbtomedia.SABNZBDPORT) url = baseURL params = {} params['apikey'] = nzbtomedia.SABNZBDAPIKEY params['mode'] = "get_files" params['output'] = 'json' params['value'] = download_id try: r = requests.get(url, params=params, verify=False) except requests.ConnectionError: logger.error("Unable to open URL") return False # failure result = r.json() if result['files']: return True return False
def Transcode_directory(dirName): if platform.system() == 'Windows': bitbucket = open('NUL') else: bitbucket = open('/dev/null') if not nzbtomedia.FFMPEG: return 1 logger.info("Checking for files to be transcoded") final_result = 0 # initialize as successful if nzbtomedia.OUTPUTVIDEOPATH: newDir = nzbtomedia.OUTPUTVIDEOPATH makeDir(newDir) else: newDir = dirName for file in nzbtomedia.listMediaFiles(dirName, media=True, audio=False, meta=False, archives=False): if os.path.splitext(file)[1] in nzbtomedia.IGNOREEXTENSIONS: continue command = buildCommands(file, newDir) newfilePath = command[-1] try: # Try to remove the file that we're transcoding to just in case. (ffmpeg will return an error if it already exists for some reason) os.remove(newfilePath) except OSError, e: if e.errno != errno.ENOENT: # Ignore the error if it's just telling us that the file doesn't exist logger.debug("Error when removing transcoding target: %s" % (e)) except Exception, e: logger.debug("Error when removing transcoding target: %s" % (e))
def reverse_filename(filename, dirname, name): head, fileExtension = os.path.splitext(os.path.basename(filename)) na_parts = season_pattern.search(head) if na_parts is not None: word_p = word_pattern.findall(na_parts.group(2)) if word_p: new_words = "" for wp in word_p: if wp[0] == ".": new_words += "." new_words += re.sub(r"\W","",wp) else: new_words = na_parts.group(2) for cr in char_replace: new_words = re.sub(cr[0],cr[1],new_words) newname = new_words[::-1] + na_parts.group(1)[::-1] else: newname = head[::-1].title() newname = newname.replace(' ', '.') logger.debug("Reversing filename %s to %s" % (head, newname), "EXCEPTION") newfile = newname + fileExtension newfilePath = os.path.join(dirname, newfile) try: os.rename(filename, newfilePath) except Exception,e: logger.error("Unable to rename file due to: %s" % (str(e)), "EXCEPTION")
def get_nzoid(inputName): nzoid = None logger.debug("Searching for nzoid from SAbnzbd ...") baseURL = "http://%s:%s/api" % (nzbtomedia.SABNZBDHOST, nzbtomedia.SABNZBDPORT) url = baseURL params = {} params['apikey'] = nzbtomedia.SABNZBDAPIKEY params['mode'] = "queue" params['output'] = 'json' try: r = requests.get(url, params=params, verify=False) except requests.ConnectionError: logger.error("Unable to open URL") return nzoid # failure try: result = r.json() cleanName = os.path.splitext(os.path.split(inputName)[1])[0] for slot in result['queue']['slots']: if slot['filename'] in [inputName, cleanName]: nzoid = slot['nzo_id'] logger.debug("Found nzoid: %s" % nzoid) break except: logger.warning("Data from SABnzbd could not be parsed") return nzoid
def rename_script(dirname): rename_file = "" for dir, dirs, files in os.walk(dirname): for file in files: if re.search('(rename\S*\.(sh|bat))', file): rename_file = os.path.join(dir, file) dirname = dir break if rename_file: rename_lines = [line.strip() for line in open(rename_file)] for line in rename_lines: cmd = filter(None, re.split('mv|Move\s(\S*)\s(\S*)', line)) if len(cmd) == 2 and os.path.isfile(os.path.join(dirname, cmd[0])): orig = os.path.join(dirname, cmd[0]) dest = os.path.join(dirname, cmd[1].split('\\')[-1].split('/')[-1]) if os.path.isfile(dest): continue logger.debug("Renaming file %s to %s" % (orig, dest), "EXCEPTION") try: os.rename(orig, dest) except Exception, e: logger.error("Unable to rename file due to: %s" % (str(e)), "EXCEPTION")
def processEpisode(self, dirName, nzbName=None, status=0, clientAgent='manual', inputCategory=None): # auto-detect correct section section = nzbtomedia.CFG.findsection(inputCategory) if not section: logger.error( "We were unable to find a section for category %s, please check your autoProcessMedia.cfg file." % inputCategory) return 1 host = nzbtomedia.CFG[section][inputCategory]["host"] port = nzbtomedia.CFG[section][inputCategory]["port"] username = nzbtomedia.CFG[section][inputCategory]["username"] password = nzbtomedia.CFG[section][inputCategory]["password"] try: ssl = int(nzbtomedia.CFG[section][inputCategory]["ssl"]) except: ssl = 0 try: web_root = nzbtomedia.CFG[section][inputCategory]["web_root"] except: web_root = "" try: remote_path = nzbtomedia.CFG[section][inputCategory]["remote_path"] except: remote_path = None nzbName, dirName = convert_to_ascii(nzbName, dirName) params = {} params['nzb_folder'] = dirName if remote_path: dirName_new = os.path.join(remote_path, os.path.basename(dirName)).replace("\\", "/") params['nzb_folder'] = dirName_new if nzbName != None: params['nzb_name'] = nzbName if ssl: protocol = "https://" else: protocol = "http://" url = "%s%s:%s%s/post_process" % (protocol, host, port, web_root) logger.debug("Opening URL: %s" % (url), section) try: r = requests.get(url, params=params, auth=(username, password), stream=True) except requests.ConnectionError: logger.error("Unable to open URL", section) return 1 # failure for line in r.iter_lines(): if line: logger.postprocess("%s" % (line), section) time.sleep(60) #wait 1 minute for now... need to see just what gets logged and how long it takes to process return 0 # Success
def rename_file(filename, newfilePath): logger.debug( "Replacing file name %s with download name %s" % (filename, newfilePath), "EXCEPTION") try: os.rename(filename, newfilePath) except Exception, e: logger.error("Unable to rename file due to: %s" % (str(e)), "EXCEPTION")
def pause_torrent(clientAgent, TorrentClass, inputHash, inputID, inputName): # if we are using links with Torrents it means we need to pause it in order to access the files logger.debug("Stoping torrent %s in %s while processing" % (inputName, clientAgent)) if clientAgent == 'utorrent' and TorrentClass != "": TorrentClass.stop(inputHash) if clientAgent == 'transmission' and TorrentClass != "": TorrentClass.stop_torrent(inputID) if clientAgent == 'deluge' and TorrentClass != "": TorrentClass.core.pause_torrent([inputID]) time.sleep(5) # Give Torrent client some time to catch up with the change
def extract_subs(file, newfilePath, bitbucket): video_details, result = getVideoDetails(file) if not video_details: return if nzbtomedia.SUBSDIR: subdir = nzbtomedia.SUBSDIR else: subdir = os.path.split(newfilePath)[0] name = os.path.splitext(os.path.split(newfilePath)[1])[0] try: subStreams = [item for item in video_details["streams"] if item["codec_type"] == "subtitle" and item["tags"]["language"] in nzbtomedia.SLANGUAGES and item["codec_name"] != "hdmv_pgs_subtitle" and item["codec_name"] != "pgssub"] except: subStreams = [item for item in video_details["streams"] if item["codec_type"] == "subtitle" and item["codec_name"] != "hdmv_pgs_subtitle" and item["codec_name"] != "pgssub"] num = len(subStreams) for n in range(num): sub = subStreams[n] idx = sub["index"] try: lan = sub["tags"]["language"] except: lan = "unk" if num == 1: outputFile = os.path.join(subdir, "%s.srt" %(name)) if os.path.isfile(outputFile): outputFile = os.path.join(subdir, "%s.%s.srt" %(name, n)) else: outputFile = os.path.join(subdir, "%s.%s.srt" %(name, lan)) if os.path.isfile(outputFile): outputFile = os.path.join(subdir, "%s.%s.%s.srt" %(name, lan, n)) command = [nzbtomedia.FFMPEG, '-loglevel', 'warning', '-i', file, '-vn', '-an', '-codec:' + str(idx), 'srt', outputFile] if platform.system() != 'Windows': command = nzbtomedia.NICENESS + command logger.info("Extracting %s subtitle from: %s" % (lan, file)) cmd = "" for item in command: cmd = cmd + " " + str(item) logger.debug("Calling command: %s" % (cmd)) result = 1 # set result to failed in case call fails. try: result = call(command, stdout=bitbucket, stderr=bitbucket) except: logger.error("Extracting subtitle has failed") if result == 0: try: shutil.copymode(file, outputFile) except: pass logger.info("Extracting %s subtitle from %s has succeeded" % (lan, file)) else: logger.error("Extracting subtitles has failed")
def ripISO(item, newDir, bitbucket): newFiles = [] failure_dir = 'failure' # Mount the ISO in your OS and call combineVTS. if not nzbtomedia.SEVENZIP: logger.error("No 7zip installed. Can't extract image file %s" % (item), "TRANSCODER") newFiles = [failure_dir] return newFiles cmd = [nzbtomedia.SEVENZIP, 'l', item] try: logger.debug("Attempting to extract .vob from image file %s" % (item), "TRANSCODER") print_cmd(cmd) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=bitbucket) out, err = proc.communicate() result = proc.returncode fileList = [ re.match(".+(VIDEO_TS[\\\/]VTS_[0-9][0-9]_[0-9].[Vv][Oo][Bb])", line).groups()[0] for line in out.splitlines() if re.match( ".+VIDEO_TS[\\\/]VTS_[0-9][0-9]_[0-9].[Vv][Oo][Bb]", line) ] combined = [] for n in range(99): concat = [] m = 1 while True: vtsName = 'VIDEO_TS%sVTS_%02d_%d.VOB' % (os.sep, n + 1, m) if vtsName in fileList: concat.append(vtsName) m += 1 else: break if not concat: break if nzbtomedia.CONCAT: combined.extend(concat) continue name = '%s.cd%s' % (os.path.splitext( os.path.split(item)[1])[0], str(n + 1)) newFiles.append({item: {'name': name, 'files': concat}}) if nzbtomedia.CONCAT: name = os.path.splitext(os.path.split(item)[1])[0] newFiles.append({item: {'name': name, 'files': combined}}) if not newFiles: logger.error("No VIDEO_TS folder found in image file %s" % (item), "TRANSCODER") newFiles = [failure_dir] except: logger.error("Failed to extract from image file %s" % (item), "TRANSCODER") newFiles = [failure_dir] return newFiles
def resume_torrent(clientAgent, inputHash, inputID, inputName): logger.debug("Starting torrent %s in %s" % (inputName, clientAgent)) if clientAgent == 'utorrent' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.start(inputHash) if clientAgent == 'transmission' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.start_torrent(inputID) if clientAgent == 'deluge' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.core.resume_torrent([inputID]) time.sleep(5)
def pause_torrent(clientAgent, inputHash, inputID, inputName): logger.debug("Stoping torrent %s in %s while processing" % (inputName, clientAgent)) if clientAgent == 'utorrent' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.stop(inputHash) if clientAgent == 'transmission' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.stop_torrent(inputID) if clientAgent == 'deluge' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.core.pause_torrent([inputID]) time.sleep(5)
def rmReadOnly(filename): if os.path.isfile(filename): #check first the read-only attribute file_attribute = os.stat(filename)[0] if (not file_attribute & stat.S_IWRITE): # File is read-only, so make it writeable logger.debug('Read only mode on file ' + filename + ' Will try to make it writeable') try: os.chmod(filename, stat.S_IWRITE) except: logger.warning('Cannot change permissions of ' + filename, logger.WARNING)
def pause_torrent(clientAgent, inputHash, inputID, inputName): logger.debug("Stopping torrent %s in %s while processing" % (inputName, clientAgent)) try: if clientAgent == 'utorrent' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.stop(inputHash) if clientAgent == 'transmission' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.stop_torrent(inputID) if clientAgent == 'deluge' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.core.pause_torrent([inputID]) time.sleep(5) except: logger.warning("Failed to stop torrent %s in %s" % (inputName, clientAgent))
def migrate(): global CFG_NEW, CFG_OLD CFG_NEW = None CFG_OLD = None try: # check for autoProcessMedia.cfg and create if it does not exist if not os.path.isfile(nzbtomedia.CONFIG_FILE): shutil.copyfile(nzbtomedia.CONFIG_SPEC_FILE, nzbtomedia.CONFIG_FILE) CFG_OLD = config(nzbtomedia.CONFIG_FILE) except Exception, e: logger.debug("Error %s when copying to .cfg" % (e))
def main(args): # Initialize the config nzbtomedia.initialize() # clientAgent for Torrents clientAgent = nzbtomedia.TORRENT_CLIENTAGENT logger.info("#########################################################") logger.info("## ..::[%s]::.. CLIENT:%s ## STARTING" % (args[0], clientAgent)) logger.info("#########################################################") # debug command line options logger.debug("Options passed into TorrentToMedia: %s" % (args)) # Post-Processing Result result = 0 try: inputDirectory, inputName, inputCategory, inputHash, inputID = parse_args(clientAgent, args) except: logger.error("There was a problem loading variables") return -1 if inputDirectory and inputName and inputHash and inputID: result = processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, clientAgent) else: # Perform Manual Run logger.warning("Invalid number of arguments received from client, Switching to manual run mode ...") # Loop and auto-process clientAgent = 'manual' for section, subsection in nzbtomedia.SUBSECTIONS.items(): for category in subsection: if nzbtomedia.CFG[section][category].isenabled(): dirNames = get_dirnames(section, category) for dirName in dirNames: logger.info("Running %s:%s as a manual run for folder %s ..." % (section, category, dirName)) results = processTorrent(dirName, os.path.basename(dirName), category, inputHash, inputID, clientAgent) if results != 0: result = results logger.error("A problem was reported when trying to manually run %s:%s." % (section, category)) else: logger.warning("%s:%s is DISABLED, you can enable this in autoProcessMedia.cfg ..." % (section, category)) if result == 0: logger.info("The %s script completed successfully." % (args[0])) else: logger.error("A problem was reported in the %s script." % (args[0])) sys.exit(result)
def get_status(self, url, apikey, dirName): logger.debug("Attempting to get current status for release:%s" % (os.path.basename(dirName))) params = {} params['apikey'] = apikey params['cmd'] = "getHistory" logger.debug("Opening URL: %s with PARAMS: %s" % (url, params)) try: r = requests.get(url, params=params, verify=False) except Exception, e: logger.error("Unable to open URL") return None
def replace_filename(filename, dirname, name): head, fileExtension = os.path.splitext(os.path.basename(filename)) if media_pattern.search(os.path.basename(dirname).replace(' ','.')) is not None: newname = os.path.basename(dirname).replace(' ', '.') logger.debug("Replacing file name %s with directory name %s" % (head, newname), "EXCEPTION") elif media_pattern.search(name.replace(' ','.').lower()) is not None: newname = name.replace(' ', '.') logger.debug("Replacing file name %s with download name %s" % (head, newname), "EXCEPTION") else: logger.warning("No name replacement determined for %s" % (head), "EXCEPTION") return newfile = newname + fileExtension newfilePath = os.path.join(dirname, newfile) return newfilePath
def listMediaFiles(path, minSize=0, delete_ignored=0, media=True, audio=True, meta=True, archives=True): files = [] if not os.path.isdir(path): if os.path.isfile(path): # Single file downloads. curFile = os.path.split(path)[1] if isMediaFile(curFile, media, audio, meta, archives): # Optionally ignore sample files if is_sample(path) or not is_minSize(path, minSize): if delete_ignored == 1: try: os.unlink(path) logger.debug( 'Ignored file %s has been removed ...' % (curFile)) except: pass else: files.append(path) return files for curFile in os.listdir(path): fullCurFile = os.path.join(path, curFile) # if it's a folder do it recursively if os.path.isdir(fullCurFile) and not curFile.startswith('.'): files += listMediaFiles(fullCurFile, minSize, delete_ignored, media, audio, meta, archives) elif isMediaFile(curFile, media, audio, meta, archives): # Optionally ignore sample files if is_sample(fullCurFile) or not is_minSize(fullCurFile, minSize): if delete_ignored == 1: try: os.unlink(fullCurFile) logger.debug('Ignored file %s has been removed ...' % (curFile)) except: pass continue files.append(fullCurFile) return files
def replaceExtensions(path): for dirpath, dirnames, filesnames in os.walk(path): for filename in filesnames: name, ext = os.path.splitext(filename) if ext in nzbtomedia.EXT_REPLACE: file = os.path.join(dirpath, filename) target = os.path.join(dirpath, name + nzbtomedia.EXT_REPLACE[ext]) try: logger.debug("Renaming %s to %s" % (file, target), 'RENAME') shutil.move(file, target) except: logger.error("Could not rename %s to %s" % (file, target), 'RENAME') else: continue
def get_status(self, url, apikey, dirName): logger.debug("Attempting to get current status for release:%s" % (os.path.basename(dirName))) params = {} params['apikey'] = apikey params['cmd'] = "getHistory" logger.debug("Opening URL: %s with PARAMS: %s" % (url, params)) try: r = requests.get(url, params=params, verify=False) except Exception, e: logger.error("Unable to open URL") return
def _find_working_git(self): test_cmd = "version" if nzbtomedia.GIT_PATH: main_git = '"' + nzbtomedia.GIT_PATH + '"' else: main_git = "git" logger.log(u"Checking if we can use git commands: " + main_git + " " + test_cmd, logger.DEBUG) output, err, exit_status = self._run_git(main_git, test_cmd) if exit_status == 0: logger.log(u"Using: " + main_git, logger.DEBUG) return main_git else: logger.log(u"Not using: " + main_git, logger.DEBUG) # trying alternatives alternative_git = [] # osx people who start SB from launchd have a broken path, so try a hail-mary attempt for them if platform.system().lower() == "darwin": alternative_git.append("/usr/local/git/bin/git") if platform.system().lower() == "windows": if main_git != main_git.lower(): alternative_git.append(main_git.lower()) if alternative_git: logger.log(u"Trying known alternative git locations", logger.DEBUG) for cur_git in alternative_git: logger.log(u"Checking if we can use git commands: " + cur_git + " " + test_cmd, logger.DEBUG) output, err, exit_status = self._run_git(cur_git, test_cmd) if exit_status == 0: logger.log(u"Using: " + cur_git, logger.DEBUG) return cur_git else: logger.log(u"Not using: " + cur_git, logger.DEBUG) # Still haven't found a working git logger.debug( "Unable to find your git executable - Set git_path in your autoProcessMedia.cfg OR delete your .git folder and run from source to enable updates." ) return None
def find_imdbid(dirName, inputName): imdbid = None logger.info('Attemping imdbID lookup for %s' % (inputName)) # find imdbid in dirName logger.info('Searching folder and file names for imdbID ...') m = re.search('(tt\d{7})', dirName+inputName) if m: imdbid = m.group(1) logger.info("Found imdbID [%s]" % imdbid) return imdbid logger.info('Searching IMDB for imdbID ...') guess = guessit.guess_movie_info(inputName) if guess: # Movie Title title = None if 'title' in guess: title = guess['title'] # Movie Year year = None if 'year' in guess: year = guess['year'] url = "http://www.omdbapi.com" logger.debug("Opening URL: %s" % url) try: r = requests.get(url, params={'y': year, 't': title}, verify=False) except requests.ConnectionError: logger.error("Unable to open URL %s" % url) return results = r.json() try: imdbid = results['imdbID'] except: pass if imdbid: logger.info("Found imdbID [%s]" % imdbid) return imdbid logger.warning('Unable to find a imdbID for %s' % (inputName))
def find_imdbid(dirName, inputName): imdbid = None logger.info('Attemping imdbID lookup for %s' % (inputName)) # find imdbid in dirName logger.info('Searching folder and file names for imdbID ...') m = re.search('(tt\d{7})', dirName + inputName) if m: imdbid = m.group(1) logger.info("Found imdbID [%s]" % imdbid) return imdbid logger.info('Searching IMDB for imdbID ...') guess = guessit.guess_movie_info(inputName) if guess: # Movie Title title = None if 'title' in guess: title = guess['title'] # Movie Year year = None if 'year' in guess: year = guess['year'] url = "http://www.omdbapi.com" logger.debug("Opening URL: %s" % url) try: r = requests.get(url, params={'y': year, 't': title}, verify=False) except requests.ConnectionError: logger.error("Unable to open URL %s" % url) return results = r.json() try: imdbid = results['imdbID'] except: pass if imdbid: logger.info("Found imdbID [%s]" % imdbid) return imdbid logger.warning('Unable to find a imdbID for %s' % (inputName))
def remove_torrent(clientAgent, inputHash, inputID, inputName): if nzbtomedia.DELETE_ORIGINAL == 1 or nzbtomedia.USELINK == 'move': logger.debug("Deleting torrent %s from %s" % (inputName, clientAgent)) try: if clientAgent == 'utorrent' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.removedata(inputHash) nzbtomedia.TORRENT_CLASS.remove(inputHash) if clientAgent == 'transmission' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.remove_torrent(inputID, True) if clientAgent == 'deluge' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.core.remove_torrent(inputID, True) time.sleep(5) except: logger.warning("Failed to delete torrent %s in %s" % (inputName, clientAgent)) else: resume_torrent(clientAgent, inputHash, inputID, inputName)
def remove_torrent(clientAgent, inputHash, inputID, inputName): if nzbtomedia.DELETE_ORIGINAL == 1 or nzbtomedia.USELINK == 'move': logger.debug("Deleting torrent %s from %s" % (inputName, clientAgent)) if clientAgent == 'utorrent' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.removedata(inputHash) nzbtomedia.TORRENT_CLASS.remove(inputHash) if clientAgent == 'transmission' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.remove_torrent(inputID, True) if clientAgent == 'deluge' and nzbtomedia.TORRENT_CLASS != "": nzbtomedia.TORRENT_CLASS.core.remove_torrent(inputID, True) time.sleep(5) else: resume_torrent(clientAgent, inputHash, inputID, inputName)
def _find_working_git(self): test_cmd = 'version' if nzbtomedia.GIT_PATH: main_git = '"' + nzbtomedia.GIT_PATH + '"' else: main_git = 'git' logger.log(u"Checking if we can use git commands: " + main_git + ' ' + test_cmd, logger.DEBUG) output, err, exit_status = self._run_git(main_git, test_cmd) if exit_status == 0: logger.log(u"Using: " + main_git, logger.DEBUG) return main_git else: logger.log(u"Not using: " + main_git, logger.DEBUG) # trying alternatives alternative_git = [] # osx people who start SB from launchd have a broken path, so try a hail-mary attempt for them if platform.system().lower() == 'darwin': alternative_git.append('/usr/local/git/bin/git') if platform.system().lower() == 'windows': if main_git != main_git.lower(): alternative_git.append(main_git.lower()) if alternative_git: logger.log(u"Trying known alternative git locations", logger.DEBUG) for cur_git in alternative_git: logger.log(u"Checking if we can use git commands: " + cur_git + ' ' + test_cmd, logger.DEBUG) output, err, exit_status = self._run_git(cur_git, test_cmd) if exit_status == 0: logger.log(u"Using: " + cur_git, logger.DEBUG) return cur_git else: logger.log(u"Not using: " + cur_git, logger.DEBUG) # Still haven't found a working git logger.debug('Unable to find your git executable - Set git_path in your autoProcessMedia.cfg OR delete your .git folder and run from source to enable updates.') return None
def replace_filename(filename, dirname, name): head, fileExtension = os.path.splitext(os.path.basename(filename)) if media_pattern.search(os.path.basename(dirname)) is not None: newname = os.path.basename(dirname) logger.debug("Replacing file name %s with directory name %s" % (head, newname), "EXCEPTION") elif media_pattern.search(name) is not None: newname = name logger.debug("Replacing file name %s with download name %s" % (head, newname), "EXCEPTION") else: logger.warning("No name replacement determined for %s" % (head), "EXCEPTION") return newfile = newname + fileExtension newfilePath = os.path.join(dirname, newfile) try: os.rename(filename, newfilePath) except Exception,e: logger.error("Unable to rename file due to: %s" % (str(e)), "EXCEPTION")
def removeEmptyFolders(path): logger.info("REMOVER: Removing empty folders in: %s" % (path)) if not os.path.isdir(path): return # Remove empty subfolders files = os.listdir(path) if len(files): for f in files: fullpath = os.path.join(path, f) if os.path.isdir(fullpath): removeEmptyFolders(fullpath) # If folder empty, delete it files = os.listdir(path) if len(files) == 0: logger.debug("REMOVER: Removing empty folder: %s" % (path)) os.rmdir(path)
def ripISO(item, newDir, bitbucket): newFiles = [] failure_dir = 'failure' # Mount the ISO in your OS and call combineVTS. if not nzbtomedia.SEVENZIP: logger.error("No 7zip installed. Can't extract image file %s" % (item), "TRANSCODER") newFiles = [failure_dir] return newFiles cmd = [nzbtomedia.SEVENZIP, 'l', item] try: logger.debug("Attempting to extract .vob from image file %s" % (item), "TRANSCODER") print_cmd(cmd) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=bitbucket) out, err = proc.communicate() result = proc.returncode fileList = [ re.match(".+(VIDEO_TS[\\\/]VTS_[0-9][0-9]_[0-9].[Vv][Oo][Bb])", line).groups()[0] for line in out.splitlines() if re.match(".+VIDEO_TS[\\\/]VTS_[0-9][0-9]_[0-9].[Vv][Oo][Bb]", line) ] combined = [] for n in range(99): concat = [] m = 1 while True: vtsName = 'VIDEO_TS%sVTS_%02d_%d.VOB' % (os.sep, n+1, m) if vtsName in fileList: concat.append(vtsName) m += 1 else: break if not concat: break if nzbtomedia.CONCAT: combined.extend(concat) continue name = '%s.cd%s' % (os.path.splitext(os.path.split(item)[1])[0] ,str(n+1)) newFiles.append({item: {'name': name , 'files': concat}}) if nzbtomedia.CONCAT: name = os.path.splitext(os.path.split(item)[1])[0] newFiles.append({item: {'name': name , 'files': combined}}) if not newFiles: logger.error("No VIDEO_TS folder found in image file %s" % (item), "TRANSCODER") newFiles = [failure_dir] except: logger.error("Failed to extract from image file %s" % (item), "TRANSCODER") newFiles = [failure_dir] return newFiles
def Transcode_directory(dirName): if not nzbtomedia.FFMPEG: return 1, dirName logger.info("Checking for files to be transcoded") final_result = 0 # initialize as successful if nzbtomedia.OUTPUTVIDEOPATH: newDir = nzbtomedia.OUTPUTVIDEOPATH makeDir(newDir) else: newDir = dirName if platform.system() == 'Windows': bitbucket = open('NUL') else: bitbucket = open('/dev/null') movieName = os.path.splitext(os.path.split(dirName)[1])[0] List = nzbtomedia.listMediaFiles(dirName, media=True, audio=False, meta=False, archives=False) List, remList, newList, success = processList(List, newDir, bitbucket) if not success: bitbucket.close() return 1, dirName for file in List: if isinstance(file, str) and os.path.splitext( file)[1] in nzbtomedia.IGNOREEXTENSIONS: continue command = buildCommands(file, newDir, movieName, bitbucket) newfilePath = command[-1] # transcoding files may remove the original file, so make sure to extract subtitles first if nzbtomedia.SEXTRACT and isinstance(file, str): extract_subs(file, newfilePath, bitbucket) try: # Try to remove the file that we're transcoding to just in case. (ffmpeg will return an error if it already exists for some reason) os.remove(newfilePath) except OSError, e: if e.errno != errno.ENOENT: # Ignore the error if it's just telling us that the file doesn't exist logger.debug("Error when removing transcoding target: %s" % (e)) except Exception, e: logger.debug("Error when removing transcoding target: %s" % (e))
def removeEmptyFolders(path, removeRoot=True): 'Function to remove empty folders' if not os.path.isdir(path): return # remove empty subfolders logger.debug("Checking for empty folders in:%s" % (path)) files = os.listdir(path) if len(files): for f in files: fullpath = os.path.join(path, f) if os.path.isdir(fullpath): removeEmptyFolders(fullpath) # if folder empty, delete it files = os.listdir(path) if len(files) == 0 and removeRoot: logger.debug("Removing empty folder:%s" % (path)) os.rmdir(path)
def replace_filename(filename, dirname, name): head, fileExtension = os.path.splitext(os.path.basename(filename)) if media_pattern.search(os.path.basename(dirname).replace( ' ', '.')) is not None: newname = os.path.basename(dirname).replace(' ', '.') logger.debug( "Replacing file name %s with directory name %s" % (head, newname), "EXCEPTION") elif media_pattern.search(name.replace(' ', '.').lower()) is not None: newname = name.replace(' ', '.') logger.debug( "Replacing file name %s with download name %s" % (head, newname), "EXCEPTION") else: logger.warning("No name replacement determined for %s" % (head), "EXCEPTION") newname = name newfile = newname + fileExtension newfilePath = os.path.join(dirname, newfile) return newfilePath
def cleanup_directories(inputCategory, processCategories, result, directory): if inputCategory in processCategories and result == 0 and os.path.isdir(directory): num_files_new = int(0) file_list = [] for dirpath, dirnames, filenames in os.walk(directory): for file in filenames: filePath = os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in nzbtomedia.MEDIACONTAINER or fileExtension in nzbtomedia.METACONTAINER: num_files_new += 1 file_list.append(file) if num_files_new is 0 or int(nzbtomedia.CFG["General"]["force_clean"]) == 1: logger.info("All files have been processed. Cleaning directory %s" % (directory)) shutil.rmtree(directory) else: logger.info( "Directory %s still contains %s media and/or meta files. This directory will not be removed." % ( directory, num_files_new)) for item in file_list: logger.debug("media/meta file found: %s" % (item))
def create_torrent_class(clientAgent): # Hardlink solution for Torrents tc = None if clientAgent == 'utorrent': try: logger.debug("Connecting to %s: %s" % (clientAgent, nzbtomedia.UTORRENTWEBUI)) tc = UTorrentClient(nzbtomedia.UTORRENTWEBUI, nzbtomedia.UTORRENTUSR, nzbtomedia.UTORRENTPWD) except: logger.error("Failed to connect to uTorrent") if clientAgent == 'transmission': try: logger.debug("Connecting to %s: http://%s:%s" % ( clientAgent, nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT)) tc = TransmissionClient(nzbtomedia.TRANSMISSIONHOST, nzbtomedia.TRANSMISSIONPORT, nzbtomedia.TRANSMISSIONUSR, nzbtomedia.TRANSMISSIONPWD) except: logger.error("Failed to connect to Transmission") if clientAgent == 'deluge': try: logger.debug("Connecting to %s: http://%s:%s" % (clientAgent, nzbtomedia.DELUGEHOST, nzbtomedia.DELUGEPORT)) tc = DelugeClient() tc.connect(host=nzbtomedia.DELUGEHOST, port=nzbtomedia.DELUGEPORT, username=nzbtomedia.DELUGEUSR, password=nzbtomedia.DELUGEPWD) except: logger.error("Failed to connect to Deluge") return tc
def rename_script(dirname): rename_file = "" for dir, dirs, files in os.walk(dirname): for file in files: if re.search('(rename\S*\.(sh|bat))',file): rename_file = os.path.join(dir, file) dirname = dir break if rename_file: rename_lines = [line.strip() for line in open(rename_file)] for line in rename_lines: cmd = filter(None, re.split('mv|Move\s(\S*)\s(\S*)',line)) if len(cmd) == 2 and os.path.isfile(os.path.join(dirname, cmd[0])): orig = os.path.join(dirname, cmd[0]) dest = os.path.join(dirname, cmd[1].split('\\')[-1].split('/')[-1]) if os.path.isfile(dest): continue logger.debug("Renaming file %s to %s" % (orig, dest), "EXCEPTION") try: os.rename(orig, dest) except Exception,e: logger.error("Unable to rename file due to: %s" % (str(e)), "EXCEPTION")
def listMediaFiles(path, minSize=0, delete_ignored=0, media=True, audio=True, meta=True, archives=True): files = [] if not os.path.isdir(path): if os.path.isfile(path): # Single file downloads. curFile = os.path.split(path)[1] if isMediaFile(curFile, media, audio, meta, archives): # Optionally ignore sample files if is_sample(path) or not is_minSize(path, minSize): if delete_ignored == 1: try: os.unlink(path) logger.debug('Ignored file %s has been removed ...' % (curFile)) except:pass else: files.append(path) return files for curFile in os.listdir(path): fullCurFile = os.path.join(path, curFile) # if it's a folder do it recursively if os.path.isdir(fullCurFile) and not curFile.startswith('.'): files += listMediaFiles(fullCurFile, minSize, delete_ignored, media, audio, meta, archives) elif isMediaFile(curFile, media, audio, meta, archives): # Optionally ignore sample files if is_sample(fullCurFile) or not is_minSize(fullCurFile, minSize): if delete_ignored == 1: try: os.unlink(fullCurFile) logger.debug('Ignored file %s has been removed ...' % (curFile)) except:pass continue files.append(fullCurFile) return files
def Transcode_directory(dirName): if not nzbtomedia.FFMPEG: return 1, dirName logger.info("Checking for files to be transcoded") final_result = 0 # initialize as successful if nzbtomedia.OUTPUTVIDEOPATH: newDir = nzbtomedia.OUTPUTVIDEOPATH makeDir(newDir) else: newDir = dirName if platform.system() == 'Windows': bitbucket = open('NUL') else: bitbucket = open('/dev/null') movieName = os.path.splitext(os.path.split(dirName)[1])[0] List = nzbtomedia.listMediaFiles(dirName, media=True, audio=False, meta=False, archives=False) List, remList, newList, success = processList(List, newDir, bitbucket) if not success: bitbucket.close() return 1, dirName for file in List: if isinstance(file, str) and os.path.splitext(file)[1] in nzbtomedia.IGNOREEXTENSIONS: continue command = buildCommands(file, newDir, movieName, bitbucket) newfilePath = command[-1] # transcoding files may remove the original file, so make sure to extract subtitles first if nzbtomedia.SEXTRACT and isinstance(file, str): extract_subs(file, newfilePath, bitbucket) try: # Try to remove the file that we're transcoding to just in case. (ffmpeg will return an error if it already exists for some reason) os.remove(newfilePath) except OSError, e: if e.errno != errno.ENOENT: # Ignore the error if it's just telling us that the file doesn't exist logger.debug("Error when removing transcoding target: %s" % (e)) except Exception, e: logger.debug("Error when removing transcoding target: %s" % (e))
def get_status(self, baseURL, apikey, dirName): logger.debug("Attempting to get current status for release:%s" % (os.path.basename(dirName))) url = baseURL params = {} params['apikey'] = apikey params['cmd'] = "getHistory" logger.debug("Opening URL: %s" % (url)) try: r = requests.get(url, params=params) except requests.ConnectionError: logger.error("Unable to open URL") return None, None try: result = r.json() for album in result: if os.path.basename(dirName) == album['FolderName']: return album["Status"].lower() except:pass
def reverse_filename(filename, dirname, name): head, fileExtension = os.path.splitext(os.path.basename(filename)) na_parts = season_pattern.search(head) if na_parts is not None: word_p = word_pattern.findall(na_parts.group(2)) if word_p: new_words = "" for wp in word_p: if wp[0] == ".": new_words += "." new_words += re.sub(r"\W", "", wp) else: new_words = na_parts.group(2) for cr in char_replace: new_words = re.sub(cr[0], cr[1], new_words) newname = new_words[::-1] + na_parts.group(1)[::-1] else: newname = head[::-1].title() newname = newname.replace(' ', '.') logger.debug("Reversing filename %s to %s" % (head, newname), "EXCEPTION") newfile = newname + fileExtension newfilePath = os.path.join(dirname, newfile) return newfilePath
def processList(List, newDir, bitbucket): remList = [] newList = [] delList = [] combine = [] vtsPath = None success = True for item in List: newfile = None ext = os.path.splitext(item)[1].lower() if ext in ['.iso', '.bin'] and not ext in nzbtomedia.IGNOREEXTENSIONS: logger.debug("Attempting to rip disk image: %s" % (item), "TRANSCODER") newList.extend(ripISO(item, newDir, bitbucket)) remList.append(item) elif re.match(".+VTS_[0-9][0-9]_[0-9].[Vv][Oo][Bb]", item) and not '.vob' in nzbtomedia.IGNOREEXTENSIONS: logger.debug("Found VIDEO_TS image file: %s" % (item), "TRANSCODER") if not vtsPath: try: vtsPath = re.match("(.+VIDEO_TS)", item).groups()[0] except: vtsPath = os.path.split(item)[0] remList.append(item) elif re.match(".+VIDEO_TS.", item) or re.match( ".+VTS_[0-9][0-9]_[0-9].", item): remList.append(item) elif nzbtomedia.CONCAT and re.match(".+[cC][dD][0-9].", item): remList.append(item) combine.append(item) else: continue if vtsPath: newList.extend(combineVTS(vtsPath)) if combine: newList.extend(combineCD(combine)) for file in newList: if isinstance( file, str) and not 'concat:' in file and not os.path.isfile(file): success = False break if success and newList: List.extend(newList) for item in remList: List.remove(item) logger.debug( "Successfully extracted .vob file %s from disk image" % (newList[0]), "TRANSCODER") elif newList and not success: newList = [] remList = [] logger.error( "Failed extracting .vob files from disk image. Stopping transcoding.", "TRANSCODER") return List, remList, newList, success
def import_subs(filename): if not nzbtomedia.GETSUBS: return try: subliminal.cache_region.configure('dogpile.cache.memory') except: pass languages = set() for item in nzbtomedia.SLANGUAGES: try: languages.add(Language(item)) except: pass if not languages: return logger.debug("Attempting to download subtitles for %s" %(filename), 'SUBTITLES') try: video = subliminal.scan_video(filename, subtitles=True, embedded_subtitles=True) subtitles = subliminal.download_best_subtitles([video], languages, hearing_impaired=False) subliminal.save_subtitles(subtitles) except: logger.error("Failed to download subtitles for %s" %(filename), 'SUBTITLES')
def resume_torrent(clientAgent, TorrentClass, inputHash, inputID, result, inputName): # Hardlink solution for uTorrent, need to implent support for deluge, transmission if clientAgent in ['utorrent', 'transmission', 'deluge'] and inputHash: # Delete torrent and torrentdata from Torrent client if processing was successful. if (int(nzbtomedia.CFG["Torrent"][ "deleteOriginal"]) is 1 and result != 1) or nzbtomedia.USELINK == 'move': # if we move files, nothing to resume seeding. logger.debug("Deleting torrent %s from %s" % (inputName, clientAgent)) if clientAgent == 'utorrent' and TorrentClass != "": TorrentClass.removedata(inputHash) TorrentClass.remove(inputHash) if clientAgent == 'transmission' and TorrentClass != "": TorrentClass.remove_torrent(inputID, True) if clientAgent == 'deluge' and TorrentClass != "": TorrentClass.core.remove_torrent(inputID, True) # we always want to resume seeding, for now manually find out what is wrong when extraction fails else: logger.debug("Starting torrent %s in %s" % (inputName, clientAgent)) if clientAgent == 'utorrent' and TorrentClass != "": TorrentClass.start(inputHash) if clientAgent == 'transmission' and TorrentClass != "": TorrentClass.start_torrent(inputID) if clientAgent == 'deluge' and TorrentClass != "": TorrentClass.core.resume_torrent([inputID]) time.sleep(5)
def import_subs(filename): if not nzbtomedia.GETSUBS: return try: subliminal.cache_region.configure('dogpile.cache.memory') except: pass languages = set() for item in nzbtomedia.SLANGUAGES: try: languages.add(Language(item)) except: pass if not languages: return logger.debug("Attempting to download subtitles for %s" %(filename), 'SUBTITLES') try: video = subliminal.scan_video(filename, subtitles=True, embedded_subtitles=True) subtitles = subliminal.download_best_subtitles([video], languages, hearing_impaired=False) subliminal.save_subtitles(subtitles) except Exception as e: logger.error("Failed to download subtitles for %s due to: %s" %(filename, e), 'SUBTITLES')
def copy_link(filePath, targetDirectory, useLink, outputDestination): if os.path.isfile(targetDirectory): logger.info("COPYLINK: target file already exists. Nothing to be done") return True makeDir(outputDestination) if useLink == "hard": try: logger.info("COPYLINK: Hard linking %s to %s" % (filePath, targetDirectory)) linktastic.link(filePath, targetDirectory) except: logger.error("COPYLINK") if os.path.isfile(targetDirectory): logger.warning( "COPYLINK: Something went wrong in linktastic.link, but the destination file was created") else: logger.warning("COPYLINK: Something went wrong in linktastic.link, copying instead") logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory)) shutil.copy(filePath, targetDirectory) elif useLink == "sym": try: logger.info("COPYLINK: Moving %s to %s before sym linking" % (filePath, targetDirectory)) shutil.move(filePath, targetDirectory) logger.info("COPYLINK: Sym linking %s to %s" % (targetDirectory, filePath)) linktastic.symlink(targetDirectory, filePath) except: logger.error("COPYLINK") if os.path.isfile(targetDirectory): logger.warning( "COPYLINK: Something went wrong in linktastic.link, but the destination file was created") else: logger.info("COPYLINK: Something went wrong in linktastic.link, copying instead") logger.debug("COPYLINK: Copying %s to %s" % (filePath, targetDirectory)) shutil.copy(filePath, targetDirectory) elif useLink == "move": logger.debug("Moving %s to %s" % (filePath, targetDirectory)) shutil.move(filePath, targetDirectory) else: logger.debug("Copying %s to %s" % (filePath, targetDirectory)) shutil.copy(filePath, targetDirectory) return True