Example #1
0
def _valid_torrent_file(path: Path) -> bool:
    try:
        bdecode(path.read_bytes())
        return True
    except BencodeError:
        pass  # We might be racing the process writing to the filesystem.

    sleep(1)  # This is literally killing kittens.

    try:
        bdecode(path.read_bytes())
        return True
    except BencodeError:
        return False
Example #2
0
    def _get_torrent_hash(result):
        if result.url.startswith('magnet'):
            result.hash = re.findall(r'urn:btih:([\w]{32,40})', result.url)[0]
            if len(result.hash) == 32:
                result.hash = b16encode(b32decode(result.hash)).lower()
        else:
            if not result.content:
                sickrage.app.log.warning('Torrent without content')
                raise Exception('Torrent without content')

            try:
                torrent_bdecode = bdecode(result.content)
            except BencodeError:
                sickrage.app.log.warning('Unable to bdecode torrent')
                sickrage.app.log.debug('Torrent bencoded data: %r' % result.content)
                raise

            try:
                info = torrent_bdecode["info"]
            except Exception:
                sickrage.app.log.warning('Unable to find info field in torrent')
                raise

            result.hash = sha1(bencode(info)).hexdigest()

        return result
Example #3
0
    def add_trackers(self, result):
        """
        Adds public trackers to either torrent file or magnet link
        :param result: SearchResult
        :return: SearchResult
        """

        try:
            trackers_list = self.session.get('https://cdn.sickrage.ca/torrent_trackers/').text.split()
        except Exception:
            trackers_list = []

        if trackers_list:
            # adds public torrent trackers to magnet url
            if result.url.startswith('magnet:'):
                if not result.url.endswith('&tr='):
                    result.url += '&tr='
                result.url += '&tr='.join(trackers_list)

            # adds public torrent trackers to content
            if result.content:
                decoded_data = bdecode(result.content)
                if not decoded_data.get('announce-list'):
                    decoded_data['announce-list'] = []

                for tracker in trackers_list:
                    if tracker not in decoded_data['announce-list']:
                        decoded_data['announce-list'].append([str(tracker)])
                result.content = bencode(decoded_data)

        return result
Example #4
0
    def validateRSS(self):
        torrent_file = None

        try:
            add_cookie = self.add_cookies_from_ui()
            if not add_cookie.get('result'):
                return add_cookie

            data = self.cache._get_rss_data()['entries']
            if not data:
                return {'result': False,
                        'message': 'No items found in the RSS feed {}'.format(self.urls['base_url'])}

            (title, url) = self._get_title_and_url(data[0])

            if not title:
                return {'result': False,
                        'message': 'Unable to get title from first item'}

            if not url:
                return {'result': False,
                        'message': 'Unable to get torrent url from first item'}

            if url.startswith('magnet:') and re.search(r'urn:btih:([\w]{32,40})', url):
                return {'result': True,
                        'message': 'RSS feed Parsed correctly'}
            else:
                try:
                    torrent_file = self.session.get(url).content
                    bdecode(torrent_file)
                except Exception as e:
                    if data:
                        self.dumpHTML(torrent_file)
                    return {'result': False,
                            'message': 'Torrent link is not a valid torrent file: {}'.format(e)}

            return {'result': True,
                    'message': 'RSS feed Parsed correctly'}

        except Exception as e:
            return {'result': False,
                    'message': 'Error when trying to load RSS: {}'.format(e)}
Example #5
0
    def _handle_file(self, tor_file_path):
        try:
            with open(tor_file_path, 'rb') as tor_file:
                metainfo = tor_file.read()
        except FileNotFoundError:
            raise TorrentError("No Torrent File With That Name.")

        metadict = bdecode(metainfo)
        self.info = metadict['info']
        self.info_hash = self._hash_info(self.info)
        self.announce = metadict['announce']
        self.length = self.info['length']
        self.piece_length = self.info['piece length']
        self.target_file_name = self.info['name']
        # The pieces entry consists of 20 byte hash values for each pieces.
        self.num_pieces = len(self.info['pieces'])//20
        self.piece_hashes = []
        hashes = self.info['pieces']
        while hashes:
            self.piece_hashes.append(hashes[:20])
            hashes = hashes[20:]
Example #6
0
    def _handle_response(self, response):
        """Parse the tracker response and return decoded dictionary
        and make necessary state changes to tracker"""
        # TODO: Implement Updating the Tracker on our status.

        # Decode the response
        response_dict = bdecode(response)

        # Check if tracker_id should be updated.
        if response_dict.get('tracker id'):
            self.tracker_id = response_dict['tracker id']

        self.interval = response_dict.get('interval', 1800)
        self.min_interval = response_dict.get('min interval', self.interval)

        # Handle list of peers
        peers = response_dict['peers']
        if isinstance(peers, list):
            self.peers = peers
        else:
            response_dict['peers'] = self._parse_binary_peers(peers)
        return response_dict
Example #7
0
 def verify_torrent(content):
     try:
         if bdecode(content).get('info'):
             return content
     except Exception:
         pass