def is_archive(path): """ Check if file in path is an ZIP, RAR or 7z file :param path: path to file :return: (zf, status, expected_extension) status: -1==Error/Retry, 0==OK, 1==Ignore """ if zipfile.is_zipfile(path): try: zf = zipfile.ZipFile(path) return 0, zf, '.zip' except: return -1, None, '' elif is_rarfile(path): try: zf = RarFile(path) return 0, zf, '.rar' except: return -1, None, '' elif is_sevenfile(path): try: zf = SevenZip(path) return 0, zf, '.7z' except: return -1, None, '' else: return 1, None, ''
def check_encrypted_rar(nzo, filepath): """ Check if file is rar and is encrypted """ encrypted = False if not nzo.password and cfg.pause_on_pwrar() and is_rarfile(filepath): try: zf = RarFile(filepath) encrypted = zf.encrypted if encrypted and int(nzo.encrypted) < 2: nzo.encrypted = 1 else: encrypted = False zf.close() del zf except: logging.debug('RAR file %s cannot be inspected', filepath) return encrypted
def check_encrypted_rar(nzo, filepath): """ Check if file is rar and is encrypted """ encrypted = False if not nzo.password and cfg.pause_on_pwrar() and is_rarfile(filepath): try: zf = RarFile(filepath, all_names=True) encrypted = zf.encrypted or is_cloaked(filepath, zf.namelist()) if encrypted and int(nzo.encrypted) < 2: nzo.encrypted = 1 else: encrypted = False zf.close() del zf except: logging.debug('RAR file %s cannot be inspected', filepath) return encrypted
def check_encrypted_rar(nzo, filepath): """ Check if file is rar and is encrypted """ encrypted = False if not nzo.password and not nzo.meta.get('password') and cfg.pause_on_pwrar() and is_rarfile(filepath): try: zf = RarFile(filepath, all_names=True) encrypted = zf.encrypted or is_cloaked(filepath, zf.namelist()) if encrypted and int(nzo.encrypted) < 2 and not nzo.reuse: nzo.encrypted = 1 else: encrypted = False zf.close() del zf except: logging.debug('RAR file %s cannot be inspected', filepath) return encrypted
def abort(self): """ Abort running instance and delete generated files """ if not self.killed: logging.info('Aborting DirectUnpack for %s', self.cur_setname) self.killed = True # Save reference to the first rarfile rarfile_nzf = self.rarfile_nzf # Abort Unrar if self.active_instance: self.active_instance.kill() # We need to wait for it to kill the process self.active_instance.wait() # Wake up the thread with self.next_file_lock: self.next_file_lock.notify() # No new sets self.next_sets = [] self.success_sets = {} # Remove files if self.unpack_dir_info: extraction_path, _, _, one_folder, _ = self.unpack_dir_info # In case of flat-unpack we need to remove the files manually if one_folder: # RarFile can fail for mysterious reasons try: rar_contents = RarFile(os.path.join( self.nzo.downpath, rarfile_nzf.filename), all_names=True).filelist() for rm_file in rar_contents: # Flat-unpack, so remove foldername from RarFile output f = os.path.join(extraction_path, os.path.basename(rm_file)) logging.debug('Removing file %s', f) os.remove(f) except: # The user will have to remove it themselves logging.info( 'Failed to clean Direct Unpack after aborting %s', rarfile_nzf.filename, exc_info=True) pass else: # We can just remove the whole path remove_all(extraction_path, recursive=True) # Remove dir-info self.unpack_dir_info = None # Reset settings self.reset_active()
def rar_contains_unwanted_file(filepath): # checks for unwanted extensions in the rar file 'filepath' # ... unwanted extensions are defined in global variable cfg.unwanted_extensions() # returns False if no unwanted extensions are found in the rar file # returns name of file if unwanted extension is found in the rar file unwanted = None if cfg.unwanted_extensions() and is_rarfile(filepath): # logging.debug('rar file to check: %s',filepath) # logging.debug('unwanted extensions are: %s', cfg.unwanted_extensions()) try: zf = RarFile(filepath, all_names=True) # logging.debug('files in rar file: %s', zf.namelist()) for somefile in zf.namelist(): logging.debug("file in rar file: %s", somefile) if os.path.splitext(somefile)[1].replace(".", "").lower() in cfg.unwanted_extensions(): logging.debug("Unwanted file %s", somefile) unwanted = somefile zf.close() except: logging.debug("RAR file %s cannot be inspected.", filepath) return unwanted
def rar_contains_unwanted_file(filepath): # checks for unwanted extensions in the rar file 'filepath' # ... unwanted extensions are defined in global variable cfg.unwanted_extensions() # returns False if no unwanted extensions are found in the rar file # returns name of file if unwanted extension is found in the rar file unwanted = None if is_rarfile(filepath): #logging.debug('rar file to check: %s',filepath) #logging.debug('unwanted extensions are: %s', cfg.unwanted_extensions()) try: zf = RarFile(filepath, all_names=True) #logging.debug('files in rar file: %s', zf.namelist()) for somefile in zf.namelist() : logging.debug('file in rar file: %s', somefile) if os.path.splitext(somefile)[1].replace('.', '').lower() in cfg.unwanted_extensions(): logging.debug('Unwanted file %s', somefile) unwanted = somefile zf.close() except: logging.debug('RAR file %s cannot be inspected.', filepath) return unwanted
def check_encrypted_rar(nzo, filepath): """ Check if file is rar and is encrypted """ encrypted = False if ( nzo.encrypted == 0 and not nzo.password and not nzo.meta.get("password") and cfg.pause_on_pwrar() and is_rarfile(filepath) ): try: zf = RarFile(filepath, all_names=True) encrypted = zf.encrypted or is_cloaked(filepath, zf.namelist()) if encrypted and not nzo.reuse: nzo.encrypted = 1 else: # Don't check other files nzo.encrypted = -1 encrypted = False zf.close() del zf except: logging.debug("RAR file %s cannot be inspected", filepath) return encrypted
def abort(self): """ Abort running instance and delete generated files """ if not self.killed and self.cur_setname: logging.info("Aborting DirectUnpack for %s", self.cur_setname) self.killed = True # Save reference to the first rarfile rarfile_nzf = self.rarfile_nzf # Abort Unrar if self.active_instance: # First we try to abort gracefully try: self.active_instance.stdin.write(b"Q\n") time.sleep(0.2) except IOError: pass # Now force kill and give it a bit of time try: self.active_instance.kill() time.sleep(0.2) except AttributeError: # Already killed by the Quit command pass # Wake up the thread with self.next_file_lock: self.next_file_lock.notify() # No new sets self.next_sets = [] self.success_sets = {} # Remove files if self.unpack_dir_info: extraction_path, _, _, one_folder, _ = self.unpack_dir_info # In case of flat-unpack we need to remove the files manually if one_folder: # RarFile can fail for mysterious reasons try: rar_contents = RarFile( os.path.join(self.nzo.downpath, rarfile_nzf.filename), single_file_check=True).filelist() for rm_file in rar_contents: # Flat-unpack, so remove foldername from RarFile output f = os.path.join(extraction_path, os.path.basename(rm_file)) remove_file(f) except: # The user will have to remove it themselves logging.info( "Failed to clean Direct Unpack after aborting %s", rarfile_nzf.filename, exc_info=True) else: # We can just remove the whole path remove_all(extraction_path, recursive=True) # Remove dir-info self.unpack_dir_info = None # Reset settings self.reset_active()
def ProcessArchiveFile(filename, path, pp=None, script=None, cat=None, catdir=None, keep=False, priority=None, url='', nzbname=None): """ Analyse ZIP file and create job(s). Accepts ZIP files with ONLY nzb/nfo/folder files in it. returns (status, nzo_ids) status: -1==Error/Retry, 0==OK, 1==Ignore """ from sabnzbd.nzbqueue import add_nzo nzo_ids = [] if catdir is None: catdir = cat filename, cat = name_to_cat(filename, catdir) if zipfile.is_zipfile(path): try: zf = zipfile.ZipFile(path) except: return -1, [] elif is_rarfile(path): try: zf = RarFile(path) except: return -1, [] else: return 1, [] status = 1 names = zf.namelist() names.sort() nzbcount = 0 for name in names: name = name.lower() if not (name.endswith('.nzb') or name.endswith('.nfo') or name.endswith('/')): status = 1 break elif name.endswith('.nzb'): status = 0 nzbcount += 1 if status == 0: if nzbcount != 1: nzbname = None for name in names: if name.lower().endswith('.nzb'): try: data = zf.read(name) except: zf.close() return -1, [] name = re.sub(r'\[.*nzbmatrix.com\]', '', name) name = os.path.basename(name) name = misc.sanitize_foldername(name) if data: try: nzo = nzbstuff.NzbObject(name, 0, pp, script, data, cat=cat, url=url, priority=priority, nzbname=nzbname) except: nzo = None if nzo: nzo_ids.append(add_nzo(nzo)) nzo.update_rating() zf.close() try: if not keep: os.remove(path) except: logging.error(Ta('Error removing %s'), path) logging.info("Traceback: ", exc_info = True) status = 1 else: zf.close() status = 1 return status, nzo_ids
def abort(self): """ Abort running instance and delete generated files """ if not self.killed and self.cur_setname: logging.info('Aborting DirectUnpack for %s', self.cur_setname) self.killed = True # Save reference to the first rarfile rarfile_nzf = self.rarfile_nzf # Abort Unrar if self.active_instance: # First we try to abort gracefully try: self.active_instance.stdin.write('Q\n') time.sleep(0.2) except IOError: pass # Now force kill and give it a bit of time self.active_instance.kill() time.sleep(0.2) # Have to collect the return-code to avoid zombie # But it will block forever if the process is in special state. # That should never happen, but it can happen on broken unrar's if self.active_instance.poll(): self.active_instance.communicate() else: # It is still running?!? This should never happen # Wait a little bit longer just to be sure.. time.sleep(2.0) if not self.active_instance.poll(): logging.warning(T('Unable to stop the unrar process.')) # Wake up the thread with self.next_file_lock: self.next_file_lock.notify() # No new sets self.next_sets = [] self.success_sets = {} # Remove files if self.unpack_dir_info: extraction_path, _, _, one_folder, _ = self.unpack_dir_info # In case of flat-unpack we need to remove the files manually if one_folder: # RarFile can fail for mysterious reasons try: rar_contents = RarFile(os.path.join( self.nzo.downpath, rarfile_nzf.filename), all_names=True).filelist() for rm_file in rar_contents: # Flat-unpack, so remove foldername from RarFile output f = os.path.join(extraction_path, os.path.basename(rm_file)) remove_file(f) except: # The user will have to remove it themselves logging.info( 'Failed to clean Direct Unpack after aborting %s', rarfile_nzf.filename, exc_info=True) else: # We can just remove the whole path remove_all(extraction_path, recursive=True) # Remove dir-info self.unpack_dir_info = None # Reset settings self.reset_active()
def ProcessArchiveFile(filename, path, pp=None, script=None, cat=None, catdir=None, keep=False, priority=None, url='', nzbname=None, password=None, nzo_id=None): """ Analyse ZIP file and create job(s). Accepts ZIP files with ONLY nzb/nfo/folder files in it. returns (status, nzo_ids) status: -1==Error/Retry, 0==OK, 1==Ignore """ from sabnzbd.nzbqueue import add_nzo nzo_ids = [] if catdir is None: catdir = cat filename, cat = name_to_cat(filename, catdir) if zipfile.is_zipfile(path): try: zf = zipfile.ZipFile(path) except: return -1, [] elif is_rarfile(path): try: zf = RarFile(path) except: return -1, [] elif is_sevenfile(path): try: zf = SevenZip(path) except: return -1, [] else: return 1, [] status = 1 names = zf.namelist() names.sort() nzbcount = 0 for name in names: name = name.lower() if not (name.endswith('.nzb') or name.endswith('.nfo') or name.endswith('/')): status = 1 break elif name.endswith('.nzb'): status = 0 nzbcount += 1 if status == 0: if nzbcount != 1: nzbname = None for name in names: if name.lower().endswith('.nzb'): try: data = zf.read(name) except: zf.close() return -1, [] name = os.path.basename(name) if data: try: nzo = nzbstuff.NzbObject(name, pp, script, data, cat=cat, url=url, priority=priority, nzbname=nzbname) if not nzo.password: nzo.password = password except: nzo = None if nzo: if nzo_id: # Re-use existing nzo_id, when a "future" job gets it payload sabnzbd.nzbqueue.NzbQueue.do.remove(nzo_id, add_to_history=False) nzo.nzo_id = nzo_id nzo_ids.append(add_nzo(nzo)) nzo.update_rating() zf.close() try: if not keep: os.remove(path) except: logging.error(T('Error removing %s'), misc.clip_path(path)) logging.info("Traceback: ", exc_info=True) status = 1 else: zf.close() status = 1 return status, nzo_ids