def auth(self): data = {'client_id': CLIENT_ID, 'response_type': 'device_code'} token = requests.post('https://www.premiumize.me/token', data=data, timeout=15).json() expiry = float(token['expires_in']) token_ttl = token['expires_in'] poll_again = True success = False progressDialog = control.progressDialog progressDialog.create( control.lang(40054), control.progress_line % (control.lang(32513) % token['verification_uri'], control.lang(32514) % token['user_code'], '')) progressDialog.update(0) while poll_again and not token_ttl <= 0 and not progressDialog.iscanceled( ): poll_again, success = self.poll_token(token['device_code']) progress_percent = 100 - int((float( (expiry - token_ttl) / expiry) * 100)) progressDialog.update(progress_percent) control.sleep(token['interval'] * 1000) token_ttl -= int(token['interval']) progressDialog.close() if success: control.notification(title=40057, message=40081, icon=pm_icon)
def _post(self, url, data): original_url = url url = rest_base_url + url if self.token == '': log_utils.log('No Real Debrid Token Found', __name__, log_utils.LOGDEBUG) return None if '?' not in url: url += "?auth_token=%s" % self.token else: url += "&auth_token=%s" % self.token response = requests.post(url, data=data, timeout=15).text if 'bad_token' in response or 'Bad Request' in response: self.refresh_token() response = self._post(original_url, data) elif 'error' in response: response = json.loads(response) control.notification(title='default', message=response.get('error'), icon='default') return None try: return json.loads(response) except: return response
def auth(self): self.secret = '' self.client_ID = 'X245A4XAIBGVM' url = 'client_id=%s&new_credentials=yes' % self.client_ID url = oauth_base_url + device_code_url % url response = json.loads(requests.get(url).text) control.progressDialog.create(control.lang(40055)) control.progressDialog.update( -1, control.progress_line % (control.lang(32513) % 'https://real-debrid.com/device', control.lang(32514) % response['user_code'], '')) self.auth_timeout = int(response['expires_in']) self.auth_step = int(response['interval']) self.device_code = response['device_code'] while self.secret == '': if control.progressDialog.iscanceled(): control.progressDialog.close() break self.auth_loop() if self.secret: if self.get_token(): control.notification(title=40058, message=40081, icon=rd_icon) else: return control.okDialog(title='default', message=control.lang(40019))
def run(self): xbmc.log( '[ script.module.myaccounts ] Addon checking available updates', LOGNOTICE) try: import re import requests repo_xml = requests.get( 'https://raw.githubusercontent.com/a4k-openproject/repository.myaccounts/master/zips/addons.xml' ) if repo_xml.status_code != 200: return xbmc.log( '[ script.module.myaccounts ] Could not connect to remote repo XML: status code = %s' % repo_xml.status_code, LOGNOTICE) repo_version = re.findall( r'<addon id=\"script.module.myaccounts\".*version=\"(\d*.\d*.\d*.\d*)\"', repo_xml.text)[0] local_version = control.addonVersion() if control.check_version_numbers(local_version, repo_version): while control.condVisibility('Library.IsScanningVideo'): control.sleep(10000) xbmc.log( '[ script.module.myaccounts ] A newer version is available. Installed Version: v%s, Repo Version: v%s' % (local_version, repo_version), LOGNOTICE) control.notification( title='default', message= 'A new verison of My Accounts is available from the repository. Please consider updating to v%s' % repo_version, icon='default', time=5000, sound=False) except: import traceback traceback.print_exc()
def get_token(self): try: url = oauth_base_url + 'token' postData = {'client_id': self.client_ID, 'client_secret': self.secret, 'code': self.device_code, 'grant_type': 'http://oauth.net/grant_type/device/1.0'} response = requests.post(url, data=postData) # log_utils.log('Authorizing Real Debrid Result: | %s |' % response, level=log_utils.LOGDEBUG) if '[204]' in str(response): return False, str(response) if 'Temporarily Down For Maintenance' in response.text: control.notification(message='Real-Debrid Temporarily Down For Maintenance', icon=rd_icon) log_utils.log('Real-Debrid Temporarily Down For Maintenance', level=log_utils.LOGWARNING) return False, response.text else: response = response.json() if 'error' in str(response): log_utils.log('response=%s' % str(response), __name__) message = response.get('error') control.notification(message=message, icon=rd_icon) log_utils.log('Real-Debrid Error: %s' % message, level=log_utils.LOGWARNING) return False, response self.token = response['access_token'] control.sleep(500) account_info = self.account_info() username = account_info['username'] control.setSetting('realdebrid.username', username) control.setSetting('realdebrid.client_id', self.client_ID) control.setSetting('realdebrid.secret', self.secret,) control.setSetting('realdebrid.token', self.token) control.setSetting('realdebrid.refresh', response['refresh_token']) return True, None except: log_utils.error('Real Debrid Authorization Failed : ') return False, None
def revoke(self): data = {"token": control.setting('trakt.token')} try: self.call("oauth/revoke", data=data, with_auth=False) except: pass control.setSetting('trakt.username', '') control.setSetting('trakt.expires', '') control.setSetting('trakt.token', '') control.setSetting('trakt.refresh', '') control.notification(title='default', message=40009, icon=trakt_icon)
def _get(self, url, url_append=''): result = None try: if self.token == '': return None url = base_url + url + '?agent=%s&apikey=%s' % ( user_agent, self.token) + url_append result = requests.get(url, timeout=self.timeout).json() if result.get('status') == 'success': if 'data' in result: result = result['data'] except requests.exceptions.ConnectionError: control.notification(title='default', message=40073, icon=ad_icon) except BaseException: log_utils.error() return result
def revoke_session_id(self): try: if control.setting('tmdb.session_id') == '': return url = self.auth_base_link + '/session?api_key=%s' % API_key post = {"session_id": "%s" % control.setting('tmdb.session_id')} result = requests.delete(url, data=post).json() if result.get('success') is True: control.setSetting('tmdb.session_id', '') control.notification(title='default', message=32681, icon='default') else: control.notification(title='default', message=32682, icon='ERROR') except: log_utils.error()
def _get(self, url): try: response = requests.get(url, headers=self.headers, timeout=15).json() if 'status' in response: if response.get('status') == 'success': return response if response.get( 'status') == 'error' and self.server_notifications: control.notification(title='default', message=response.get('message'), icon='default') except: log_utils.error() return response
def auth_loop(self): control.sleep(5000) response = requests.get(self.check_url, timeout=self.timeout).json() response = response['data'] if 'error' in response: self.token = 'failed' return control.notification(title='default', message=40021, icon='default') if response['activated']: try: control.progressDialog.close() self.token = str(response['apikey']) control.setSetting('alldebrid.token', self.token) except: self.token = 'failed' return control.notification(title='default', message=40021, icon='default') return
def auth(self): self.token = '' url = base_url + 'pin/get?agent=%s' % user_agent response = requests.get(url, timeout=self.timeout).json() response = response['data'] control.progressDialog.create(control.lang(40056)) control.progressDialog.update(-1, control.progress_line % (control.lang(32513) % 'https://alldebrid.com/pin/', control.lang(32514) % response['pin'], '')) self.check_url = response.get('check_url') control.sleep(2000) while not self.token: if control.progressDialog.iscanceled(): control.progressDialog.close() break self.auth_loop() if self.token in (None, '', 'failed'): return control.sleep(2000) account_info = self.account_info() control.setSetting('alldebrid.username', str(account_info['user']['username'])) control.notification(title=40059, message=40081, icon=ad_icon)
def auth(self): try: code = self.get_device_code() token = self.get_device_token(code) if token: expires_at = time.time() + 60 * 60 * 24 * 30 control.setSetting('trakt.expires', str(expires_at)) control.setSetting('trakt.token', token["access_token"]) control.setSetting('trakt.refresh', token["refresh_token"]) control.sleep(1000) try: user = self.call("users/me", with_auth=True) control.setSetting('trakt.username', str(user['username'])) except: pass control.notification(message=40074, icon=trakt_icon) return True control.notification(message=40075, icon=trakt_icon) return False except: log_utils.error()
def refresh_token(self): try: self.client_ID = control.setting('realdebrid.client_id') self.secret = control.setting('realdebrid.secret') self.device_code = control.setting('realdebrid.refresh') if not self.client_ID or not self.secret or not self.device_code: return False # avoid if previous refresh attempt revoked accnt, loops twice. log_utils.log('Refreshing Expired Real Debrid Token: | %s | %s |' % (self.client_ID, self.device_code), __name__, log_utils.LOGDEBUG) success, error = self.get_token() if not success: if not 'Temporarily Down For Maintenance' in error: if any(value == error.get('error_code') for value in [9, 12, 13, 14]): self.revoke() # empty all auth settings to force a re-auth on next use control.notification(message='Real-Debrid Auth revoked due to: %s' % error.get('error'), icon=rd_icon) log_utils.log('Unable to Refresh Real Debrid Token: %s' % error.get('error'), level=log_utils.LOGWARNING) return False else: log_utils.log('Real Debrid Token Successfully Refreshed', level=log_utils.LOGDEBUG) return True except: log_utils.error() return False
def create_session_id(self): try: if control.setting('tmdb.username') == '' or control.setting('tmdb.password') == '': control.notification(title='default', message=32683, icon='ERROR') return url = self.auth_base_link + '/token/new?api_key=%s' % API_key result = requests.get(url).json() # token = result.get('request_token').encode('utf-8') token = result.get('request_token') url2 = self.auth_base_link + '/token/validate_with_login?api_key=%s' % API_key username = control.setting('tmdb.username') password = control.setting('tmdb.password') post2 = {"username": "******" % username, "password": "******" % password, "request_token": "%s" % token} result2 = requests.post(url2, data=post2).json() url3 = self.auth_base_link + '/session/new?api_key=%s' % API_key post3 = {"request_token": "%s" % token} result3 = requests.post(url3, data=post3).json() if result3.get('success') is True: session_id = result3.get('session_id') msg = '%s' % ('username ='******'[CR]password ='******'[CR]token = ' + token + '[CR]confirm?') if control.yesnoDialog(msg): control.setSetting('tmdb.session_id', session_id) control.notification(title='default', message=32679, icon='default') else: control.notification(title='default', message=32680, icon='ERROR') except: log_utils.error()
def run(self): from datetime import datetime from myaccounts.modules import alldebrid from myaccounts.modules import premiumize from myaccounts.modules import realdebrid xbmc.log( '[ script.module.myaccounts ] Debrid Account Expiry Notification Service Starting...', LOGNOTICE) self.duration = [(15, 10), (11, 7), (8, 4), (5, 2), (3, 0)] if control.setting('alldebrid.username') != '' and control.setting( 'alldebrid.expiry.notice') == 'true': account_info = alldebrid.AllDebrid().account_info()['user'] if account_info: if not account_info['isSubscribed']: # log_utils.log('AD account_info = %s' % account_info, log_utils.LOGNOTICE) expires = datetime.fromtimestamp( account_info['premiumUntil']) days_remaining = (expires - datetime.today()).days # int if self.withinRangeCheck('alldebrid', days_remaining): control.notification( message='AllDebrid Account expires in %s days' % days_remaining, icon=control.joinPath(control.artPath(), 'alldebrid.png')) if control.setting('premiumize.username') != '' and control.setting( 'premiumize.expiry.notice') == 'true': account_info = premiumize.Premiumize().account_info() if account_info: # log_utils.log('PM account_info = %s' % account_info, log_utils.LOGNOTICE) expires = datetime.fromtimestamp(account_info['premium_until']) days_remaining = (expires - datetime.today()).days # int if self.withinRangeCheck('premiumize', days_remaining): control.notification( message='Premiumize.me Account expires in %s days' % days_remaining, icon=control.joinPath(control.artPath(), 'premiumize.png')) if control.setting('realdebrid.username') != '' and control.setting( 'realdebrid.expiry.notice') == 'true': account_info = realdebrid.RealDebrid().account_info() if account_info: import time # log_utils.log('RD account_info = %s' % account_info, log_utils.LOGNOTICE) FormatDateTime = "%Y-%m-%dT%H:%M:%S.%fZ" try: expires = datetime.strptime(account_info['expiration'], FormatDateTime) except: expires = datetime(*(time.strptime( account_info['expiration'], FormatDateTime)[0:6])) days_remaining = (expires - datetime.today()).days # int if self.withinRangeCheck('realdebrid', days_remaining): control.notification( message='Real-Debrid Account expires in %s days' % days_remaining, icon=control.joinPath(control.artPath(), 'realdebrid.png'))
def refresh_token(self): traktToken = None traktRefresh = None traktExpires = None data = { "client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", "grant_type": "refresh_token", "refresh_token": control.setting('trakt.refresh') } response = self.call("oauth/token", data=data, with_auth=False, return_str=True) try: code = str(response[1]) except: code = '' if code.startswith('5') or ( response and isinstance(response, py_tools.string_types) and '<html' in response ) or not response: # covers Maintenance html responses ["Bad Gateway", "We're sorry, but something went wrong (500)"]) log_utils.log('Temporary Trakt Server Problems', level=log_utils.LOGNOTICE) control.notification(title=32315, message=33676) return False elif response and code in ['423']: log_utils.log('Locked User Account - Contact Trakt Support: %s' % str(response[0]), level=log_utils.LOGWARNING) control.notification(title=32315, message=33675) return False if response and code not in ['401', '405']: try: response = response.json() except: log_utils.error() return False if 'error' in response and response['error'] == 'invalid_grant': log_utils.log('Please Re-Authorize your Trakt Account: %s' % response['error'], __name__, level=log_utils.LOGWARNING) control.notification(title=32315, message=33677) return False traktToken = response["access_token"] traktRefresh = response["refresh_token"] traktExpires = time.time() + 7776000 control.setSetting('trakt.token', traktToken) control.setSetting('trakt.refresh', traktRefresh) control.setSetting('trakt.expires', str(traktExpires)) self.token = traktToken
def upload_LogFile(): from myaccounts.modules.control import notification url = 'https://paste.kodi.tv/' log_file = joinPath(LOGPATH, 'myaccounts.log') if not existsPath(log_file): return notification( message='Log File not found, likely logging is not enabled.') try: import requests from myaccounts.modules.control import addonVersion, selectDialog f = open(log_file, 'r', encoding='utf-8', errors='ignore') text = f.read() f.close() UserAgent = 'MyAccounts %s' % addonVersion() response = requests.post(url + 'documents', data=text.encode('utf-8', errors='ignore'), headers={'User-Agent': UserAgent}) # log('log_response: ' + str(response)) if 'key' in response.json(): result = url + response.json()['key'] log('My Accounts log file uploaded to: %s' % result) from sys import platform as sys_platform supported_platform = any(value in sys_platform for value in ['win32', 'linux2']) highlight_color = 'gold' list = [ ('[COLOR %s]url:[/COLOR] %s' % (highlight_color, str(result)), str(result)) ] if supported_platform: list += [('[COLOR %s] -- Copy url To Clipboard[/COLOR]' % highlight_color, ' ')] select = selectDialog([i[0] for i in list], lang(32349)) if 'Copy url To Clipboard' in list[select][0]: copy2clip(list[select - 1][1]) elif 'message' in response.json(): notification(message='myaccounts Log upload failed: %s' % str(response.json()['message'])) log('My Accounts Log upload failed: %s' % str(response.json()['message']), level=LOGERROR) else: notification(message='myaccounts Log upload failed') log('My Accounts Log upload failed: %s' % response.text, level=LOGERROR) except: error('My Accounts log upload failed') notification(message='pastebin post failed: See log for more info')
def view_LogFile(name): try: from myaccounts.windows.textviewer import TextViewerXML from myaccounts.modules.control import addonPath log_file = joinPath(LOGPATH, '%s.log' % name.lower()) if not existsPath(log_file): from myaccounts.modules.control import notification return notification( message='Log File not found, likely logging is not enabled.') f = open(log_file, 'r', encoding='utf-8', errors='ignore') text = f.read() f.close() heading = '[B]%s - LogFile[/B]' % name windows = TextViewerXML('textviewer.xml', addonPath(), heading=heading, text=text) windows.run() del windows except: error()
elif action == 'ShowChangelog': from myaccounts.modules import changelog changelog.get() elif action == 'ShowHelp': from myaccounts.help import help help.get(params.get('name')) elif action == 'ShowOKDialog': control.okDialog(params.get('title', 'default'), int(params.get('message', ''))) elif action == 'tools_clearLogFile': from myaccounts.modules import log_utils cleared = log_utils.clear_logFile() if cleared == 'canceled': pass elif cleared: control.notification( message='My Accounts Log File Successfully Cleared') else: control.notification( message= 'Error clearing My Accounts Log File, see kodi.log for more info') elif action == 'tools_viewLogFile': from myaccounts.modules import log_utils log_utils.view_LogFile(params.get('name')) elif action == 'tools_uploadLogFile': from myaccounts.modules import log_utils log_utils.upload_LogFile()
def error_notification(line1, error): if suppress_error_notification: return return control.notification(title='default', message='%s: %s' % (line1, error), icon=trakt_icon)