def isRarSupported(): """ Test Packing Support: - Simulating in memory rar extraction on test.rar file """ try: rar_path = os.path.join(app.PROG_DIR, 'lib', 'unrar2', 'test.rar') testing = RarFile(rar_path).read_files('*test.txt') if testing[0][1] == 'This is only a test.': return 'supported' logger.log('Rar Not Supported: Can not read the content of test file', logger.ERROR) return 'not supported' except Exception as msg: logger.log('Rar Not Supported: {error}'.format(error=ex(msg)), logger.ERROR) return 'not supported'
def unRAR(path, rarFiles, force, result): """ Extracts RAR files :param path: Path to look for files in :param rarFiles: Names of RAR files :param force: process currently processing items :param result: Previous results :return: List of unpacked file names """ unpacked_files = [] if sickbeard.UNPACK and rarFiles: result.output += logHelper(u"Packed Releases detected: " + str(rarFiles), logger.DEBUG) for archive in rarFiles: result.output += logHelper(u"Unpacking archive: " + archive, logger.DEBUG) try: rar_handle = RarFile(os.path.join(path, archive)) # Skip extraction if any file in archive has previously been extracted skip_file = False for file_in_archive in [os.path.basename(x.filename) for x in rar_handle.infolist() if not x.isdir]: if already_postprocessed(path, file_in_archive, force, result): result.output += logHelper( u"Archive file already post-processed, extraction skipped: " + file_in_archive, logger.DEBUG) skip_file = True break if skip_file: continue rar_handle.extract(path=path, withSubpath=False, overwrite=False) for x in rar_handle.infolist(): if not x.isdir: basename = os.path.basename(x.filename) if basename not in unpacked_files: unpacked_files.append(basename) del rar_handle except FatalRARError: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Fatal Error".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Fatal error unpacking archive") continue except CRCRARError: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Archive CRC Error".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : CRC error unpacking archive") continue except IncorrectRARPassword: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Invalid Password".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Password protected RAR") continue except NoFileToExtract: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: No file extracted, check the parent folder and destination file permissions.".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Nothing was unpacked (file permissions?)") continue except GenericRARError: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Generic Error".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking Failed with a Generic Error") continue except Exception, e: result.output += logHelper(u"Failed Unrar archive " + archive + ': ' + ex(e), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking failed for an unknown reason") continue result.output += logHelper(u"UnRar content: " + str(unpacked_files), logger.DEBUG)
def unRAR(path, rarFiles, force, result): unpacked_files = [] if sickbeard.UNPACK and rarFiles: result.output += logHelper(u"Packed Releases detected: " + str(rarFiles), logger.DEBUG) for archive in rarFiles: result.output += logHelper(u"Unpacking archive: " + archive, logger.DEBUG) try: rar_handle = RarFile(os.path.join(path, archive)) # Skip extraction if any file in archive has previously been extracted skip_file = False for file_in_archive in [os.path.basename(x.filename) for x in rar_handle.infolist() if not x.isdir]: if already_postprocessed(path, file_in_archive, force, result): result.output += logHelper( u"Archive file already post-processed, extraction skipped: " + file_in_archive, logger.DEBUG) skip_file = True break if skip_file: continue rar_handle.extract(path=path, withSubpath=False, overwrite=False) for x in rar_handle.infolist(): if not x.isdir: basename = os.path.basename(x.filename) if basename not in unpacked_files: unpacked_files.append(basename) del rar_handle except FatalRARError: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Fatal Error".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Fatal error unpacking archive") continue except CRCRARError: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Archive CRC Error".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : CRC error unpacking archive") continue except IncorrectRARPassword: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Invalid Password".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Password protected RAR") continue except NoFileToExtract: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: No file extracted, check the parent folder and destination file permissions.".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Nothing was unpacked (file permissions?)") continue except GenericRARError: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Generic Error".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking Failed with a Generic Error") continue except Exception, e: result.output += logHelper(u"Failed Unrar archive " + archive + ': ' + ex(e), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking failed for an unknown reason") continue result.output += logHelper(u"UnRar content: " + str(unpacked_files), logger.DEBUG)
def unrar(self, path, rar_files, force=False): """ Extract RAR files. :param path: Path to look for files in :param rar_files: Names of RAR files :param force: process currently processing items :return: List of unpacked file names """ unpacked_files = [] if app.UNPACK and rar_files: self._log('Packed files detected: {0}'.format(rar_files), logger.DEBUG) for archive in rar_files: self._log('Unpacking archive: {0}'.format(archive), logger.DEBUG) failure = None try: rar_handle = RarFile(os.path.join(path, archive)) # Skip extraction if any file in archive has previously been extracted skip_extraction = False for file_in_archive in [ os.path.basename(each.filename) for each in rar_handle.infolist() if not each.isdir ]: if not force and self.already_postprocessed( file_in_archive): self._log( 'Archive file already post-processed, extraction skipped: {0}' .format(file_in_archive), logger.DEBUG) skip_extraction = True break if app.POSTPONE_IF_NO_SUBS and os.path.isfile( os.path.join(path, file_in_archive)): self._log( 'Archive file already extracted, extraction skipped: {0}' .format(file_in_archive), logger.DEBUG) skip_extraction = True break if not skip_extraction: rar_handle.extract(path=path, withSubpath=False, overwrite=False) for each in rar_handle.infolist(): if not each.isdir: basename = os.path.basename(each.filename) unpacked_files.append(basename) del rar_handle except ArchiveHeaderBroken: failure = ( 'Archive Header Broken', 'Unpacking failed because the Archive Header is Broken' ) except IncorrectRARPassword: failure = ( 'Incorrect RAR Password', 'Unpacking failed because of an Incorrect Rar Password' ) except FileOpenError: failure = ( 'File Open Error, check the parent folder and destination file permissions.', 'Unpacking failed with a File Open Error (file permissions?)' ) except InvalidRARArchiveUsage: failure = ( 'Invalid Rar Archive Usage', 'Unpacking Failed with Invalid Rar Archive Usage') except InvalidRARArchive: failure = ( 'Invalid Rar Archive', 'Unpacking Failed with an Invalid Rar Archive Error') except Exception as error: failure = (ex(error), 'Unpacking failed for an unknown reason') if failure is not None: self._log( 'Failed unpacking archive {0}: {1}'.format( archive, failure[0]), logger.WARNING) self.missedfiles.append( '{0}: Unpacking failed: {1}'.format( archive, failure[1])) self.result = False continue self._log('Extracted content: {0}'.format(unpacked_files), logger.DEBUG) return unpacked_files
def unRAR(path, rarFiles, force, result): """ Extracts RAR files :param path: Path to look for files in :param rarFiles: Names of RAR files :param force: process currently processing items :param result: Previous results :return: List of unpacked file names """ unpacked_files = [] if sickbeard.UNPACK and rarFiles: result.output += logHelper( "Packed Releases detected: " + str(rarFiles), logging.DEBUG) for archive in rarFiles: result.output += logHelper("Unpacking archive: " + archive, logging.DEBUG) try: rar_handle = RarFile(ek(os.path.join, path, archive)) # Skip extraction if any file in archive has previously been extracted skip_file = False for file_in_archive in [ ek(os.path.basename, x.filename) for x in rar_handle.infolist() if not x.isdir ]: if already_postprocessed(path, file_in_archive, force, result): result.output += logHelper( "Archive file already post-processed, extraction skipped: " + file_in_archive, logging.DEBUG) skip_file = True break if skip_file: continue rar_handle.extract(path=path, withSubpath=False, overwrite=False) for x in rar_handle.infolist(): if not x.isdir: basename = ek(os.path.basename, x.filename) if basename not in unpacked_files: unpacked_files.append(basename) del rar_handle except ArchiveHeaderBroken as e: result.output += logHelper( "Failed Unrar archive {0}: Unrar: Archive Header Broken". format(archive), logging.ERROR) result.result = False result.missedfiles.append( archive + " : Unpacking failed because the Archive Header is Broken") continue except IncorrectRARPassword: result.output += logHelper( "Failed Unrar archive {0}: Unrar: Incorrect Rar Password". format(archive), logging.ERROR) result.result = False result.missedfiles.append( archive + " : Unpacking failed because of an Incorrect Rar Password") continue except FileOpenError: result.output += logHelper( "Failed Unrar archive {0}: Unrar: File Open Error, check the parent folder and destination file permissions." .format(archive), logging.ERROR) result.result = False result.missedfiles.append( archive + " : Unpacking failed with a File Open Error (file permissions?)" ) continue except InvalidRARArchiveUsage: result.output += logHelper( "Failed Unrar archive {0}: Unrar: Invalid Rar Archive Usage" .format(archive), logging.ERROR) result.result = False result.missedfiles.append( archive + " : Unpacking Failed with Invalid Rar Archive Usage") continue except InvalidRARArchive: result.output += logHelper( "Failed Unrar archive {0}: Unrar: Invalid Rar Archive". format(archive), logging.ERROR) result.result = False result.missedfiles.append( archive + " : Unpacking Failed with an Invalid Rar Archive Error") continue except Exception as e: result.output += logHelper( "Failed Unrar archive " + archive + ': ' + ex(e), logging.ERROR) result.result = False result.missedfiles.append( archive + " : Unpacking failed for an unknown reason") continue result.output += logHelper("UnRar content: " + str(unpacked_files), logging.DEBUG) return unpacked_files
def unRAR(path, rarFiles, force, result): # pylint: disable=too-many-branches,too-many-statements """ Extracts RAR files :param path: Path to look for files in :param rarFiles: Names of RAR files :param force: process currently processing items :param result: Previous results :return: List of unpacked file names """ unpacked_files = [] if sickbeard.UNPACK and rarFiles: result.output += logHelper(u"Packed Releases detected: %s" % rarFiles, logger.DEBUG) for archive in rarFiles: result.output += logHelper(u"Unpacking archive: %s" % archive, logger.DEBUG) failure = None try: rar_handle = RarFile(ek(os.path.join, path, archive)) # Skip extraction if any file in archive has previously been extracted skip_file = False for file_in_archive in [ek(os.path.basename, x.filename) for x in rar_handle.infolist() if not x.isdir]: if already_postprocessed(path, file_in_archive, force, result): result.output += logHelper( u"Archive file already post-processed, extraction skipped: %s" % file_in_archive, logger.DEBUG, ) skip_file = True break if skip_file: continue rar_handle.extract(path=path, withSubpath=False, overwrite=False) for x in rar_handle.infolist(): if not x.isdir: basename = ek(os.path.basename, x.filename) if basename not in unpacked_files: unpacked_files.append(basename) del rar_handle except ArchiveHeaderBroken: failure = (u"Archive Header Broken", u"Unpacking failed because the Archive Header is Broken") except IncorrectRARPassword: failure = (u"Incorrect RAR Password", u"Unpacking failed because of an Incorrect Rar Password") except FileOpenError: failure = ( u"File Open Error, check the parent folder and destination file permissions.", u"Unpacking failed with a File Open Error (file permissions?)", ) except InvalidRARArchiveUsage: failure = (u"Invalid Rar Archive Usage", u"Unpacking Failed with Invalid Rar Archive Usage") except InvalidRARArchive: failure = (u"Invalid Rar Archive", u"Unpacking Failed with an Invalid Rar Archive Error") except Exception as e: failure = (ex(e), u"Unpacking failed for an unknown reason") if failure is not None: result.output += logHelper(u"Failed Unrar archive %s: %s" % (archive, failure[0]), logger.ERROR) result.missedfiles += logHelper(u"%s : Unpacking failed: %s" % (archive, failure[1])) result.result = False continue result.output += logHelper(u"UnRar content: %s" % unpacked_files, logger.DEBUG) return unpacked_files
def unRAR(path, rarFiles, force, result): # pylint: disable=too-many-branches,too-many-statements """ Extracts RAR files :param path: Path to look for files in :param rarFiles: Names of RAR files :param force: process currently processing items :param result: Previous results :return: List of unpacked file names """ unpacked_files = [] if sickbeard.UNPACK and rarFiles: result.output += logHelper(u"Packed Releases detected: %s" % rarFiles, logger.DEBUG) for archive in rarFiles: result.output += logHelper(u"Unpacking archive: %s" % archive, logger.DEBUG) failure = None try: rar_handle = RarFile(ek(os.path.join, path, archive)) # Skip extraction if any file in archive has previously been extracted skip_file = False for file_in_archive in [ ek(os.path.basename, x.filename) for x in rar_handle.infolist() if not x.isdir ]: if already_postprocessed(path, file_in_archive, force, result): result.output += logHelper( u"Archive file already post-processed, extraction skipped: %s" % file_in_archive, logger.DEBUG) skip_file = True break if skip_file: continue rar_handle.extract(path=path, withSubpath=False, overwrite=False) for x in rar_handle.infolist(): if not x.isdir: basename = ek(os.path.basename, x.filename) if basename not in unpacked_files: unpacked_files.append(basename) del rar_handle except ArchiveHeaderBroken: failure = ( u'Archive Header Broken', u'Unpacking failed because the Archive Header is Broken') except IncorrectRARPassword: failure = ( u'Incorrect RAR Password', u'Unpacking failed because of an Incorrect Rar Password') except FileOpenError: failure = ( u'File Open Error, check the parent folder and destination file permissions.', u'Unpacking failed with a File Open Error (file permissions?)' ) except InvalidRARArchiveUsage: failure = (u'Invalid Rar Archive Usage', u'Unpacking Failed with Invalid Rar Archive Usage') except InvalidRARArchive: failure = ( u'Invalid Rar Archive', u'Unpacking Failed with an Invalid Rar Archive Error') except Exception as e: failure = (ex(e), u'Unpacking failed for an unknown reason') if failure is not None: result.output += logHelper( u'Failed Unrar archive {}: {}'.format(archive, failure[0]), logger.ERROR) result.missedfiles.append(u'{} : Unpacking failed: {}'.format( archive, failure[1])) result.result = False continue result.output += logHelper(u"UnRar content: %s" % unpacked_files, logger.DEBUG) return unpacked_files
def extractFiles(self, folder = None, movie_folder = None, files = None, cleanup = False): if not files: files = [] # RegEx for finding rar files archive_regex = '(?P<file>^(?P<base>(?:(?!\.part\d+\.rar$).)*)\.(?:(?:part0*1\.)?rar)$)' restfile_regex = '(^%s\.(?:part(?!0*1\.rar$)\d+\.rar$|[rstuvw]\d+$))' extr_files = [] # Check input variables if not folder: folder = self.conf('from') check_file_date = True if movie_folder: check_file_date = False if not files: for root, folders, names in os.walk(folder): files.extend([os.path.join(root, name) for name in names]) # Find all archive files archives = [re.search(archive_regex, name).groupdict() for name in files if re.search(archive_regex, name)] #Extract all found archives for archive in archives: # Check if it has already been processed by CPS if self.hastagDir(os.path.dirname(archive['file'])): continue # Find all related archive files archive['files'] = [name for name in files if re.search(restfile_regex % re.escape(archive['base']), name)] archive['files'].append(archive['file']) # Check if archive is fresh and maybe still copying/moving/downloading, ignore files newer than 1 minute if check_file_date: file_too_new = False for cur_file in archive['files']: if not os.path.isfile(cur_file): file_too_new = time.time() break file_time = [os.path.getmtime(cur_file), os.path.getctime(cur_file)] for t in file_time: if t > time.time() - 60: file_too_new = tryInt(time.time() - t) break if file_too_new: break if file_too_new: try: time_string = time.ctime(file_time[0]) except: try: time_string = time.ctime(file_time[1]) except: time_string = 'unknown' log.info('Archive seems to be still copying/moving/downloading or just copied/moved/downloaded (created on %s), ignoring for now: %s', (time_string, os.path.basename(archive['file']))) continue log.info('Archive %s found. Extracting...', os.path.basename(archive['file'])) try: rar_handle = RarFile(archive['file']) extr_path = os.path.join(self.conf('from'), os.path.relpath(os.path.dirname(archive['file']), folder)) self.makeDir(extr_path) for packedinfo in rar_handle.infolist(): if not packedinfo.isdir and not os.path.isfile(os.path.join(extr_path, os.path.basename(packedinfo.filename))): log.debug('Extracting %s...', packedinfo.filename) rar_handle.extract(condition = [packedinfo.index], path = extr_path, withSubpath = False, overwrite = False) extr_files.append(os.path.join(extr_path, os.path.basename(packedinfo.filename))) del rar_handle except Exception, e: log.error('Failed to extract %s: %s %s', (archive['file'], e, traceback.format_exc())) continue # Delete the archive files for filename in archive['files']: if cleanup: try: os.remove(filename) except Exception, e: log.error('Failed to remove %s: %s %s', (filename, e, traceback.format_exc())) continue files.remove(filename)
def unrar(self, path, rar_files, force=False): """ Extract RAR files. :param path: Path to look for files in :param rar_files: Names of RAR files :param force: process currently processing items :return: List of unpacked file names """ unpacked_files = [] if app.UNPACK and rar_files: self.log('Packed files detected: {0}'.format(rar_files), logger.DEBUG) for archive in rar_files: self.log('Unpacking archive: {0}'.format(archive), logger.DEBUG) failure = None try: rar_handle = RarFile(os.path.join(path, archive)) # Skip extraction if any file in archive has previously been extracted skip_extraction = False for file_in_archive in [os.path.basename(each.filename) for each in rar_handle.infolist() if not each.isdir]: if not force and self.already_postprocessed(file_in_archive): self.log('Archive file already post-processed, extraction skipped: {0}'.format (file_in_archive), logger.DEBUG) skip_extraction = True break if app.POSTPONE_IF_NO_SUBS and os.path.isfile(os.path.join(path, file_in_archive)): self.log('Archive file already extracted, extraction skipped: {0}'.format (file_in_archive), logger.DEBUG) skip_extraction = True break if not skip_extraction: rar_handle.extract(path=path, withSubpath=False, overwrite=False) for each in rar_handle.infolist(): if not each.isdir: basename = os.path.basename(each.filename) unpacked_files.append(basename) del rar_handle except ArchiveHeaderBroken: failure = ('Archive Header Broken', 'Unpacking failed because the Archive Header is Broken') except IncorrectRARPassword: failure = ('Incorrect RAR Password', 'Unpacking failed because of an Incorrect Rar Password') except FileOpenError: failure = ('File Open Error, check the parent folder and destination file permissions.', 'Unpacking failed with a File Open Error (file permissions?)') except InvalidRARArchiveUsage: failure = ('Invalid Rar Archive Usage', 'Unpacking Failed with Invalid Rar Archive Usage') except InvalidRARArchive: failure = ('Invalid Rar Archive', 'Unpacking Failed with an Invalid Rar Archive Error') except Exception as error: failure = (ex(error), 'Unpacking failed for an unknown reason') if failure is not None: self.log('Failed unpacking archive {0}: {1}'.format(archive, failure[0]), logger.WARNING) self.missedfiles.append('{0}: Unpacking failed: {1}'.format(archive, failure[1])) self.result = False continue self.log('Extracted content: {0}'.format(unpacked_files), logger.DEBUG) return unpacked_files
def unRAR(path, rarFiles, force, result): """ Extracts RAR files :param path: Path to look for files in :param rarFiles: Names of RAR files :param force: process currently processing items :param result: Previous results :return: List of unpacked file names """ unpacked_files = [] if sickbeard.UNPACK and rarFiles: result.output += logHelper(u"Packed Releases detected: " + str(rarFiles), logger.DEBUG) for archive in rarFiles: result.output += logHelper(u"Unpacking archive: " + archive, logger.DEBUG) try: rar_handle = RarFile(ek(os.path.join, path, archive)) # Skip extraction if any file in archive has previously been extracted skip_file = False for file_in_archive in [ek(os.path.basename, x.filename) for x in rar_handle.infolist() if not x.isdir]: if already_postprocessed(path, file_in_archive, force, result): result.output += logHelper( u"Archive file already post-processed, extraction skipped: " + file_in_archive, logger.DEBUG) skip_file = True break if skip_file: continue rar_handle.extract(path=path, withSubpath=False, overwrite=False) for x in rar_handle.infolist(): if not x.isdir: basename = ek(os.path.basename, x.filename) if basename not in unpacked_files: unpacked_files.append(basename) del rar_handle except ArchiveHeaderBroken as e: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Archive Header Broken".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking failed because the Archive Header is Broken") continue except IncorrectRARPassword: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Incorrect Rar Password".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking failed because of an Incorrect Rar Password") continue except FileOpenError: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: File Open Error, check the parent folder and destination file permissions.".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking failed with a File Open Error (file permissions?)") continue except InvalidRARArchiveUsage: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Invalid Rar Archive Usage".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking Failed with Invalid Rar Archive Usage") continue except InvalidRARArchive: result.output += logHelper(u"Failed Unrar archive {0}: Unrar: Invalid Rar Archive".format(archive), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking Failed with an Invalid Rar Archive Error") continue except Exception as e: result.output += logHelper(u"Failed Unrar archive " + archive + ': ' + ex(e), logger.ERROR) result.result = False result.missedfiles.append(archive + " : Unpacking failed for an unknown reason") continue result.output += logHelper(u"UnRar content: " + str(unpacked_files), logger.DEBUG) return unpacked_files