Esempio n. 1
0
def track(args):
    if len(args) == 0:
        print formatDefinitions(defaults, 80)
        return
    try:
        config, _ = parseargs(args, defaults, 0, 0)
    except ValueError as e:
        print 'error: ' + str(e)
        print 'run with no arguments for parameter explanations'
        return
    r = RawServer(threading.Event(), config['timeout_check_interval'],
                  config['socket_timeout'], ipv6_enable=config['ipv6_enabled'])
    t = Tracker(config, r)
    r.bind(config['port'], config['bind'],
           reuse=True, ipv6_socket_style=config['ipv6_binds_v4'])
    r.listen_forever(
        HTTPHandler(t.get, config['min_time_between_log_flushes']))
    t.save_state()
    print '# Shutting down: ' + isotime()
Esempio n. 2
0
    def __init__(self, config, Output):
        try:
            self.config = config
            self.Output = Output

            self.torrent_dir = config['torrent_dir']
            self.torrent_cache = {}
            self.file_cache = {}
            self.blocked_files = {}
            self.scan_period = config['parse_dir_interval']
            self.stats_period = config['display_interval']

            self.torrent_list = []
            self.downloads = {}
            self.counter = 0
            self.doneflag = threading.Event()

            self.hashcheck_queue = []
            self.hashcheck_current = None

            self.rawserver = RawServer(self.doneflag,
                                       config['timeout_check_interval'],
                                       config['timeout'],
                                       ipv6_enable=config['ipv6_enabled'],
                                       failfunc=self.failed,
                                       errorfunc=self.exchandler)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    self.listen_port = self.rawserver.find_and_bind(
                        config['minport'],
                        config['maxport'],
                        config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type,
                        randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        self.Output.message(
                            'WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    self.failed("Couldn't listen - " + str(e))
                    return

            self.ratelimiter = RateLimiter(self.rawserver.add_task,
                                           config['upload_unit_size'])
            self.ratelimiter.set_upload_rate(config['max_upload_rate'])

            self.handler = MultiHandler(self.rawserver, self.doneflag, config)
            random.seed(createPeerID())
            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            self.handler.listen_forever()

            self.Output.message('shutting down')
            self.hashcheck_queue = []
            for hash in self.torrent_list:
                self.Output.message('dropped "{}"'.format(
                    self.torrent_cache[hash]['path']))
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except Exception:
            data = StringIO()
            print_exc(file=data)
            Output.exception(data.getvalue())
Esempio n. 3
0
class LaunchMany:
    def __init__(self, config, Output):
        try:
            self.config = config
            self.Output = Output

            self.torrent_dir = config['torrent_dir']
            self.torrent_cache = {}
            self.file_cache = {}
            self.blocked_files = {}
            self.scan_period = config['parse_dir_interval']
            self.stats_period = config['display_interval']

            self.torrent_list = []
            self.downloads = {}
            self.counter = 0
            self.doneflag = threading.Event()

            self.hashcheck_queue = []
            self.hashcheck_current = None

            self.rawserver = RawServer(self.doneflag,
                                       config['timeout_check_interval'],
                                       config['timeout'],
                                       ipv6_enable=config['ipv6_enabled'],
                                       failfunc=self.failed,
                                       errorfunc=self.exchandler)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    self.listen_port = self.rawserver.find_and_bind(
                        config['minport'],
                        config['maxport'],
                        config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type,
                        randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        self.Output.message(
                            'WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    self.failed("Couldn't listen - " + str(e))
                    return

            self.ratelimiter = RateLimiter(self.rawserver.add_task,
                                           config['upload_unit_size'])
            self.ratelimiter.set_upload_rate(config['max_upload_rate'])

            self.handler = MultiHandler(self.rawserver, self.doneflag, config)
            random.seed(createPeerID())
            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            self.handler.listen_forever()

            self.Output.message('shutting down')
            self.hashcheck_queue = []
            for hash in self.torrent_list:
                self.Output.message('dropped "{}"'.format(
                    self.torrent_cache[hash]['path']))
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except Exception:
            data = StringIO()
            print_exc(file=data)
            Output.exception(data.getvalue())

    def scan(self):
        self.rawserver.add_task(self.scan, self.scan_period)

        r = parsedir(self.torrent_dir,
                     self.torrent_cache,
                     self.file_cache,
                     self.blocked_files,
                     return_metainfo=True,
                     errfunc=self.Output.message)

        (self.torrent_cache, self.file_cache, self.blocked_files, added,
         removed) = r

        for hash, data in removed.iteritems():
            self.Output.message('dropped "{}"'.format(data['path']))
            self.remove(hash)
        for hash, data in added.iteritems():
            self.Output.message('added "{}"'.format(data['path']))
            self.add(hash, data)

    def stats(self):
        self.rawserver.add_task(self.stats, self.stats_period)
        data = []
        for hash in self.torrent_list:
            cache = self.torrent_cache[hash]
            if self.config['display_path']:
                name = cache['path']
            else:
                name = cache['name']
            size = cache['length']
            d = self.downloads[hash]
            progress = '0.0%'
            peers = 0
            seeds = 0
            seedsmsg = "S"
            dist = 0.0
            uprate = 0.0
            dnrate = 0.0
            upamt = 0
            dnamt = 0
            t = 0
            if d.is_dead():
                status = 'stopped'
            elif d.waiting:
                status = 'waiting for hash check'
            elif d.checking:
                status = d.status_msg
                progress = '{:.1%}'.format(d.status_done)
            else:
                stats = d.statsfunc()
                s = stats['stats']
                if d.seed:
                    status = 'seeding'
                    progress = '100.0%'
                    seeds = s.numOldSeeds
                    seedsmsg = "s"
                    dist = s.numCopies
                else:
                    if s.numSeeds + s.numPeers:
                        t = stats['time']
                        if t == 0:  # unlikely
                            t = 0.01
                        status = formatIntClock(t) or 'downloading'
                    else:
                        t = -1
                        status = 'connecting to peers'
                    progress = '{:.1%}'.format(stats['frac'])
                    seeds = s.numSeeds
                    dist = s.numCopies2
                    dnrate = stats['down']
                peers = s.numPeers
                uprate = stats['up']
                upamt = s.upTotal
                dnamt = s.downTotal

            if d.is_dead() or d.status_errtime + 300 > clock():
                msg = d.status_err[-1]
            else:
                msg = ''

            data.append((name, status, progress, peers, seeds, seedsmsg, dist,
                         uprate, dnrate, upamt, dnamt, size, t, msg))
        stop = self.Output.display(data)
        if stop:
            self.doneflag.set()

    def remove(self, hash):
        self.torrent_list.remove(hash)
        self.downloads[hash].shutdown()
        del self.downloads[hash]

    def add(self, hash, data):
        c = self.counter
        self.counter += 1
        x = ''
        for _ in xrange(3):
            x = mapbase64[c & 0x3F] + x
            c >>= 6
        peer_id = createPeerID(x)
        d = SingleDownload(self, hash, data['metainfo'], self.config, peer_id)
        self.torrent_list.append(hash)
        self.downloads[hash] = d
        d.start()

    def saveAs(self, hash, name, saveas, isdir):
        x = self.torrent_cache[hash]
        style = self.config['saveas_style']
        if style == 1 or style == 3:
            if saveas:
                saveas = os.path.join(saveas, x['file'][:-1 - len(x['type'])])
            else:
                saveas = x['path'][:-1 - len(x['type'])]
            if style == 3:
                if not os.path.isdir(saveas):
                    try:
                        os.mkdir(saveas)
                    except OSError:
                        raise OSError("couldn't create directory for {} ({})"
                                      ''.format(x['path'], saveas))
                if not isdir:
                    saveas = os.path.join(saveas, name)
        else:
            if saveas:
                saveas = os.path.join(saveas, name)
            else:
                saveas = os.path.join(os.path.split(x['path'])[0], name)

        if isdir and not os.path.isdir(saveas):
            try:
                os.mkdir(saveas)
            except OSError:
                raise OSError("couldn't create directory for {} ({})".format(
                    x['path'], saveas))
        return saveas

    def hashchecksched(self, hash=None):
        if hash:
            self.hashcheck_queue.append(hash)
        if not self.hashcheck_current:
            self._hashcheck_start()

    def _hashcheck_start(self):
        self.hashcheck_current = self.hashcheck_queue.pop(0)
        self.downloads[self.hashcheck_current].hashcheck_start(
            self.hashcheck_callback)

    def hashcheck_callback(self):
        self.downloads[self.hashcheck_current].hashcheck_callback()
        if self.hashcheck_queue:
            self._hashcheck_start()
        else:
            self.hashcheck_current = None

    def died(self, hash):
        if hash in self.torrent_cache:
            self.Output.message('DIED: "{}"'.format(
                self.torrent_cache[hash]['path']))

    def was_stopped(self, hash):
        try:
            self.hashcheck_queue.remove(hash)
        except ValueError:
            pass
        if self.hashcheck_current == hash:
            self.hashcheck_current = None
            if self.hashcheck_queue:
                self._hashcheck_start()

    def failed(self, s):
        self.Output.message('FAILURE: ' + s)

    def exchandler(self, s):
        self.Output.exception(s)
Esempio n. 4
0
def run(params):
    h = HeadlessDisplayer()
    while 1:
        configdir = ConfigDir('downloadheadless')
        defaultsToIgnore = ['metafile', 'url', 'priority']
        configdir.setDefaults(defaults, defaultsToIgnore)
        configdefaults = configdir.loadConfig()
        defaults.append(
            ('save_options', 0, 'whether to save the current options as the '
             'new default configuration (only for btdownloadheadless.py)'))
        try:
            config = parse_params(params, configdefaults)
        except ValueError as e:
            print('error: {}\n'.format(e),
                  'run with no args for parameter explanations')
            break
        if not config:
            print(get_usage(defaults, 80, configdefaults))
            break
        if config['save_options']:
            configdir.saveConfig(config)
        configdir.deleteOldCacheData(config['expire_cache_data'])

        myid = createPeerID()
        random.seed(myid)

        doneflag = threading.Event()

        def disp_exception(text):
            print(text)

        rawserver = RawServer(doneflag,
                              config['timeout_check_interval'],
                              config['timeout'],
                              ipv6_enable=config['ipv6_enabled'],
                              failfunc=h.failed,
                              errorfunc=disp_exception)
        upnp_type = UPnP_test(config['upnp_nat_access'])
        while True:
            try:
                listen_port = rawserver.find_and_bind(
                    config['minport'],
                    config['maxport'],
                    config['bind'],
                    ipv6_socket_style=config['ipv6_binds_v4'],
                    upnp=upnp_type,
                    randomizer=config['random_port'])
                break
            except socket.error as e:
                if upnp_type and e == UPnP_ERROR:
                    print('WARNING: COULD NOT FORWARD VIA UPnP')
                    upnp_type = 0
                    continue
                print("error: Couldn't listen - ", e)
                h.failed()
                return

        metainfo = get_metainfo(config['metafile'], config['url'], h.error)
        if not metainfo:
            break

        infohash = hashlib.sha1(bencode(metainfo['info'])).digest()

        dow = BT1Download(h.display, h.finished, h.error, disp_exception,
                          doneflag, config, metainfo, infohash, myid,
                          rawserver, listen_port, configdir)

        if not dow.saveAs(h.chooseFile, h.newpath):
            break

        if not dow.initFiles(old_style=True):
            break
        if not dow.startEngine():
            dow.shutdown()
            break
        dow.startRerequester()
        dow.autoStats()

        if not dow.am_I_finished():
            h.display(activity='connecting to peers')
        rawserver.listen_forever(dow.getPortHandler())
        h.display(activity='shutting down')
        dow.shutdown()
        break
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not h.done:
        h.failed()
Esempio n. 5
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir('downloadcurses')
            defaultsToIgnore = ['responsefile', 'url', 'priority']
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                ('save_options', 0, 'whether to save the current options as '
                 'the new default configuration (only for btdownloadcurses.py)'
                 ))
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error('error: {}\nrun with no args for parameter '
                        'explanations'.format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config['save_options']:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config['expire_cache_data'])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag, config['timeout_check_interval'], config['timeout'],
                ipv6_enable=config['ipv6_enabled'], failfunc=d.failed,
                errorfunc=d.error)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error('WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            response = get_response(config['responsefile'], config['url'],
                                    d.error)
            if not response:
                break

            infohash = hashlib.sha1(bencode(response['info'])).digest()

            dow = BT1Download(
                d.display, d.finished, d.error, d.error, doneflag, config,
                response, infohash, myid, rawserver, listen_port, configdir)

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity='connecting to peers')
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity='shutting down')
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
Esempio n. 6
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir('downloadcurses')
            defaultsToIgnore = ['responsefile', 'url', 'priority']
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                ('save_options', 0, 'whether to save the current options as '
                 'the new default configuration (only for btdownloadcurses.py)'
                 ))
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error('error: {}\nrun with no args for parameter '
                        'explanations'.format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config['save_options']:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config['expire_cache_data'])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag, config['timeout_check_interval'], config['timeout'],
                ipv6_enable=config['ipv6_enabled'], failfunc=d.failed,
                errorfunc=d.error)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error('WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            response = get_response(config['responsefile'], config['url'],
                                    d.error)
            if not response:
                break

            infohash = hashlib.sha1(bencode(response['info'])).digest()

            dow = BT1Download(
                d.display, d.finished, d.error, d.error, doneflag, config,
                response, infohash, myid, rawserver, listen_port, configdir)

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity='connecting to peers')
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity='shutting down')
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
Esempio n. 7
0
    def __init__(self, config, Output):
        try:
            self.config = config
            self.Output = Output

            self.torrent_dir = config['torrent_dir']
            self.torrent_cache = {}
            self.file_cache = {}
            self.blocked_files = {}
            self.scan_period = config['parse_dir_interval']
            self.stats_period = config['display_interval']

            self.torrent_list = []
            self.downloads = {}
            self.counter = 0
            self.doneflag = threading.Event()

            self.hashcheck_queue = []
            self.hashcheck_current = None

            self.rawserver = RawServer(
                self.doneflag, config['timeout_check_interval'],
                config['timeout'], ipv6_enable=config['ipv6_enabled'],
                failfunc=self.failed, errorfunc=self.exchandler)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    self.listen_port = self.rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        self.Output.message(
                            'WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    self.failed("Couldn't listen - " + str(e))
                    return

            self.ratelimiter = RateLimiter(self.rawserver.add_task,
                                           config['upload_unit_size'])
            self.ratelimiter.set_upload_rate(config['max_upload_rate'])

            self.handler = MultiHandler(self.rawserver, self.doneflag, config)
            random.seed(createPeerID())
            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            self.handler.listen_forever()

            self.Output.message('shutting down')
            self.hashcheck_queue = []
            for hash in self.torrent_list:
                self.Output.message('dropped "{}"'.format(
                    self.torrent_cache[hash]['path']))
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except Exception:
            data = StringIO()
            print_exc(file=data)
            Output.exception(data.getvalue())
Esempio n. 8
0
class LaunchMany:
    def __init__(self, config, Output):
        try:
            self.config = config
            self.Output = Output

            self.torrent_dir = config['torrent_dir']
            self.torrent_cache = {}
            self.file_cache = {}
            self.blocked_files = {}
            self.scan_period = config['parse_dir_interval']
            self.stats_period = config['display_interval']

            self.torrent_list = []
            self.downloads = {}
            self.counter = 0
            self.doneflag = threading.Event()

            self.hashcheck_queue = []
            self.hashcheck_current = None

            self.rawserver = RawServer(
                self.doneflag, config['timeout_check_interval'],
                config['timeout'], ipv6_enable=config['ipv6_enabled'],
                failfunc=self.failed, errorfunc=self.exchandler)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    self.listen_port = self.rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        self.Output.message(
                            'WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    self.failed("Couldn't listen - " + str(e))
                    return

            self.ratelimiter = RateLimiter(self.rawserver.add_task,
                                           config['upload_unit_size'])
            self.ratelimiter.set_upload_rate(config['max_upload_rate'])

            self.handler = MultiHandler(self.rawserver, self.doneflag, config)
            random.seed(createPeerID())
            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            self.handler.listen_forever()

            self.Output.message('shutting down')
            self.hashcheck_queue = []
            for hash in self.torrent_list:
                self.Output.message('dropped "{}"'.format(
                    self.torrent_cache[hash]['path']))
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except Exception:
            data = StringIO()
            print_exc(file=data)
            Output.exception(data.getvalue())

    def scan(self):
        self.rawserver.add_task(self.scan, self.scan_period)

        r = parsedir(self.torrent_dir, self.torrent_cache, self.file_cache,
                     self.blocked_files, return_metainfo=True,
                     errfunc=self.Output.message)

        (self.torrent_cache, self.file_cache, self.blocked_files, added,
         removed) = r

        for hash, data in removed.items():
            self.Output.message('dropped "{}"'.format(data['path']))
            self.remove(hash)
        for hash, data in added.items():
            self.Output.message('added "{}"'.format(data['path']))
            self.add(hash, data)

    def stats(self):
        self.rawserver.add_task(self.stats, self.stats_period)
        data = []
        for hash in self.torrent_list:
            cache = self.torrent_cache[hash]
            if self.config['display_path']:
                name = cache['path']
            else:
                name = cache['name']
            size = cache['length']
            d = self.downloads[hash]
            progress = '0.0%'
            peers = 0
            seeds = 0
            seedsmsg = "S"
            dist = 0.0
            uprate = 0.0
            dnrate = 0.0
            upamt = 0
            dnamt = 0
            t = 0
            if d.is_dead():
                status = 'stopped'
            elif d.waiting:
                status = 'waiting for hash check'
            elif d.checking:
                status = d.status_msg
                progress = '{:.1%}'.format(d.status_done)
            else:
                stats = d.statsfunc()
                s = stats['stats']
                if d.seed:
                    status = 'seeding'
                    progress = '100.0%'
                    seeds = s.numOldSeeds
                    seedsmsg = "s"
                    dist = s.numCopies
                else:
                    if s.numSeeds + s.numPeers:
                        t = stats['time']
                        if t == 0:  # unlikely
                            t = 0.01
                        status = formatIntClock(t) or 'downloading'
                    else:
                        t = -1
                        status = 'connecting to peers'
                    progress = '{:.1%}'.format(stats['frac'])
                    seeds = s.numSeeds
                    dist = s.numCopies2
                    dnrate = stats['down']
                peers = s.numPeers
                uprate = stats['up']
                upamt = s.upTotal
                dnamt = s.downTotal

            if d.is_dead() or d.status_errtime + 300 > clock():
                msg = d.status_err[-1]
            else:
                msg = ''

            data.append((name, status, progress, peers, seeds, seedsmsg, dist,
                         uprate, dnrate, upamt, dnamt, size, t, msg))
        stop = self.Output.display(data)
        if stop:
            self.doneflag.set()

    def remove(self, hash):
        self.torrent_list.remove(hash)
        self.downloads[hash].shutdown()
        del self.downloads[hash]

    def add(self, hash, data):
        peer_id = createPeerID(self.counter)
        self.counter += 1
        d = SingleDownload(self, hash, data['metainfo'], self.config, peer_id)
        self.torrent_list.append(hash)
        self.downloads[hash] = d
        d.start()

    def saveAs(self, hash, name, saveas, isdir):
        x = self.torrent_cache[hash]
        style = self.config['saveas_style']
        if style == 1 or style == 3:
            if saveas:
                saveas = os.path.join(saveas, x['file'][:-1 - len(x['type'])])
            else:
                saveas = x['path'][:-1 - len(x['type'])]
            if style == 3:
                if not os.path.isdir(saveas):
                    try:
                        os.mkdir(saveas)
                    except OSError:
                        raise OSError("couldn't create directory for {} ({})"
                                      ''.format(x['path'], saveas))
                if not isdir:
                    saveas = os.path.join(saveas, name)
        else:
            if saveas:
                saveas = os.path.join(saveas, name)
            else:
                saveas = os.path.join(os.path.split(x['path'])[0], name)

        if isdir and not os.path.isdir(saveas):
            try:
                os.mkdir(saveas)
            except OSError:
                raise OSError("couldn't create directory for {} ({})".format(
                              x['path'], saveas))
        return saveas

    def hashchecksched(self, hash=None):
        if hash:
            self.hashcheck_queue.append(hash)
        if not self.hashcheck_current:
            self._hashcheck_start()

    def _hashcheck_start(self):
        self.hashcheck_current = self.hashcheck_queue.pop(0)
        self.downloads[self.hashcheck_current].hashcheck_start(
            self.hashcheck_callback)

    def hashcheck_callback(self):
        self.downloads[self.hashcheck_current].hashcheck_callback()
        if self.hashcheck_queue:
            self._hashcheck_start()
        else:
            self.hashcheck_current = None

    def died(self, hash):
        if hash in self.torrent_cache:
            self.Output.message('DIED: "{}"'.format(
                self.torrent_cache[hash]['path']))

    def was_stopped(self, hash):
        try:
            self.hashcheck_queue.remove(hash)
        except ValueError:
            pass
        if self.hashcheck_current == hash:
            self.hashcheck_current = None
            if self.hashcheck_queue:
                self._hashcheck_start()

    def failed(self, s):
        self.Output.message('FAILURE: ' + s)

    def exchandler(self, s):
        self.Output.exception(s)
Esempio n. 9
0
def run(params):
    h = HeadlessDisplayer()
    while 1:
        configdir = ConfigDir('downloadheadless')
        defaultsToIgnore = ['metafile', 'url', 'priority']
        configdir.setDefaults(defaults, defaultsToIgnore)
        configdefaults = configdir.loadConfig()
        defaults.append(
            ('save_options', 0, 'whether to save the current options as the '
             'new default configuration (only for btdownloadheadless.py)'))
        try:
            config = parse_params(params, configdefaults)
        except ValueError as e:
            print('error: {}\n'.format(e),
                  'run with no args for parameter explanations')
            break
        if not config:
            print(get_usage(defaults, 80, configdefaults))
            break
        if config['save_options']:
            configdir.saveConfig(config)
        configdir.deleteOldCacheData(config['expire_cache_data'])

        myid = createPeerID()
        random.seed(myid)

        doneflag = threading.Event()

        def disp_exception(text):
            print(text)
        rawserver = RawServer(
            doneflag, config['timeout_check_interval'], config['timeout'],
            ipv6_enable=config['ipv6_enabled'], failfunc=h.failed,
            errorfunc=disp_exception)
        upnp_type = UPnP_test(config['upnp_nat_access'])
        while True:
            try:
                listen_port = rawserver.find_and_bind(
                    config['minport'], config['maxport'], config['bind'],
                    ipv6_socket_style=config['ipv6_binds_v4'],
                    upnp=upnp_type, randomizer=config['random_port'])
                break
            except socket.error as e:
                if upnp_type and e == UPnP_ERROR:
                    print('WARNING: COULD NOT FORWARD VIA UPnP')
                    upnp_type = 0
                    continue
                print("error: Couldn't listen - ", e)
                h.failed()
                return

        metainfo = get_metainfo(config['metafile'], config['url'], h.error)
        if not metainfo:
            break

        infohash = hashlib.sha1(bencode(metainfo['info'])).digest()

        dow = BT1Download(
            h.display, h.finished, h.error, disp_exception, doneflag, config,
            metainfo, infohash, myid, rawserver, listen_port, configdir)

        if not dow.saveAs(h.chooseFile, h.newpath):
            break

        if not dow.initFiles(old_style=True):
            break
        if not dow.startEngine():
            dow.shutdown()
            break
        dow.startRerequester()
        dow.autoStats()

        if not dow.am_I_finished():
            h.display(activity='connecting to peers')
        rawserver.listen_forever(dow.getPortHandler())
        h.display(activity='shutting down')
        dow.shutdown()
        break
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not h.done:
        h.failed()
Esempio n. 10
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir("downloadcurses")
            defaultsToIgnore = ["metafile", "url", "priority"]
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                (
                    "save_options",
                    0,
                    "whether to save the current options as "
                    "the new default configuration (only for btdownloadcurses.py)",
                )
            )
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error("error: {}\nrun with no args for parameter " "explanations".format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config["save_options"]:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config["expire_cache_data"])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag,
                config["timeout_check_interval"],
                config["timeout"],
                ipv6_enable=config["ipv6_enabled"],
                failfunc=d.failed,
                errorfunc=d.error,
            )

            upnp_type = UPnP_test(config["upnp_nat_access"])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config["minport"],
                        config["maxport"],
                        config["bind"],
                        ipv6_socket_style=config["ipv6_binds_v4"],
                        upnp=upnp_type,
                        randomizer=config["random_port"],
                    )
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error("WARNING: COULD NOT FORWARD VIA UPnP")
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            metainfo = get_metainfo(config["metafile"], config["url"], d.error)
            if not metainfo:
                break

            infohash = hashlib.sha1(bencode(metainfo["info"])).digest()

            dow = BT1Download(
                d.display,
                d.finished,
                d.error,
                d.error,
                doneflag,
                config,
                metainfo,
                infohash,
                myid,
                rawserver,
                listen_port,
                configdir,
            )

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity="connecting to peers")
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity="shutting down")
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()