def set_trakt_user(self, trakt_username): cursor = self._get_cursor() tools.log('Setting Trakt Username: %s' % trakt_username) cursor.execute('UPDATE activities SET trakt_username=?', (trakt_username, )) cursor.connection.commit() cursor.close()
def onPlayBackStarted(self): try: tools.execute('Dialog.Close(all,true)') self.current_time = self.getTime() self.media_length = self.getTotalTime() if self.offset is not None and int(self.offset) != 0: tools.log("Seeking %s seconds" % self.offset, 'info') self.seekTime(self.offset) self.offset = None else: tools.log("No seeking applied") self.traktStartWatching() if 'episodeInfo' in self.args and tools.getSetting( 'smartplay.upnext') == 'true': source_id = 'plugin.video.%s' % tools.addonName.lower() return_id = 'plugin.video.%s_play_action' % tools.addonName.lower( ) try: next_info = self.next_info() AddonSignals.sendSignal('upnext_data', next_info, source_id=source_id) AddonSignals.registerSlot('upnextprovider', return_id, self.signals_callback) except: import traceback traceback.print_exc() pass except: pass
def post_url(self, url, data): if self.headers['Authorization'] == 'Bearer ': tools.log('User is not authorised to make PM requests') return None url = "https://www.premiumize.me/api{}".format(url) req = requests.post(url, headers=self.headers, data=data, timeout=10).json() return req
def wrapper(*args, **kwarg): try: response = func(*args, **kwarg) if response.status_code in [200, 201]: return response if response.status_code == 429: tools.log( 'Alldebrid Throttling Applied, Sleeping for {} seconds'. format(1), '') tools.kodi.sleep(1 * 1000) response = func(*args, **kwarg) tools.log( 'AllDebrid returned a {} ({}): while requesting {}'.format( response.status_code, AllDebrid.http_codes[response.status_code], response.url), 'warning') return None except requests.exceptions.ConnectionError: return None except not requests.exceptions.ConnectionError: tools.showDialog.ok( tools.addonName, "Somethign wnet wrong with AllDebrid cancelling action") return None
def fill_playlist(self): self.window = PersistentBackground('persistent_background.xml', tools.addonDir, actionArgs=self.actionArgs) self.window.setText(tools.lang(32094)) self.window.show() self.window.setText(tools.lang(32095)) tools.playList.clear() season = self.info_dictionary['info']['season'] episode = self.info_dictionary['info']['episode'] self.window.setText(tools.lang(32096)) self.window.setText(tools.lang(32097)) self._build_playlist(season, episode) self.window.setText('Starting Playback') tools.log( 'Begining play from Season %s Episode %s' % (season, episode), 'info') self.window.close() tools.player().play(tools.playList)
def onInit(self): self.display_list = self.getControl(1000) menu_items = [] for idx, i in enumerate(self.sources): menu_item = tools.menuItem(label=('%s) %s' % (idx + 1, i['release_title']))) for info in i.keys(): try: tools.log(i) tools.log(info) value = i[info] if type(value) == list: value = [str(k) for k in value] value = ' '.join(sorted(value)) if info == 'size': value = tools.source_size_display(value) if info == 'type' and i.get(info) == 'hoster': menu_item.setProperty('provider', str(value).replace('_', ' ')) menu_item.setProperty(info, str(value).replace('_', ' ')) except UnicodeEncodeError: menu_item.setProperty(info, i[info]) menu_items.append(menu_item) self.display_list.addItem(menu_item) self.setFocusId(1000)
def start_playback(self): try: tools.execute('Dialog.Close(all,true)') self.current_time = self.getTime() self.media_length = self.getTotalTime() if self.offset is not None and int(self.offset) != 0: tools.log("Seeking %s seconds" % self.offset, 'info') self.seekTime(self.offset) self.offset = None else: tools.log("No seeking applied") self.traktStartWatching() if 'episodeInfo' in self.args and tools.getSetting('smartplay.upnext') == 'true': source_id = 'plugin.video.%s' % tools.addonName.lower() return_id = 'plugin.video.%s_play_action' % tools.addonName.lower() try: next_info = self.next_info() AddonSignals.sendSignal('upnext_data', next_info, source_id=source_id) AddonSignals.registerSlot('upnextprovider', return_id, self.signals_callback) except: import traceback traceback.print_exc() pass if tools.getSetting('general.smartplay') is not 'false' and self.media_type is 'episode': if int(tools.playList.getposition()) == (tools.playList.size() - 1): self.next_season = smartPlay.SmartPlay(self.args).append_next_season() self.playback_started = True except: pass
def delete_request(self, url, refreshCheck=False): if refreshCheck == False: url = self.ApiUrl + url try: response = requests.delete(url, headers=self.headers) if response.status_code == 401: if refreshCheck == False: self.refreshToken() self.delete_request(url, refreshCheck=True) else: tools.log( 'Failed to perform trakt request even after token refresh', 'error') if response.status_code > 499: return None except requests.exceptions.ConnectionError: return except not requests.exceptions.ConnectionError: return return response.text
def auto_cache(self, torrent_list): """ NOTE: This entry is locking :param torrent_list: LIST :return: None """ if not torrent_list: return debrid_class = self.locations[g.get_int_setting( "general.cachelocation")][1] if len(torrent_list) == 0: selected_source = torrent_list[0] else: selected_source = _approx_best_source(torrent_list) try: debrid_class = debrid_class(selected_source) debrid_class.status_update_loop() except DebridNotEnabled: tools.log( "Failed to start cache assist as selected debrid provider is not enabled or setup correctly", "error", ) return xbmcgui.Dialog().notification(g.ADDON_NAME, g.get_language_string(30483))
def post_request(self, url, postData, limit=True, refreshCheck=False): if refreshCheck == False: url = self.ApiUrl + url if limit == True: limitAmount = tools.getSetting('item.limit') if not '?' in url: url += '?limit=%s' % limitAmount else: url += '&limit=%s' % limitAmount try: response = requests.post(url, json=postData, headers=self.headers) self.response_headers = response.headers if response.status_code == 401: if refreshCheck == False: self.refreshToken() self.post_request(url, postData, limit=limit, refreshCheck=True) else: tools.log( 'Failed to perform trakt request even after token refresh', 'error') if response.status_code > 499: return None except requests.exceptions.ConnectionError as e: return except not requests.exceptions.ConnectionError as e: return return response.text
def add_provider(provider_name, package, status, language, provider_type): try: hash = _hash_function('%s%s' % (provider_name, package)) cursor = _get_connection_cursor(tools.providersDB) cursor.execute( "CREATE TABLE IF NOT EXISTS providers (hash TEXT," " provider_name TEXT, status TEXT, package TEXT, country TEXT, provider_type TEXT, UNIQUE(hash))" ) cursor.execute('SELECT * FROM providers WHERE hash=?', (hash, )) current_settings = cursor.fetchall() if len(current_settings) == 0: tools.log('Inserting %s' % hash) cursor.execute("INSERT INTO providers Values (?, ?, ?, ?, ?, ?)", (hash, provider_name, status, package, language, provider_type)) else: tools.log('skipping provider') cursor.connection.commit() cursor.close() except: try: cursor.close() except: pass import traceback traceback.print_exc() pass
def sourceSelect(source_list, info): try: if len(source_list) == 0: return None display_list = [] for source in source_list: display_list.append(build_display_title(source)) if tools.getSetting('general.sourceselect') == '1': window = source_select_list(display_list, info) selection = window.doModal() del window elif tools.getSetting('general.sourceselect') == '0': selection = tools.showDialog.select( tools.addonName + ': %s' % tools.lang(32099).encode('utf-8'), display_list) except: import traceback traceback.print_exc() selection = -1 if selection == -1: try: tools.playList.clear() except: pass tools.log('Source Selection was cancelled', 'info') return [] return source_list[selection:]
def _handle_re_auth(self, response): tools.log( 'Trakt OAuth Failure, %s %s' % (str(response.text), response.request.headers), 'info') self.refreshToken()
def check_for_addon_update(): try: if tools.getSetting('general.checkAddonUpdates') == 'false': return update_timestamp = float( tools.getSetting('addon.updateCheckTimeStamp')) if time.time() > (update_timestamp + (24 * (60 * 60))): repo_xml = requests.get( 'https://raw.githubusercontent.com/nixgates/nixgates/master/packages/addons.xml' ) if not repo_xml.status_code == 200: tools.log( 'Could not connect to repo XML, status: %s' % repo_xml.status_code, 'error') return repo_version = re.findall( r'<addon id=\"plugin.video.seren\" version=\"(\d*.\d*.\d*)\"', repo_xml.text)[0] local_verison = tools.addonVersion if tools.check_version_numbers(local_verison, repo_version): tools.showDialog.ok(tools.addonName, tools.lang(40136) % repo_version) tools.setSetting('addon.updateCheckTimeStamp', str(time.time())) except: pass
def refresh_apis(): rd_token = tools.getSetting('rd.auth') rd_expiry = int(float(tools.getSetting('rd.expiry'))) tvdb_token = tools.getSetting('tvdb.jw') tvdb_expiry = int(float(tools.getSetting('tvdb.expiry'))) try: if rd_token != '': if time.time() > (rd_expiry - (10 * 60)): from resources.lib.debrid import real_debrid tools.log('Service Refreshing Real Debrid Token') real_debrid.RealDebrid().refreshToken() except: pass try: if tvdb_token != '': if time.time() > (tvdb_expiry - (30 * 60)): tools.log('Service Refreshing TVDB Token') from resources.lib.indexers import tvdb if time.time() > tvdb_expiry: tvdb.TVDBAPI().newToken() else: tvdb.TVDBAPI().renewToken() else: from resources.lib.indexers import tvdb tvdb.TVDBAPI().newToken() except: pass
def token_request(self): import time if self.ClientSecret is '': return postData = { 'client_id': self.ClientID, 'client_secret': self.ClientSecret, 'code': self.DeviceCode, 'grant_type': 'http://oauth.net/grant_type/device/1.0' } url = self.OauthUrl + self.TokenUrl response = requests.post(url, data=postData).text response = json.loads(response) tools.setSetting('rd.auth', response['access_token']) tools.setSetting('rd.refresh', response['refresh_token']) self.token = response['access_token'] self.refresh = response['refresh_token'] tools.setSetting('rd.expiry', str(time.time() + int(response['expires_in']))) username = self.get_url('user')['username'] tools.setSetting('rd.username', username) tools.showDialog.ok(tools.addonName, 'Real Debrid ' + tools.lang(32026).encode('utf-8')) tools.log('Authorised Real Debrid successfully', 'info')
def run_maintenance(): tools.log('Performing Maintenance') # ADD COMMON HOUSE KEEPING ITEMS HERE # # Refresh API tokens try: refresh_apis() except: pass # Check cloud account status and alert user if expired try: if tools.getSetting('general.accountNotifications') == 'true': account_notifications() except: pass # Deploy the init.py file for the providers folder and make sure it's refreshed on startup try: customProviders.providers().deploy_init() except: pass try: update_provider_packages() except: pass # Check Premiumize Fair Usage for cleanup try: if tools.getSetting('premiumize.enabled') == 'true' and tools.getSetting('premiumize.autodelete') == 'true': premiumize_transfer_cleanup() except: pass
def traktBookmark(self): if not self.trakt_integration(): return try: offset = None if self.media_type == 'episode': progress = self.trakt_api.json_response('sync/playback/episodes?extended=full') for i in progress: if self.trakt_id == i['episode']['ids']['trakt']: # Calculating Offset to seconds offset = int((float(i['progress'] / 100) * int(i['episode']['runtime']) * 60)) else: progress = self.trakt_api.json_response('sync/playback/movies?extended=full') for i in progress: if self.trakt_id == i['movie']['ids']['trakt']: # Calculating Offset to seconds offset = int((float(i['progress'] / 100) * int(i['movie']['runtime']) * 60)) if tools.getSetting('smartPlay.bookmarkprompt') == 'true': if offset is not None and offset is not 0: prompt = tools.showDialog.yesno(tools.addonName + ': Resume', '%s %s' % (tools.lang(32092).encode('utf-8'), datetime.timedelta(seconds=offset)), nolabel="Resume", yeslabel="Restart") if prompt == 0: tools.log('Found progress, resuming from %s ' % str(offset * 60), 'error') self.offset = offset else: return else: self.offset = offset except: import traceback traceback.print_exc()
def refreshToken(self): url = self.ApiUrl + "/oauth/token" postData = { 'refresh_token': self.RefreshToken, 'client_id': self.ClientID, 'client_secret': self.ClientSecret, 'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob', 'grant_type': 'refresh_token' } response = requests.post(url, data=postData) try: response = json.loads(response.text) tools.setSetting('trakt.auth', response['access_token']) tools.setSetting('trakt.refresh', response['refresh_token']) self.AccessToken = response['access_token'] self.RefreshToken = response['refresh_token'] tools.log('Refreshed Trakt Token') if not self.AccessToken is '': self.headers['Authorization'] = self.AccessToken return except: import traceback traceback.print_exc() tools.log('Failed to refresh Trakt Access Token', 'error') return
def showListBuilder(self, trakt_list, forceResume=False, info_only=False): try: if len(trakt_list) == 0: tools.log('We received no titles to build a list', 'error') return except: import traceback traceback.print_exc() return if 'show' in trakt_list[0]: trakt_list = [i['show'] for i in trakt_list] show_ids = [i['ids']['trakt'] for i in trakt_list] self.itemList = trakt_database.get_show_list(show_ids) self.itemList = [x for x in self.itemList if x is not None and 'info' in x] self.itemList = tools.sort_list_items(self.itemList, trakt_list) item_list = [] for item in self.itemList: try: # Add Arguments to pass with items args = {'trakt_id': item['ids']['trakt'], 'item_type': 'show'} args = tools.quote(json.dumps(args, sort_keys=True)) name = tools.display_string(item['info']['tvshowtitle']) if info_only: return args if not self.is_aired(item['info']): if tools.getSetting('general.hideUnAired') == 'true': continue name = tools.colorString(name, 'red') name = tools.italic_string(name) item['info'] = tools.clean_air_dates(item['info']) item['info']['title'] = item['info']['tvshowtitle'] if tools.getSetting('smartplay.clickresume') == 'true' or forceResume is True: action = 'playbackResume' else: if tools.getSetting('general.flatten.episodes') == 'true': action = 'flatEpisodes' else: action = 'showSeasons' except: import traceback traceback.print_exc() continue item_list.append(tools.addDirectoryItem(name, action, item['info'], item['art'], item['cast'], isFolder=True, isPlayable=False, actionArgs=args, bulk_add=True, set_ids=item['ids'])) tools.addMenuItems(syshandle, item_list, len(item_list))
def _check_skin_for_update(self, skin_info): try: remote_meta = requests.get(skin_info['remote_meta']).json() return tools.check_version_numbers(skin_info['version'], remote_meta['version']) except: tools.log('Failed to obtain remote meta information for skin: {}'.format(skin_info['skin_name'])) return False
def signals_callback(self, data): tools.log('WE HAVE A CALLBACK') if not self.play_next_triggered: self.stopped = True self.traktStopWatching() self.play_next_triggered = True # Using a seek here as playnext causes Kodi gui to wig out. So we seek instead so it looks more graceful self.seekTime(self.media_length)
def set_trakt_user(self, trakt_username): tools.traktSyncDB_lock.acquire() cursor = self._get_cursor() tools.log('Setting Trakt Username: %s' % trakt_username) cursor.execute('UPDATE activities SET trakt_username=?', (trakt_username, )) cursor.connection.commit() cursor.close() tools.try_release_lock(tools.traktSyncDB_lock)
def myFilesFolder(self, args): args = json.loads(args) tools.log(args) if args['id'] is None: tools.log('isNone') self.providers[args['debrid_provider']][1]().get_init_list() else: self.providers[args['debrid_provider']][1]().get_folder(args) tools.closeDirectory('addons', sort='title')
def seasonListBuilder(self, show_id, smartPlay=False): self.itemList = trakt_database.get_season_list(show_id) self.itemList = [x for x in self.itemList if x is not None and 'info' in x] self.itemList = sorted(self.itemList, key=lambda k: int(k['info']['season'])) if len(self.itemList) == 0: tools.log('We received no titles to build a list', 'error') return hide_specials = False if tools.getSetting('general.hideSpecials') == 'true': hide_specials = True item_list = [] for item in self.itemList: try: if hide_specials and int(item['info']['season']) == 0: continue action = 'seasonEpisodes' args = {'trakt_id': item['showInfo']['ids']['trakt'], 'season': item['info']['season'], 'item_type': 'season'} args = tools.quote(json.dumps(args, sort_keys=True)) item['trakt_object']['show_id'] = item['showInfo']['ids']['trakt'] name = item['info']['season_title'] if not self.is_aired(item['info']) or 'aired' not in item['info']: if tools.getSetting('general.hideUnAired') == 'true': continue name = tools.colorString(name, 'red') name = tools.italic_string(name) item['info']['title'] = name item['info'] = tools.clean_air_dates(item['info']) except: import traceback traceback.print_exc() continue if smartPlay is True: return args item_list.append(tools.addDirectoryItem(name, action, item['info'], item['art'], item['cast'], isFolder=True, isPlayable=False, actionArgs=args, set_ids=item['ids'], bulk_add=True)) tools.addMenuItems(syshandle, item_list, len(item_list))
def keepAlive(self): for i in range(0, 240): if self.isPlayingVideo(): break tools.kodi.sleep(1000) while self.isPlayingVideo(): try: if not self.playback_started: tools.kodi.sleep(1000) continue if not self.playback_started: self.start_playback() if self.offset is not None and int( self.offset) != 0 and self.playback_resumed is False: tools.log("Seeking %s seconds" % self.offset, 'info') self.seekTime(self.offset) self.offset = None self.playback_resumed = True else: self.playback_resumed = True try: position = self.getTime() self.current_time = position total_length = self.getTotalTime() self.media_length = total_length except: pass if self.pre_cache_initiated is False: try: if self.getWatchedPercent() > 80 and tools.getSetting( 'smartPlay.preScrape') == 'true': self.pre_cache_initiated = True smartPlay.SmartPlay(self.args).pre_scrape() except: pass # We manually check and signal this as Kodi always fires playbackEnded after a new player # class is created, marking the wrong episode watched if self.getWatchedPercent() > 90 and not self.scrobbled: self.traktStopWatching() self.scrobbled = True except: import traceback traceback.print_exc() tools.kodi.sleep(1000) continue tools.kodi.sleep(3000) self.traktStopWatching()
def addTorrent(item_meta, torrent_objects): if tools.getSetting('general.torrentCache') == 'false': return if 'showInfo' in item_meta: season = item_meta['info']['season'] episode = item_meta['info']['episode'] trakt_id = item_meta['showInfo']['ids']['trakt'] else: season = 0 episode = 0 trakt_id = item_meta['ids']['trakt'] cursor = _get_connection_cursor(tools.torrentScrapeCacheFile) try: # Confirm we are on the newer version of the torrent cache database columns = [ i['name'] for i in cursor.execute("PRAGMA table_info(cache);").fetchall() ] if 'trakt_id' not in columns: raise Exception except: tools.log("WE ARE UPGRADING") cursor.execute("DROP TABLE IF EXISTS cache") cursor.execute("CREATE TABLE IF NOT EXISTS %s (" "trakt_id TEXT, " "meta TEXT, " "hash TEXT, " "season TEXT, " "episode TEXT, " "package, " "UNIQUE(hash))" % cache_table) for torrent_object in torrent_objects: try: hash = torrent_object['hash'] pack = torrent_object['package'] update_result = cursor.execute( "UPDATE %s SET trakt_id=?, meta=?, season=?, episode=?, package=? WHERE hash=?" % cache_table, (trakt_id, str(torrent_object), season, episode, pack, hash)) if update_result.rowcount is 0: cursor.execute( "INSERT INTO %s Values (?, ?, ?, ?, ?, ?)" % cache_table, (trakt_id, str(torrent_object), hash, season, episode, pack)) except: import traceback traceback.print_exc() cursor.connection.commit() cursor.close()
def get_provider_packages(): tools.log('Getting provider packages') cursor = _get_connection_cursor(tools.providersDB) cursor.execute( "CREATE TABLE IF NOT EXISTS packages (hash TEXT," " pack_name TEXT, author TEXT, remote_meta TEXT, version TEXT, UNIQUE(hash))" ) cursor.execute("SELECT * FROM packages") packages = cursor.fetchall() return packages
def _is_folder(self, list_item): if len(list_item['links']) > 1: return True else: try: try: list_item['link'] = list_item['links'].iteritems[0][1] except: list_item['link'] = list_item['links'].items()[0][1] except KeyError: tools.log(list_item['links']) return False
def confirm_marked_unwatched(self, response, type): try: if response['deleted'][type] > 0: return True raise Exception except Exception as e: tools.showDialog.notification('{}: {}'.format(tools.addonName, tools.lang(40280)), tools.lang(40281)) tools.log('Failed to mark item as unwatched, error: %s \n Trakt Response: %s' % (e, response)) return False