Ejemplo n.º 1
0
def Make(logger, path, torrentPath):
    def Callback(meta):
        metafile.assign_fields(meta, ['info.source=PTP'])

    logger.info("Making torrent from '%s' to '%s'." % (path, torrentPath))
    torrent = metafile.Metafile(torrentPath, datapath=path)

    if os.path.exists(torrentPath):
        raise PtpUploaderException("Can't create torrent because path '%s' already exists." % torrentPath)

    torrent.create(path, Settings.PtpAnnounceUrl, created_by="PtpUploader", private=True, progress=None,
                   callback=Callback)
Ejemplo n.º 2
0
    def mainloop(self):
        """ The main loop.
        """
        if not self.args:
            self.parser.print_help()
            self.parser.exit()
        elif len(self.args) < 1:
            self.parser.error("Expecting at least a metafile name")

        # Read metafile
        metapath = self.args[0]
        try:
            metainfo = bencode.bread(metapath)
        except (KeyError, bencode.BencodeError) as exc:
            self.fatal("Bad metafile %r (%s)" % (metapath, type(exc).__name__), exc)
            raise
        else:
            # Check metafile integrity
            try:
                metafile.check_meta(metainfo)
            except ValueError as exc:
                self.fatal("Metafile %r failed integrity check" % (metapath,), exc)
                raise
            else:
                if len(self.args) > 1:
                    datapath = self.args[1].rstrip(os.sep)
                else:
                    datapath = metainfo["info"]["name"]

                # Check the hashes
                torrent = metafile.Metafile(metapath)
                try:
                    ok = torrent.check(metainfo, datapath,
                        progress=None if self.options.quiet else metafile.console_progress())
                    if not ok:
                        self.fatal("Metafile %r has checksum errors" % (metapath,))
                        sys.exit(1)
                except OSError as exc:
                    self.fatal("Torrent data file missing", exc)
                    raise
Ejemplo n.º 3
0
    def mainloop(self):
        """ The main loop.
        """
        if not self.args:
            self.parser.print_help()
            self.parser.exit()

        for idx, filename in enumerate(self.args):
            torrent = metafile.Metafile(filename)
            if idx and not self.options.output:
                print('')
                print("~" * 79)

            try:
                # Read and check metafile
                try:
                    data = metafile.checked_open(
                        filename,
                        log=self.LOG if self.options.skip_validation else None,
                        quiet=(self.options.quiet
                               and (self.options.output or self.options.raw)))
                except EnvironmentError as exc:
                    self.fatal("Can't read '%s' (%s)" % (
                        filename,
                        str(exc).replace(": '%s'" % filename, ""),
                    ))
                    raise

                listing = None

                if self.options.raw or self.options.json:
                    if not self.options.reveal and "info" in data:
                        # Shorten useless binary piece hashes
                        data["info"]["pieces"] = "<%d piece hashes>" % (
                            len(data["info"]["pieces"]) /
                            len(hashlib.sha1().digest())  # bogus pylint: disable=E1101
                        )

                    if self.options.json:
                        listing = json.dumps(data,
                                             default=repr,
                                             indent=4,
                                             sort_keys=True)
                    else:
                        pprinter = (pprint.PrettyPrinter if self.options.reveal
                                    else metafile.MaskingPrettyPrinter)()
                        listing = pprinter.pformat(data)
                elif self.options.output:

                    def splitter(fields):
                        "Yield single names for a list of comma-separated strings."
                        for flist in fields:
                            for field in flist.split(','):
                                yield field.strip()

                    data["__file__"] = filename
                    if 'info' in data:
                        data["__hash__"] = metafile.info_hash(data)
                        data["__size__"] = metafile.data_size(data)
                    values = []
                    for field in splitter(self.options.output):
                        try:
                            val = data
                            for key in field.split('.'):
                                val = val[key]
                        except KeyError as exc:
                            self.LOG.error("%s: Field %r not found (%s)" %
                                           (filename, field, exc))
                            break
                        else:
                            values.append(str(val))
                    else:
                        listing = '\t'.join(values)
                else:
                    listing = '\n'.join(
                        torrent.listing(masked=not self.options.reveal))
            except (ValueError, KeyError, bencode.BencodeError) as exc:
                if self.options.debug:
                    raise
                self.LOG.warning("Bad metafile %r (%s: %s)" %
                                 (filename, type(exc).__name__, exc))
            else:
                if listing is not None:
                    print(fmt.to_utf8(listing))
Ejemplo n.º 4
0
    def mainloop(self):
        """ The main loop.
        """
        if len(self.args) == 1 and "=urn:btih:" in self.args[0]:
            # Handle magnet link
            self.make_magnet_meta(self.args[0])
            return

        if not self.args:
            self.parser.print_help()
            self.parser.exit()
        elif len(self.args) < 2:
            self.parser.error(
                "Expected a path and at least one announce URL, got: %s" %
                (' '.join(self.args), ))

        # Create and configure metafile factory
        datapath = self.args[0].rstrip(os.sep)
        metapath = datapath
        if self.options.output_filename:
            metapath = self.options.output_filename
            if os.path.isdir(metapath):
                metapath = os.path.join(metapath, os.path.basename(datapath))
        if not metapath.endswith(".torrent"):
            metapath += ".torrent"
        torrent = metafile.Metafile(metapath)
        torrent.ignore.extend(self.options.exclude)

        def callback(meta):
            "Callback to set label and resume data."
            if self.options.cross_seed:
                if self.options.cross_seed == "@entropy":
                    meta["info"]["entropy"] = format(
                        random.getrandbits(self.ENTROPY_BITS),
                        'x').zfill(self.ENTROPY_BITS // 4)
                else:
                    meta["info"][
                        "x_cross_seed_label"] = self.options.cross_seed
            if self.options.no_cross_seed:
                del meta["info"]["x_cross_seed"]

            # Set specific keys?
            metafile.assign_fields(meta, self.options.set, self.options.debug)

        # Create and write the metafile(s)
        # TODO: make it work better with multiple trackers (hash only once), also create fast-resume file for each tracker
        meta = torrent.create(datapath,
                              self.args[1:],
                              progress=None if self.options.quiet else
                              metafile.console_progress(),
                              root_name=self.options.root_name,
                              private=self.options.private,
                              no_date=self.options.no_date,
                              comment=self.options.comment,
                              created_by="PyroScope %s" % self.version,
                              callback=callback)
        tied_file = metapath

        # Create second metafile with fast-resume?
        if self.options.hashed:
            try:
                metafile.add_fast_resume(meta, datapath)
            except EnvironmentError as exc:
                self.fatal("Error making fast-resume data (%s)" % (exc, ))
                raise

            hashed_path = re.sub(r"\.torrent$", "",
                                 metapath) + "-resume.torrent"
            self.LOG.info("Writing fast-resume metafile %r..." %
                          (hashed_path, ))
            try:
                bencode.bwrite(hashed_path, meta)
                tied_file = hashed_path
            except EnvironmentError as exc:
                self.fatal("Error writing fast-resume metafile %r (%s)" % (
                    hashed_path,
                    exc,
                ))
                raise

        # Load into client on demand
        if self.options.load or self.options.start:
            proxy = config.engine.open()
            info_hash = metafile.info_hash(meta)
            try:
                item_name = proxy.d.name(info_hash, fail_silently=True)
            except xmlrpc.HashNotFound:
                load_item = proxy.load.start_verbose if self.options.start else proxy.load.verbose
                load_item(xmlrpc.NOHASH, os.path.abspath(tied_file))
                time.sleep(.05)  # let things settle
                try:
                    item_name = proxy.d.name(info_hash, fail_silently=True)
                    self.LOG.info(
                        "OK: Item #%s %s client.", info_hash,
                        'started in' if self.options.start else 'loaded into')
                except xmlrpc.HashNotFound as exc:
                    self.fatal("Error while loading item #%s into client: %s" %
                               (
                                   info_hash,
                                   exc,
                               ))
            else:
                self.LOG.warning(
                    "Item #%s already exists in client, --load/--start is ignored!",
                    info_hash)
Ejemplo n.º 5
0
    def mainloop(self):
        """ The main loop.
        """
        if len(self.args) == 1 and "=urn:btih:" in self.args[0]:
            # Handle magnet link
            self.make_magnet_meta(self.args[0])
            return

        if not self.args:
            self.parser.print_help()
            self.parser.exit()
        elif len(self.args) < 2:
            self.parser.error("Expected a path and at least one announce URL, got: %s" % (' '.join(self.args),))

        # Create and configure metafile factory
        datapath = self.args[0].rstrip(os.sep)
        metapath = datapath
        if self.options.output_filename:
            metapath = self.options.output_filename
            if os.path.isdir(metapath):
                metapath = os.path.join(metapath, os.path.basename(datapath))
        if not metapath.endswith(".torrent"):
            metapath += ".torrent"
        torrent = metafile.Metafile(metapath)
        torrent.ignore.extend(self.options.exclude)

        def callback(meta):
            "Callback to set label and resume data."
            if self.options.cross_seed:
                if self.options.cross_seed == "@entropy":
                    meta["info"]["entropy"] = format(random.getrandbits(self.ENTROPY_BITS),
                                                     'x').zfill(self.ENTROPY_BITS//4)
                else:
                    meta["info"]["x_cross_seed_label"] = self.options.cross_seed
            if self.options.no_cross_seed:
                del meta["info"]["x_cross_seed"]

            # Set specific keys?
            metafile.assign_fields(meta, self.options.set)

        # Create and write the metafile(s)
        # TODO: make it work better with multiple trackers (hash only once), also create fast-resume file for each tracker
        meta = torrent.create(datapath, self.args[1:],
            progress=None if self.options.quiet else metafile.console_progress(),
            root_name=self.options.root_name, private=self.options.private, no_date=self.options.no_date,
            comment=self.options.comment, created_by="PyroScope %s" % self.version, callback=callback
        )

        # Create second metafile with fast-resume?
        if self.options.hashed:
            try:
                metafile.add_fast_resume(meta, datapath)
            except EnvironmentError as exc:
                self.fatal("Error making fast-resume data (%s)" % (exc,))
                raise

            hashed_path = re.sub(r"\.torrent$", "", metapath) + "-resume.torrent"
            self.LOG.info("Writing fast-resume metafile %r..." % (hashed_path,))
            try:
                bencode.bwrite(hashed_path, meta)
            except EnvironmentError as exc:
                self.fatal("Error writing fast-resume metafile %r (%s)" % (hashed_path, exc,))
                raise
Ejemplo n.º 6
0
            metainfo = bencode.bread(metapath)
        except (KeyError, bencode.BencodeError), exc:
            self.LOG.error("Bad metafile %r (%s: %s)" % (metapath, type(exc).__name__, exc))
        else:
            # Check metafile integrity
            try:
                metafile.check_meta(metainfo)
            except ValueError, exc:
                self.LOG.error("Metafile %r failed integrity check: %s" % (metapath, exc,))
            else:
                if len(self.args) > 1:
                    datapath = self.args[1].rstrip(os.sep)
                else:
                    datapath = metainfo["info"]["name"]

                # Check the hashes
                torrent = metafile.Metafile(metapath)
                torrent.check(metainfo, datapath, progress=None if self.options.quiet else metafile.console_progress())


def run(): #pragma: no cover
    """ The entry point.
    """
    ScriptBase.setup()
    MetafileChecker().run()


if __name__ == "__main__":
    run()