diff --git a/couchpotato/core/providers/torrent/thepiratebay/__init__.py b/couchpotato/core/providers/torrent/thepiratebay/__init__.py index 810e713a..9c132dd7 100644 --- a/couchpotato/core/providers/torrent/thepiratebay/__init__.py +++ b/couchpotato/core/providers/torrent/thepiratebay/__init__.py @@ -1,6 +1,38 @@ -from .main import ThePirateBay +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from main import ThePirateBay + def start(): return ThePirateBay() -config = [] + +config = [{'name': 'ThePirateBay', 'groups': [{ + 'tab': 'searcher', + 'subtab': 'providers', + 'name': 'ThePirateBay', + 'description': 'The world\'s largest bittorrent tracker.', + 'options': [{'name': 'enabled', 'type': 'enabler', + 'default': False}, { + 'name': 'domain_for_tpb', + 'label': 'Proxy server', + 'default': 'http://thepiratebay.se', + 'description': 'Which domain do you preferr(or it\'s not blocked)', + 'type': 'dropdown', + 'values': [ + ('(Sweden) thepiratebay.se', 'http://thepiratebay.se'), + ('(Sweden) tpb.ipredator.se (ssl)', + 'https://tpb.ipredator.se'), + ('(Germany) depiraatbaai.be', 'http://depiraatbaai.be'), + ('(UK) piratereverse.info (ssl)', + 'https://piratereverse.info'), + ('(UK) tpb.pirateparty.org.uk (ssl)', + 'https://tpb.pirateparty.org.uk'), + ('(Netherlands) thepiratebay.se.coevoet.nl', + 'http://thepiratebay.se.coevoet.nl'), + ('(direct) 194.71.107.80', 'http://194.71.107.80'), + ('(direct) 194.71.107.83', 'http://194.71.107.81'), + ], + }], + }]}] diff --git a/couchpotato/core/providers/torrent/thepiratebay/main.py b/couchpotato/core/providers/torrent/thepiratebay/main.py index 3664ffcd..626e1210 100644 --- a/couchpotato/core/providers/torrent/thepiratebay/main.py +++ b/couchpotato/core/providers/torrent/thepiratebay/main.py @@ -1,146 +1,143 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from bs4 import BeautifulSoup +from couchpotato.core.event import fireEvent +from couchpotato.core.helpers.variable import getTitle from couchpotato.core.logger import CPLog from couchpotato.core.providers.torrent.base import TorrentProvider - +import re +from urllib import quote_plus +import urllib2 log = CPLog(__name__) class ThePirateBay(TorrentProvider): - urls = { - 'download': 'http://torrents.depiraatbaai.be/%s/%s.torrent', - 'nfo': 'https://depiraatbaai.be/torrent/%s', - 'detail': 'https://depiraatbaai.be/torrent/%s', - 'search': 'https://depiraatbaai.be/search/%s/0/7/%d', - } + urls = {'detail': '%s/torrent/%s', 'search': '%s/search/%s/0/7/%d'} - cat_ids = [ - ([207], ['720p', '1080p']), - ([200], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr', 'brrip']), - ([202], ['dvdr']) - ] + cat_ids = [([207], ['720p', '1080p']), ([201], [ + 'cam', + 'ts', + 'dvdrip', + 'tc', + 'r5', + 'scr', + 'brrip', + ]), ([202], ['dvdr'])] cat_backup_id = 200 - ignore_string = { - '720p': ' -brrip -bdrip', - '1080p': ' -brrip -bdrip' - } + def getAPIurl(self): + return ("http://thepiratebay.se", self.conf('domain_for_tpb'))[self.conf('domain_for_tpb') != None] - def __init__(self): - pass - - def find(self, movie, quality, type): + def search(self, movie, quality): results = [] - if not self.enabled(): + if self.isDisabled(): return results - url = self.apiUrl % (quote_plus(self.toSearchString(movie.name + ' ' + quality) + self.makeIgnoreString(type)), self.getCatId(type)) - - log.info('Searching: %s', url) - - data = self.urlopen(url) + movie_name = re.sub("\W", ' ', getTitle(movie['library'])) + movie_name = re.sub(' ', ' ', movie_name) + log.info('API url: %s', self.getAPIurl()) + log.info('Cleaned Name: %s', movie_name) + cache_key = 'thepiratebay.%s.%s' % (movie['library' + ]['identifier'], quality.get('identifier')) + searchUrl = self.urls['search'] % (self.getAPIurl(), + quote_plus(movie_name + ' ' + quality['identifier']), + self.getCatId(quality['identifier'])[0]) + log.info('searchUrl: %s', searchUrl) + data = self.getCache(cache_key, searchUrl) + #print data if not data: - log.error('Failed to get data from %s.', url) + log.error('Failed to get data from %s.', searchUrl) return results try: - tables = SoupStrainer('table') - html = BeautifulSoup(data, parseOnlyThese = tables) - resultTable = html.find('table', attrs = {'id':'searchResult'}) - for result in resultTable.findAll('tr'): - details = result.find('a', attrs = {'class':'detLink'}) - if details: - href = re.search('/(?P\d+)/', details['href']) - id = href.group('id') - name = self.toSaveString(details.contents[0]) - desc = result.find('font', attrs = {'class':'detDesc'}).contents[0].split(',') - date = '' - size = 0 - for item in desc: - # Weird date stuff - if 'uploaded' in item.lower(): - date = item.replace('Uploaded', '') - date = date.replace('Today', '') + soup = BeautifulSoup(data) + resultsTable = soup.find('table', + attrs={'id': 'searchResult'}) + entries = resultsTable.findAll('tr') + for result in entries[1:]: + link = result.find(href=re.compile('torrent\/\d+\/')) + download = result.find(href=re.compile('magnet:')) + #Uploaded 06-28 02:27, Size 1.37 GiB, + size = re.search('Size (?P.+),', unicode(result.select("font.detDesc")[0])).group("size") + if link and download: + new = { + 'type': 'torrent', + 'check_nzb': False, + 'description': '', + 'provider': self.getName(), + } + trusted = (0, 10)[result.find('img', + alt=re.compile('Trusted')) != None] + vip = (0, 20)[result.find('img', + alt=re.compile('VIP')) != None] + moderated = (0, 50)[result.find('img', + alt=re.compile('Moderator')) != None] + log.info('Name: %s', link.string) - # Do something with yesterday - yesterdayMinus = 0 - if 'Y-day' in date: - date = date.replace('Y-day', '') - yesterdayMinus = 86400 + log.info('Seeders: %s', result.findAll('td' + )[2].string) + log.info('Leechers: %s', result.findAll('td' + )[3].string) + log.info('Size: %s', size) + log.info('Score(trusted + vip + moderated): %d', + trusted + vip + moderated) - datestring = date.replace(' ', ' ').strip() - date = int(time.mktime(parse(datestring).timetuple())) - yesterdayMinus - # size - elif 'size' in item.lower(): - size = item.replace('Size', '') + new['name'] = link.string + new['id'] = re.search('/(?P\d+)/', link['href' + ]).group('id') + new['url'] = link['href'] + new['download'] = self.getAPIurl() + download['href'] + new['size'] = self.parseSize(size) + new['seeders'] = int(result.findAll('td')[2].string) + new['leechers'] = int(result.findAll('td' + )[3].string) + new['imdbid'] = movie['library']['identifier'] + new['prtbscore'] = trusted + vip + moderated - seedleech = [] - for td in result.findAll('td'): - try: - seedleech.append(int(td.contents[0])) - except ValueError: - pass + new['extra_score'] = self.extra_score + new['score'] = fireEvent('score.calculate', new, + movie, single=True) + is_correct_movie = fireEvent( + 'searcher.correct_movie', + nzb=new, + movie=movie, + quality=quality, + imdb_results=True, + single_category=False, + single=True, + ) - seeders = 0 - leechers = 0 - if len(seedleech) == 2 and seedleech[0] > 0 and seedleech[1] > 0: - seeders = seedleech[0] - leechers = seedleech[1] - - # to item - new = self.feedItem() - new.id = id - new.type = 'torrent' - new.name = name - new.date = date - new.size = self.parseSize(size) - new.seeders = seeders - new.leechers = leechers - new.url = self.downloadLink(id, name) - new.score = self.calcScore(new, movie) + self.uploader(result) + (seeders / 10) - - if seeders > 0 and (new.date + (int(self.conf('wait')) * 60 * 60) < time.time()) and Qualities.types.get(type).get('minSize') <= new.size: - new.detailUrl = self.detailLink(id) - new.content = self.getInfo(new.detailUrl) - if self.isCorrectMovie(new, movie, type): - results.append(new) - log.info('Found: %s', new.name) + if is_correct_movie: + results.append(new) + self.found(new) return results + except Exception, e: + log.debug(e) + log.info('Error occured during parsing! Passing only processed entries' + ) + return results - except AttributeError: - log.debug('No search results found.') + def extra_score(self, torrent): + url = self.getAPIurl() + torrent['url'] + log.info('extra_score: %s', url) + imdbId = torrent['imdbid'] + return self.imdbMatch(url, imdbId) + torrent['prtbscore'] - return [] - - def makeIgnoreString(self, type): - ignore = self.ignoreString.get(type) - return ignore if ignore else '' - - def uploader(self, html): - score = 0 - if html.find('img', attr = {'alt':'VIP'}): - score += 3 - if html.find('img', attr = {'alt':'Trusted'}): - score += 1 - return score - - - def getInfo(self, url): - log.debug('Getting info: %s', url) - - data = self.urlopen(url) - if not data: - log.error('Failed to get data from %s.', url) - return '' - - div = SoupStrainer('div') - html = BeautifulSoup(data, parseOnlyThese = div) - html = html.find('div', attrs = {'class':'nfo'}) - return str(html).decode("utf-8", "replace") - - def downloadLink(self, id, name): - return self.downloadUrl % (id, quote_plus(name)) - - def isEnabled(self): - return self.conf('enabled') and TorrentProvider.isEnabled(self) + def imdbMatch(self, url, imdbId): + log.info('imdbMatch: %s', url) + try: + data = urllib2.urlopen(url).read() + pass + except: + log.error('Failed to open %s.' % url) + return 0 + imdbIdAlt = re.sub('tt[0]*', 'tt', imdbId) + data = unicode(data, errors='ignore') + if 'imdb.com/title/' + imdbId in data or 'imdb.com/title/' \ + + imdbIdAlt in data: + return 50 + return 0