Exemple #1
0
    def getSubtileInfosForInfohash(self, infohash):
        '''
        Retrieve available information about subtitles for the given infohash.
        
        Given the infohash of a .torrent, retrieves every
        information about subtitles published for that .torrent that is
        currently available in the DB. 
        
        @param infohash: a .torrent infohash (binary)
        @return: a dictionary. The dictionary looks like this::
                { 
                  channel_id1 : {langCode : L{SubtitleInfo}, ...} ,
                  channel_id2 : {langCode : L{SubtitleInfo}, ... },
                  ...
                } 
            Each entry in the dictionary has the following semantics:
                - channel_id is the permid identifiying the channel (binary).
                - langCode is an ISO 693-2 three characters language code
        '''
        assert utilities.isValidInfohash(infohash)
        assert self._registered, "Instance is not registered"

        returnDictionary = dict()

        #a metadataDTO corresponds to all metadata for a pair channel, infohash
        metadataDTOs = self.richMetadata_db.getAllMetadataForInfohash(infohash)

        for metadataDTO in metadataDTOs:
            channel = metadataDTO.channel
            subtitles = metadataDTO.getAllSubtitles()
            if len(subtitles) > 0:
                returnDictionary[channel] = subtitles

        return returnDictionary
 def getSubtileInfosForInfohash(self, infohash):
     '''
     Retrieve available information about subtitles for the given infohash.
     
     Given the infohash of a .torrent, retrieves every
     information about subtitles published for that .torrent that is
     currently available in the DB. 
     
     @param infohash: a .torrent infohash (binary)
     @return: a dictionary. The dictionary looks like this::
             { 
               channel_id1 : {langCode : L{SubtitleInfo}, ...} ,
               channel_id2 : {langCode : L{SubtitleInfo}, ... },
               ...
             } 
         Each entry in the dictionary has the following semantics:
             - channel_id is the permid identifiying the channel (binary).
             - langCode is an ISO 693-2 three characters language code
     '''
     assert utilities.isValidInfohash(infohash)
     assert self._registered, "Instance is not registered"
     
     returnDictionary = dict()
     
     #a metadataDTO corresponds to all metadata for a pair channel, infohash
     metadataDTOs = self.richMetadata_db.getAllMetadataForInfohash(infohash)
     
     for metadataDTO in metadataDTOs:
         channel = metadataDTO.channel
         subtitles = metadataDTO.getAllSubtitles()
         if len(subtitles) > 0 :
             returnDictionary[channel] = subtitles
     
     return returnDictionary
    def send_metadata_request(self, permid, infohash, selversion=-1, caller="BC"):
        if DEBUG:
            print >> sys.stderr,time.asctime(),'-', "metadata: Connect to send GET_METADATA to",show_permid_short(permid)
        if not isValidInfohash(infohash):
            return False
        
        filename,metadata = self.torrent_exists(infohash)
        if filename is not None:    # torrent already exists on disk
            if DEBUG:
                print >> sys.stderr,time.asctime(),'-', "metadata: send_meta_req: Already on disk??!"
            self.notify_torrent_is_in(infohash, metadata, filename)
            return True
        
        if caller == "dlhelp":
            self.requested_torrents.add(infohash)
        
        if self.min_free_space != 0 and (self.free_space - self.avg_torrent_size < self.min_free_space):   # no space to collect
            self.free_space = self.get_free_space()
            if self.free_space - self.avg_torrent_size < self.min_free_space:
                self.warn_disk_full()
                return True

        try:
            # Optimization: don't connect if we're connected, although it won't 
            # do any harm.
            if selversion == -1: # not currently connected
                self.overlay_bridge.connect(permid,lambda e,d,p,s:self.get_metadata_connect_callback(e,d,p,s,infohash))
            else:
                self.get_metadata_connect_callback(None,None,permid,selversion,infohash)
            
        except:
            print_exc()
            return False
        return True
    def sendSubtitleRequest(self, permid, channel_id, infohash, languages,
                            callback=None, selversion= -1):
        """
        Send a request for subtitle files. Only called by the OLThread
        
        Send a GET_SUBS request to the peer identified by permid.
        The request asks for several subtitles file, for a given channel_id
        and torrent infohash. The subtitles file to request are specified
        by the languages parameter that is a list of 3 characters language
        codes.
        
        The contents of a GET_SUBS request are:
            - channel_id: the identifier of the channel for which the subtitles
              were added. (a permid). Binary.
            - infohash: the infohash of the torrent, the subtitles refer to.
              Binary.
            - bitmask:  a 32 bit bitmask (an integer) which specifies the 
              languages requested
        
        @param permid: the destination of the request (binary)
        @param channel_id: the identifier of the channel for which the subtitle
                           was added (binary)
        @param infohash: the infohash of a torrent the subtitles refers to (binary).
        @param languages: a list of 3-characters language codes. It must be
                          on of the supported language codes (see Languages)
        @param callback: a function that will be called WHENEVER some of the
                         requested subtitles are received. It must have exactly
                         one parameter that will be bound to a list of 
                         the languages that were received
        @param selversion: the protocol version of the peer whe are sending 
                            the request to
        
        @raise SubtitleMsgHandlerException: if the message failed its attempt to be sent.
                                      Notice that also if the method returns without
                                      raising any exception it doesn't mean
                                      that the message has been sent.
        """
        
        assert utilities.isValidInfohash(infohash), SUBS_LOG_PREFIX + "Invalid infohash %s" % infohash
        assert utilities.isValidPermid(permid), SUBS_LOG_PREFIX + "Invlaid destination permid %s" % permid
        assert self.languagesUtility.isLangListSupported(languages), SUBS_LOG_PREFIX + "Some of the languages where not supported"

        if DEBUG:
            print >> sys.stderr, SUBS_LOG_PREFIX + "preparing to send GET_SUBS to " + utilities.show_permid_short(permid)
            
        if len(languages) == 0:
            if DEBUG:
                print >> sys.stderr, SUBS_LOG_PREFIX + " no subtitles to request."
            return
            
        requestDetails = dict()
        requestDetails['channel_id'] = channel_id
        requestDetails['infohash'] = infohash
        requestDetails['languages'] = languages
        
        self._subsMsgHndlr.sendSubtitleRequest(permid, requestDetails,
                                                lambda e,d,c,i,b : \
                                                    self._subsRequestSent(e,d,c,i,b),
                                                    callback,
                                                    selversion)
    def send_metadata(self, permid, message, selversion):
        try:
            infohash = bdecode(message[1:])
        except:
            print_exc()
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: error becoding"
            return False
        if not isValidInfohash(infohash):
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: invalid hash"
            return False

        # TODO:
        res = self.torrent_db.getOne(('torrent_file_name', 'status_id'), infohash=bin2str(infohash))
        if not res:
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: not in database"
            return True    # don't close connection because I don't have the torrent
        torrent_file_name, status_id = res
        if status_id == self.torrent_db._getStatusID('dead'):
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: Torrent was dead"
            return True
        if not torrent_file_name:
            return True
        torrent_path = os.path.join(self.torrent_dir, torrent_file_name)
        if not os.path.isfile(torrent_path):
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: not existing", res, torrent_path
            return True
#        
#        data = self.torrent_db.getTorrent(infohash)
#        if not data or not data['torrent_name']:
#            return True     # don't close connection
#        live = data.get('status', 'unknown')
#        #print "**************** check live before send metadata", live
#        if live == 'dead':
#            return True    # don't send dead torrents around
#        
#        torrent_path = None
#        try:
#            torrent_path = os.path.join(data['torrent_dir'], data['torrent_name'])
#            if not os.path.isfile(torrent_path):
#                torrent_path = None
#        except:
#            print_exc()
#            
#        if not torrent_path:
#            if DEBUG:
#                print >> sys.stderr,"metadata: GET_METADATA: not torrent path"
#            return True
        
        task = {'permid':permid, 'infohash':infohash, 'torrent_path':torrent_path, 'selversion':selversion}
        self.upload_queue.append(task)
        if int(time()) >= self.next_upload_time:
            self.checking_upload_queue()
        
        return True
    def got_metadata(self, permid, message, selversion):    
        """ receive torrent file from others """
        
        # Arno, 2007-06-20: Disabled the following code. What's this? Somebody sends 
        # us something and we refuse? Also doesn't take into account download help 
        #and remote-query extension.
        
        #if self.upload_rate <= 0:    # if no upload, no download, that's the game
        #    return True    # don't close connection
        
        try:
            message = bdecode(message[1:])
        except:
            print_exc()
            return False
        if not isinstance(message, dict):
            return False
        try:
            infohash = message['torrent_hash']
            if not isValidInfohash(infohash):
                return False

            if not infohash in self.requested_torrents:    # got a torrent which was not requested
                return True
            if self.torrent_db.hasMetaData(infohash):
                return True
            
            metadata = message['metadata']
            if not self.valid_metadata(infohash, metadata):
                return False
            if DEBUG:
                torrent_size = len(metadata)
                print >> sys.stderr,"metadata: Recvd torrent", `infohash`, sha(infohash).hexdigest(), torrent_size
            
            extra_info = {}
            if selversion >= OLPROTO_VER_FOURTH:
                try:
                    extra_info = {'leecher': message.get('leecher', -1),
                              'seeder': message.get('seeder', -1),
                              'last_check_time': message.get('last_check_time', -1),
                              'status':message.get('status', 'unknown')}
                except Exception, msg:
                    print_exc()
                    print >> sys.stderr, "metadata: wrong extra info in msg - ", message
                    extra_info = {}
                
            filename = self.save_torrent(infohash, metadata, extra_info=extra_info)
            self.requested_torrents.remove(infohash)
            
            if DEBUG:
                print >>sys.stderr,"metadata: Was I asked to dlhelp someone",self.dlhelper

            self.notify_torrent_is_in(infohash,metadata,filename)
            
            
            # BarterCast: add bytes of torrent to BarterCastDB
            # Save exchanged KBs in BarterCastDB
            if permid != None and BARTERCAST_TORRENTS:
                self.overlay_bridge.add_task(lambda:self.olthread_bartercast_torrentexchange(permid, 'downloaded'), 0)
Exemple #7
0
    def __init__(self,
                 publisher,
                 infohash,
                 timestamp=None,
                 description=u"",
                 subtitles=None,
                 signature=None):
        """
        Create a MetataDTO instance.
        
        publisher and infohash are mandatory to be not null
        @param publisher: the permid  of the owner of the 
                          channel this instance refers to
        @param infohash: the infohash of the item in the channel this instance
                         refers to 
        @param timestamp: the timestamp of the creation of this metadata
                          instance. This can be later reset with 
                          resetTimestamp()
        @param description: an optional utf-8 string description for the item. 
                            Defaults to an empty string
        @param subtitles: a dictionary of type {langCode : SubtitleInfo}
        @param signature: signature of the packed version of this metadataDTO.
                          Defaults to None. It can be later signed with sign()
        """

        assert publisher is not None
        assert infohash is not None
        assert isValidPermid(publisher)
        assert isValidInfohash(infohash)

        #stringified permid of the owner of the channel
        self.channel = publisher

        #stringified infohash (bin2str) of the torrent
        self.infohash = infohash
        if timestamp is not None:
            timestring = int(floor(timestamp))
        else:
            timestring = int(floor(time.time()))

        #integer timestamp of the creation of this content
        #(the content, not the MetadataDTO instance)
        self.timestamp = timestring

        #utf-8 string description
        if isinstance(description, str):
            description = unicode(description, "utf-8")

        self.description = description

        if subtitles is None:
            subtitles = {}
        self._subtitles = subtitles
        self.signature = signature
Exemple #8
0
    def publishSubtitle(self, infohash, lang, pathToSrtSubtitle):
        '''
        Allows an user to publish an srt subtitle file in his channel.
        
        Called by a channel owner this method inserts a new subtitle for
        a torrent published in his channel. 
        The method assumes that the torrent identified by the infohash
        parameter is already in the channel, and that the parameter 
        pathToSrtSubtitle points to an existing srt file on the local
        filesystem.
        If a subtitle for the same language was already associated to the 
        specified infohash and channel, it will be overwritten.
        After calling this method the newly inserted subtitle will be 
        disseminated via Channelcast.
        
        @param infohash: the infohash of the torrent to associate the subtitle
                         with, binary
        @param lang: a 3 characters code for the language of the subtitle as
                     specified in ISO 639-2. Currently just 32 language codes
                     will be supported.
        @param pathToSrtSubtitle: a path in the local filesystem to a subtitle
                                  in srt format.
        
        @raise RichMetadataException: if something "general" goes wrong while
                                      adding new metadata
        @raise IOError: if disk related problems occur
        '''
        assert utilities.isValidInfohash(infohash), "Invalid Infohash"
        assert lang is not None and self.langUtility.isLangCodeSupported(lang)
        assert self._registered, "Instance is not registered"

        channelid = bin2str(self.my_permid)
        base64infohash = bin2str(infohash)
        # consisnstency check: I want to assure that this method is called
        # for an item that is actually in my channel
        consinstent = self.channelcast_db.isItemInChannel(
            channelid, base64infohash)

        if not consinstent:
            msg = "Infohash %s not found in my channel. Rejecting subtitle" % base64infohash
            if DEBUG:
                print >> sys.stderr, msg
            raise RichMetadataException(msg)
        try:
            filepath = self.subtitlesHandler.copyToSubtitlesFolder(
                pathToSrtSubtitle, self.my_permid, infohash, lang)
        except Exception, e:
            if DEBUG:
                print >> sys.stderr, "Failed to read and copy subtitle to appropriate folder: %s" % str(
                    e)
Exemple #9
0
    def send_metadata_request(self,
                              permid,
                              infohash,
                              selversion=-1,
                              caller="BC"):
        assert isinstance(
            infohash, str), "INFOHASH has invalid type: %s" % type(infohash)
        assert len(
            infohash
        ) == INFOHASH_LENGTH, "INFOHASH has invalid length: %d" % len(infohash)
        if DEBUG:
            print >> sys.stderr, "metadata: Connect to send GET_METADATA to", show_permid_short(
                permid)
        if not isValidInfohash(infohash):
            return False

        filename, metadata = self.torrent_exists(infohash)
        if filename is not None:  # torrent already exists on disk
            if DEBUG:
                print >> sys.stderr, "metadata: send_meta_req: Already on disk??!"
            self.notify_torrent_is_in(infohash, metadata, filename)
            return True

        if caller == "proxyservice":
            self.requested_torrents.add(infohash)

        if self.min_free_space != 0 and (
                self.free_space - self.avg_torrent_size <
                self.min_free_space):  # no space to collect
            self.free_space = self.get_free_space()
            if self.free_space - self.avg_torrent_size < self.min_free_space:
                self.warn_disk_full()
                return True

        try:
            # Optimization: don't connect if we're connected, although it won't
            # do any harm.
            if selversion == -1:  # not currently connected
                self.overlay_bridge.connect(
                    permid,
                    lambda e, d, p, s: self.get_metadata_connect_callback(
                        e, d, p, s, infohash))
            else:
                self.get_metadata_connect_callback(None, None, permid,
                                                   selversion, infohash)

        except:
            print_exc()
            return False
        return True
 def __init__(self, publisher,infohash,timestamp = None,
              description=u"", subtitles=None,signature=None):
     """
     Create a MetataDTO instance.
     
     publisher and infohash are mandatory to be not null
     @param publisher: the permid  of the owner of the 
                       channel this instance refers to
     @param infohash: the infohash of the item in the channel this instance
                      refers to 
     @param timestamp: the timestamp of the creation of this metadata
                       instance. This can be later reset with 
                       resetTimestamp()
     @param description: an optional utf-8 string description for the item. 
                         Defaults to an empty string
     @param subtitles: a dictionary of type {langCode : SubtitleInfo}
     @param signature: signature of the packed version of this metadataDTO.
                       Defaults to None. It can be later signed with sign()
     """
     
     assert publisher is not None
     assert infohash is not None
     assert isValidPermid(publisher)
     assert isValidInfohash(infohash)
     
     #stringified permid of the owner of the channel
     self.channel = publisher
     
     #stringified infohash (bin2str) of the torrent
     self.infohash = infohash
     if timestamp is not None:
         timestring = int(floor(timestamp))
     else:
         timestring = int(floor(time.time()))
     
     #integer timestamp of the creation of this content
     #(the content, not the MetadataDTO instance)
     self.timestamp = timestring
     
     #utf-8 string description
     if isinstance(description, str):
         description = unicode(description, "utf-8")
         
     self.description = description
     
     if subtitles is None:
         subtitles = {}
     self._subtitles = subtitles
     self.signature = signature
   def publishSubtitle(self, infohash, lang, pathToSrtSubtitle):
       '''
       Allows an user to publish an srt subtitle file in his channel.
       
       Called by a channel owner this method inserts a new subtitle for
       a torrent published in his channel. 
       The method assumes that the torrent identified by the infohash
       parameter is already in the channel, and that the parameter 
       pathToSrtSubtitle points to an existing srt file on the local
       filesystem.
       If a subtitle for the same language was already associated to the 
       specified infohash and channel, it will be overwritten.
       After calling this method the newly inserted subtitle will be 
       disseminated via Channelcast.
       
       @param infohash: the infohash of the torrent to associate the subtitle
                        with, binary
       @param lang: a 3 characters code for the language of the subtitle as
                    specified in ISO 639-2. Currently just 32 language codes
                    will be supported.
       @param pathToSrtSubtitle: a path in the local filesystem to a subtitle
                                 in srt format.
       
       @raise RichMetadataException: if something "general" goes wrong while
                                     adding new metadata
       @raise IOError: if disk related problems occur
       '''
       assert utilities.isValidInfohash(infohash), "Invalid Infohash"
       assert lang is not None and self.langUtility.isLangCodeSupported(lang)
       assert self._registered, "Instance is not registered"
 
       channelid = bin2str(self.my_permid)
       base64infohash = bin2str(infohash)
       # consisnstency check: I want to assure that this method is called
       # for an item that is actually in my channel
       consinstent = self.channelcast_db.isItemInChannel(channelid,base64infohash)
       
       if not consinstent:
           msg = "Infohash %s not found in my channel. Rejecting subtitle"% base64infohash
           if DEBUG:
               print >> sys.stderr, msg
           raise RichMetadataException(msg)
       try:
           filepath = self.subtitlesHandler.copyToSubtitlesFolder(pathToSrtSubtitle,
                                                           self.my_permid,infohash,
                                                           lang)
       except Exception,e:
           if DEBUG:
               print >> sys.stderr, "Failed to read and copy subtitle to appropriate folder: %s" % str(e)
Exemple #12
0
    def send_metadata(self, permid, message, selversion):
        try:
            infohash = bdecode(message[1:])
        except:
            print_exc()
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: error becoding"
            return False
        if not isValidInfohash(infohash):
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: invalid hash"
            return False

        # TODO:
        res = self.torrent_db.getOne(('torrent_file_name', 'status_id'),
                                     infohash=bin2str(infohash))
        if not res:
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: not in database", infohash
            return True  # don't close connection because I don't have the torrent
        torrent_file_name, status_id = res
        if status_id == self.torrent_db._getStatusID('dead'):
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: Torrent was dead"
            return True
        if not torrent_file_name:
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: no torrent file name"
            return True
        torrent_path = os.path.join(self.torrent_dir, torrent_file_name)
        if not os.path.isfile(torrent_path):
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: not existing", res, torrent_path
            return True

        task = {
            'permid': permid,
            'infohash': infohash,
            'torrent_path': torrent_path,
            'selversion': selversion
        }
        self.upload_queue.append(task)
        if int(time()) >= self.next_upload_time:
            self.checking_upload_queue()

        return True
    def send_metadata(self, permid, message, selversion):
        try:
            infohash = bdecode(message[1:])
        except:
            print_exc()
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: error becoding"
            return False
        if not isValidInfohash(infohash):
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: invalid hash"
            return False

        # TODO:
        res = self.torrent_db.getOne(('torrent_file_name', 'status_id'), infohash=bin2str(infohash))
        if not res:
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: not in database", infohash
            return True    # don't close connection because I don't have the torrent
        torrent_file_name, status_id = res
        if status_id == self.torrent_db._getStatusID('dead'):
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: Torrent was dead"
            return True
        if not torrent_file_name:
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: no torrent file name"
            return True
        torrent_path = os.path.join(self.torrent_dir, torrent_file_name)
        if not os.path.isfile(torrent_path):
            if DEBUG:
                print >> sys.stderr,"metadata: GET_METADATA: not existing", res, torrent_path
            return True
        
        task = {'permid':permid, 'infohash':infohash, 'torrent_path':torrent_path, 'selversion':selversion}
        self.upload_queue.append(task)
        if int(time()) >= self.next_upload_time:
            self.checking_upload_queue()
        
        return True
Exemple #14
0
    def got_metadata(self, permid, message, selversion):
        """ receive torrent file from others """

        # Arno, 2007-06-20: Disabled the following code. What's this? Somebody sends
        # us something and we refuse? Also doesn't take into account download help
        #and remote-query extension.

        #if self.upload_rate <= 0:    # if no upload, no download, that's the game
        #    return True    # don't close connection

        try:
            message = bdecode(message[1:])
        except:
            print_exc()
            return False
        if not isinstance(message, dict):
            return False
        try:
            infohash = message['torrent_hash']
            if not isValidInfohash(infohash):
                # 19/02/10 Boudewijn: isValidInfohash either returns
                # True or raises a ValueError. So this part of the
                # code will never be reached...
                return False

            assert isinstance(
                infohash,
                str), "INFOHASH has invalid type: %s" % type(infohash)
            assert len(
                infohash
            ) == INFOHASH_LENGTH, "INFOHASH has invalid length: %d" % len(
                infohash)

            #print >>sys.stderr,"metadata: got_metadata: hexinfohash: get_collected_torrent_filename(infohash)

            if not infohash in self.requested_torrents:  # got a torrent which was not requested
                return True
            if self.torrent_db.hasMetaData(infohash):
                return True

            # P2PURL
            goturl = False
            if selversion >= OLPROTO_VER_ELEVENTH:
                if 'metatype' in message and message[
                        'metatype'] == URL_MIME_TYPE:
                    try:
                        tdef = TorrentDef.load_from_url(message['metadata'])
                        # Internal storage format is still .torrent file
                        metainfo = tdef.get_metainfo()
                        metadata = bencode(metainfo)
                        goturl = True
                    except:
                        print_exc()
                        return False
                else:
                    metadata = message['metadata']
            else:
                metadata = message['metadata']

            if not self.valid_metadata(infohash, metadata):
                return False

            if DEBUG:
                torrent_size = len(metadata)
                if goturl:
                    mdt = "URL"
                else:
                    mdt = "torrent"
                print >> sys.stderr, "metadata: Recvd", mdt, ` infohash `, sha(
                    infohash).hexdigest(), torrent_size

            extra_info = {}
            if selversion >= OLPROTO_VER_FOURTH:
                try:
                    extra_info = {
                        'leecher': message.get('leecher', -1),
                        'seeder': message.get('seeder', -1),
                        'last_check_time': message.get('last_check_time', -1),
                        'status': message.get('status', 'unknown')
                    }
                except Exception, msg:
                    print_exc()
                    print >> sys.stderr, "metadata: wrong extra info in msg - ", message
                    extra_info = {}

            filename = self.save_torrent(infohash,
                                         metadata,
                                         extra_info=extra_info)
            self.requested_torrents.remove(infohash)

            #if DEBUG:
            #    print >>sys.stderr,"metadata: Was I asked to relay for someone", self.proxy_message_handler

            if filename is not None:
                self.notify_torrent_is_in(infohash, metadata, filename)

            # BarterCast: add bytes of torrent to BarterCastDB
            # Save exchanged KBs in BarterCastDB
            if permid is not None and BARTERCAST_TORRENTS:
                self.overlay_bridge.add_task(
                    lambda: self.olthread_bartercast_torrentexchange(
                        permid, 'downloaded'), 0)
Exemple #15
0
    def send_metadata(self, permid, message, selversion):
        try:
            infohash = bdecode(message[1:])
        except:
            print_exc()
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: error becoding"
            return False
        if not isValidInfohash(infohash):
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: invalid hash"
            return False

        # TODO:
        res = self.torrent_db.getOne(('torrent_file_name', 'status_id'),
                                     infohash=bin2str(infohash))
        if not res:
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: not in database"
            return True  # don't close connection because I don't have the torrent
        torrent_file_name, status_id = res
        if status_id == self.torrent_db._getStatusID('dead'):
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: Torrent was dead"
            return True
        if not torrent_file_name:
            return True
        torrent_path = os.path.join(self.torrent_dir, torrent_file_name)
        if not os.path.isfile(torrent_path):
            if DEBUG:
                print >> sys.stderr, "metadata: GET_METADATA: not existing", res, torrent_path
            return True
#
#        data = self.torrent_db.getTorrent(infohash)
#        if not data or not data['torrent_name']:
#            return True     # don't close connection
#        live = data.get('status', 'unknown')
#        #print "**************** check live before send metadata", live
#        if live == 'dead':
#            return True    # don't send dead torrents around
#
#        torrent_path = None
#        try:
#            torrent_path = os.path.join(data['torrent_dir'], data['torrent_name'])
#            if not os.path.isfile(torrent_path):
#                torrent_path = None
#        except:
#            print_exc()
#
#        if not torrent_path:
#            if DEBUG:
#                print >> sys.stderr,"metadata: GET_METADATA: not torrent path"
#            return True

        task = {
            'permid': permid,
            'infohash': infohash,
            'torrent_path': torrent_path,
            'selversion': selversion
        }
        self.upload_queue.append(task)
        if int(time()) >= self.next_upload_time:
            self.checking_upload_queue()

        return True
Exemple #16
0
    def got_metadata(self, permid, message, selversion):
        """ receive torrent file from others """

        # Arno, 2007-06-20: Disabled the following code. What's this? Somebody sends
        # us something and we refuse? Also doesn't take into account download help
        #and remote-query extension.

        #if self.upload_rate <= 0:    # if no upload, no download, that's the game
        #    return True    # don't close connection

        try:
            message = bdecode(message[1:])
        except:
            print_exc()
            return False
        if not isinstance(message, dict):
            return False
        try:
            infohash = message['torrent_hash']
            if not isValidInfohash(infohash):
                return False

            if not infohash in self.requested_torrents:  # got a torrent which was not requested
                return True
            if self.torrent_db.hasMetaData(infohash):
                return True

            metadata = message['metadata']
            if not self.valid_metadata(infohash, metadata):
                return False
            if DEBUG:
                torrent_size = len(metadata)
                print >> sys.stderr, "metadata: Recvd torrent", ` infohash `, sha(
                    infohash).hexdigest(), torrent_size

            extra_info = {}
            if selversion >= OLPROTO_VER_FOURTH:
                try:
                    extra_info = {
                        'leecher': message.get('leecher', -1),
                        'seeder': message.get('seeder', -1),
                        'last_check_time': message.get('last_check_time', -1),
                        'status': message.get('status', 'unknown')
                    }
                except Exception, msg:
                    print_exc()
                    print >> sys.stderr, "metadata: wrong extra info in msg - ", message
                    extra_info = {}

            filename = self.save_torrent(infohash,
                                         metadata,
                                         extra_info=extra_info)
            self.requested_torrents.remove(infohash)

            if DEBUG:
                print >> sys.stderr, "metadata: Was I asked to dlhelp someone", self.dlhelper

            self.notify_torrent_is_in(infohash, metadata, filename)

            # BarterCast: add bytes of torrent to BarterCastDB
            # Save exchanged KBs in BarterCastDB
            if permid != None and BARTERCAST_TORRENTS:
                self.overlay_bridge.add_task(
                    lambda: self.olthread_bartercast_torrentexchange(
                        permid, 'downloaded'), 0)
    def got_metadata(self, permid, message, selversion):    
        """ receive torrent file from others """
        
        # Arno, 2007-06-20: Disabled the following code. What's this? Somebody sends 
        # us something and we refuse? Also doesn't take into account download help 
        #and remote-query extension.
        
        #if self.upload_rate <= 0:    # if no upload, no download, that's the game
        #    return True    # don't close connection
        
        try:
            message = bdecode(message[1:])
        except:
            print_exc()
            return False
        if not isinstance(message, dict):
            return False
        try:
            infohash = message['torrent_hash']
            if not isValidInfohash(infohash):
                # 19/02/10 Boudewijn: isValidInfohash either returns
                # True or raises a ValueError. So this part of the
                # code will never be reached...
                return False
            
            assert isinstance(infohash, str), "INFOHASH has invalid type: %s" % type(infohash)
            assert len(infohash) == INFOHASH_LENGTH, "INFOHASH has invalid length: %d" % len(infohash)
            
            #print >>sys.stderr,"metadata: got_metadata: hexinfohash: get_collected_torrent_filename(infohash)

            if not infohash in self.requested_torrents:    # got a torrent which was not requested
                return True
            if self.torrent_db.hasMetaData(infohash):
                return True

            # P2PURL
            goturl = False
            if selversion >= OLPROTO_VER_ELEVENTH:
                if 'metatype' in message and message['metatype'] == URL_MIME_TYPE:
                    try:
                        tdef = TorrentDef.load_from_url(message['metadata'])
                        # Internal storage format is still .torrent file
                        metainfo = tdef.get_metainfo()
                        metadata = bencode(metainfo)
                        goturl = True
                    except:
                        print_exc()
                        return False
                else:
                    metadata = message['metadata']
            else:
                metadata = message['metadata']
                    
            if not self.valid_metadata(infohash, metadata):
                return False
            
            if DEBUG:
                torrent_size = len(metadata)
                if goturl:
                    mdt = "URL"
                else:
                    mdt = "torrent" 
                print >> sys.stderr,"metadata: Recvd",mdt,`infohash`,sha(infohash).hexdigest(), torrent_size
            
            extra_info = {}
            if selversion >= OLPROTO_VER_FOURTH:
                try:
                    extra_info = {'leecher': message.get('leecher', -1),
                              'seeder': message.get('seeder', -1),
                              'last_check_time': message.get('last_check_time', -1),
                              'status':message.get('status', 'unknown')}
                except Exception, msg:
                    print_exc()
                    print >> sys.stderr, "metadata: wrong extra info in msg - ", message
                    extra_info = {}
                
            filename = self.save_torrent(infohash, metadata, extra_info=extra_info)
            self.requested_torrents.remove(infohash)
            
            #if DEBUG:
            #    print >>sys.stderr,"metadata: Was I asked to relay for someone", self.proxy_message_handler

            if filename is not None:
                self.notify_torrent_is_in(infohash,metadata,filename)
            
            
            # BarterCast: add bytes of torrent to BarterCastDB
            # Save exchanged KBs in BarterCastDB
            if permid is not None and BARTERCAST_TORRENTS:
                self.overlay_bridge.add_task(lambda:self.olthread_bartercast_torrentexchange(permid, 'downloaded'), 0)