Ejemplo n.º 1
0
    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,
                )
            )
Ejemplo n.º 2
0
    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,
        ))
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
 def set_folder(x):
     return self.pyload.api.set_package_data(
         pid, {"_folder": safename(x or "")})