def announce(): keys = set(request.args.keys()) response = {} # Check if arguments are all present if defaults['announce_required'] - keys: response = bencode({'failure reason' : 'Incorrect arguments'}) return (response, 200, {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}) # This is ugly info_hash = request.args.get('info_hash') peer_id = request.args.get('peer_id') port = request.args.get('port') uploaded = request.args.get('uploaded') downloaded = request.args.get('downloaded') left = request.args.get('left') ip = request.remote_addr tracker.add_peer(info_hash, peer_id, ip, port, uploaded, downloaded, left) peer_list = tracker.get_peers(info_hash) response = bencode({'peers' : peer_list}) app.logger.info(response) return (response, 200, {'Content-Type': 'text/plain', 'Pragma': 'no-cache'})
def announce(): keys = set(request.args.keys()) response = {} # Check if arguments are all present if defaults['announce_required'] - keys: response = bencode({'failure reason': 'Incorrect arguments'}) return (response, 200, { 'Content-Type': 'text/plain', 'Pragma': 'no-cache' }) # This is ugly info_hash = request.args.get('info_hash') peer_id = request.args.get('peer_id') port = request.args.get('port') uploaded = request.args.get('uploaded') downloaded = request.args.get('downloaded') left = request.args.get('left') ip = request.remote_addr tracker.add_peer(info_hash, peer_id, ip, port, uploaded, downloaded, left) peer_list = tracker.get_peers(info_hash) response = bencode({'peers': peer_list}) app.logger.info(response) return (response, 200, { 'Content-Type': 'text/plain', 'Pragma': 'no-cache' })
def _get_torrent_hash(self, result): if result.url.startswith('magnet'): result.hash = re.findall('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: logger.log('Torrent without content', logger.ERROR) raise Exception('Torrent without content') try: torrent_bdecode = bdecode(result.content) except BTFailure as e: logger.log('Unable to bdecode torrent', logger.ERROR) logger.log('Torrent bencoded data: {0}'.format(str(result.content)), logger.DEBUG) raise try: info = torrent_bdecode["info"] except Exception as e: logger.log('Unable to find info field in torrent', logger.ERROR) raise result.hash = sha1(bencode(info)).hexdigest() return result
def _get_torrent_hash(self, result): if result.url.startswith('magnet'): result.hash = re.findall('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: logger.log('Torrent without content', logger.ERROR) raise Exception('Torrent without content') try: torrent_bdecode = bdecode(result.content) except BTFailure as e: logger.log('Unable to bdecode torrent', logger.ERROR) logger.log( 'Torrent bencoded data: {0}'.format(str(result.content)), logger.DEBUG) raise try: info = torrent_bdecode["info"] except Exception as e: logger.log('Unable to find info field in torrent', logger.ERROR) raise result.hash = sha1(bencode(info)).hexdigest() return result
def calculate_torrent_hash(link, data=None): """ Calculate the torrent hash from a magnet link or data. Returns empty string when it cannot create a torrent hash given the input data. """ if link.startswith("magnet:"): torrent_hash = re.findall("urn:btih:([\w]{32,40})", link)[0] if len(torrent_hash) == 32: torrent_hash = b16encode(b32decode(torrent_hash)).lower() elif data: try: # noinspection PyUnresolvedReferences info = bdecode(data)["info"] torrent_hash = sha1(bencode(info)).hexdigest() except Exception as e: logger.error("Error calculating hash: %s" % e) return '' else: logger.error( "Cannot calculate torrent hash without magnet link or data") return '' logger.debug('Torrent Hash: ' + torrent_hash) return torrent_hash
def get_torrent(self, url, savelocation=None): torrent_id = dict([part.split('=') for part in urlparse(url)[4].split('&')])['t'] self.cookiejar.set_cookie(cookielib.Cookie(version=0, name='bb_dl', value=torrent_id, port=None, port_specified=False, domain='.rutracker.org', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)) downloadurl = 'http://dl.rutracker.org/forum/dl.php?t=' + torrent_id torrent_name = torrent_id + '.torrent' try: prev = os.umask(headphones.UMASK) page = self.opener.open(downloadurl) torrent = page.read() decoded = bdecode(torrent) metainfo = decoded['info'] tor_hash = sha1(bencode(metainfo)).hexdigest() if savelocation: download_path = os.path.join(savelocation, torrent_name) else: tempdir = mkdtemp(suffix='_rutracker_torrents') download_path = os.path.join(tempdir, torrent_name) fp = open (download_path, 'wb') fp.write (torrent) fp.close () os.umask(prev) # Add file to utorrent if headphones.TORRENT_DOWNLOADER == 2: self.utorrent_add_file(download_path) except Exception, e: logger.error('Error getting torrent: %s' % e) return False
def scrape(): #@todo: Implement scrape where no info_hash specified info_hash = request.args.get('info_hash') if info_hash in tracker.torrents: #@todo: Implement correct scrape values response = bencode({'files': { info_hash : { 'complete' : 0, 'downloaded' : 0, 'incomplete': 0 } } }) else: response = bencode({'failure reason' : 'Incorrect or no info hash given'}) return (response, 200, {'Content-Type': 'text/plain', 'Pragma': 'no-cache'})
def request_metadata(the_socket, ut_metadata, piece): msg = chr(20).encode('utf-8') + chr(ut_metadata).encode('utf-8') + bencode( { 'msg_type': 0, 'piece': piece }) send_message(the_socket, msg)
def _get_torrent_hash(self, result): if result.url.startswith('magnet'): torrent_hash = re.findall('urn:btih:([\w]{32,40})', result.url)[0] else: info = bdecode(result.content)["info"] torrent_hash = sha1(bencode(info)).hexdigest() return torrent_hash
def _TorrentHash(url=None, torrent=None): hash = None if url.startswith('magnet'): hash = re.search('urn:btih:([\w]{32,40})', url).group(1) if len(hash) == 32: hash = b16encode(b32decode(hash)).upper() else: info = bdecode(torrent)["info"] hash = sha1(bencode(info)).hexdigest().upper() return hash
def _TorrentHash(url=None,torrent=None): hash=None if url.startswith('magnet'): hash = re.search('urn:btih:([\w]{32,40})', url).group(1) if len(hash) == 32: hash = b16encode(b32decode(hash)).upper() else: info = bdecode(torrent)["info"] hash = sha1(bencode(info)).hexdigest().upper() return hash
def _get_torrent_hash(self, result): if result.url.startswith('magnet'): result.hash = re.findall('urn:btih:([\w]{32,40})', result.url)[0] if len(result.hash) == 32: result.hash = b16encode(b32decode(result.hash)).lower() else: info = bdecode(result.content)['info'] result.hash = sha1(bencode(info)).hexdigest() return result
def _get_torrent_hash(result): if result.url.startswith('magnet'): result.hash = re.findall('urn:btih:([\w]{32,40})', result.url)[0] if 32 == len(result.hash): result.hash = b16encode(b32decode(result.hash)).lower() else: info = bdecode(result.content)['info'] result.hash = sha1(bencode(info)).hexdigest() return result
def CalcTorrentHash(torrent): if torrent.startswith('magnet'): hash = re.findall('urn:btih:([\w]{32,40})', torrent)[0] if len(hash) == 32: hash = b16encode(b32decode(hash)).lower() else: info = bdecode(torrent)["info"] hash = sha1(bencode(info)).hexdigest() logger.debug('Torrent Hash: ' + hash) return hash
def _get_torrent_hash(self, result): if result.url.startswith("magnet"): result.hash = re.findall("urn:btih:([\w]{32,40})", result.url)[0] if len(result.hash) == 32: result.hash = b16encode(b32decode(result.hash)).lower() else: result.content = result.provider.getURL(result.url) info = bdecode(result.content)["info"] result.hash = sha1(bencode(info)).hexdigest() return result
def _get_torrent_hash(self, result): if result.url.startswith('magnet'): result.hash = re.findall('urn:btih:([\w]{32,40})', result.url)[0] if len(result.hash) == 32: result.hash = b16encode(b32decode(result.hash)).lower() else: result.content = result.provider.getURL(result.url) info = bdecode(result.content)["info"] result.hash = sha1(bencode(info)).hexdigest() return result
def get_hash(url, mode='torrent'): if url.startswith('magnet'): return url.split('&')[0].split(':')[-1] else: try: req = urllib2.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) torrent = urllib2.urlopen(req).read() metadata = bencode.bdecode(torrent) hashcontents = bencode.bencode(metadata['info']) return hashlib.sha1(hashcontents).hexdigest() except Exception, e: #noqa return None
def scrape(): #@todo: Implement scrape where no info_hash specified info_hash = request.args.get('info_hash') if info_hash in tracker.torrents: #@todo: Implement correct scrape values response = bencode({ 'files': { info_hash: { 'complete': 0, 'downloaded': 0, 'incomplete': 0 } } }) else: response = bencode( {'failure reason': 'Incorrect or no info hash given'}) return (response, 200, { 'Content-Type': 'text/plain', 'Pragma': 'no-cache' })
def _get_torrent_hash(self, result): if result.url.startswith('magnet'): torrent_hash = re.findall('urn:btih:([\w]{32,40})', result.url)[0] else: if hasattr(result , 'extraInfo') and len(result.extraInfo)>0: torrent_hash = result.extraInfo[0] elif hasattr(result,'content') : info = bdecode(result.content)["info"] torrent_hash = sha1(bencode(info)).hexdigest() else: torrent_hash = result.url return torrent_hash
def from_torrent_url(url): import base64 from lib import bencode import hashlib print "#### url: %s" % (url) torrent_data = url_get(url) metadata = bencode.bdecode(torrent_data) hashcontents = bencode.bencode(metadata["info"]) digest = hashlib.sha1(hashcontents).digest() b32hash = base64.b32encode(digest) params = {"dn": metadata["info"]["name"], "tr": metadata["announce"]} logger.info(params) paramstr = urllib.urlencode(params) return "magnet:?%s&%s" % ("xt=urn:btih:%s" % b32hash, paramstr)
def from_torrent_url(url): import base64 from lib import bencode import hashlib print "#### url: %s" % (url) torrent_data = url_get(url) metadata = bencode.bdecode(torrent_data) hashcontents = bencode.bencode(metadata['info']) digest = hashlib.sha1(hashcontents).digest() b32hash = base64.b32encode(digest) params = { 'dn': metadata['info']['name'], 'tr': metadata['announce'], } logger.info(params) paramstr = urllib.urlencode(params) return 'magnet:?%s&%s' % ('xt=urn:btih:%s' % b32hash, paramstr)
def calculate_torrent_hash(link, data=None): """ Calculate the torrent hash from a magnet link or data. Returns empty string when it cannot create a torrent hash given the input data. """ if link.startswith("magnet:"): torrent_hash = re.findall("urn:btih:([\w]{32,40})", link)[0] if len(torrent_hash) == 32: torrent_hash = b16encode(b32decode(torrent_hash)).lower() elif data: try: # noinspection PyUnresolvedReferences info = bdecode(data)["info"] torrent_hash = sha1(bencode(info)).hexdigest() except Exception as e: logger.error("Error calculating hash: %s" % e) return '' else: logger.error("Cannot calculate torrent hash without magnet link or data") return '' logger.debug('Torrent Hash: ' + torrent_hash) return torrent_hash
def DirectDownloadMethod(bookid=None, dl_title=None, dl_url=None, library='eBook'): myDB = database.DBConnection() Source = "DIRECT" logger.debug("Starting Direct Download for [%s]" % dl_title) proxies = proxyList() headers = {'Accept-encoding': 'gzip', 'User-Agent': getUserAgent()} try: r = requests.get(dl_url, headers=headers, timeout=90, proxies=proxies) except requests.exceptions.Timeout: res = 'Timeout fetching file from url: %s' % dl_url logger.warn(res) return False, res except Exception as e: if hasattr(e, 'reason'): res = '%s fetching file from url: %s, %s' % (type(e).__name__, dl_url, e.reason) else: res = '%s fetching file from url: %s, %s' % (type(e).__name__, dl_url, str(e)) logger.warn(res) return False, res if not str(r.status_code).startswith('2'): res = "Got a %s response for %s" % (r.status_code, dl_url) logger.debug(res) return False, res elif len(r.content) < 1000: res = "Only got %s bytes for %s" % (len(r.content), dl_title) logger.debug(res) return False, res else: extn = '' basename = '' if ' ' in dl_title: basename, extn = dl_title.rsplit(' ', 1) # last word is often the extension - but not always... if extn and extn in getList(lazylibrarian.CONFIG['EBOOK_TYPE']): dl_title = '.'.join(dl_title.rsplit(' ', 1)) elif magic: mtype = magic.from_buffer(r.content) if 'EPUB' in mtype: extn = 'epub' elif 'Mobipocket' in mtype: # also true for azw and azw3, does it matter? extn = 'mobi' elif 'PDF' in mtype: extn = 'pdf' else: logger.debug("magic reports %s" % mtype) basename = dl_title else: logger.warn("Don't know the filetype for %s" % dl_title) basename = dl_title logger.debug("File download got %s bytes for %s" % (len(r.content), dl_title)) destdir = os.path.join(lazylibrarian.DIRECTORY('Download'), basename) # destdir = os.path.join(lazylibrarian.DIRECTORY('Download'), '%s LL.(%s)' % (basename, bookid)) if not os.path.isdir(destdir): _ = mymakedirs(destdir) try: hashid = dl_url.split("md5=")[1].split("&")[0] except IndexError: hashid = sha1(bencode(dl_url)).hexdigest() destfile = os.path.join(destdir, basename + '.' + extn) if os.name == 'nt': #Windows has max path length of 256 destfile = '\\\\?\\' + destfile try: with open(destfile, 'wb') as bookfile: bookfile.write(r.content) setperm(destfile) downloadID = hashid except Exception as e: res = "%s writing book to %s, %s" % (type(e).__name__, destfile, e) logger.error(res) return False, res if downloadID: logger.debug('File %s has been downloaded from %s' % (dl_title, dl_url)) if library == 'eBook': myDB.action('UPDATE books SET status="Snatched" WHERE BookID=?', (bookid,)) elif library == 'AudioBook': myDB.action('UPDATE books SET audiostatus="Snatched" WHERE BookID=?', (bookid,)) myDB.action('UPDATE wanted SET status="Snatched", Source=?, DownloadID=? WHERE NZBurl=?', (Source, downloadID, dl_url)) return True, '' else: res = 'Failed to download file @ <a href="%s">%s</a>' % (dl_url, dl_url) logger.error(res) return False, res
def send_ext_handshake(the_socket): msg = chr(20).encode('utf-8') + chr(0).encode('utf-8') + bencode( {'m': { 'ut_metadata': 1 }}) send_message(the_socket, msg)
def send_krpc(self, msg, address): # noinspection PyBroadException try: self.ufd.sendto(bencode(msg), address) except Exception: pass
def DirectDownloadMethod(bookid=None, dl_title=None, dl_url=None, library='eBook'): myDB = database.DBConnection() Source = "DIRECT" logger.debug("Starting Direct Download for [%s]" % dl_title) proxies = proxyList() headers = {'Accept-encoding': 'gzip', 'User-Agent': getUserAgent()} try: r = requests.get(dl_url, headers=headers, timeout=90, proxies=proxies) except requests.exceptions.Timeout: res = 'Timeout fetching file from url: %s' % dl_url logger.warn(res) return False, res except Exception as e: if hasattr(e, 'reason'): res = '%s fetching file from url: %s, %s' % (type(e).__name__, dl_url, e.reason) else: res = '%s fetching file from url: %s, %s' % (type(e).__name__, dl_url, str(e)) logger.warn(res) return False, res if not str(r.status_code).startswith('2'): res = "Got a %s response for %s" % (r.status_code, dl_url) logger.debug(res) return False, res elif len(r.content) < 1000: res = "Only got %s bytes for %s" % (len(r.content), dl_title) logger.debug(res) return False, res else: extn = '' basename = '' if ' ' in dl_title: basename, extn = dl_title.rsplit( ' ', 1) # last word is often the extension - but not always... if extn and extn in getList(lazylibrarian.CONFIG['EBOOK_TYPE']): dl_title = '.'.join(dl_title.rsplit(' ', 1)) elif magic: mtype = magic.from_buffer(r.content) if 'EPUB' in mtype: extn = 'epub' elif 'Mobipocket' in mtype: # also true for azw and azw3, does it matter? extn = 'mobi' elif 'PDF' in mtype: extn = 'pdf' else: logger.debug("magic reports %s" % mtype) basename = dl_title else: logger.warn("Don't know the filetype for %s" % dl_title) basename = dl_title logger.debug("File download got %s bytes for %s" % (len(r.content), dl_title)) destdir = os.path.join(lazylibrarian.DIRECTORY('Download'), basename) # destdir = os.path.join(lazylibrarian.DIRECTORY('Download'), '%s LL.(%s)' % (basename, bookid)) if not os.path.isdir(destdir): _ = mymakedirs(destdir) try: hashid = dl_url.split("md5=")[1].split("&")[0] except IndexError: hashid = sha1(bencode(dl_url)).hexdigest() destfile = os.path.join(destdir, basename + '.' + extn) if os.name == 'nt': #Windows has max path length of 256 destfile = '\\\\?\\' + destfile try: with open(destfile, 'wb') as bookfile: bookfile.write(r.content) setperm(destfile) downloadID = hashid except Exception as e: res = "%s writing book to %s, %s" % (type(e).__name__, destfile, e) logger.error(res) return False, res if downloadID: logger.debug('File %s has been downloaded from %s' % (dl_title, dl_url)) if library == 'eBook': myDB.action('UPDATE books SET status="Snatched" WHERE BookID=?', (bookid, )) elif library == 'AudioBook': myDB.action( 'UPDATE books SET audiostatus="Snatched" WHERE BookID=?', (bookid, )) myDB.action( 'UPDATE wanted SET status="Snatched", Source=?, DownloadID=? WHERE NZBurl=?', (Source, downloadID, dl_url)) return True, '' else: res = 'Failed to download file @ <a href="%s">%s</a>' % (dl_url, dl_url) logger.error(res) return False, res