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 = 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 socketerror, 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)
            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 "'+self.torrent_cache[hash]['path']+'"')
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except:
Example #2
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 = 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 1:
                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 socketerror, 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)
            seed(createPeerID())
            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            self.start()
        except:
Example #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 = 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 socketerror, 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)
            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 "'+self.torrent_cache[hash]['path']+'"')
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except:
Example #4
0
    def startEngine(self, ratelimiter=None, statusfunc=None):
        if self.doneflag.isSet():
            return False
        if not statusfunc:
            statusfunc = self.statusfunc

        self.checking = False

        if not CRYPTO_OK:
            if self.config['crypto_allowed']:
                self.errorfunc('warning - crypto library not installed')
            self.config['crypto_allowed'] = 0
            self.config['crypto_only'] = 0
            self.config['crypto_stealth'] = 0

        for i in xrange(self.len_pieces):
            if self.storagewrapper.do_I_have(i):
                self.picker.complete(i)
        self.upmeasure = Measure(self.config['max_rate_period'],
                                 self.config['upload_rate_fudge'])
        self.downmeasure = Measure(self.config['max_rate_period'])

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

        self.ratemeasure = RateMeasure()
        self.ratemeasure_datarejected = self.ratemeasure.data_rejected

        self.downloader = Downloader(
            self.storagewrapper, self.picker, self.config['request_backlog'],
            self.config['max_rate_period'], self.len_pieces,
            self.config['download_slice_size'], self._received_data,
            self.config['snub_time'], self.config['auto_kick'],
            self._kick_peer, self._ban_peer)
        self.downloader.set_download_rate(self.config['max_download_rate'])
        self.connecter = Connecter(
            self._make_upload, self.downloader, self.choker, self.len_pieces,
            self.upmeasure, self.config, self.ratelimiter,
            self.rawserver.add_task)
        self.encoder = Encoder(
            self.connecter, self.rawserver, self.myid,
            self.config['max_message_length'], self.rawserver.add_task,
            self.config['keepalive_interval'], self.infohash,
            self._received_raw_data, self.config)
        self.encoder_ban = self.encoder.ban

        self.httpdownloader = HTTPDownloader(
            self.storagewrapper, self.picker, self.rawserver, self.finflag,
            self.errorfunc, self.downloader, self.config['max_rate_period'],
            self.infohash, self._received_http_data, self.connecter.got_piece)
        if 'httpseeds' in self.response and not self.finflag.isSet():
            for u in self.response['httpseeds']:
                self.httpdownloader.make_download(u)

        if self.selector_enabled:
            self.fileselector.tie_in(self.picker, self._cancelfunc,
                                     self._reqmorefunc,
                                     self.rerequest_ondownloadmore)
            if self.priority:
                self.fileselector.set_priorities_now(self.priority)

            # erase old data once you've started modifying it
            self.appdataobj.deleteTorrentData(self.infohash)

        if self.config['super_seeder']:
            self.set_super_seed()

        self.started = True
        return True
Example #5
0
class BT1Download:
    def __init__(self, statusfunc, finfunc, errorfunc, excfunc, doneflag,
                 config, response, infohash, id, rawserver, port,
                 appdataobj=None):
        self.statusfunc = statusfunc
        self.finfunc = finfunc
        self.errorfunc = errorfunc
        self.excfunc = excfunc
        self.doneflag = doneflag
        self.config = config
        self.response = response
        self.infohash = infohash
        self.myid = id
        self.rawserver = rawserver
        self.port = port

        self.info = self.response['info']
        self.pieces = [self.info['pieces'][x:x + 20]
                       for x in xrange(0, len(self.info['pieces']), 20)]
        self.len_pieces = len(self.pieces)
        self.argslistheader = argslistheader
        self.unpauseflag = threading.Event()
        self.unpauseflag.set()
        self.downloader = None
        self.storagewrapper = None
        self.fileselector = None
        self.super_seeding_active = False
        self.filedatflag = threading.Event()
        self.spewflag = threading.Event()
        self.superseedflag = threading.Event()
        self.whenpaused = None
        self.finflag = threading.Event()
        self.rerequest = None
        self.tcp_ack_fudge = config['tcp_ack_fudge']

        self.selector_enabled = config['selector_enabled']
        if appdataobj:
            self.appdataobj = appdataobj
        elif self.selector_enabled:
            self.appdataobj = ConfigDir()
            self.appdataobj.deleteOldCacheData(config['expire_cache_data'],
                                               [self.infohash])

        self.excflag = self.rawserver.get_exception_flag()
        self.failed = False
        self.checking = False
        self.started = False

        self.picker = PiecePicker(self.len_pieces,
                                  config['rarest_first_cutoff'],
                                  config['rarest_first_priority_cutoff'])
        self.choker = Choker(config, rawserver.add_task,
                             self.picker, self.finflag.isSet)

    def checkSaveLocation(self, loc):
        if 'length' in self.info:
            return os.path.exists(loc)
        return any(os.path.exists(os.path.join(loc, x['path'][0]))
                   for x in self.info['files'])

    def saveAs(self, filefunc, pathfunc=None):
        try:
            def make(f, forcedir=False):
                if not forcedir:
                    f = os.path.split(f)[0]
                if f != '' and not os.path.exists(f):
                    os.makedirs(f)

            if 'length' in self.info:
                file_length = self.info['length']
                file = filefunc(self.info['name'], file_length,
                                self.config['saveas'], False)
                if file is None:
                    return None
                make(file)
                files = [(file, file_length)]
            else:
                file_length = sum(x['length'] for x in self.info['files'])
                file = filefunc(self.info['name'], file_length,
                                self.config['saveas'], True)
                if file is None:
                    return None

                # if this path exists, and no files from the info dict exist,
                # we assume it's a new download and the user wants to create a
                # new directory with the default name
                existing = 0
                if os.path.exists(file):
                    if not os.path.isdir(file):
                        self.errorfunc(file + 'is not a dir')
                        return None
                    if len(os.listdir(file)) > 0:  # if it's not empty
                        existing = any(
                            os.path.exists(os.path.join(file, x['path'][0]))
                            for x in self.info['files'])
                        if not existing:
                            file = os.path.join(file, self.info['name'])
                            if os.path.exists(file) and \
                                    not os.path.isdir(file):
                                if file[-8:] == '.torrent':
                                    file = file[:-8]
                                if os.path.exists(file) and \
                                        not os.path.isdir(file):
                                    self.errorfunc("Can't create dir - " +
                                                   self.info['name'])
                                    return None
                make(file, True)

                # alert the UI to any possible change in path
                if pathfunc is not None:
                    pathfunc(file)

                files = []
                for x in self.info['files']:
                    n = os.path.join(file, *x['path'])
                    files.append((n, x['length']))
                    make(n)
        except OSError as e:
            self.errorfunc("Couldn't allocate dir - " + str(e))
            return None

        self.filename = file
        self.files = files
        self.datalength = file_length

        return file

    def getFilename(self):
        return self.filename

    def _finished(self):
        self.finflag.set()
        try:
            self.storage.set_readonly()
        except (IOError, OSError) as e:
            self.errorfunc('trouble setting readonly at end - ' + str(e))
        if self.superseedflag.isSet():
            self._set_super_seed()
        self.choker.set_round_robin_period(
            max(self.config['round_robin_period'],
                self.config['round_robin_period'] *
                self.info['piece length'] / 200000))
        self.rerequest_complete()
        self.finfunc()

    def _data_flunked(self, amount, index):
        self.ratemeasure_datarejected(amount)
        if not self.doneflag.isSet():
            self.errorfunc('piece {:d} failed hash check, re-downloading it'
                           ''.format(index))

    def _failed(self, reason):
        self.failed = True
        self.doneflag.set()
        if reason is not None:
            self.errorfunc(reason)

    def initFiles(self, old_style=False, statusfunc=None):
        if self.doneflag.isSet():
            return None
        if not statusfunc:
            statusfunc = self.statusfunc

        disabled_files = None
        if self.selector_enabled:
            self.priority = self.config['priority']
            if self.priority:
                try:
                    self.priority = self.priority.split(',')
                    assert len(self.priority) == len(self.files)
                    self.priority = [int(p) for p in self.priority]
                    for p in self.priority:
                        assert p >= -1
                        assert p <= 2
                except:
                    self.errorfunc('bad priority list given, ignored')
                    self.priority = None

            data = self.appdataobj.getTorrentData(self.infohash)
            try:
                d = data['resume data']['priority']
                assert len(d) == len(self.files)
                disabled_files = [x == -1 for x in d]
            except:
                try:
                    disabled_files = [x == -1 for x in self.priority]
                except:
                    pass

        try:
            try:
                self.storage = Storage(
                    self.files, self.info['piece length'], self.doneflag,
                    self.config, disabled_files)
            except IOError as e:
                self.errorfunc('trouble accessing files - ' + str(e))
                return None
            if self.doneflag.isSet():
                return None

            self.storagewrapper = StorageWrapper(
                self.storage, self.config['download_slice_size'],
                self.pieces, self.info['piece length'], self._finished,
                self._failed, statusfunc, self.doneflag,
                self.config['check_hashes'], self._data_flunked,
                self.rawserver.add_task, self.config, self.unpauseflag)

        except ValueError as e:
            self._failed('bad data - ' + str(e))
        except IOError as e:
            self._failed('IOError - ' + str(e))
        if self.doneflag.isSet():
            return None

        if self.selector_enabled:
            self.fileselector = FileSelector(
                self.files, self.info['piece length'],
                self.appdataobj.getPieceDir(self.infohash), self.storage,
                self.storagewrapper, self.rawserver.add_task, self._failed)
            if data:
                data = data.get('resume data')
                if data:
                    self.fileselector.unpickle(data)

        self.checking = True
        if old_style:
            return self.storagewrapper.old_style_init()
        return self.storagewrapper.initialize

    def getCachedTorrentData(self):
        return self.appdataobj.getTorrentData(self.infohash)

    def _make_upload(self, connection, ratelimiter, totalup):
        return Upload(connection, ratelimiter, totalup,
                      self.choker, self.storagewrapper, self.picker,
                      self.config)

    def _kick_peer(self, connection):
        self.rawserver.add_task(connection.close, 0)

    def _ban_peer(self, ip):
        self.encoder_ban(ip)

    def _received_raw_data(self, x):
        if self.tcp_ack_fudge:
            x = int(x * self.tcp_ack_fudge)
            self.ratelimiter.adjust_sent(x)

    def _received_data(self, x):
        self.downmeasure.update_rate(x)
        self.ratemeasure.data_came_in(x)

    def _received_http_data(self, x):
        self.downmeasure.update_rate(x)
        self.ratemeasure.data_came_in(x)
        self.downloader.external_data_received(x)

    def _cancelfunc(self, pieces):
        self.downloader.cancel_piece_download(pieces)
        self.httpdownloader.cancel_piece_download(pieces)

    def _reqmorefunc(self, pieces):
        self.downloader.requeue_piece_download(pieces)

    def startEngine(self, ratelimiter=None, statusfunc=None):
        if self.doneflag.isSet():
            return False
        if not statusfunc:
            statusfunc = self.statusfunc

        self.checking = False

        if not CRYPTO_OK:
            if self.config['crypto_allowed']:
                self.errorfunc('warning - crypto library not installed')
            self.config['crypto_allowed'] = 0
            self.config['crypto_only'] = 0
            self.config['crypto_stealth'] = 0

        for i in xrange(self.len_pieces):
            if self.storagewrapper.do_I_have(i):
                self.picker.complete(i)
        self.upmeasure = Measure(self.config['max_rate_period'],
                                 self.config['upload_rate_fudge'])
        self.downmeasure = Measure(self.config['max_rate_period'])

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

        self.ratemeasure = RateMeasure()
        self.ratemeasure_datarejected = self.ratemeasure.data_rejected

        self.downloader = Downloader(
            self.storagewrapper, self.picker, self.config['request_backlog'],
            self.config['max_rate_period'], self.len_pieces,
            self.config['download_slice_size'], self._received_data,
            self.config['snub_time'], self.config['auto_kick'],
            self._kick_peer, self._ban_peer)
        self.downloader.set_download_rate(self.config['max_download_rate'])
        self.connecter = Connecter(
            self._make_upload, self.downloader, self.choker, self.len_pieces,
            self.upmeasure, self.config, self.ratelimiter,
            self.rawserver.add_task)
        self.encoder = Encoder(
            self.connecter, self.rawserver, self.myid,
            self.config['max_message_length'], self.rawserver.add_task,
            self.config['keepalive_interval'], self.infohash,
            self._received_raw_data, self.config)
        self.encoder_ban = self.encoder.ban

        self.httpdownloader = HTTPDownloader(
            self.storagewrapper, self.picker, self.rawserver, self.finflag,
            self.errorfunc, self.downloader, self.config['max_rate_period'],
            self.infohash, self._received_http_data, self.connecter.got_piece)
        if 'httpseeds' in self.response and not self.finflag.isSet():
            for u in self.response['httpseeds']:
                self.httpdownloader.make_download(u)

        if self.selector_enabled:
            self.fileselector.tie_in(self.picker, self._cancelfunc,
                                     self._reqmorefunc,
                                     self.rerequest_ondownloadmore)
            if self.priority:
                self.fileselector.set_priorities_now(self.priority)

            # erase old data once you've started modifying it
            self.appdataobj.deleteTorrentData(self.infohash)

        if self.config['super_seeder']:
            self.set_super_seed()

        self.started = True
        return True

    def rerequest_complete(self):
        if self.rerequest:
            self.rerequest.announce(1)

    def rerequest_stopped(self):
        if self.rerequest:
            self.rerequest.announce(2)

    def rerequest_lastfailed(self):
        if self.rerequest:
            return self.rerequest.last_failed
        return False

    def rerequest_ondownloadmore(self):
        if self.rerequest:
            self.rerequest.hit()

    def startRerequester(self, seededfunc=None, force_rapid_update=False):
        trackerlist = self.response.get('announce-list',
                                        [[self.response['announce']]])

        self.rerequest = Rerequester(
            self.port, self.myid, self.infohash, trackerlist, self.config,
            self.rawserver.add_task, self.rawserver.add_task, self.errorfunc,
            self.excfunc, self.encoder.start_connections,
            self.connecter.how_many_connections,
            self.storagewrapper.get_amount_left, self.upmeasure.get_total,
            self.downmeasure.get_total, self.upmeasure.get_rate,
            self.downmeasure.get_rate, self.doneflag, self.unpauseflag,
            seededfunc, force_rapid_update)

        self.rerequest.start()

    def _init_stats(self):
        self.statistics = Statistics(
            self.upmeasure, self.downmeasure, self.connecter,
            self.httpdownloader, self.ratelimiter, self.rerequest_lastfailed,
            self.filedatflag)
        if 'files' in self.info:
            self.statistics.set_dirstats(self.files, self.info['piece length'])
        if self.config['spew']:
            self.spewflag.set()

    def autoStats(self, displayfunc=None):
        if not displayfunc:
            displayfunc = self.statusfunc

        self._init_stats()
        DownloaderFeedback(
            self.choker, self.httpdownloader, self.rawserver.add_task,
            self.upmeasure.get_rate, self.downmeasure.get_rate,
            self.ratemeasure, self.storagewrapper.get_stats, self.datalength,
            self.finflag, self.spewflag, self.statistics, displayfunc,
            self.config['display_interval'])

    def startStats(self):
        self._init_stats()
        d = DownloaderFeedback(
            self.choker, self.httpdownloader, self.rawserver.add_task,
            self.upmeasure.get_rate, self.downmeasure.get_rate,
            self.ratemeasure, self.storagewrapper.get_stats, self.datalength,
            self.finflag, self.spewflag, self.statistics)
        return d.gather

    def getPortHandler(self):
        return self.encoder

    def shutdown(self, torrentdata={}):
        if self.checking or self.started:
            self.storagewrapper.sync()
            self.storage.close()
            self.rerequest_stopped()
        if self.fileselector and self.started:
            if not self.failed:
                self.fileselector.finish()
                torrentdata['resume data'] = self.fileselector.pickle()
            try:
                self.appdataobj.writeTorrentData(self.infohash, torrentdata)
            except:
                self.appdataobj.deleteTorrentData(self.infohash)  # clear it
        return not self.failed and not self.excflag.isSet()
        # if returns false, you may wish to auto-restart the torrent

    def setUploadRate(self, rate):
        try:
            def s(self=self, rate=rate):
                self.config['max_upload_rate'] = rate
                self.ratelimiter.set_upload_rate(rate)
            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def setConns(self, conns, conns2=None):
        if not conns2:
            conns2 = conns
        try:
            def s(self=self, conns=conns, conns2=conns2):
                self.config['min_uploads'] = conns
                self.config['max_uploads'] = conns2
                if (conns > 30):
                    self.config['max_initiate'] = conns + 10
            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def setDownloadRate(self, rate):
        try:
            def s(self=self, rate=rate):
                self.config['max_download_rate'] = rate
                self.downloader.set_download_rate(rate)
            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def startConnection(self, ip, port, id):
        self.encoder._start_connection((ip, port), id)

    def _startConnection(self, ipandport, id):
        self.encoder._start_connection(ipandport, id)

    def setInitiate(self, initiate):
        try:
            def s(self=self, initiate=initiate):
                self.config['max_initiate'] = initiate
            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def getConfig(self):
        return self.config

    def getDefaults(self):
        return defaultargs(defaults)

    def getUsageText(self):
        return self.argslistheader

    def reannounce(self, special=None):
        try:
            def r(self=self, special=special):
                if special is None:
                    self.rerequest.announce()
                else:
                    self.rerequest.announce(specialurl=special)
            self.rawserver.add_task(r)
        except AttributeError:
            pass

    def getResponse(self):
        try:
            return self.response
        except:
            return None

    def Pause(self):
        if not self.storagewrapper:
            return False
        self.unpauseflag.clear()
        self.rawserver.add_task(self.onPause)
        return True

    def onPause(self):
        self.whenpaused = clock()
        if not self.downloader:
            return
        self.downloader.pause(True)
        self.encoder.pause(True)
        self.choker.pause(True)

    def Unpause(self):
        self.unpauseflag.set()
        self.rawserver.add_task(self.onUnpause)

    def onUnpause(self):
        if not self.downloader:
            return
        self.downloader.pause(False)
        self.encoder.pause(False)
        self.choker.pause(False)
        # rerequest automatically if paused for >60 seconds
        if self.rerequest and self.whenpaused and \
                clock() - self.whenpaused > 60:
            self.rerequest.announce(3)

    def set_super_seed(self):
        try:
            self.superseedflag.set()

            def s(self=self):
                if self.finflag.isSet():
                    self._set_super_seed()
            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def _set_super_seed(self):
        if not self.super_seeding_active:
            self.super_seeding_active = True
            self.errorfunc('        ** SUPER-SEED OPERATION ACTIVE **\n  '
                           'please set Max uploads so each peer gets 6-8 kB/s')

            def s(self=self):
                self.downloader.set_super_seed()
                self.choker.set_super_seed()
            self.rawserver.add_task(s)
            # mode started when already finished
            if self.finflag.isSet():
                def r(self=self):
                    # so after kicking everyone off, reannounce
                    self.rerequest.announce(3)
                self.rawserver.add_task(r)

    def am_I_finished(self):
        return self.finflag.isSet()

    def get_transfer_stats(self):
        return self.upmeasure.get_total(), self.downmeasure.get_total()
Example #6
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 = 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)
            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:
            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 = fmttime(t)
                    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 i 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:
                        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:
                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:
            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)
from flask import Flask,jsonify
import sqlalchemy
from RateLimiter import RateLimiter
from UICOMPONENTS import DataVisualization as ui
from UICOMPONENTS import GeoVisualization as Geo

app = Flask(__name__)
ctx = app.app_context()
ctx.push()
rl_index = RateLimiter(5)
rl_eh = RateLimiter(5)
rl_ed = RateLimiter(5)
rl_sh = RateLimiter(5)
rl_sd = RateLimiter(5)
rl_poi = RateLimiter(5)
figure = ui()
geo = Geo()

# database engine
engine = sqlalchemy.create_engine('postgresql://*****:*****@#[email protected]:5432/work_samples')
def queryHelper(query):
    with engine.connect() as conn:
        result = conn.execute(query).fetchall()
        return jsonify([dict(row.items()) for row in result])

@app.route('/')
@rl_index.request
def index():
    return 'welcome eq works'

@app.route('/events/hourly')
Example #8
0
    def startEngine(self, ratelimiter=None, statusfunc=None):
        if self.doneflag.isSet():
            return False
        if not statusfunc:
            statusfunc = self.statusfunc

        self.checking = False

        if not CRYPTO_OK:
            if self.config['crypto_allowed']:
                self.errorfunc('warning - crypto library not installed')
            self.config['crypto_allowed'] = 0
            self.config['crypto_only'] = 0
            self.config['crypto_stealth'] = 0

        for i in xrange(self.len_pieces):
            if self.storagewrapper.do_I_have(i):
                self.picker.complete(i)
        self.upmeasure = Measure(self.config['max_rate_period'],
                                 self.config['upload_rate_fudge'])
        self.downmeasure = Measure(self.config['max_rate_period'])

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

        self.ratemeasure = RateMeasure()
        self.ratemeasure_datarejected = self.ratemeasure.data_rejected

        self.downloader = Downloader(
            self.storagewrapper, self.picker, self.config['request_backlog'],
            self.config['max_rate_period'], self.len_pieces,
            self.config['download_slice_size'], self._received_data,
            self.config['snub_time'], self.config['auto_kick'],
            self._kick_peer, self._ban_peer)
        self.downloader.set_download_rate(self.config['max_download_rate'])
        self.connecter = Connecter(self._make_upload, self.downloader,
                                   self.choker, self.len_pieces,
                                   self.upmeasure, self.config,
                                   self.ratelimiter, self.rawserver.add_task)
        self.encoder = Encoder(self.connecter, self.rawserver, self.myid,
                               self.config['max_message_length'],
                               self.rawserver.add_task,
                               self.config['keepalive_interval'],
                               self.infohash, self._received_raw_data,
                               self.config)
        self.encoder_ban = self.encoder.ban

        self.httpdownloader = HTTPDownloader(
            self.storagewrapper, self.picker, self.rawserver, self.finflag,
            self.errorfunc, self.downloader, self.config['max_rate_period'],
            self.infohash, self._received_http_data, self.connecter.got_piece)
        if 'httpseeds' in self.response and not self.finflag.isSet():
            for u in self.response['httpseeds']:
                self.httpdownloader.make_download(u)

        if self.selector_enabled:
            self.fileselector.tie_in(self.picker, self._cancelfunc,
                                     self._reqmorefunc,
                                     self.rerequest_ondownloadmore)
            if self.priority:
                self.fileselector.set_priorities_now(self.priority)

            # erase old data once you've started modifying it
            self.appdataobj.deleteTorrentData(self.infohash)

        if self.config['super_seeder']:
            self.set_super_seed()

        self.started = True
        return True
Example #9
0
class BT1Download:
    def __init__(self,
                 statusfunc,
                 finfunc,
                 errorfunc,
                 excfunc,
                 doneflag,
                 config,
                 response,
                 infohash,
                 id,
                 rawserver,
                 port,
                 appdataobj=None):
        self.statusfunc = statusfunc
        self.finfunc = finfunc
        self.errorfunc = errorfunc
        self.excfunc = excfunc
        self.doneflag = doneflag
        self.config = config
        self.response = response
        self.infohash = infohash
        self.myid = id
        self.rawserver = rawserver
        self.port = port

        self.info = self.response['info']
        self.pieces = [
            self.info['pieces'][x:x + 20]
            for x in xrange(0, len(self.info['pieces']), 20)
        ]
        self.len_pieces = len(self.pieces)
        self.argslistheader = argslistheader
        self.unpauseflag = threading.Event()
        self.unpauseflag.set()
        self.downloader = None
        self.storagewrapper = None
        self.fileselector = None
        self.super_seeding_active = False
        self.filedatflag = threading.Event()
        self.spewflag = threading.Event()
        self.superseedflag = threading.Event()
        self.whenpaused = None
        self.finflag = threading.Event()
        self.rerequest = None
        self.tcp_ack_fudge = config['tcp_ack_fudge']

        self.selector_enabled = config['selector_enabled']
        if appdataobj:
            self.appdataobj = appdataobj
        elif self.selector_enabled:
            self.appdataobj = ConfigDir()
            self.appdataobj.deleteOldCacheData(config['expire_cache_data'],
                                               [self.infohash])

        self.excflag = self.rawserver.get_exception_flag()
        self.failed = False
        self.checking = False
        self.started = False

        self.picker = PiecePicker(self.len_pieces,
                                  config['rarest_first_cutoff'],
                                  config['rarest_first_priority_cutoff'])
        self.choker = Choker(config, rawserver.add_task, self.picker,
                             self.finflag.isSet)

    def checkSaveLocation(self, loc):
        if 'length' in self.info:
            return os.path.exists(loc)
        return any(
            os.path.exists(os.path.join(loc, x['path'][0]))
            for x in self.info['files'])

    def saveAs(self, filefunc, pathfunc=None):
        try:

            def make(f, forcedir=False):
                if not forcedir:
                    f = os.path.split(f)[0]
                if f != '' and not os.path.exists(f):
                    os.makedirs(f)

            if 'length' in self.info:
                file_length = self.info['length']
                file = filefunc(self.info['name'], file_length,
                                self.config['saveas'], False)
                if file is None:
                    return None
                make(file)
                files = [(file, file_length)]
            else:
                file_length = sum(x['length'] for x in self.info['files'])
                file = filefunc(self.info['name'], file_length,
                                self.config['saveas'], True)
                if file is None:
                    return None

                # if this path exists, and no files from the info dict exist,
                # we assume it's a new download and the user wants to create a
                # new directory with the default name
                existing = 0
                if os.path.exists(file):
                    if not os.path.isdir(file):
                        self.errorfunc(file + 'is not a dir')
                        return None
                    if len(os.listdir(file)) > 0:  # if it's not empty
                        existing = any(
                            os.path.exists(os.path.join(file, x['path'][0]))
                            for x in self.info['files'])
                        if not existing:
                            file = os.path.join(file, self.info['name'])
                            if os.path.exists(file) and \
                                    not os.path.isdir(file):
                                if file[-8:] == '.torrent':
                                    file = file[:-8]
                                if os.path.exists(file) and \
                                        not os.path.isdir(file):
                                    self.errorfunc("Can't create dir - " +
                                                   self.info['name'])
                                    return None
                make(file, True)

                # alert the UI to any possible change in path
                if pathfunc is not None:
                    pathfunc(file)

                files = []
                for x in self.info['files']:
                    n = os.path.join(file, *x['path'])
                    files.append((n, x['length']))
                    make(n)
        except OSError as e:
            self.errorfunc("Couldn't allocate dir - " + str(e))
            return None

        self.filename = file
        self.files = files
        self.datalength = file_length

        return file

    def getFilename(self):
        return self.filename

    def _finished(self):
        self.finflag.set()
        try:
            self.storage.set_readonly()
        except (IOError, OSError) as e:
            self.errorfunc('trouble setting readonly at end - ' + str(e))
        if self.superseedflag.isSet():
            self._set_super_seed()
        self.choker.set_round_robin_period(
            max(
                self.config['round_robin_period'],
                self.config['round_robin_period'] * self.info['piece length'] /
                200000))
        self.rerequest_complete()
        self.finfunc()

    def _data_flunked(self, amount, index):
        self.ratemeasure_datarejected(amount)
        if not self.doneflag.isSet():
            self.errorfunc('piece {:d} failed hash check, re-downloading it'
                           ''.format(index))

    def _failed(self, reason):
        self.failed = True
        self.doneflag.set()
        if reason is not None:
            self.errorfunc(reason)

    def initFiles(self, old_style=False, statusfunc=None):
        if self.doneflag.isSet():
            return None
        if not statusfunc:
            statusfunc = self.statusfunc

        disabled_files = None
        if self.selector_enabled:
            self.priority = self.config['priority']
            if self.priority:
                try:
                    self.priority = self.priority.split(',')
                    assert len(self.priority) == len(self.files)
                    self.priority = [int(p) for p in self.priority]
                    for p in self.priority:
                        assert p >= -1
                        assert p <= 2
                except:
                    self.errorfunc('bad priority list given, ignored')
                    self.priority = None

            data = self.appdataobj.getTorrentData(self.infohash)
            try:
                d = data['resume data']['priority']
                assert len(d) == len(self.files)
                disabled_files = [x == -1 for x in d]
            except:
                try:
                    disabled_files = [x == -1 for x in self.priority]
                except:
                    pass

        try:
            try:
                self.storage = Storage(self.files, self.info['piece length'],
                                       self.doneflag, self.config,
                                       disabled_files)
            except IOError as e:
                self.errorfunc('trouble accessing files - ' + str(e))
                return None
            if self.doneflag.isSet():
                return None

            self.storagewrapper = StorageWrapper(
                self.storage, self.config['download_slice_size'], self.pieces,
                self.info['piece length'], self._finished, self._failed,
                statusfunc, self.doneflag, self.config['check_hashes'],
                self._data_flunked, self.rawserver.add_task, self.config,
                self.unpauseflag)

        except ValueError as e:
            self._failed('bad data - ' + str(e))
        except IOError as e:
            self._failed('IOError - ' + str(e))
        if self.doneflag.isSet():
            return None

        if self.selector_enabled:
            self.fileselector = FileSelector(
                self.files, self.info['piece length'],
                self.appdataobj.getPieceDir(self.infohash), self.storage,
                self.storagewrapper, self.rawserver.add_task, self._failed)
            if data:
                data = data.get('resume data')
                if data:
                    self.fileselector.unpickle(data)

        self.checking = True
        if old_style:
            return self.storagewrapper.old_style_init()
        return self.storagewrapper.initialize

    def getCachedTorrentData(self):
        return self.appdataobj.getTorrentData(self.infohash)

    def _make_upload(self, connection, ratelimiter, totalup):
        return Upload(connection, ratelimiter, totalup, self.choker,
                      self.storagewrapper, self.picker, self.config)

    def _kick_peer(self, connection):
        self.rawserver.add_task(connection.close, 0)

    def _ban_peer(self, ip):
        self.encoder_ban(ip)

    def _received_raw_data(self, x):
        if self.tcp_ack_fudge:
            x = int(x * self.tcp_ack_fudge)
            self.ratelimiter.adjust_sent(x)

    def _received_data(self, x):
        self.downmeasure.update_rate(x)
        self.ratemeasure.data_came_in(x)

    def _received_http_data(self, x):
        self.downmeasure.update_rate(x)
        self.ratemeasure.data_came_in(x)
        self.downloader.external_data_received(x)

    def _cancelfunc(self, pieces):
        self.downloader.cancel_piece_download(pieces)
        self.httpdownloader.cancel_piece_download(pieces)

    def _reqmorefunc(self, pieces):
        self.downloader.requeue_piece_download(pieces)

    def startEngine(self, ratelimiter=None, statusfunc=None):
        if self.doneflag.isSet():
            return False
        if not statusfunc:
            statusfunc = self.statusfunc

        self.checking = False

        if not CRYPTO_OK:
            if self.config['crypto_allowed']:
                self.errorfunc('warning - crypto library not installed')
            self.config['crypto_allowed'] = 0
            self.config['crypto_only'] = 0
            self.config['crypto_stealth'] = 0

        for i in xrange(self.len_pieces):
            if self.storagewrapper.do_I_have(i):
                self.picker.complete(i)
        self.upmeasure = Measure(self.config['max_rate_period'],
                                 self.config['upload_rate_fudge'])
        self.downmeasure = Measure(self.config['max_rate_period'])

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

        self.ratemeasure = RateMeasure()
        self.ratemeasure_datarejected = self.ratemeasure.data_rejected

        self.downloader = Downloader(
            self.storagewrapper, self.picker, self.config['request_backlog'],
            self.config['max_rate_period'], self.len_pieces,
            self.config['download_slice_size'], self._received_data,
            self.config['snub_time'], self.config['auto_kick'],
            self._kick_peer, self._ban_peer)
        self.downloader.set_download_rate(self.config['max_download_rate'])
        self.connecter = Connecter(self._make_upload, self.downloader,
                                   self.choker, self.len_pieces,
                                   self.upmeasure, self.config,
                                   self.ratelimiter, self.rawserver.add_task)
        self.encoder = Encoder(self.connecter, self.rawserver, self.myid,
                               self.config['max_message_length'],
                               self.rawserver.add_task,
                               self.config['keepalive_interval'],
                               self.infohash, self._received_raw_data,
                               self.config)
        self.encoder_ban = self.encoder.ban

        self.httpdownloader = HTTPDownloader(
            self.storagewrapper, self.picker, self.rawserver, self.finflag,
            self.errorfunc, self.downloader, self.config['max_rate_period'],
            self.infohash, self._received_http_data, self.connecter.got_piece)
        if 'httpseeds' in self.response and not self.finflag.isSet():
            for u in self.response['httpseeds']:
                self.httpdownloader.make_download(u)

        if self.selector_enabled:
            self.fileselector.tie_in(self.picker, self._cancelfunc,
                                     self._reqmorefunc,
                                     self.rerequest_ondownloadmore)
            if self.priority:
                self.fileselector.set_priorities_now(self.priority)

            # erase old data once you've started modifying it
            self.appdataobj.deleteTorrentData(self.infohash)

        if self.config['super_seeder']:
            self.set_super_seed()

        self.started = True
        return True

    def rerequest_complete(self):
        if self.rerequest:
            self.rerequest.announce(1)

    def rerequest_stopped(self):
        if self.rerequest:
            self.rerequest.announce(2)

    def rerequest_lastfailed(self):
        if self.rerequest:
            return self.rerequest.last_failed
        return False

    def rerequest_ondownloadmore(self):
        if self.rerequest:
            self.rerequest.hit()

    def startRerequester(self, seededfunc=None, force_rapid_update=False):
        trackerlist = self.response.get('announce-list',
                                        [[self.response['announce']]])

        self.rerequest = Rerequester(
            self.port, self.myid, self.infohash, trackerlist, self.config,
            self.rawserver.add_task, self.rawserver.add_task, self.errorfunc,
            self.excfunc, self.encoder.start_connections,
            self.connecter.how_many_connections,
            self.storagewrapper.get_amount_left, self.upmeasure.get_total,
            self.downmeasure.get_total, self.upmeasure.get_rate,
            self.downmeasure.get_rate, self.doneflag, self.unpauseflag,
            seededfunc, force_rapid_update)

        self.rerequest.start()

    def _init_stats(self):
        self.statistics = Statistics(self.upmeasure, self.downmeasure,
                                     self.connecter, self.httpdownloader,
                                     self.ratelimiter,
                                     self.rerequest_lastfailed,
                                     self.filedatflag)
        if 'files' in self.info:
            self.statistics.set_dirstats(self.files, self.info['piece length'])
        if self.config['spew']:
            self.spewflag.set()

    def autoStats(self, displayfunc=None):
        if not displayfunc:
            displayfunc = self.statusfunc

        self._init_stats()
        DownloaderFeedback(self.choker, self.httpdownloader,
                           self.rawserver.add_task, self.upmeasure.get_rate,
                           self.downmeasure.get_rate, self.ratemeasure,
                           self.storagewrapper.get_stats, self.datalength,
                           self.finflag, self.spewflag, self.statistics,
                           displayfunc, self.config['display_interval'])

    def startStats(self):
        self._init_stats()
        d = DownloaderFeedback(self.choker, self.httpdownloader,
                               self.rawserver.add_task,
                               self.upmeasure.get_rate,
                               self.downmeasure.get_rate, self.ratemeasure,
                               self.storagewrapper.get_stats, self.datalength,
                               self.finflag, self.spewflag, self.statistics)
        return d.gather

    def getPortHandler(self):
        return self.encoder

    def shutdown(self, torrentdata={}):
        if self.checking or self.started:
            self.storagewrapper.sync()
            self.storage.close()
            self.rerequest_stopped()
        if self.fileselector and self.started:
            if not self.failed:
                self.fileselector.finish()
                torrentdata['resume data'] = self.fileselector.pickle()
            try:
                self.appdataobj.writeTorrentData(self.infohash, torrentdata)
            except:
                self.appdataobj.deleteTorrentData(self.infohash)  # clear it
        return not self.failed and not self.excflag.isSet()
        # if returns false, you may wish to auto-restart the torrent

    def setUploadRate(self, rate):
        try:

            def s(self=self, rate=rate):
                self.config['max_upload_rate'] = rate
                self.ratelimiter.set_upload_rate(rate)

            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def setConns(self, conns, conns2=None):
        if not conns2:
            conns2 = conns
        try:

            def s(self=self, conns=conns, conns2=conns2):
                self.config['min_uploads'] = conns
                self.config['max_uploads'] = conns2
                if (conns > 30):
                    self.config['max_initiate'] = conns + 10

            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def setDownloadRate(self, rate):
        try:

            def s(self=self, rate=rate):
                self.config['max_download_rate'] = rate
                self.downloader.set_download_rate(rate)

            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def startConnection(self, ip, port, id):
        self.encoder._start_connection((ip, port), id)

    def _startConnection(self, ipandport, id):
        self.encoder._start_connection(ipandport, id)

    def setInitiate(self, initiate):
        try:

            def s(self=self, initiate=initiate):
                self.config['max_initiate'] = initiate

            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def getConfig(self):
        return self.config

    def getDefaults(self):
        return defaultargs(defaults)

    def getUsageText(self):
        return self.argslistheader

    def reannounce(self, special=None):
        try:

            def r(self=self, special=special):
                if special is None:
                    self.rerequest.announce()
                else:
                    self.rerequest.announce(specialurl=special)

            self.rawserver.add_task(r)
        except AttributeError:
            pass

    def getResponse(self):
        try:
            return self.response
        except:
            return None

    def Pause(self):
        if not self.storagewrapper:
            return False
        self.unpauseflag.clear()
        self.rawserver.add_task(self.onPause)
        return True

    def onPause(self):
        self.whenpaused = clock()
        if not self.downloader:
            return
        self.downloader.pause(True)
        self.encoder.pause(True)
        self.choker.pause(True)

    def Unpause(self):
        self.unpauseflag.set()
        self.rawserver.add_task(self.onUnpause)

    def onUnpause(self):
        if not self.downloader:
            return
        self.downloader.pause(False)
        self.encoder.pause(False)
        self.choker.pause(False)
        # rerequest automatically if paused for >60 seconds
        if self.rerequest and self.whenpaused and \
                clock() - self.whenpaused > 60:
            self.rerequest.announce(3)

    def set_super_seed(self):
        try:
            self.superseedflag.set()

            def s(self=self):
                if self.finflag.isSet():
                    self._set_super_seed()

            self.rawserver.add_task(s)
        except AttributeError:
            pass

    def _set_super_seed(self):
        if not self.super_seeding_active:
            self.super_seeding_active = True
            self.errorfunc('        ** SUPER-SEED OPERATION ACTIVE **\n  '
                           'please set Max uploads so each peer gets 6-8 kB/s')

            def s(self=self):
                self.downloader.set_super_seed()
                self.choker.set_super_seed()

            self.rawserver.add_task(s)
            # mode started when already finished
            if self.finflag.isSet():

                def r(self=self):
                    # so after kicking everyone off, reannounce
                    self.rerequest.announce(3)

                self.rawserver.add_task(r)

    def am_I_finished(self):
        return self.finflag.isSet()

    def get_transfer_stats(self):
        return self.upmeasure.get_total(), self.downmeasure.get_total()
Example #10
0
    def __init__(self, config, Output, isAnonymous):
        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 = Event()

            self.hashcheck_queue = []
            self.hashcheck_current = None

            self.rawserver = JashRawServer()
            upnp_type = UPnP_test(config['upnp_nat_access'])
            self.listen_port = None
            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 socketerror, e:
                    if upnp_type and e == UPnP_ERROR:
                        log_msg('WARNING: COULD NOT FORWARD VIA UPnP', 0)
                        upnp_type = 0
                        continue
                    self.failed("Couldn't listen - " + str(e))
                    return

            self.dht = None
            if isAnonymous:
                self.dht = dht.Proxy.DHTProxy(
                    BitTorrent.BitTorrentClient.get())
            else:
                if self.listen_port:
                    self.dht = dht.Node.LocalDHTNode(self.listen_port,
                                                     config['dht_file_name'])
            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)
            seed(createPeerID())
            #self.rawserver.add_task(self.scan, 0)
            if self.scan_period:
                self.scan()
                self.scanEvent = Scheduler.schedule_repeat(
                    self.scan_period, self.scan)
            else:
                self.scanEvent = None
Example #11
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 = 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)
            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:
            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 = fmttime(t)
                    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 i 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:
                        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:
                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:
            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)
Example #12
0
from Config import Config
from flask import Flask, render_template, jsonify, request, redirect, Response, request, abort
import json
import re
from urllib.parse import urlparse, urlunparse
import requests
import logging
import random
from RateLimiter import RateLimiter

app = Flask(__name__)

config = Config(DEFAULT_CONFIG)  # Global configuration object

# Initialize Firewall
limiter = RateLimiter(config)

LOG = logging.getLogger("app.py")


# Monitor servers
@app.route('/iwaf_admin', methods=["GET"])
def iwaf_admin():
    return render_template('server_status.html')


# Get configs
@app.route('/iwaf_admin', methods=["POST"])
def iwaf_get_params():
    global config
    return jsonify(config.get_public_params())