示例#1
0
    def set_media_file(self, path):
        if "x265" in path.lower():
            self.abort("HVEC x265 files not supported")
            return

        self.media_file = [x for x in self.files if x.path == path][0]
        Logger().write(
            LogVerbosity.Info, "Media file: " + str(self.media_file.name) +
            ", " + str(self.media_file.start_byte) + " - " +
            str(self.media_file.end_byte) + "/" + str(self.total_size))

        self.data_manager.set_piece_info(self.piece_length, self.piece_hashes)
        self.cache_manager.init(self.piece_length, self.media_file.length,
                                self.media_file.start_byte)

        self.__set_state(TorrentState.Downloading)
        self.left = self.data_manager.get_piece_by_offset(
            self.media_file.end_byte
        ).end_byte - self.data_manager.get_piece_by_offset(
            self.media_file.start_byte).start_byte
        Logger().write(
            LogVerbosity.Info, "To download: " + str(self.left) + " (" +
            str(self.left - self.media_file.length) +
            " overhead), piece length: " + str(self.piece_length))
        EventManager.throw_event(EventType.TorrentMediaFileSet,
                                 [self.media_file.name])
示例#2
0
    def announce_torrent(self, torrent):
        self.last_announce = current_time()
        announce_message = TrackerMessages.TrackerAnnounceMessage.for_http(torrent.info_hash, 2, torrent.total_size - torrent.left, torrent.left, torrent.uploaded, self.tracker_peer_request_amount)

        path = self.uri.path + announce_message.as_param_string()
        response = RequestFactory.make_request(path)
        if response is None:
            return False

        try:
            response_dict = Bencode.bdecode(response)
        except BTFailure:
            Logger().write(LogVerbosity.Info, 'Invalid tracker response: ' + str(response))
            return False

        if b"peers" not in response_dict:
            return False

        peers_data = response_dict[b"peers"]
        total_peers = int(len(peers_data) / 6)
        offset = 0
        peers = []
        for index in range(total_peers):
            peers.append(uri_from_bytes(peers_data[offset:offset + 6]))
            offset += 6
        EventManager.throw_event(EventType.PeersFound, [peers, PeerSource.HttpTracker])
示例#3
0
    def stop(self):
        if self.__state == TorrentState.Stopping:
            return

        Logger().write(LogVerbosity.Info, 'Torrent stopping')
        self.__set_state(TorrentState.Stopping)
        EventManager.deregister_event(self._user_file_selected_id)

        self.engine.stop()
        Logger().write(LogVerbosity.Debug, 'Torrent engines stopped')

        self.peer_processor.stop()
        self.peer_manager.stop()
        self.tracker_manager.stop()
        self.network_manager.stop()
        self.metadata_manager.stop()
        self.stream_manager.stop()
        self.message_processor.stop()
        self.download_manager.stop()
        self.data_manager.stop()
        self.cache_manager.stop()
        Logger().write(LogVerbosity.Debug, 'Torrent managers stopped')

        for file in self.files:
            file.close()

        self.files = []
        self.media_file = None

        self.finish()
        EventManager.throw_event(EventType.TorrentStopped, [])
        Logger().write(LogVerbosity.Important, 'Torrent stopped')
示例#4
0
    def __init__(self, torrent):
        super().__init__(torrent, "download")

        self.torrent = torrent

        self.init = False
        self.prio = False
        self.last_get_result = 0, 0
        self.last_get_time = 0

        self.queue = []
        self.slow_peer_piece_offset = 0
        self._ticks = 0

        self.start_piece = 0
        self.end_piece = 0
        self.stream_end_buffer_pieces = 0
        self.stream_play_buffer_high_priority = 0
        self.max_chunk_size = Settings.get_int("max_chunk_size")

        self.download_mode = DownloadMode.Full
        self.peers_per_piece = [(100, 2, 5), (95, 1, 2), (0, 1, 1)]

        self._event_id_stopped = EventManager.register_event(
            EventType.TorrentStopped, self.unregister)
        self._event_id_torrent_state = EventManager.register_event(
            EventType.TorrentStateChange, self.init_queue)

        self.queue_log = ""
示例#5
0
    def __init__(self):
        self.subtitle_sources = [
            SubtitlesOpenSubtitles(),
        ]

        self.sub_file_directory = Settings.get_string("base_folder") + "/subs/"
        self.sub_files = []

        self.file_size = 0
        self.file_length = 0
        self.file_name = None
        self.first_64k = None
        self.last_64k = None

        # create subtitles directory
        if not os.path.exists(self.sub_file_directory):
            os.makedirs(self.sub_file_directory)

        # remove old subtitles files
        file_list = glob.glob(self.sub_file_directory + "*.srt")
        for f in file_list:
            os.remove(f)

        EventManager.register_event(EventType.SearchSubtitles,
                                    self.search_subtitles)
示例#6
0
 def wait_for_event(max_time, event):
     UtilController.health_cache[event] = False
     evnt = EventManager.register_event(
         event, lambda *x: UtilController.assign(event))
     result = UtilController.wait_for(
         max_time, lambda: UtilController.health_cache[event])
     EventManager.deregister_event(evnt)
     return result
示例#7
0
 def __set_state(self, value):
     Logger().write(
         LogVerbosity.Info, "Setting torrent state from " +
         TorrentState.get_str(self.__state) + " to " +
         TorrentState.get_str(value))
     old = self.__state
     self.__state = value
     EventManager.throw_event(EventType.TorrentStateChange, [old, value])
示例#8
0
    def request_movies(url):
        data = RequestFactory.make_request(url)

        if data is not None:
            return MovieController.parse_movie_data(data.decode('utf-8'))
        else:
            EventManager.throw_event(EventType.Error, ["get_error", "Could not get movie data"])
            Logger().write(LogVerbosity.Info, "Error fetching movies")
            return []
示例#9
0
 def process_file_info_for_subtitles(self, size, first_64k, last_64k):
     Logger().write(LogVerbosity.Debug,
                    "Received file info from master, requesting subs")
     EventManager.throw_event(EventType.SearchSubtitles, [
         self.media_data.title, size,
         VLCPlayer().get_length(),
         first_64k.encode('utf8'),
         last_64k.encode('utf8')
     ])
示例#10
0
    def search_subtitles_thread(self, source, size, file_length, file_name,
                                first_64k, last_64k):
        sub_paths = source.get_subtitles(size, file_length, file_name,
                                         first_64k, last_64k)
        for path in sub_paths:
            file_hash = self.get_sub_hash(path)
            if len([x for x in self.sub_files if x.hash == file_hash]) == 0:
                self.sub_files.append(Subtitle(file_hash, path))

        Logger().write(LogVerbosity.Info,
                       "Found " + str(len(sub_paths)) + " subtitle files")
        EventManager.throw_event(EventType.SetSubtitleFiles, [sub_paths])
示例#11
0
    def __init__(self):
        self.media_data = MediaData()
        self.torrent_data = TorrentData()

        self.torrent = None
        self.subtitle_provider = SubtitleProvider()
        self.next_episode_manager = NextEpisodeManager()
        self.play_position = 0
        self.play_length = 0

        self.history_id = 0
        self.last_tracking_update = 0

        self.dht_enabled = Settings.get_bool("dht")
        if self.dht_enabled:
            self.dht = DHTEngine()
            self.dht.start()

        EventManager.register_event(EventType.AbortingTorrent,
                                    self.aborting_torrent)
        EventManager.register_event(EventType.TorrentMediaSelectionRequired,
                                    self.media_selection_required)
        EventManager.register_event(EventType.TorrentMediaFileSet,
                                    lambda x: self._start_playing_torrent())
        EventManager.register_event(EventType.TorrentStopped,
                                    lambda: self.on_torrent_stopped())

        VLCPlayer().player_state.register_callback(self.player_state_change)
        self.torrent_observer = CustomThread(self.observe_torrent,
                                             "Torrent observer")
        self.torrent_observer.start()
        self.next_epi_thread = None
示例#12
0
    def __init__(self):
        self.own_node = None

        self.routing_table = Table(self)
        self.table_lock = Lock()

        self.socket = Socket(Settings.get_int("dht_port"), self.on_node_seen,
                             self.on_node_timeout, self.on_query)
        self.engine = Engine("DHT Engine", 5000)
        self.engine.add_work_item("DHT Refresh buckets", 1000 * 60,
                                  self.refresh_buckets, False)
        self.engine.add_work_item("DHT Save nodes", 1000 * 60 * 5,
                                  self.save_nodes, False)

        self.running_tasks = []
        self.torrent_nodes = dict()

        EventManager.register_event(EventType.RequestPeers, self.search_peers)
        EventManager.register_event(EventType.NewDHTNode, self.add_node)
示例#13
0
    def _start_torrent(self, url, media_file):
        if self.torrent is not None:
            Logger().write(LogVerbosity.Important,
                           "Can't start new torrent, still torrent active")
            return

        success, torrent = Torrent.create_torrent(1, url)
        if success:
            self.torrent = torrent
            if media_file is not None:
                self.torrent.set_selected_media_file(media_file)
            torrent.start()
            self.last_torrent_start = current_time()
            TVManager().switch_input_to_pi()
        else:
            Logger().write(LogVerbosity.Important, "Invalid torrent")
            EventManager.throw_event(EventType.Error,
                                     ["torrent_error", "Invalid torrent"])
            self.stop_torrent()
示例#14
0
 def update_subtitles(self, new_state):
     media_type = self.media_data.type
     if media_type == "File":
         if Settings.get_bool("slave"):
             SlaveClientController.request_master_cb(
                 "get_file_info", self.process_file_info_for_subtitles, 5,
                 self.media_data.url)
         else:
             size, first_64k, last_64k = get_file_info(self.media_data.url)
             EventManager.throw_event(EventType.SearchSubtitles, [
                 self.media_data.title, size,
                 VLCPlayer().get_length(), first_64k, last_64k
             ])
     elif media_type == "Show" or media_type == "Movie" or media_type == "Torrent":
         EventManager.throw_event(EventType.SearchSubtitles, [
             os.path.basename(self.torrent.media_file.name),
             self.torrent.media_file.length,
             VLCPlayer().get_length(), self.torrent.media_file.first_64k,
             self.torrent.media_file.last_64k
         ])
示例#15
0
    def search_peers(self, torrent):
        if torrent.info_hash.sha1_hashed_bytes in self.torrent_nodes:
            Logger().write(
                LogVerbosity.Debug, "DHT: found " + str(
                    len(self.torrent_nodes[
                        torrent.info_hash.sha1_hashed_bytes])) +
                " nodes in torrent_nodes")
            EventManager.throw_event(EventType.PeersFound, [[
                x.uri for x in self.torrent_nodes[
                    torrent.info_hash.sha1_hashed_bytes]
            ], PeerSource.DHT])

        self.start_task(
            GetPeersTask(
                self, self.own_node.byte_id,
                torrent.info_hash.sha1_hashed_bytes,
                self.routing_table.get_closest_nodes(
                    torrent.info_hash.sha1_hashed_bytes)),
            lambda x: EventManager.throw_event(
                EventType.PeersFound, [x.found_peers, PeerSource.DHT]))
示例#16
0
    def __init__(self, torrent):
        super().__init__(torrent, "network")

        self.running = True
        self.torrent = torrent

        self.speed_log = 0

        self.average_download_counter = AverageCounter(self, 3)

        self.thread = None
        self._event_id_stopped = EventManager.register_event(EventType.TorrentStopped, self.unregister)
示例#17
0
    def announce_torrent(self, torrent):
        self.last_announce = current_time()

        if not self.connect():
            return False

        announce_message = TrackerMessages.TrackerAnnounceMessage.for_udp(self.connection_id, self.transaction_id, torrent.info_hash, 2,
                                                                          torrent.total_size - torrent.left, torrent.left, torrent.uploaded, self.tracker_peer_request_amount,
                                                                          6881)

        send_okay = self.connection.send(announce_message.as_bytes())
        response_message_bytes = self.connection.receive()
        if not send_okay or response_message_bytes is None:
            return False

        response_message = TrackerMessages.TrackerResponseMessage.from_bytes(response_message_bytes)
        if response_message is None or response_message.error is not None:
            return False

        EventManager.throw_event(EventType.PeersFound, [response_message.peers, PeerSource.UdpTracker])
        return True
示例#18
0
    def __init__(self):
        self.__vlc_instance = None
        self.player_state = PlayerData()

        self.instantiate_vlc()

        self.media = None
        self.__player = self.__vlc_instance.media_player_new()
        self.__list_player = self.__vlc_instance.media_list_player_new()
        self.__list_player.set_media_player(self.__player)

        self.__event_manager = self.__player.event_manager()

        self.set_volume(75)

        EventManager.register_event(EventType.SetSubtitleFiles,
                                    self.set_subtitle_files)
        EventManager.register_event(EventType.StopPlayer, self.stop)

        self.player_observer = CustomThread(self.observe_player,
                                            "Player observer")
        self.player_observer.start()
        self.stop_player_thread = None
示例#19
0
    def __init__(self, torrent):
        super().__init__(torrent, "peers")

        self.torrent = torrent
        self.potential_peers = []
        self.connecting_peers = []
        self.connected_peers = []
        self.disconnected_peers = []
        self.cant_connect_peers = []
        self.complete_peer_list = []
        self.max_peers_connected = Settings.get_int("max_peers_connected")
        self.max_peers_connecting = Settings.get_int("max_peers_connecting")
        self._peer_request_interval = Settings.get_int("peer_request_interval")
        self._peer_request_interval_no_potential = Settings.get_int(
            "peer_request_interval_no_potential")
        self.random = Random()
        self.download_start = 0
        self.start_time = current_time()
        self.last_peer_request = 0
        self.checked_no_peers = False

        self._event_id_stopped = EventManager.register_event(
            EventType.TorrentStopped, self.unregister)
        self._event_id_torrent_change = EventManager.register_event(
            EventType.TorrentStateChange, self.torrent_state_change)
        self._event_id_peers_found = EventManager.register_event(
            EventType.PeersFound, self.add_potential_peers)

        self.high_speed_peers = 0
        self.medium_speed_peers = 0

        # Log properties
        self.potential_peers_log = 0
        self.connecting_peers_log = 0
        self.connected_peers_log = 0
        self.disconnected_peers_log = 0
        self.cant_connect_peers_log = 0
示例#20
0
    def __init__(self, torrent):
        super().__init__(torrent, "data")
        self.torrent = torrent
        self._pieces = dict()
        self.init_done = False
        self.total_pieces = 0
        self.piece_length = 0
        self.bitfield = None
        self.hashes = []

        self.block_size = Settings.get_int("block_size")
        self.broadcasted_hash_data = False
        self._event_id_stopped = EventManager.register_event(
            EventType.TorrentStopped, self.unregister)
        self.blocks_done_length = 0
        self.last_piece_index = 0
示例#21
0
    def __init__(self, id, uri):
        super().__init__(None, "Torrent")

        self.left = 0
        self.overhead = 0

        self.name = None
        self.id = id
        self.uri = uri
        self.total_size = 0
        self.uploaded = 0
        self.piece_length = 0
        self.piece_hashes = None
        self.announce_uris = []
        self.info_hash = None
        self.files = []
        self.__state = TorrentState.Initial

        self.media_file = None
        self.selected_media_file = None

        self.stream_file_hash = None

        self._user_file_selected_id = EventManager.register_event(
            EventType.TorrentMediaFileSelection, self.user_file_selected)

        self.engine = Engine.Engine('Main processor', 500, self)

        self.tracker_manager = TrackerManager()
        self.peer_manager = TorrentPeerManager(self)
        self.data_manager = TorrentDataManager(self)
        self.download_manager = TorrentDownloadManager(self)
        self.stream_manager = StreamManager(self)
        self.metadata_manager = TorrentMetadataManager(self)
        self.network_manager = TorrentNetworkManager(self)
        self.message_processor = TorrentMessageProcessor(self)
        self.peer_processor = TorrentPeerProcessor(self)
        self.cache_manager = TorrentCacheManager(self)
示例#22
0
    def __init__(self):
        self.trackers = []
        self.initialized = False

        self.request_peers_id = EventManager.register_event(EventType.RequestPeers, self.request_peers)
示例#23
0
 def unregister(self):
     EventManager.deregister_event(self._event_id_stopped)
     EventManager.deregister_event(self._event_id_torrent_change)
     EventManager.deregister_event(self._event_id_peers_found)
示例#24
0
 def stop(self):
     EventManager.deregister_event(self.request_peers_id)
示例#25
0
    def handle_message(self, peer, message, timestamp):
        if peer.protocol_logger is None:
            return

        if isinstance(message, PieceMessage):
            Logger().write(
                LogVerbosity.All,
                str(peer.id) + ' Received piece message: ' +
                str(message.index) + ', offset ' + str(message.offset))
            peer.protocol_logger.update("Sending/receiving requests", True)
            self.torrent.data_manager.block_done(peer, message.index,
                                                 message.offset, message.data)
            peer.download_manager.block_done(
                message.index * self.torrent.data_manager.piece_length +
                message.offset, timestamp)
            peer.counter.add_value(message.length)
            return

        elif isinstance(message, KeepAliveMessage):
            Logger().write(LogVerbosity.Debug,
                           str(peer.id) + ' Received keep alive message')
            peer.protocol_logger.update("Received KeepAlive")
            return

        elif isinstance(message, ChokeMessage):
            Logger().write(LogVerbosity.Debug,
                           str(peer.id) + ' Received choke message')
            peer.protocol_logger.update("Received Choke")
            peer.communication_state.in_choke = PeerChokeState.Choked
            return

        elif isinstance(message, UnchokeMessage):
            Logger().write(LogVerbosity.Debug,
                           str(peer.id) + ' Received unchoke message')
            peer.protocol_logger.update("Received UnChoke")
            peer.communication_state.in_choke = PeerChokeState.Unchoked
            return

        elif isinstance(message, InterestedMessage):
            Logger().write(LogVerbosity.Info,
                           str(peer.id) + ' Received interested message')
            peer.protocol_logger.update("Received Interested")
            peer.communication_state.in_interest = PeerInterestedState.Interested
            return

        elif isinstance(message, UninterestedMessage):
            Logger().write(LogVerbosity.Debug,
                           str(peer.id) + ' Received uninterested message')
            peer.protocol_logger.update("Received Uninterested")
            peer.communication_state.in_interest = PeerInterestedState.Uninterested
            return

        elif isinstance(message, HaveMessage):
            if peer.state == PeerState.Started:
                Logger().write(
                    LogVerbosity.All,
                    str(peer.id) + ' Received have message for piece ' +
                    str(message.piece_index))
                peer.protocol_logger.update("Received Have", True)
                peer.bitfield.update_piece(message.piece_index, True)
            return

        elif isinstance(message, BitfieldMessage):
            if peer.state == PeerState.Started:
                Logger().write(LogVerbosity.All,
                               str(peer.id) + ' Received bitfield message')
                peer.protocol_logger.update("Received Bitfield")
                peer.bitfield.update(message.bitfield)
            return

        elif isinstance(message, RequestMessage):
            Logger().write(LogVerbosity.Info,
                           str(peer.id) + ' Received request message')
            peer.protocol_logger.update("Received Request")
            return

        elif isinstance(message, CancelMessage):
            Logger().write(LogVerbosity.Debug,
                           str(peer.id) + ' Received cancel message')
            peer.protocol_logger.update("Received Cancel")
            return

        elif isinstance(message, PortMessage):
            Logger().write(
                LogVerbosity.All,
                str(peer.id) + ' Received port message, port = ' +
                str(message.port))
            peer.protocol_logger.update("Received Port")
            EventManager.throw_event(
                EventType.NewDHTNode,
                [peer.connection_manager.uri.hostname, message.port])
            return

        elif isinstance(message, HaveAllMessage):
            if peer.state == PeerState.Started:
                Logger().write(LogVerbosity.All,
                               str(peer.id) + " Received HaveAll message")
                peer.protocol_logger.update("Received HaveAll")
                peer.bitfield.set_has_all()
            return

        elif isinstance(message, HaveNoneMessage):
            if peer.state == PeerState.Started:
                Logger().write(LogVerbosity.All,
                               str(peer.id) + " Received HaveNone message")
                peer.protocol_logger.update("Received HaveNone")
                peer.bitfield.set_has_none()
            return

        elif isinstance(message, AllowedFastMessage):
            if peer.state == PeerState.Started:
                Logger().write(LogVerbosity.All,
                               str(peer.id) + " Received AllowedFast message")
                peer.protocol_logger.update("Received AllowedFast", True)
                peer.allowed_fast_pieces.append(message.piece_index)
            return

        elif isinstance(message, SuggestPieceMessage):
            Logger().write(LogVerbosity.All,
                           str(peer.id) + " Received SuggestPiece message")
            peer.protocol_logger.update("Received SuggestPiece", True)
            return

        elif isinstance(message, RejectRequestMessage):
            if peer.state == PeerState.Started:
                Logger().write(
                    LogVerbosity.Debug,
                    str(peer.id) + " Received RejectRequest message")
                peer.protocol_logger.update("Received RejectRequest", True)
                peer.download_manager.request_rejected(message.index,
                                                       message.offset,
                                                       message.data_length)
            return

        elif isinstance(message, ExtensionHandshakeMessage):
            Logger().write(
                LogVerbosity.All,
                str(peer.id) + ' Received extension handshake message')
            peer.protocol_logger.update("Received ExtensionHandshake")

            try:
                dic = Bencode.bdecode(message.bencoded_payload)
            except BTFailure:
                Logger().write(LogVerbosity.Debug,
                               "Invalid extension handshake received")
                peer.stop_async("Invalid extension handshake")
                return

            peer.extension_manager.parse_dictionary(dic)
            if b'metadata_size' in dic:
                if peer is not None:
                    self.torrent.metadata_manager.set_total_size(
                        dic[b'metadata_size'])

            return

        elif isinstance(message, PeerExchangeMessage):
            peer.protocol_logger.update("Received PeerExchange")
            Logger().write(
                LogVerbosity.Debug,
                str(peer.id) + ' Received ' + str(len(message.added)) +
                ' peers from peer exchange')
            self.torrent.peer_manager.add_potential_peers(
                message.added, PeerSource.PeerExchange)
            return

        elif isinstance(message, MetadataMessage):
            if message.metadata_message_type == MetadataMessageType.Data:
                peer.protocol_logger.update("Received Metadata")
                Logger().write(
                    LogVerbosity.Debug,
                    str(peer.id) + ' Received metadata message index ' +
                    str(message.piece_index))
                self.torrent.metadata_manager.add_metadata_piece(
                    message.piece_index, message.data)
            else:
                peer.protocol_logger.update("Received Metadata rejected")
                Logger().write(
                    LogVerbosity.Debug,
                    str(peer.id) + ' Received metadata reject message ' +
                    str(message.piece_index))
            return
示例#26
0
 def abort(self, reason):
     Logger().write(LogVerbosity.Important, "Aborting torrent: " + reason)
     EventManager.throw_event(EventType.AbortingTorrent, [reason])
示例#27
0
 def unregister(self):
     EventManager.deregister_event(self._event_id_stopped)
示例#28
0
    def parse_info_dictionary(self, info_dict):
        self.name = info_dict[b'name'].decode('utf8')

        if b'files' in info_dict:
            # Multifile
            files = info_dict[b'files']
            total_length = 0
            for file in files:
                file_length = file[b'length']
                path = self.name
                path_list = file[b'path']
                last_path = ""
                for path_part in path_list:
                    path += "/" + path_part.decode('utf8')
                    last_path = path_part.decode('utf8')

                fi = TorrentDownloadFile(self, file_length, total_length,
                                         last_path, path, is_media_file(path))
                self.files.append(fi)

                total_length += file_length
                Logger().write(LogVerbosity.Info, "File: " + fi.path)
        else:
            # Singlefile
            total_length = info_dict[b'length']
            file = TorrentDownloadFile(self, total_length, 0, self.name,
                                       self.name, is_media_file(self.name))
            self.files.append(file)
            Logger().write(LogVerbosity.Info, "File: " + file.path)

        self.piece_length = info_dict[b'piece length']
        self.piece_hashes = info_dict[b'pieces']
        self.total_size = total_length
        media_files = [x for x in self.files if x.is_media]
        if len(media_files) == 0:
            # No media file, can't play so just stop
            Logger().write(LogVerbosity.Important,
                           "No media file found in torrent, stopping")
            EventManager.throw_event(EventType.StopPlayer, [])
        elif len(media_files) == 1:
            # Single media file, just play that
            self.set_media_file(media_files[0].path)
        elif self.selected_media_file is not None:
            self.set_media_file([
                x for x in media_files if x.name == self.selected_media_file
            ][0].path)
        else:
            ordered = sorted(media_files, key=lambda x: x.length, reverse=True)
            biggest = ordered[0]
            second = ordered[1]
            if biggest.length > second.length * 8:
                # One file is significantly bigger than the others, play that
                self.set_media_file(biggest.path)
            else:
                # Multiple files, let user decide
                self.__set_state(TorrentState.WaitingUserFileSelection)
                for file in media_files:
                    season, epi = try_parse_season_episode(file.path)
                    if season:
                        file.season = season
                    if epi:
                        file.episode = epi
                EventManager.throw_event(
                    EventType.TorrentMediaSelectionRequired, [media_files])

        Logger().write(LogVerbosity.Info, "Torrent metadata read")
示例#29
0
    def update_new_peers(self):
        if self.torrent.state != TorrentState.Downloading and self.torrent.state != TorrentState.DownloadingMetaData and self.torrent.state != TorrentState.WaitingUserFileSelection:
            return True

        if current_time() - self.last_peer_request > self._peer_request_interval or \
                                len(self.potential_peers) <= 10 and current_time() - self.last_peer_request > self._peer_request_interval_no_potential:
            Logger().write(LogVerbosity.Debug, "Requesting peers")
            EventManager.throw_event(EventType.RequestPeers, [self.torrent])
            self.last_peer_request = current_time()

        currently_connecting = len(self.connecting_peers)
        currently_connected = len(self.connected_peers)

        if not self.checked_no_peers and current_time(
        ) - self.start_time > 45000:
            self.checked_no_peers = True

            if len(
                    self.potential_peers
            ) == 0 and currently_connecting == 0 and currently_connected == 0:
                self.torrent.abort("No peers available")
                return False

        if currently_connected >= self.max_peers_connected:
            # already have max connections
            return True

        if currently_connecting >= self.max_peers_connecting:
            # already have max connecting
            return True

        connected_peers_under_max = self.max_peers_connected - currently_connected
        connecting_peers_under_max = self.max_peers_connecting - currently_connecting
        peers_to_connect = min(connecting_peers_under_max,
                               connected_peers_under_max)

        peer_list = self.potential_peers  # Try connecting to new peers from potential list
        peer_list_size = len(peer_list)
        using_disconnected = False
        if peer_list_size == 0:
            using_disconnected = True
            peer_list = [
                x for x in self.disconnected_peers
                if current_time() - x[2] > 10000
            ][peers_to_connect:]  # If we dont have any new peers to try, try connecting to disconnected peers
            peer_list_size = len(peer_list)
            if peer_list_size == 0:
                return True  # No peers available

        peers_to_connect = min(peer_list_size, peers_to_connect)
        Logger().write(LogVerbosity.Debug,
                       'starting ' + str(peers_to_connect) + ' new peers')
        selected_peers = self.random.sample(peer_list, peers_to_connect)
        if not using_disconnected:
            self.potential_peers = [
                x for x in peer_list if x not in selected_peers
            ]
        else:
            self.disconnected_peers = [
                x for x in peer_list if x not in selected_peers
            ]
        for peer in selected_peers:
            self.__peer_id += 1
            new_peer = Peer(self.__peer_id, self.torrent, peer[0], peer[1])
            self.connecting_peers.append(new_peer)
            new_peer.start()

        self.potential_peers_log = len(self.potential_peers)
        self.disconnected_peers_log = len(self.disconnected_peers)
        return True