def create_unrar_instance(self): """ Start the unrar instance using the user's options """ # Generate extraction path and save for post-proc if not self.unpack_dir_info: self.unpack_dir_info = prepare_extraction_path(self.nzo) extraction_path, _, _, one_folder, _ = self.unpack_dir_info # Set options if self.nzo.password: password_command = '-p%s' % self.nzo.password else: password_command = '-p-' if one_folder or cfg.flat_unpack(): action = 'e' else: action = 'x' # The first NZF self.rarfile_nzf = self.have_next_volume() # Generate command rarfile_path = os.path.join(self.nzo.downpath, self.rarfile_nzf.filename) if sabnzbd.WIN32: if not has_win_device(rarfile_path): command = [ '%s' % sabnzbd.newsunpack.RAR_COMMAND, action, '-vp', '-idp', '-o+', '-ai', password_command, '%s' % clip_path(rarfile_path), clip_path(extraction_path) ] else: # Need long-path notation in case of forbidden-names command = [ '%s' % sabnzbd.newsunpack.RAR_COMMAND, action, '-vp', '-idp', '-o+', '-ai', password_command, '%s' % clip_path(rarfile_path), '%s\\' % extraction_path ] else: # Don't use "-ai" (not needed for non-Windows) command = [ '%s' % sabnzbd.newsunpack.RAR_COMMAND, action, '-vp', '-idp', '-o+', password_command, '%s' % rarfile_path, '%s/' % extraction_path ] if cfg.ignore_unrar_dates(): command.insert(3, '-tsm-') # Let's start from the first one! self.cur_volume = 1 stup, need_shell, command, creationflags = build_command(command) logging.debug('Running unrar for DirectUnpack %s', command) self.active_instance = Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, creationflags=creationflags) # Add to runners ACTIVE_UNPACKERS.append(self) # Doing the first logging.info('DirectUnpacked volume %s for %s', self.cur_volume, self.cur_setname)
def check_encrypted_and_unwanted_files(nzo, filepath): """ Combines check for unwanted and encrypted files to save on CPU and IO """ encrypted = False unwanted = None if (cfg.unwanted_extensions() and cfg.action_on_unwanted_extensions()) or ( nzo.encrypted == 0 and cfg.pause_on_pwrar()): # These checks should not break the assembler try: # Rarfile freezes on Windows special names, so don't try those! if sabnzbd.WIN32 and has_win_device(filepath): return encrypted, unwanted # Is it even a rarfile? if rarfile.is_rarfile(filepath): # Open the rar rarfile.UNRAR_TOOL = sabnzbd.newsunpack.RAR_COMMAND zf = rarfile.RarFile(filepath, all_names=True) # Check for encryption if nzo.encrypted == 0 and cfg.pause_on_pwrar() and ( zf.needs_password() or is_cloaked(nzo, filepath, zf.namelist())): # Load all passwords passwords = get_all_passwords(nzo) # Cloaked job? if is_cloaked(nzo, filepath, zf.namelist()): encrypted = True elif not sabnzbd.HAVE_CRYPTOGRAPHY and not passwords: # if no cryptography installed, only error when no password was set logging.info(T('%s missing'), 'Python Cryptography') nzo.encrypted = 1 encrypted = True elif sabnzbd.HAVE_CRYPTOGRAPHY: # Lets test if any of the password work password_hit = False for password in passwords: if password: logging.info( 'Trying password "%s" on job "%s"', password, nzo.final_name) try: zf.setpassword(password) except: # On weird passwords the setpassword() will fail # but the actual rartest() will work pass try: zf.testrar() password_hit = password break except rarfile.RarCRCError: # On CRC error we can continue! password_hit = password break except Exception as e: # Did we start from the right volume? if 'need to start extraction from a previous volume' in e[ 0]: return encrypted, unwanted # This one failed pass # Did any work? if password_hit: # We always trust the user's input if not nzo.password: nzo.password = password_hit # Don't check other files logging.info('Password "%s" matches for job "%s"', password_hit, nzo.final_name) nzo.encrypted = -1 encrypted = False else: # Encrypted and none of them worked nzo.encrypted = 1 encrypted = True else: # Don't check other files nzo.encrypted = -1 encrypted = False # Check for unwanted extensions if cfg.unwanted_extensions( ) and cfg.action_on_unwanted_extensions(): for somefile in zf.namelist(): logging.debug('File contains: %s', somefile) if get_ext(somefile).replace( '.', '').lower() in cfg.unwanted_extensions(): logging.debug('Unwanted file %s', somefile) unwanted = somefile zf.close() del zf except: logging.info('Error during inspection of RAR-file %s', filepath) logging.debug('Traceback: ', exc_info=True) return encrypted, unwanted
def check_encrypted_and_unwanted_files(nzo, filepath): """ Combines check for unwanted and encrypted files to save on CPU and IO """ encrypted = False unwanted = None if (cfg.unwanted_extensions() and cfg.action_on_unwanted_extensions()) or (nzo.encrypted == 0 and cfg.pause_on_pwrar()): # These checks should not break the assembler try: # Rarfile freezes on Windows special names, so don't try those! if sabnzbd.WIN32 and has_win_device(filepath): return encrypted, unwanted # Is it even a rarfile? if rarfile.is_rarfile(filepath): # Open the rar rarfile.UNRAR_TOOL = sabnzbd.newsunpack.RAR_COMMAND zf = rarfile.RarFile(filepath, all_names=True) # Check for encryption if nzo.encrypted == 0 and cfg.pause_on_pwrar() and (zf.needs_password() or is_cloaked(nzo, filepath, zf.namelist())): # Load all passwords passwords = get_all_passwords(nzo) # Cloaked job? if is_cloaked(nzo, filepath, zf.namelist()): encrypted = True elif not sabnzbd.HAVE_CRYPTOGRAPHY and not passwords: # if no cryptography installed, only error when no password was set logging.info(T('%s missing'), 'Python Cryptography') nzo.encrypted = 1 encrypted = True elif sabnzbd.HAVE_CRYPTOGRAPHY: # Lets test if any of the password work password_hit = False for password in passwords: if password: logging.info('Trying password "%s" on job "%s"', password, nzo.final_name) try: zf.setpassword(password) except: # On weird passwords the setpassword() will fail # but the actual rartest() will work pass try: zf.testrar() password_hit = password break except rarfile.RarCRCError: # On CRC error we can continue! password_hit = password break except Exception as e: # Did we start from the right volume? if 'need to start extraction from a previous volume' in e[0]: return encrypted, unwanted # This one failed pass # Did any work? if password_hit: # Don't check other files logging.info('Password "%s" matches for job "%s"', password_hit, nzo.final_name) nzo.encrypted = -1 encrypted = False else: # Encrypted and none of them worked nzo.encrypted = 1 encrypted = True else: # Don't check other files nzo.encrypted = -1 encrypted = False # Check for unwanted extensions if cfg.unwanted_extensions() and cfg.action_on_unwanted_extensions(): for somefile in zf.namelist(): logging.debug('File contains: %s', somefile) if os.path.splitext(somefile)[1].replace('.', '').lower() in cfg.unwanted_extensions(): logging.debug('Unwanted file %s', somefile) unwanted = somefile zf.close() del zf except: logging.info('Error during inspection of RAR-file %s', filepath, exc_info=True) return encrypted, unwanted