def _search_tmdbid(self, tmdbid): url = u'https://api.themoviedb.org/3/movie/{}?language=en-US&append_to_response=alternative_titles,external_ids,release_dates'.format(tmdbid) logging.info('Searching TMDB {}'.format(url)) url = url + '&api_key={}'.format(_k('tmdb')) request = Url.request(url) request = Url.request(url) while self.get_tokens() < 3: sleep(0.3) self.use_token() try: response = Url.open(request) results = json.loads(response) if results.get('status_code'): logging.warning(results.get('status_code')) return [''] else: return [results] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Error searching for TMDBID on TMDB.', exc_info=True) return ['']
def _login(url, username, password): data = {'username': username, 'password': password } post_data = urllib.urlencode(data) url = u'{}login'.format(url) request = Url.request(url, post_data=post_data) try: response = urllib2.urlopen(request) QBittorrent.cookie = response.headers.get('Set-Cookie') result = response.read() response.close() if result == 'Ok.': return True elif result == 'Fails.': return u'Incorrect usename or password' else: return result except (SystemExit, KeyboardInterrupt): raise except Exception, e: logging.error(u'qbittorrent test_connection', exc_info=True) return u'{}.'.format(str(e.reason))
def get_trailer(self, title_date): ''' Gets trailer embed url from Youtube. :param title_date: str movie title and date ("Movie Title 2016") Attempts to connect 3 times in case Youtube is down or not responding Can fail if no response is recieved. Returns str or None ''' search_term = Url.encode((title_date + '+trailer')) search_string = u"https://www.googleapis.com/youtube/v3/search?part=snippet&q={}&maxResults=1&key={}".format(search_term, _k('youtube')) request = Url.request(search_string) tries = 0 while tries < 3: try: response = Url.open(request) results = json.loads(response) return results['items'][0]['id']['videoId'] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa if tries == 2: logging.error(u'Unable to get trailer from Youtube.', exc_info=True) tries += 1
def test_connection(indexer, apikey): ''' Tests connection to NewzNab API ''' if not indexer: return {'response': False, 'error': 'Indexer field is blank.'} while indexer[-1] == '/': indexer = indexer[:-1] response = {} logging.info(u'Testing connection to {}.'.format(indexer)) url = u'{}/api?apikey={}&t=search&id=tt0063350'.format(indexer, apikey) request = Url.request(url) try: response = Url.open(request) except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Newz/TorzNab connection check.', exc_info=True) return { 'response': False, 'message': 'No connection could be made because the target machine actively refused it.' }
def _search_imdbid(self, imdbid): url = u'https://api.themoviedb.org/3/find/{}?language=en-US&external_source=imdb_id'.format(imdbid) logging.info('Searching TMDB {}'.format(url)) url = url + '&api_key={}'.format(_k('tmdb')) request = Url.request(url) while self.get_tokens() < 3: sleep(0.5) self.use_token() try: response = Url.open(request) results = json.loads(response) if results['movie_results'] == []: return [''] else: response = results['movie_results'][0] response['imdbid'] = imdbid return [response] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Error searching for IMDBID on TMDB.', exc_info=True) return ['']
def test_connection(data): ''' Tests connectivity to Sabnzbd :para data: dict of Sab server information Tests if we can get Sab's stats using server info in 'data' Return True on success or str error message on failure ''' host = data['host'] port = data['port'] api = data['api'] url = u'http://{}:{}/sabnzbd/api?apikey={}&mode=server_stats'.format( host, port, api) request = Url.request(url) try: response = Url.open(request) if 'error' in response: return response return True except (SystemExit, KeyboardInterrupt): raise except Exception, e: logging.error(u'Sabnzbd connection test failed.', exc_info=True) return u'{}.'.format(e.reason)
def search_newznab(self, url_base, apikey, **params): ''' Searches Newznab for imdbid url_base: str base url for all requests (https://indexer.com/) apikey: str api key for indexer params: parameters to url encode and append to url Creates url based off url_base. Appends url-encoded **params to url. Returns list of dicts of search results ''' url = u'{}api?apikey={}&{}'.format(url_base, apikey, urllib.urlencode(params)) logging.info(u'SEARCHING: {}api?apikey=APIKEY&{}'.format( url_base, urllib.urlencode(params))) proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] request = Url.request(url) try: if proxy_enabled and Proxy.whitelist(url) is True: response = Proxy.bypass(request) else: response = Url.open(request) return self.parse_newznab_xml(response) except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Newz/TorzNab backlog search.', exc_info=True) return []
def _login(url, password): command = { 'method': 'auth.login', 'params': [password], 'id': DelugeWeb.command_id } DelugeWeb.command_id += 1 post_data = json.dumps(command) request = Url.request(url, post_data, headers=DelugeWeb.headers) try: response = urllib2.urlopen(request) DelugeWeb.cookie = response.headers.get('Set-Cookie') if DelugeWeb.cookie is None: return 'Incorrect password.' if response.msg == 'OK': return True else: return response.msg except (SystemExit, KeyboardInterrupt): raise except Exception, e: logging.error(u'DelugeWeb test_connection', exc_info=True) return u'{}.'.format(e.reason)
def add_torrent(data): ''' Adds torrent or magnet to qbittorrent data: dict of torrrent/magnet information Adds torrents to default/path/<category> Returns dict {'response': True, 'download_id': 'id'} {'response': False, 'error': 'exception'} ''' conf = core.CONFIG['Downloader']['Torrent']['QBittorrent'] host = conf['host'] port = conf['port'] base_url = u'{}:{}/'.format(host, port) user = conf['user'] password = conf['pass'] # check cookie validity while getting default download dir download_dir = QBittorrent._get_download_dir(base_url) if not download_dir: if QBittorrent._login(base_url, user, password) is not True: return {'response': False, 'error': 'Incorrect usename or password.'} download_dir = QBittorrent._get_download_dir(base_url) if not download_dir: return {'response': False, 'error': 'Unable to get path information.'} # if we got download_dir we can connect. post_data = {} post_data['urls'] = data['torrentfile'] post_data['savepath'] = u'{}{}'.format(download_dir, conf['category']) post_data['category'] = conf['category'] url = u'{}command/download'.format(base_url) post_data = urllib.urlencode(post_data) request = Url.request(url, post_data=post_data) request.add_header('cookie', QBittorrent.cookie) try: Url.open(request) # QBit returns an empty string downloadid = Torrent.get_hash(data['torrentfile']) return {'response': True, 'downloadid': downloadid} except (SystemExit, KeyboardInterrupt): raise except Exception, e: logging.error(u'QBittorrent connection test failed.', exc_info=True) return {'response': False, 'error': str(e.reason)}
def add_nzb(data): ''' Adds nzb file to sab to download :param data: dict of nzb information Returns dict {'response': True, 'downloadid': 'id'} {'response': False, 'error': 'exception'} ''' conf = core.CONFIG['Downloader']['Usenet']['Sabnzbd'] host = conf['host'] port = conf['port'] api = conf['api'] base_url = u'http://{}:{}/sabnzbd/api?apikey={}'.format( host, port, api) mode = u'addurl' name = urllib2.quote(data['guid']) nzbname = data['title'] cat = conf['category'] priority_keys = { 'Paused': '-2', 'Low': '-1', 'Normal': '0', 'High': '1', 'Forced': '2' } priority = priority_keys[conf['priority']] command_url = u'&mode={}&name={}&nzbname={}&cat={}&priority={}&output=json'.format( mode, name, nzbname, cat, priority) url = base_url + command_url request = Url.request(url) try: response = json.load(Url.open(request)) if response['status'] is True and len(response['nzo_ids']) > 0: downloadid = response['nzo_ids'][0] logging.info( 'NZB sent to SABNzbd - downloadid {}.'.format(downloadid)) return {'response': True, 'downloadid': downloadid} else: logging.error( 'Unable to send NZB to Sabnzbd. {}'.format(response)) return {'response': False, 'error': 'Unable to add NZB.'} except Exception as e: logging.error('Unable to send NZB to Sabnzbd.', exc_info=True) return {'response': False, 'error': str(e.reason)}
def _get_download_dir(base_url): try: url = u'{}query/preferences'.format(base_url) request = Url.request(url) request.add_header('cookie', QBittorrent.cookie) response = json.loads(Url.open(request)) return response['save_path'] except urllib2.HTTPError: return False except Exception, e: logging.error(u'QBittorrent unable to get download dir.', exc_info=True) return {'response': False, 'error': str(e.reason)}
def get_newest_hash(self): api_url = u'{}/commits/{}'.format(core.GIT_API, core.CONFIG['Server']['gitbranch']) request = Url.request(api_url) try: response = Url.open(request) result = json.loads(response) hash = result['sha'] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Could not get newest hash from git.', exc_info=True) return None
def get_token(): url = u'https://www.torrentapi.org/pubapi_v2.php?get_token=get_token' request = Url.request(url) try: response = Url.open(request) result = json.loads(response) token = result.get('token') return token except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Failed to get Rarbg token.', exc_info=True) return None
def update_check(self): ''' Gets commit delta from GIT Sets core.UPDATE_STATUS to return value. Returns dict: {'status': 'error', 'error': <error> } {'status': 'behind', 'behind_count': #, 'local_hash': 'abcdefg', 'new_hash': 'bcdefgh'} {'status': 'current'} ''' os.chdir(core.PROG_PATH) logging.info(u'Checking git for a new Zip.') core.UPDATE_LAST_CHECKED = datetime.datetime.now() result = {} logging.info(u'Getting local version hash.') local_hash = self.current_hash if not local_hash: result['status'] = u'error' result['error'] = u'Could not get local hash. Check logs for details.' core.UPDATE_STATUS = result return result logging.info(u'Getting newest version hash.') newest_hash = self.get_newest_hash() if not newest_hash: result['status'] = u'error' result['error'] = u'Could not get latest update hash. Check logs for details.' core.UPDATE_STATUS = result return result compare_url = u'{}/compare/{}...{}'.format(core.GIT_API, newest_hash, local_hash) request = Url.request(compare_url) try: response = Url.open(request) result = json.loads(response) behind_count = result['behind_by'] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Could not get update information from git.', exc_info=True) result['status'] = u'error' result['error'] = u'Could not get update information from git.' core.UPDATE_STATUS = result return result
def get_album(self, album_id): url = u'https://itunes.apple.com/lookup?albumId={}&entity=song'.format( album_id) request = Url.request(url) try: response = Url.open(request) response = json.loads(response) if response.get('resultCount', 0) == 0: return None else: album = response['results'] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'iTunes search.', exc_info=True) return None
def _get_rss(self): ''' Get latest uploads from all indexers Returns list of dicts with parsed nzb info ''' self.imdbid = None proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] if self.feed_type == 'nzb': indexers = core.CONFIG['Indexers']['NewzNab'].values() else: indexers = core.CONFIG['Indexers']['TorzNab'].values() results = [] for indexer in indexers: if indexer[2] is False: continue url_base = indexer[0] if url_base[-1] != u'/': url_base = url_base + '/' apikey = indexer[1] url = u'{}api?t=movie&cat=2000&extended=1&offset=0&apikey={}'.format( url_base, apikey) logging.info( u'RSS_SYNC: {}api?t=movie&cat=2000&extended=1&offset=0&apikey=APIKEY' .format(url_base)) request = Url.request(url) try: if proxy_enabled and Proxy.whitelist(url) is True: response = Proxy.bypass(request) else: response = Url.open(request) return self.parse_newznab_xml(response) except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Newz/TorzNab rss get xml.', exc_info=True)
def _get_torrent_file(torrent_url, deluge_url): command = {'method': 'web.download_torrent_from_url', 'params': [torrent_url], 'id': DelugeWeb.command_id } DelugeWeb.command_id += 1 post_data = json.dumps(command) request = Url.request(deluge_url, post_data=post_data, headers=DelugeWeb.headers) request.add_header('cookie', DelugeWeb.cookie) try: response = DelugeWeb._read(Url.open(request)) if response['error'] is None: return {'response': True, 'torrentfile': response['result']} except (SystemExit, KeyboardInterrupt): raise except Exception, e: #noqa logging.error(u'Delugeweb download_torrent_from_url', exc_info=True) return {'response': False, 'error': str(e)[1:-1]}
def _get_download_dir(url): command = {'method': 'core.get_config_value', 'params': ['download_location'], 'id': DelugeWeb.command_id } DelugeWeb.command_id += 1 post_data = json.dumps(command) request = Url.request(url, post_data=post_data, headers=DelugeWeb.headers) request.add_header('cookie', DelugeWeb.cookie) try: response = DelugeWeb._read(Url.open(request)) return response['result'] except Exception, e: logging.error(u'delugeweb get_download_dir', exc_info=True) return {'response': False, 'error': str(e.reason)[1:-1]}
def get_feed(self): ''' Gets feed from iTunes new release rss Gets raw feed , sends to self.parse_xml to turn into dict Returns True or None on success or failure (due to exception or empty movie list) ''' new_albums = None logging.info(u'Syncing new album releases.') request = Url.request(self.rss) try: response = Url.open(request) new_albums = self.parse(response) except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Unable to get iTunes rss.', exc_info=True) return None
def get_imdbid(self, tmdbid=None, title=None, year=''): ''' Gets imdbid from tmdbid tmdbid: str TMDB movie id # title: str movie title year str year of movie release MUST supply either tmdbid or title. Year is optional with title, but results are more reliable with it. Returns str imdbid or None on failure ''' if not tmdbid and not title: logging.warning(u'Neither tmdbid or title supplied. Unable to find imdbid.') return None if not tmdbid: title = Url.encode(title) year = Url.encode(year) url = u'https://api.themoviedb.org/3/search/movie?api_key={}&language=en-US&query={}&year={}&page=1&include_adult=false'.format(_k('tmdb'), title, year) request = Url.request(url) while self.get_tokens() < 3: sleep(0.3) self.use_token() try: response = Url.open(request) results = json.loads(response) results = results['results'] if results: tmdbid = results[0]['id'] else: return None except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Error attempting to get TMDBID from TMDB.', exc_info=True) return None
def get_albums(self, artist_id): ''' Gets all albums/tracks by artists artist_id: str artist id # ''' url = u'https://itunes.apple.com/lookup?id={}&entity=album'.format( artist_id) request = Url.request(url) try: response = Url.open(request) response = json.loads(response) if response.get('resultCount', 0) == 0: return None else: albums = response['results'][1:] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'iTunes search.', exc_info=True) return None
def get_feed(self): ''' Gets feed from popular-movies (https://github.com/sjlu/popular-movies) Gets raw feed (JSON), sends to self.parse_xml to turn into dict Returns True or None on success or failure (due to exception or empty movie list) ''' movies = None logging.info(u'Syncing popular movie feed.') request = Url.request( 'https://s3.amazonaws.com/popular-movies/movies.json', headers={'User-Agent': 'Mozilla/5.0'}) try: response = Url.open(request) movies = json.loads(response) except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Popular feed request failed.', exc_info=True) return None
def get_rss(self, url): ''' Gets rss feed from imdb :param rss_url: str url to rss feed Gets raw rss, sends to self.parse_xml to turn into dict Returns True or None on success or failure (due to exception or empty movie list) ''' if 'rss' in url: list_id = filter(unicode.isdigit, url) logging.info(u'Syncing rss IMDB watchlist {}'.format(url)) request = Url.request(url) try: response = Url.open(request) except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'IMDB rss request.', exc_info=True) return None movies = self.parse_xml(response)
def _search_title(self, title): ''' Search TMDB for title title: str movie title Title can include year ie Move Title 2017 Returns list results or str error/fail message ''' title = Url.encode(title) url = u'https://api.themoviedb.org/3/search/movie?page=1&include_adult=false&' if title[-4:].isdigit(): query = u'query={}&year={}'.format(title[:-5], title[-4:]) else: query = u'query={}'.format(title) url = url + query logging.info('Searching TMDB {}'.format(url)) url = url + '&api_key={}'.format(_k('tmdb')) request = Url.request(url) while self.get_tokens() < 3: sleep(0.3) self.use_token() try: response = Url.open(request) results = json.loads(response) if results.get('success') == 'false': return None else: return results['results'][:6] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Error searching for title on TMDB.', exc_info=True) return ['']
def get_rss(): proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] logging.info(u'Fetching latest RSS from Rarbg.') if Rarbg.timeout: now = datetime.datetime.now() while Rarbg.timeout > now: time.sleep(1) now = datetime.datetime.now() if not Rarbg.token: Rarbg.token = Rarbg.get_token() if Rarbg.token is None: logging.error(u'Unable to get Rarbg token.') return [] url = u'https://www.torrentapi.org/pubapi_v2.php?token={}&mode=list&category=movies&format=json_extended&app_id=Watcher'.format(Rarbg.token) request = Url.request(url) Rarbg.timeout = datetime.datetime.now() + datetime.timedelta(seconds=2) try: if proxy_enabled and Proxy.whitelist('https://www.torrentapi.org') is True: response = Proxy.bypass(request) else: response = Url.open(request) results = json.loads(response).get('torrent_results') if results: return Rarbg.parse(results) else: logging.info(u'Nothing found in Rarbg RSS.') return [] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Rarbg RSS fetch failed.', exc_info=True) return []
def get_rss(): proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] logging.info(u'Fetching latest RSS from ThePirateBay.') url = u'https://www.thepiratebay.org/browse/201/0/3/0' request = Url.request(url) try: if proxy_enabled and Proxy.whitelist('https://www.thepiratebay.org') is True: response = Proxy.bypass(request) else: response = Url.open(request) if response: return ThePirateBay.parse(response, None) else: return [] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'ThePirateBay RSS fetch failed.', exc_info=True) return []
def get_rss(): proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] logging.info(u'Fetching latest RSS from Torrentz2.') url = u'https://www.torrentz2.eu/feed?f=movies' request = Url.request(url) try: if proxy_enabled and Proxy.whitelist('https://www.torrentz2.eu') is True: response = Proxy.bypass(request) else: response = Url.open(request) if response: return Torrentz2.parse(response, None) else: return [] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Torrentz2 RSS fetch failed.', exc_info=True) return []
def search(imdbid, term): proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] logging.info(u'Searching Torrentz2 for {}.'.format(term)) url = u'https://www.torrentz2.eu/feed?f={}'.format(term) request = Url.request(url) try: if proxy_enabled and Proxy.whitelist('https://www.torrentz2.eu') is True: response = Proxy.bypass(request) else: response = Url.open(request) if response: return Torrentz2.parse(response, imdbid) else: return [] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Torrentz2 search failed.', exc_info=True) return []
def get_rss(): proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] logging.info(u'Fetching latest RSS from BitSnoop.') url = u'https://www.bitsnoop.com/browse/video-movies/?sort=dt_reg&fmt=rss' request = Url.request(url) try: if proxy_enabled and Proxy.whitelist('https://www.bitsnoop.com') is True: response = Proxy.bypass(request) else: response = Url.open(request) if response: return BitSnoop.parse(response, None) else: return [] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'BitSnoop RSS fetch failed.', exc_info=True) return []
def search(imdbid, term): proxy_enabled = core.CONFIG['Server']['Proxy']['enabled'] logging.info(u'Searching BitSnoop for {}.'.format(term)) url = u'https://www.bitsnoop.com/search/video/{}/c/d/1/?fmt=rss'.format(term) request = Url.request(url) try: if proxy_enabled and Proxy.whitelist('https://www.bitsnoop.com') is True: response = Proxy.bypass(request) else: response = Url.open(request) if response: return BitSnoop.parse(response, imdbid) else: return [] except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'BitSnoop search failed.', exc_info=True) return []