def get_session(username=None, password=None): """Creates a requests session which is authenticated to trakt.""" session = Session() session.headers = { 'Content-Type': 'application/json', 'trakt-api-version': 2, 'trakt-api-key': API_KEY } if username: session.headers['trakt-user-login'] = username if username and password: auth = {'login': username, 'password': password} try: r = session.post(urljoin(API_URL, 'auth/login'), data=json.dumps(auth)) except RequestException as e: if e.response and e.response.status_code in [401, 403]: raise plugin.PluginError( 'Authentication to trakt failed, check your username/password: %s' % e.args[0]) else: raise plugin.PluginError('Authentication to trakt failed: %s' % e.args[0]) try: session.headers['trakt-user-token'] = r.json()['token'] except (ValueError, KeyError): raise plugin.PluginError( 'Got unexpected response content while authorizing to trakt: %s' % r.text) return session
def on_task_input(self, task, config): """Search on What.cd""" self.session = Session() # From the API docs: "Refrain from making more than five (5) requests every ten (10) seconds" self.session.add_domain_limiter( TokenBucketLimiter('ssl.what.cd', 2, '2 seconds')) # Custom user agent user_agent = config.pop('user_agent', None) if user_agent: self.session.headers.update({"User-Agent": user_agent}) # Login self._login(config.pop('username'), config.pop('password')) # Logged in successfully, it's ok if nothing matches task.no_entries_ok = True # NOTE: Any values still in config at this point MUST be valid search parameters # Perform the search and parse the needed information out of the response results = self._search_results(config) return list(self._get_entries(results))
def on_task_input(self, task, config): """Search on What.cd""" self.session = Session() # From the API docs: "Refrain from making more than five (5) requests every ten (10) seconds" self.session.set_domain_delay('ssl.what.cd', '2 seconds') # Login self._login(config) # Perform the query results = [] page = 1 while True: result = self._request("browse", page=page, **config) if not result['results']: break results.extend(result["results"]) pages = result['pages'] page = result['currentPage'] log.info("Got {0} of {1} pages".format(page, pages)) if page >= pages: break page += 1 # Logged in and made a request successfully, it's ok if nothing matches task.no_entries_ok = True # Parse the needed information out of the response entries = [] for result in results: # Get basic information on the release info = dict( (k, result[k]) for k in ('artist', 'groupName', 'groupYear')) # Releases can have multiple download options for tor in result['torrents']: temp = info.copy() temp.update( dict( (k, tor[k]) for k in ('media', 'encoding', 'format', 'torrentId'))) entries.append( Entry( title="{artist} - {groupName} - {groupYear} " "({media} - {format} - {encoding})-{torrentId}.torrent" .format(**temp), url="https://what.cd/torrents.php?action=download&" "id={0}&authkey={1}&torrent_pass={2}".format( temp['torrentId'], self.authkey, self.passkey), torrent_seeds=tor['seeders'], torrent_leeches=tor['leechers'], # Size is given in bytes, convert it content_size=int(tor['size'] / (1024**2) * 100) / 100)) return entries
def __init__(self, config): self.config = config self._session = Session() self._session.add_domain_limiter(TimedLimiter('imdb.com', '5 seconds')) self._session.headers = {'Accept-Language': config.get('force_language', 'en-us')} self.user_id = None self.list_id = None self._items = None self._authenticated = False
def session(self): # TODO: This is not used for all requests even .. if self.requests is None: self.requests = Session() requests.headers.update({ 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' }) requests.add_domain_limiter( TimedLimiter('descargas2020.com', '2 seconds')) return self.requests
import re from flexget import plugin from flexget.event import event from flexget.plugins.internal.urlrewriting import UrlRewritingError from flexget.utils.requests import Session, TimedLimiter from flexget.utils.soup import get_soup from flexget.entry import Entry from flexget.utils.search import normalize_unicode import unicodedata log = logging.getLogger('newpct') requests = Session() requests.headers.update( {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}) requests.add_domain_limiter(TimedLimiter('newpct1.com', '2 seconds')) requests.add_domain_limiter(TimedLimiter('newpct.com', '2 seconds')) NEWPCT_TORRENT_FORMAT = 'http://www.newpct.com/torrents/{:0>6}.torrent' NEWPCT1_TORRENT_FORMAT = 'http://www.newpct1.com/download/{}.torrent' class UrlRewriteNewPCT(object): """NewPCT urlrewriter and search.""" schema = {'type': 'boolean', 'default': False} # urlrewriter API
import logging import re from urllib import quote from flexget import plugin from flexget import validator from flexget.entry import Entry from flexget.event import event from flexget.utils.soup import get_soup from flexget.utils.search import torrent_availability, normalize_unicode, clean_title from flexget.utils.requests import Session log = logging.getLogger('search_torrentshack') session = Session() CATEGORIES = { 'Apps/PC': 100, 'Apps/misc': 150, 'eBooks': 180, 'Games/PC': 200, 'Games/PS3': 240, 'Games/Xbox360': 260, 'HandHeld': 280, 'Movies/x264': 300, 'REMUX': 320, 'Movies/DVD-R': 350, 'Movies/XviD': 400, 'Music/MP3': 450, 'Music/FLAC': 480,
import logging from flexget import plugin from flexget.entry import Entry from flexget.event import event from flexget.utils.cached_input import cached from flexget.utils.requests import RequestException, Session, TimedLimiter from flexget.utils.soup import get_soup log = logging.getLogger('letterboxd') requests = Session(max_retries=5) requests.add_domain_limiter(TimedLimiter('letterboxd.com', '1 seconds')) base_url = 'http://letterboxd.com' SLUGS = { 'default': {'p_slug': '/%(user)s/list/%(list)s/', 'f_slug': 'data-film-slug'}, 'diary': {'p_slug': '/%(user)s/films/diary/', 'f_slug': 'data-film-slug'}, 'likes': {'p_slug': '/%(user)s/likes/films/', 'f_slug': 'data-film-link'}, 'rated': {'p_slug': '/%(user)s/films/ratings/', 'f_slug': 'data-film-slug'}, 'watched': {'p_slug': '/%(user)s/films/', 'f_slug': 'data-film-slug'}, 'watchlist': {'p_slug': '/%(user)s/watchlist/', 'f_slug': 'data-film-slug'}, } SORT_BY = { 'default': '', 'added': 'by/added/', 'length-ascending': 'by/shortest/', 'length-descending': 'by/longest/', 'name': 'by/name/', 'popularity': 'by/popular/',
def __init__(self, username=None, password=None, url_scheme='https'): self.credentials = {'username': username, 'password': password} self.api_token = None self.api_template_url = url_scheme + '://' + T411API_DOMAIN_URL + '%s' self.web_session = Session()
def __init__(self): self.session = Session() self.url_template = 'https://maker.ifttt.com/trigger/{}/with/key/{}'
def search(self, entry, config=None): """ Search for entries on SceneAccess """ try: multip = int(config['gravity_multiplier']) except KeyError: multip = 1 # Login... params = {'username': config['username'], 'password': config['password'], 'submit': 'come on in'} session = Session() session.headers = {'User agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0'} log.debug('Logging in to %s...' % URL) session.post(URL + 'login', data=params) # Prepare queries... BASE_URLS = list() entries = set() for category in self.processCategories(config): BASE_URLS.append(URL + '%(url_path)s?method=2%(category_url_string)s' % category) # Search... for search_string in entry.get('search_strings', [entry['title']]): search_string_normalized = normalize_unicode(clean_title(search_string)) search_string_url_fragment = '&search=' + quote(search_string_normalized.encode('utf8')) for url in BASE_URLS: url += search_string_url_fragment log.debug('Search URL for `%s`: %s' % (search_string, url)) page = session.get(url).content soup = get_soup(page) for result in soup.findAll('tr', attrs={'class': 'tt_row'}): entry = Entry() entry['title'] = result.find('a', href=re.compile(r'details\?id=\d+'))['title'] entry['url'] = URL + result.find('a', href=re.compile(r'.torrent$'))['href'] entry['torrent_seeds'] = result.find('td', attrs={'class': 'ttr_seeders'}).string entry['torrent_leeches'] = result.find('td', attrs={'class': 'ttr_leechers'}).string entry['search_sort'] = torrent_availability(entry['torrent_seeds'], entry['torrent_leeches'])*multip size = result.find('td', attrs={'class': 'ttr_size'}).next size = re.search('(\d+(?:[.,]\d+)*)\s?([KMG]B)', size) if size: if size.group(2) == 'GB': entry['content_size'] = int(float(size.group(1)) * 1000 ** 3 / 1024 ** 2) elif size.group(2) == 'MB': entry['content_size'] = int(float(size.group(1)) * 1000 ** 2 / 1024 ** 2) elif size.group(2) == 'KB': entry['content_size'] = int(float(size.group(1)) * 1000 / 1024 ** 2) else: entry['content_size'] = int(float(size.group(1)) / 1024 ** 2) entries.add(entry) return entries
def search(self, entry, config=None): try: multip = int(config['gravity_multiplier']) except KeyError: multip = 1 if not isinstance(config['category'], list): config['category'] = [config['category']] categories_id = list() for category in config['category']: if not isinstance(category, int): categories_id.append(CATEGORIES.get(category)) else: categories_id.append(category) category_url_fragment = ''.join( ['&' + quote('filter_cat[%s]' % id) + '=1' for id in categories_id]) params = { 'username': config['username'], 'password': config['password'], 'keeplogged': '1', 'login': '******' } session = Session() log.debug('Logging in to %s...' % URL) session.post(URL + 'login.php', data=params) entries = set() for search_string in entry.get('search_strings', [entry['title']]): search_string_normalized = normalize_unicode(clean_title(search_string)) search_string_url_fragment = 'searchstr=' + quote(search_string_normalized.encode('utf8')) url = URL + 'torrents.php?' + search_string_url_fragment + category_url_fragment log.debug('Fetching URL for `%s`: %s' % (search_string, url)) page = session.get(url).content soup = get_soup(page) for result in soup.findAll('tr', attrs={'class': 'torrent'}): entry = Entry() entry['title'] = result.find('span', attrs={'class': 'torrent_name_link'}).string entry['url'] = URL + result.find('a', href=re.compile(r'torrents.php\?action=download'), attrs={'title': 'Download'})['href'] entry['torrent_seeds'] = result.findAll('td')[-3].string entry['torrent_leeches'] = result.findAll('td')[-2].string entry['search_sort'] = torrent_availability(entry['torrent_seeds'], entry['torrent_leeches']) * multip size = result.findAll('td')[-5].string size = re.search('(\d+(?:[.,]\d+)*)\s?([KMG]B)', size) if size: if size.group(2) == 'GB': entry['content_size'] = int(float(size.group(1).replace(',', '')) * 1000 ** 3 / 1024 ** 2) elif size.group(2) == 'MB': entry['content_size'] = int(float(size.group(1).replace(',', '')) * 1000 ** 2 / 1024 ** 2) elif size.group(2) == 'KB': entry['content_size'] = int(float(size.group(1).replace(',', '')) * 1000 / 1024 ** 2) else: entry['content_size'] = int(float(size.group(1).replace(',', '')) / 1024 ** 2) entries.add(entry) return entries
import difflib import logging import re from flexget.utils.soup import get_soup from flexget.utils.requests import Session from flexget.utils.tools import str_to_int from BeautifulSoup import NavigableString, Tag log = logging.getLogger('utils.imdb') # IMDb delivers a version of the page which is unparsable to unknown (and some known) user agents, such as requests' # Spoof the old urllib user agent to keep results consistent requests = Session(headers={'User-Agent': 'Python-urllib/2.6'}) # give imdb a little break between requests (see: http://flexget.com/ticket/129#comment:1) requests.set_domain_delay('imdb.com', '3 seconds') def is_imdb_url(url): """Tests the url to see if it's for imdb.com.""" if not isinstance(url, basestring): return # Probably should use urlparse. return re.match(r'https?://[^/]*imdb\.com/', url) def extract_id(url): """Return IMDb ID of the given URL. Return None if not valid or if URL is not a string.""" if not isinstance(url, basestring): return m = re.search(r'((?:nm|tt)[\d]{7})', url) if m: return m.group(1)