diff --git a/nzb2media/__init__.py b/nzb2media/__init__.py index c401449e..b605e7cf 100644 --- a/nzb2media/__init__.py +++ b/nzb2media/__init__.py @@ -37,13 +37,13 @@ except ImportError: def which(name): - proc = subprocess.Popen(['which', name], stdout=PIPE) - try: - proc_out, proc_err = proc.communicate() - except Exception: - return '' - else: - return proc_out.strip().decode() + with subprocess.Popen(['which', name], stdout=PIPE) as proc: + try: + proc_out, proc_err = proc.communicate() + except Exception: + return '' + else: + return proc_out.strip().decode() def module_path(module=__file__): @@ -544,8 +544,8 @@ def configure_remote_paths(): def configure_niceness(): global NICENESS try: - proc = subprocess.Popen(['nice'], stdout=DEVNULL, stderr=DEVNULL) - proc.communicate() + with subprocess.Popen(['nice'], stdout=DEVNULL, stderr=DEVNULL) as proc: + proc.communicate() niceness = CFG['Posix']['niceness'] if ( len(niceness.split(',')) > 1 @@ -556,8 +556,8 @@ def configure_niceness(): except Exception: pass try: - proc = subprocess.Popen(['ionice'], stdout=DEVNULL, stderr=DEVNULL) - proc.communicate() + with subprocess.Popen(['ionice'], stdout=DEVNULL, stderr=DEVNULL) as proc: + proc.communicate() try: ionice = CFG['Posix']['ionice_class'] NICENESS.extend(['ionice', f'-c{int(ionice)}']) diff --git a/nzb2media/extractor/__init__.py b/nzb2media/extractor/__init__.py index 569a4ae9..5f42aacd 100644 --- a/nzb2media/extractor/__init__.py +++ b/nzb2media/extractor/__init__.py @@ -8,6 +8,7 @@ import stat import subprocess from subprocess import call from subprocess import Popen +from subprocess import DEVNULL from time import sleep import nzb2media @@ -87,35 +88,23 @@ def extract(file_path, output_destination): } # Test command exists and if not, remove if not os.getenv('TR_TORRENT_DIR'): - devnull = open(os.devnull, 'w') for cmd in required_cmds: - if call( - ['which', cmd], - stdout=devnull, - stderr=devnull, - ): # note, returns 0 if exists, or 1 if doesn't exist. + if call(['which', cmd], stdout=DEVNULL, stderr=DEVNULL): + # note, returns 0 if exists, or 1 if doesn't exist. for key, val in extract_commands.items(): if cmd in val[0]: - if not call( - ['which', '7zr'], - stdout=devnull, - stderr=devnull, - ): # we do have '7zr' + if not call(['which', '7zr'], stdout=DEVNULL, stderr=DEVNULL): + # we do have '7zr' extract_commands[key] = ['7zr', 'x', '-y'] - elif not call( - ['which', '7z'], stdout=devnull, stderr=devnull, - ): # we do have '7z' + elif not call(['which', '7z'], stdout=DEVNULL, stderr=DEVNULL): + # we do have '7z' extract_commands[key] = ['7z', 'x', '-y'] - elif not call( - ['which', '7za'], - stdout=devnull, - stderr=devnull, - ): # we do have '7za' + elif not call(['which', '7za'], stdout=DEVNULL, stderr=DEVNULL): + # we do have '7za' extract_commands[key] = ['7za', 'x', '-y'] else: log.error(f'EXTRACTOR: {cmd} not found, disabling support for {key}') del extract_commands[key] - devnull.close() else: log.warning('EXTRACTOR: Cannot determine which tool to use when called from Transmission') @@ -130,19 +119,10 @@ def extract(file_path, output_destination): cmd = extract_commands[f'.tar{ext[1]}'] else: # Try gunzip cmd = extract_commands[ext[1]] - elif ext[1] in ('.1', '.01', '.001') and os.path.splitext(ext[0])[1] in ( - '.rar', - '.zip', - '.7z', - ): + elif ext[1] in ('.1', '.01', '.001') and os.path.splitext(ext[0])[1] in ('.rar', '.zip', '.7z'): cmd = extract_commands[os.path.splitext(ext[0])[1]] - elif ext[1] in ( - '.cb7', - '.cba', - '.cbr', - '.cbt', - '.cbz', - ): # don't extract these comic book archives. + elif ext[1] in ('.cb7', '.cba', '.cbr', '.cbt', '.cbz'): + # don't extract these comic book archives. return False else: if ext[1] in extract_commands: @@ -157,10 +137,11 @@ def extract(file_path, output_destination): if nzb2media.PASSWORDS_FILE and os.path.isfile( os.path.normpath(nzb2media.PASSWORDS_FILE), ): - passwords = [ - line.strip() - for line in open(os.path.normpath(nzb2media.PASSWORDS_FILE)) - ] + with open(os.path.normpath(nzb2media.PASSWORDS_FILE)) as fin: + passwords = [ + line.strip() + for line in fin + ] else: passwords = [] @@ -179,7 +160,6 @@ def extract(file_path, output_destination): os.chdir( output_destination, ) # Not all unpack commands accept full paths, so just extract into this directory - devnull = open(os.devnull, 'w') try: # now works same for nt and *nix info = None @@ -192,9 +172,8 @@ def extract(file_path, output_destination): cmd2 = cmd if 'gunzip' not in cmd: # gunzip doesn't support password cmd2.append('-p-') # don't prompt for password. - res = Popen( - cmd2, stdout=devnull, stderr=devnull, startupinfo=info, - ).wait() # should extract files fine. + with Popen(cmd2, stdout=DEVNULL, stderr=DEVNULL, startupinfo=info) as proc: + res = proc.wait() # should extract files fine. if res == 0: # Both Linux and Windows return 0 for successful. log.info(f'EXTRACTOR: Extraction was successful for {file_path} to {output_destination}') success = 1 @@ -209,10 +188,8 @@ def extract(file_path, output_destination): # append password here. passcmd = f'-p{password}' cmd2.append(passcmd) - proc = Popen( - cmd2, stdout=devnull, stderr=devnull, startupinfo=info, - ) - res = proc.wait() # should extract files fine. + with Popen(cmd2, stdout=DEVNULL, stderr=DEVNULL, startupinfo=info) as proc: + res = proc.wait() # should extract files fine. if (res >= 0 and platform == 'Windows') or res == 0: log.info(f'EXTRACTOR: Extraction was successful for {file_path} to {output_destination} using password: {password}') success = 1 diff --git a/nzb2media/scene_exceptions.py b/nzb2media/scene_exceptions.py index 7cef618d..24d3cb16 100644 --- a/nzb2media/scene_exceptions.py +++ b/nzb2media/scene_exceptions.py @@ -177,7 +177,11 @@ def rename_script(dirname): dirname = directory break if rename_file: - rename_lines = [line.strip() for line in open(rename_file)] + with open(rename_file) as fin: + rename_lines = [ + line.strip() + for line in fin + ] for line in rename_lines: if re.search('^(mv|Move)', line, re.IGNORECASE): cmd = shlex.split(line)[1:] @@ -219,9 +223,9 @@ def par2(dirname): cmd = f'{cmd} {item}' log.debug(f'calling command:{cmd}') try: - proc = subprocess.Popen(command, stdout=DEVNULL, stderr=DEVNULL) - proc.communicate() - result = proc.returncode + with subprocess.Popen(command, stdout=DEVNULL, stderr=DEVNULL) as proc: + proc.communicate() + result = proc.returncode except Exception: log.error(f'par2 file processing for {parfile} has failed') if result == 0: diff --git a/nzb2media/transcoder.py b/nzb2media/transcoder.py index 7fc439a1..04e80b76 100644 --- a/nzb2media/transcoder.py +++ b/nzb2media/transcoder.py @@ -100,16 +100,16 @@ def is_video_good(video: pathlib.Path, status, require_lan=None): def zip_out(file, img): - proc = None if os.path.isfile(file): cmd = ['cat', file] else: cmd = [nzb2media.SEVENZIP, '-so', 'e', img, file] try: - proc = subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) + with subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) as proc: + return proc except Exception: log.error(f'Extracting [{file}] has failed') - return proc + return None def get_video_details(videofile, img=None): @@ -136,13 +136,15 @@ def get_video_details(videofile, img=None): print_cmd(command) if img: procin = zip_out(file, img) - proc = subprocess.Popen(command, stdout=PIPE, stdin=procin.stdout) + with subprocess.Popen(command, stdout=PIPE, stdin=procin.stdout) as proc: + proc_out, proc_err = proc.communicate() + result = proc.returncode procin.stdout.close() else: - proc = subprocess.Popen(command, stdout=PIPE) - out, err = proc.communicate() - result = proc.returncode - video_details = json.loads(out.decode()) + with subprocess.Popen(command, stdout=PIPE) as proc: + proc_out, proc_err = proc.communicate() + result = proc.returncode + video_details = json.loads(proc_out.decode()) except Exception: try: # try this again without -show error in case of ffmpeg limitation command = [ @@ -158,13 +160,15 @@ def get_video_details(videofile, img=None): print_cmd(command) if img: procin = zip_out(file, img) - proc = subprocess.Popen(command, stdout=PIPE, stdin=procin.stdout) + with subprocess.Popen(command, stdout=PIPE, stdin=procin.stdout) as proc: + proc_out, proc_err = proc.communicate() + result = proc.returncode procin.stdout.close() else: - proc = subprocess.Popen(command, stdout=PIPE) - out, err = proc.communicate() - result = proc.returncode - video_details = json.loads(out.decode()) + with subprocess.Popen(command, stdout=PIPE) as proc: + proc_out, proc_err = proc.communicate() + result = proc.returncode + video_details = json.loads(proc_out.decode()) except Exception: log.error(f'Checking [{file}] has failed') return video_details, result @@ -804,11 +808,9 @@ def extract_subs(file, newfile_path): print_cmd(command) result = 1 # set result to failed in case call fails. try: - proc = subprocess.Popen( - command, stdout=DEVNULL, stderr=DEVNULL, - ) - proc_out, proc_error = proc.communicate() - result = proc.returncode + with subprocess.Popen(command, stdout=DEVNULL, stderr=DEVNULL) as proc: + proc_out, proc_error = proc.communicate() + result = proc.returncode except Exception: log.error('Extracting subtitle has failed') @@ -905,8 +907,8 @@ def mount_iso(item, new_dir): # Currently only supports Linux Mount when permis make_dir(mount_point) cmd = ['mount', '-o', 'loop', item, mount_point] print_cmd(cmd) - proc = subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) - out, err = proc.communicate() + with subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) as proc: + proc_out, proc_err = proc.communicate() nzb2media.MOUNTED = ( mount_point # Allows us to verify this has been done and then cleanup. ) @@ -956,13 +958,13 @@ def rip_iso(item, new_dir): try: log.debug(f'Attempting to extract .vob or .mts from image file {item}') print_cmd(cmd) - proc = subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) - out, err = proc.communicate() + with subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) as proc: + proc_out, proc_err = proc.communicate() file_match_gen = ( re.match( r'.+(VIDEO_TS[/\\]VTS_[0-9][0-9]_[0-9].[Vv][Oo][Bb])', line, ) - for line in out.decode().splitlines() + for line in proc_out.decode().splitlines() ) file_list = [ file_match.groups()[0] @@ -994,7 +996,7 @@ def rip_iso(item, new_dir): else: # check BlueRay for BDMV/STREAM/XXXX.MTS mts_list_gen = ( re.match(r'.+(BDMV[/\\]STREAM[/\\][0-9]+[0-9].[Mm]).', line) - for line in out.decode().splitlines() + for line in proc_out.decode().splitlines() ) mts_list = [ file_match.groups()[0] @@ -1182,17 +1184,18 @@ def transcode_directory(dir_name): result = 1 # set result to failed in case call fails. try: if isinstance(file, str): - proc = subprocess.Popen(command, stdout=DEVNULL, stderr=PIPE) + with subprocess.Popen(command, stdout=DEVNULL, stderr=PIPE) as proc: + out, err = proc.communicate() else: img, data = next(file.items()) - proc = subprocess.Popen(command, stdout=DEVNULL, stderr=PIPE, stdin=PIPE) - for vob in data['files']: - procin = zip_out(vob, img) - if procin: - log.debug(f'Feeding in file: {vob} to Transcoder') - shutil.copyfileobj(procin.stdout, proc.stdin) - procin.stdout.close() - out, err = proc.communicate() + with subprocess.Popen(command, stdout=DEVNULL, stderr=PIPE, stdin=PIPE) as proc: + for vob in data['files']: + procin = zip_out(vob, img) + if procin: + log.debug(f'Feeding in file: {vob} to Transcoder') + shutil.copyfileobj(procin.stdout, proc.stdin) + procin.stdout.close() + out, err = proc.communicate() if err: log.error(f'Transcoder returned:{err} has failed') result = proc.returncode @@ -1231,8 +1234,8 @@ def transcode_directory(dir_name): time.sleep(5) # play it safe and avoid failing to unmount. cmd = ['umount', '-l', nzb2media.MOUNTED] print_cmd(cmd) - proc = subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) - out, err = proc.communicate() + with subprocess.Popen(cmd, stdout=PIPE, stderr=DEVNULL) as proc: + proc_out, proc_err = proc.communicate() time.sleep(5) os.rmdir(nzb2media.MOUNTED) nzb2media.MOUNTED = None diff --git a/nzb2media/user_scripts.py b/nzb2media/user_scripts.py index d761ddd0..92a2c0bf 100644 --- a/nzb2media/user_scripts.py +++ b/nzb2media/user_scripts.py @@ -118,20 +118,20 @@ def external_script(output_destination, torrent_name, torrent_label, settings): cmd = f'{cmd} {item}' log.info(f'Running script {cmd} on file {file_path}.') try: - proc = Popen(command) - res = proc.wait() - if ( - str(res) in nzb2media.USER_SCRIPT_SUCCESSCODES - ): # Linux returns 0 for successful. + with Popen(command) as proc: + res = proc.wait() + except Exception: + log.error(f'UserScript {command[0]} has failed') + result = 1 + else: + if str(res) in nzb2media.USER_SCRIPT_SUCCESSCODES: + # Linux returns 0 for successful. log.info(f'UserScript {command[0]} was successfull') result = 0 else: log.error(f'UserScript {command[0]} has failed with return code: {res}') log.info(f'If the UserScript completed successfully you should add {res} to the user_script_successCodes') - result = int(1) - except Exception: - log.error(f'UserScript {command[0]} has failed') - result = int(1) + result = 1 final_result += result num_files_new = 0 diff --git a/nzb2media/utils/processes.py b/nzb2media/utils/processes.py index 752b0afb..cf4756cc 100644 --- a/nzb2media/utils/processes.py +++ b/nzb2media/utils/processes.py @@ -110,8 +110,8 @@ def restart(): if popen_list: popen_list += nzb2media.SYS_ARGV log.info(f'Restarting nzbToMedia with {popen_list}') - proc = subprocess.Popen(popen_list, cwd=os.getcwd()) - proc.wait() - status = proc.returncode + with subprocess.Popen(popen_list, cwd=os.getcwd()) as proc: + proc.wait() + status = proc.returncode os._exit(status) diff --git a/nzb2media/version_check.py b/nzb2media/version_check.py index cf95e8b2..fed1e778 100644 --- a/nzb2media/version_check.py +++ b/nzb2media/version_check.py @@ -160,52 +160,49 @@ class GitUpdateManager(UpdateManager): def _run_git(self, git_path, args): - proc_out = None + result = None proc_err = None if not git_path: log.debug('No git specified, can\'t use git commands') proc_status = 1 - return proc_out, proc_err, proc_status + return result, proc_err, proc_status cmd = f'{git_path} {args}' try: log.debug(f'Executing {cmd} with your shell in {nzb2media.APP_ROOT}') - proc = subprocess.Popen( + with subprocess.Popen( cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT, shell=True, cwd=nzb2media.APP_ROOT, - ) - proc_out, proc_err = proc.communicate() - proc_status = proc.returncode + ) as proc: + proc_out, proc_err = proc.communicate() + proc_status = proc.returncode - proc_out = proc_out.decode('utf-8') - - if proc_out: - proc_out = proc_out.strip() if nzb2media.LOG_GIT: - log.debug(f'git output: {proc_out}') + msg = proc_out.decode('utf-8').strip() + log.debug(f'git output: {msg}') except OSError: log.error(f'Command {cmd} didn\'t work') proc_status = 1 - proc_status = 128 if ('fatal:' in proc_out) or proc_err else proc_status + proc_status = 128 if ('fatal:' in result) or proc_err else proc_status if proc_status == 0: log.debug(f'{cmd} : returned successful') proc_status = 0 elif nzb2media.LOG_GIT and proc_status in (1, 128): - log.debug(f'{cmd} returned : {proc_out}') + log.debug(f'{cmd} returned : {result}') else: if nzb2media.LOG_GIT: - log.debug(f'{cmd} returned : {proc_out}, treat as error for now') + log.debug(f'{cmd} returned : {result}, treat as error for now') proc_status = 1 - return proc_out, proc_err, proc_status + return result, proc_err, proc_status def _find_installed_version(self): """ @@ -480,9 +477,8 @@ class SourceUpdateManager(UpdateManager): # extract to sb-update dir log.info(f'Extracting file {tar_download_path}') - tar = tarfile.open(tar_download_path) - tar.extractall(sb_update_dir) - tar.close() + with tarfile.open(tar_download_path) as tar: + tar.extractall(sb_update_dir) # delete .tar.gz log.info(f'Deleting file {tar_download_path}')