def decrypt(self, pyfile): fs_filename = os.fsencode(pyfile.url) with open(fs_filename, mode="rb") as fp: torrent_content = fp.read() time_ref = "{:.2f}".format(time.time())[-6:].replace(".", "") pack_name = "torrent {}".format(time_ref) if pyfile.url.endswith(".magnet"): if torrent_content.startswith(b"magnet:?"): self.packages.append((pyfile.package().name, [to_str(torrent_content)], pyfile.package().folder)) elif pyfile.url.endswith(".torrent"): m = re.search(rb"name(\d+):", torrent_content) if m: m = re.search( b"".join((b"name", m.group(1), b":(.{", m.group(1), b"})")), torrent_content ) if m: pack_name = safename(to_str(m.group(1))) torrent_filename = os.path.join( self.pyload.tempdir, "tmp_{}.torrent".format(pack_name) ) with open(torrent_filename, mode="wb") as fp: fp.write(torrent_content) self.packages.append( ( pack_name, ["file://{}".format(urllib.request.pathname2url(torrent_filename))], pack_name, ) )
def decrypt(self, pyfile): with open(pyfile.url, mode="rb") as fp: torrent_content = fp.read() time_ref = "{:.2f}".format(time.time())[-6:].replace(".", "") pack_name = "torrent {}".format(time_ref) m = re.search(r"name(\d+):", torrent_content) if m: m = re.search(r"name{}:(.{{{}}})".format(m.group(1), m.group(1)), torrent_content) if m: pack_name = safename(m.group(1)) torrent_filename = os.path.join(self.pyload.tempdir, "tmp_{}.torrent".format(pack_name)) with open(torrent_filename, mode="wb") as fp: fp.write(torrent_content) self.packages.append(( pack_name, [ "file://{}".format( urllib.request.pathname2url(torrent_filename)) ], pack_name, ))
def extract(self, ids, thread=None ): # TODO: Use pypack, not pid to improve method usability if not ids: return False extracted = [] failed = [] def to_list(value): return value.replace(" ", "").replace(",", "|").replace(";", "|").split("|") destination = self.config.get("destination") subfolder = self.config.get("subfolder") fullpath = self.config.get("fullpath") overwrite = self.config.get("overwrite") priority = self.config.get("priority") recursive = self.config.get("recursive") keepbroken = self.config.get("keepbroken") extensions = [ x.lstrip(".").lower() for x in to_list(self.config.get("extensions")) ] excludefiles = to_list(self.config.get("excludefiles")) if extensions: self.log_debug(f"Use for extensions: .{'|.'.join(extensions)}") #: Reload from txt file self.reload_passwords() dl_folder = self.pyload.config.get("general", "storage_folder") #: Iterate packages -> extractors -> targets for pid in ids: pypack = self.pyload.files.get_package(pid) if not pypack: self.queue.remove(pid) continue self.log_info(self._("Check package: {}").format(pypack.name)) pack_dl_folder = os.path.join(dl_folder, pypack.folder, "") #: Force trailing slash #: Determine output folder extract_folder = os.path.join(pack_dl_folder, destination, "") #: Force trailing slash if subfolder: extract_folder = os.path.join( extract_folder, pypack.folder or safename(pypack.name.replace("http://", "")), ) if not exists(extract_folder): os.makedirs(extract_folder) if subfolder: self.set_permissions(extract_folder) matched = False success = True files_ids = list({ fdata["name"]: ( fdata["id"], (os.path.join(pack_dl_folder, fdata["name"])), extract_folder, ) for fdata in pypack.get_children().values() }.values()) #: : Remove duplicates #: Check as long there are unseen files while files_ids: new_files_ids = [] if extensions: #: Include only specified archive types files_ids = [ file_id for file_id in files_ids if any([ Extractor.archivetype(file_id[1]) in extensions for Extractor in self.extractors ]) ] #: Sort by filename to ensure (or at least try) that a multi-volume archive is targeted by its first part #: This is important because, for example, UnRar ignores preceding parts in listing mode files_ids.sort(key=lambda file_id: file_id[1]) for Extractor in self.extractors: targets = Extractor.get_targets(files_ids) if targets: self.log_debug("Targets for {}: {}".format( Extractor.__name__, targets)) matched = True for fid, fname, fout in targets: name = os.path.basename(fname) if not exists(fname): self.log_debug(name, "File not found") continue self.log_info( name, self._("Extract to: {}").format(fout)) try: pyfile = self.pyload.files.get_file(fid) archive = Extractor( pyfile, fname, fout, fullpath, overwrite, excludefiles, priority, keepbroken, ) thread.add_active(pyfile) archive.init() #: Save for removal from file processing list, which happens after deletion. #: So archive.chunks() would just return an empty list. chunks = archive.chunks() try: new_files = self._extract( pyfile, archive, pypack.password) finally: pyfile.set_progress(100) thread.finish_file(pyfile) except Exception as exc: self.log_error(name, exc) success = False continue #: Remove processed file and related multiparts from list files_ids = [(_fid, _fname, _fout) for _fid, _fname, _fout in files_ids if _fname not in chunks] self.log_debug(f"Extracted files: {new_files}") new_folders = [] for _f in new_files: _d = os.path.dirname(_f) while extract_folder in _d: if _d not in new_folders: new_folders.append(_d) _d = os.path.dirname(_d) for foldername in new_folders: self.set_permissions(foldername) for filename in new_files: self.set_permissions(filename) for filename in new_files: if not exists(filename): self.log_debug( f"New file {filename} does not exists") continue if recursive and os.path.isfile(filename): new_files_ids.append( (fid, filename, os.path.dirname(filename) )) #: Append as new target self.m.dispatch_event("archive_extracted", pyfile, archive) files_ids = new_files_ids #: Also check extracted files if matched: if success: #: Delete empty pack folder if extract_folder resides outside download folder if self.config.get("delete") and self.pyload.config.get( "general", "folder_per_package"): if not extract_folder.startswith(pack_dl_folder): if len(os.listdir(pack_dl_folder)) == 0: try: os.rmdir(pack_dl_folder) self.log_debug( "Successfully deleted pack folder {}". format(pack_dl_folder)) except OSError: self.log_warning( "Unable to delete pack folder {}". format(pack_dl_folder)) else: self.log_warning( "Not deleting pack folder {}, folder not empty" .format(pack_dl_folder)) extracted.append(pid) self.m.dispatch_event("package_extracted", pypack) else: failed.append(pid) self.m.dispatch_event("package_extract_failed", pypack) else: self.log_info(self._("No files found to extract")) if not matched or not success and subfolder: try: os.rmdir(extract_folder) except OSError: pass self.queue.remove(pid) return True if not failed else False
def set_folder(x): return self.pyload.api.set_package_data( pid, {"_folder": safename(x or "")})