def _set_dir(self): profile = xbmc.translatePath('special://profile/') self.profile = os.path.join(profile, 'addon_data', config.addon.getAddonInfo('id')) self.cache = os.path.join(self.profile, 'cache') self.resources = xbmc.translatePath( os.path.join(config.path.base, 'resources')) self.image = xbmc.translatePath( os.path.join(config.path.resources, 'img', 'theme', 'default')) self.combined_covers = os.path.join(self.profile, 'combined_covers')
def SaveCookies(session, cookies_name="tmp_cookies"): try: path = xbmc.translatePath(os.path.join(TMP_FOLDER, cookies_name)) session.cookies.save(filename=path, ignore_discard=True, ignore_expires=True) xbmc.log("Cookies saved!",1) except Exception as e: pass
def delete_playlists(self): ''' Remove all jellyfin playlists. ''' path = xbmc.translatePath("special://profile/playlists/video/") _, files = xbmcvfs.listdir(path) for file in files: if file.startswith('jellyfin'): self.delete_playlist(os.path.join(path, file))
def save_obj(self, obj, name): folder = xbmc.translatePath(self.addon.getAddonInfo('profile')) self.log("Saving: " + folder + name + '.ecdata') with open(folder + name + '.ecdata', 'wb') as f: try: f.write(self.encrypt_credential_v1(json.dumps(obj))) except TypeError: f.write(bytes(self.encrypt_credential_v1(json.dumps(obj)), 'utf8'))
def _ia_cdm_path(cls): """Return the specified CDM path for inputstream.adaptive.""" addon = xbmcaddon.Addon('inputstream.adaptive') cdm_path = xbmc.translatePath(addon.getSetting('DECRYPTERPATH')) if not xbmcvfs.exists(cdm_path): xbmcvfs.mkdir(cdm_path) return cdm_path
def githubSelect(name): from packlib import githubissues githubissues.run('tvaddonsco/plugin.video.adultflix', '%s' % name) file = xbmc.translatePath( os.path.join(kodi.datafolder, '%s-issues-%s.csv' % (kodi.get_id(), name))) global msg_text with open(file, mode='r') as f: txt = f.read() items = re.findall('<item>(.+?)</item>', txt, re.DOTALL) if len(items) < 1: msg_text = kodi.giveColor( 'No %s issues with AdultFlix at this time.' % name.title(), 'deeppink', True) else: msg_text = kodi.giveColor( '%s Issues with AdultFlix\n' % name.title(), 'deeppink', True ) + kodi.giveColor( 'Report Issues @ https://github.com/tvaddonsco/plugin.video.adultflix/issues', 'white', True) + '\n---------------------------------\n\n' for item in items: try: id = re.findall('<id>([^<]+)', item)[0] except: id = 'Unknown' try: user = re.findall('<username>([^<]+)', item)[0] except: user = '******' try: label = re.findall('<label>([^<]+)', item)[0] except: label = 'Unknown' try: title = re.findall('<title>([^<]+)', item)[0] except: title = 'Unknown' try: body = re.findall('<body>([^<]+)', item)[0] except: body = 'Unknown' try: created = re.findall('<created>([^<]+)', item)[0] date, time = created.split('T') except: date = 'Unknown' time = 'Unknwon' msg_text += '[B]ID: %s | Label: %s \nBy: %s on %s at %s[/B] \n\nTitle: %s \nMessage %s \n\n---------------------------------\n\n' \ % (id, kodi.githubLabel(label), user, date, time.replace('Z', ''), title, body)
def __init__(self, transcode=False, delete=False): try: self.kodi_id = sys.listitem.getVideoInfoTag().getDbId() or None self.media = self.get_media_type() self.server_id = sys.listitem.getProperty('jellyfinserver') or None self.api_client = Jellyfin(self.server_id).get_client().jellyfin item_id = sys.listitem.getProperty('jellyfinid') except AttributeError: self.server_id = None if xbmc.getInfoLabel('ListItem.Property(jellyfinid)'): item_id = xbmc.getInfoLabel('ListItem.Property(jellyfinid)') else: self.kodi_id = xbmc.getInfoLabel('ListItem.DBID') self.media = xbmc.getInfoLabel('ListItem.DBTYPE') item_id = None addon_data = xbmc.translatePath( "special://profile/addon_data/plugin.video.jellyfin/data.json") with open(addon_data, 'rb') as infile: data = json.load(infile) try: server_data = data['Servers'][0] self.api_client.config.data['auth.server'] = server_data.get( 'address') self.api_client.config.data['auth.server-name'] = server_data.get( 'Name') self.api_client.config.data['auth.user_id'] = server_data.get( 'UserId') self.api_client.config.data['auth.token'] = server_data.get( 'AccessToken') except Exception as e: LOG.warning('Addon appears to not be configured yet: {}'.format(e)) if self.server_id or item_id: self.item = self.api_client.get_item(item_id) else: self.item = self.get_item_id() if self.item: if transcode: self.transcode() elif delete: self.delete_item() elif self.select_menu(): self.action_menu() if self._selected_option in (OPTIONS['Delete'], OPTIONS['AddFav'], OPTIONS['RemoveFav']): xbmc.sleep(500) xbmc.executebuiltin('Container.Refresh')
def list_all(self, current_archive_file=None, current_directory_out=None): files_out = list() if current_archive_file is None: current_archive_file = self.archive_file if current_directory_out is None: current_directory_out = self.directory_out if current_archive_file is not None: if current_directory_out is None: #Default to the same directory as the current_archive_file directory_to = os.path.join( os.path.split(xbmc.translatePath(current_archive_file))[0], '') else: directory_to = os.path.join( xbmc.translatePath(current_directory_out), '') if 'archive://' in current_archive_file or 'rar://' in current_archive_file: archive_path = current_archive_file else: if self.use_vfs_rar: archive_path = 'rar://%(archive_file)s' % { 'archive_file': url_quote(xbmc.translatePath(current_archive_file)) } else: archive_path = 'archive://%(archive_file)s' % { 'archive_file': url_quote(xbmc.translatePath(current_archive_file)) } dirs_in_archive, files_in_archive = xbmcvfs.listdir(archive_path) for ff in files_in_archive: file_from = os.path.join(archive_path, ff).replace( '\\', '/' ) #Windows unexpectedly requires a forward slash in the path files_out.append( file_from) #Append the file to the list of extracted files for dd in dirs_in_archive: files_out2 = self.list_all( current_archive_file=os.path.join(archive_path, dd, '').replace('\\', '/'), current_directory_out=os.path.join(directory_to, dd)) files_out = files_out + files_out2 #Append the files in the subdir to the list of extracted files return files_out
def get_nodes(self): ''' Set up playlists, video nodes, window prop. ''' node_path = xbmc.translatePath("special://profile/library/video") playlist_path = xbmc.translatePath("special://profile/playlists/video") index = 0 with Database('jellyfin') as jellyfindb: db = jellyfin_db.JellyfinDatabase(jellyfindb.cursor) for library in self.sync['Whitelist']: library = library.replace('Mixed:', "") view = db.get_view(library) if view: view = {'Id': library, 'Name': view[0], 'Tag': view[0], 'Media': view[1]} if view['Media'] == 'mixed': for media in ('movies', 'tvshows'): temp_view = dict(view) temp_view['Media'] = media self.add_playlist(playlist_path, temp_view, True) self.add_nodes(node_path, temp_view, True) else: # Compensate for the duplicate. index += 1 else: if view['Media'] in ('movies', 'tvshows', 'musicvideos'): self.add_playlist(playlist_path, view) if view['Media'] not in ('music',): self.add_nodes(node_path, view) index += 1 for single in [{'Name': translate('fav_movies'), 'Tag': "Favorite movies", 'Media': "movies"}, {'Name': translate('fav_tvshows'), 'Tag': "Favorite tvshows", 'Media': "tvshows"}, {'Name': translate('fav_episodes'), 'Tag': "Favorite episodes", 'Media': "episodes"}]: self.add_single_node(node_path, index, "favorites", single) index += 1 self.window_nodes()
def __init__(self): self.path = xbmc.translatePath(__addon__.getAddonInfo("profile")) if not xbmcvfs.exists(self.path): logger.debug("Making path structure: %s" % repr(self.path)) xbmcvfs.mkdir(self.path) self.path = os.path.join(self.path, 'queue.db') self._connection_cache = {} with self._get_conn() as conn: conn.execute(self._create)
def clean_sub_cache(self, silent=True): import shutil subs_folder = xbmc.translatePath(self.addon.getAddonInfo('profile')) subs_folder = subs_folder + 'subs' shutil.rmtree(subs_folder, ignore_errors=True) if not silent: icon = self.get_resource("icon.png") xbmcgui.Dialog().notification(self.language(30726), self.LB_INFO, icon)
def SaveCookies(session, cookies_name="tmp_cookies"): try: path = xbmc.translatePath(os.path.join(TMP_FOLDER, cookies_name)) session.cookies.save(filename=path, ignore_discard=True, ignore_expires=True) xbmc.log("Cookies saved!", 1) except Exception as e: pass
def run(REPO, STATE): """ Exports Issues from a specified repository to a CSV file Uses basic authentication (Github username + password) to retrieve Issues from a repository that username has access to. Supports Github API v3. """ ISSUES_FOR_REPO_URL = 'http://api.github.com/repos/%s/issues?state=%s' % ( REPO, STATE) def write_issues(response): "output a list of issues to csv" if not r.status_code == 200: raise Exception(r.status_code) for issue in r.json(): username = issue.get("user", {}).get('login', {}) if issue['labels']: labels = issue['labels'] for label in labels: # if label['name'] == "Client Requested": csvout.writerow([ '\n<item>\n<id>' + str(issue['number']) + '</id>\n<username>' + username + '</username>\n<label>' + label['name'] + '</label>\n<title>' + issue['title'].encode('utf-8') + '</title>\n<body>' + issue['body'].encode('utf-8') + '</body>\n<created>' + issue['created_at'] + '</created>\n</item>\n' ]) else: csvout.writerow([ '\n<item>\n<id>' + str(issue['number']) + '</id>\n<username>' + username + '</username>\n<label>No Label</label>\n<title>' + issue['title'].encode('utf-8') + '</title>\n<body>' + issue['body'].encode('utf-8') + '</body>\n<created>' + issue['created_at'] + '</created>\n</item>\n' ]) r = requests.get(ISSUES_FOR_REPO_URL, verify=False) csvfile = xbmc.translatePath( os.path.join(kodi.datafolder, '%s-issues-%s.csv' % (kodi.get_id(), STATE))) csvout = csv.writer(open(csvfile, 'wb')) write_issues(r) # more pages? examine the 'link' header returned if 'link' in r.headers: pages = dict([ (rel[6:-1], url[url.index('<') + 1:-1]) for url, rel in [link.split(';') for link in r.headers['link'].split(',')] ]) while 'last' in pages and 'next' in pages: r = requests.get(pages['next']) write_issues(r) if pages['next'] == pages['last']: break
def readLastRun(self): if (self.last_run == 0): # read it in from the settings if (xbmcvfs.exists( xbmc.translatePath(utils.data_dir() + "last_run.txt"))): runFile = xbmcvfs.File( xbmc.translatePath(utils.data_dir() + "last_run.txt")) try: # there may be an issue with this file, we'll get it the next time through self.last_run = float(runFile.read()) except ValueError: self.last_run = 0 runFile.close() else: self.last_run = 0
def _test_file(name): global _profile_ try: f = open(xbmc.translatePath(os.path.join(_profile_, name)), 'r') except IOError: return False else: f.close() return True
def load_obj(self, name): folder = xbmc.translatePath(self.addon.getAddonInfo('profile')) self.log("Trying to load: " + folder + name + '.ecdata') try: with open(folder + name + '.ecdata', 'rb') as f: return json.loads(self.decrypt_credential_v1(f.read())) except Exception: self.log("OBJECT RELOAD ERROR") self.log("Stack trace: " + traceback.format_exc()) return None
def __init__(self, output_path=None, forced=False): self.output_path = output_path or xbmc.translatePath( settings.get('output_dir', '').strip() or ADDON_PROFILE) if not os.path.exists(self.output_path): os.makedirs(self.output_path) self.forced = forced self.tmp_file = os.path.join(self.output_path, 'iptv_merge_tmp') self.integrations = get_integrations() self._playlist_epgs = []
def set_info_controls(self): Background = pyxbmct.Image( xbmc.translatePath( os.path.join('special://home/addons/script.adultflix.artwork', 'resources/art/dialog/bg.jpg'))) self.placeControl(Background, 0, 0, 10, 30) self.textbox = pyxbmct.TextBox() self.placeControl(self.textbox, 0, 1, 9, 28) self.textbox.setText(msg_text) self.textbox.autoScroll(1000, 2000, 1000)
def service_thread(): conn = sqlite3.connect(xbmc.translatePath( '%sxmltv.db' % plugin.addon.getAddonInfo('profile')), detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) cursor = conn.cursor() if not check_has_db_filled_show_error_message_ifn(cursor): return refresh()
def translate_path(path): ''' Use new library location for translate path starting in Kodi 19 ''' version = kodi_version() if version > 18: return xbmcvfs.translatePath(path) else: return xbmc.translatePath(path)
def __init__(self, addon): self.log('Creating object') self.dialog = xbmcgui.Dialog() self.addon = addon self.logFile = codecs.open( xbmc.translatePath(r'special://logpath/kodi.log'), 'r', encoding='utf-8', errors='ignore') self.logFileLastSize = 0 #for first run, read from top
def play_external(path): cmd = [plugin.get_setting('external.player', str)] args = plugin.get_setting('external.player.args', str) if args: cmd.append(args) cmd.append(xbmc.translatePath(path)) subprocess.Popen(cmd, shell=windows())
def get_media_url(self, host, media_id): video = None web_url = self.get_url(host, media_id) if xbmc.getCondVisibility( 'System.HasAddon(plugin.googledrive)') and self.get_setting( 'use_gdrive') == "true": addon = xbmcaddon.Addon('plugin.googledrive') if six.PY3: db = xbmcvfs.translatePath( addon.getAddonInfo('profile')) + 'accounts.db' else: db = xbmc.translatePath( addon.getAddonInfo('profile')) + 'accounts.db' conn = sqlite3.connect(db) c = conn.cursor() c.execute("SELECT key FROM store;") driveid = c.fetchone()[0] conn.close() doc_id = re.search(r'[-\w]{25,}', web_url) if doc_id: common.kodi.notify(header=None, msg='Resolving with Google Drive', duration=3000) video = 'plugin://plugin.googledrive/?action=play&content_type=video&driveid={0}&item_id={1}'.format( driveid, doc_id.group(0)) if not video: response, video_urls = self._parse_google(web_url) if video_urls: video_urls.sort(key=self.__key, reverse=True) video = helpers.pick_source(video_urls) if response is not None: res_headers = response.get_headers(as_dict=True) if 'Set-Cookie' in res_headers: self.headers['Cookie'] = res_headers['Set-Cookie'] if not video: if any(url_match in web_url for url_match in self.url_matches): video = self._parse_redirect(web_url, hdrs=self.headers) elif 'googlevideo.' in web_url: video = web_url + helpers.append_headers(self.headers) elif 'plugin://' not in video: if any(url_match in video for url_match in self.url_matches): video = self._parse_redirect(video, hdrs=self.headers) if video: if 'plugin://' in video: # google plus embedded videos may result in this return video else: return video + helpers.append_headers(self.headers) raise ResolverError('File not found')
def safe_copy(src, dst, del_src=False): src = xbmc.translatePath(src) dst = xbmc.translatePath(dst) if not xbmcvfs.exists(src) or same_file(src, dst): return if xbmcvfs.exists(dst): if xbmcvfs.delete(dst): log.debug('Deleted: {}'.format(dst)) else: log.debug('Failed to delete: {}'.format(dst)) if xbmcvfs.copy(src, dst): log.debug('Copied: {} > {}'.format(src, dst)) else: log.debug('Failed to copy: {} > {}'.format(src, dst)) if del_src: xbmcvfs.delete(src)
def iptv_is_setup(): addon = get_addon(IPTV_SIMPLE_ID, required=False, install=False) if not addon: return False output_dir = xbmc.translatePath(settings.get('output_dir', '').strip() or ADDON_PROFILE) playlist_path = os.path.join(output_dir, PLAYLIST_FILE_NAME) epg_path = os.path.join(output_dir, EPG_FILE_NAME) return addon.getSetting('m3uPathType') == '0' and addon.getSetting('epgPathType') == '0' \ and addon.getSetting('m3uPath') == playlist_path and addon.getSetting('epgPath') == epg_path
def nuke(): if not (xbmcgui.Dialog().yesno("IPTV Archive Downloader", addon.getLocalizedString(30057))): return xbmcvfs.delete( xbmc.translatePath('%sxmltv.db' % plugin.addon.getAddonInfo('profile'))) time.sleep(5) full_service()
def showNotification(message, time_ms=3000, icon_path=None, header=ADDON.getAddonInfo('name')): try: icon_path = icon_path or xbmc.translatePath( ADDON.getAddonInfo('icon')).decode('utf-8') xbmc.executebuiltin('Notification({0},{1},{2},{3})'.format( header, message, time_ms, icon_path)) except RuntimeError: # Happens when disabling the addon LOG(message)
def delete_playlist_by_id(self, view_id): ''' Remove playlist based based on view_id. ''' path = xbmc.translatePath("special://profile/playlists/video/") _, files = xbmcvfs.listdir(path) for file in files: file = file if file.startswith('jellyfin') and file.endswith( '%s.xsp' % view_id): self.delete_playlist(os.path.join(path, file))
def menu(): try: url = urljoin(base_domain, 'categories?o=al') c = client.request(url) r = dom_parser2.parse_dom(c, 'li', {'class': 'cat_pic'}) r = [(dom_parser2.parse_dom(i, 'a', req=['href', 'alt']), \ dom_parser2.parse_dom(i, 'var'), \ dom_parser2.parse_dom(i, 'img', req='src')) \ for i in r if i] r = [(urljoin(base_domain, i[0][0].attrs['href']), i[0][0].attrs['alt'], i[1][0].content, i[2][0].attrs['src']) for i in r if i] if (not r): log_utils.log( 'Scraping Error in %s:: Content of request: %s' % (base_name.title(), str(c)), xbmc.LOGERROR) kodi.notify(msg='Scraping Error: Info Added To Log File', duration=6000, sound=True) quit() except Exception as e: log_utils.log( 'Fatal Error in %s:: Error: %s' % (base_name.title(), str(e)), xbmc.LOGERROR) kodi.notify(msg='Fatal Error', duration=4000, sound=True) quit() dirlst = [] for i in r: try: name = kodi.sortX(i[1].encode('utf-8')) name = name.title() + ' - [ %s ]' % i[2].split(' ')[0] fanarts = xbmc.translatePath( os.path.join('special://home/addons/script.adultflix.artwork', 'resources/art/%s/fanart.jpg' % filename)) dirlst.append({ 'name': name, 'url': i[0], 'mode': content_mode, 'icon': i[3], 'fanart': fanarts, 'folder': True }) except Exception as e: log_utils.log( 'Error adding menu item %s in %s:: Error: %s' % (i[1].title(), base_name.title(), str(e)), xbmc.LOGERROR) if dirlst: buildDirectory(dirlst) else: kodi.notify(msg='No Menu Items Found') quit()
def nuke(): if not (xbmcgui.Dialog().yesno( "IPTV Archive Downloader", get_string("Delete Everything and Start Again?"))): return xbmcvfs.delete( xbmc.translatePath('%sxmltv.db' % plugin.addon.getAddonInfo('profile'))) time.sleep(5) full_service()
def get_streamurl(add_url): PLog("get_streamurl:") streamurl = '' ID = '' PLog(add_url[:100]) ID = get_Source_Funcs_ID(add_url) if ID == '' or ID == "PlayVideo": # PlayVideo: Url liegt schon vor return '' pos = add_url.find('/?action=') MY_SCRIPT_fparams = add_url[pos + 1:] PLog("MY_SCRIPT_fparams: " + MY_SCRIPT_fparams) # Ermittlung Streamquelle + Start PlayVideo bis 'PlayVideo_Start: listitem'. # Bei Bedarf den Flag FLAG_OnlyUrl hierher verlegen und in PlayVideo beachten. # Hinw.: True für blocking call zur Erzeugung der HLS_List + MP4_List durch # MY_SCRIPT MY_SCRIPT = xbmc.translatePath('special://home/addons/%s/ardundzdf.py' % ADDON_ID) xbmc.executebuiltin( 'RunScript(%s, %s, %s)' % (MY_SCRIPT, HANDLE, MY_SCRIPT_fparams), True) hls_list = os.path.join(DICTSTORE, "%s_HLS_List" % ID) mp4_list = os.path.join(DICTSTORE, "%s_MP4_List" % ID) max_cnt = 0 while (1): # file_event: für die schwachbrüstigen Clients sleep(1) max_cnt = max_cnt + 1 PLog("waiting: %d" % max_cnt) if os.path.exists(mp4_list) or os.path.exists(hls_list) or max_cnt > 3: break PLog("strm_ID: " + ID) HLS_List = Dict("load", "%s_HLS_List" % ID) PLog("strm_HLS_List: " + str(HLS_List[:100])) MP4_List = Dict("load", "%s_MP4_List" % ID) PLog("strm_MP4_List: " + str(MP4_List[:100])) # todo: Dateiflag urlonly setzen/löschen - Übergabe via script unsicher # ev. auch Rückgabe via Datei # Url entspr. Settings holen: title_org = '' img = '' Plot = '' # hier nicht benötigt # s. Beachte im Log: es überschneiden sich MY_SCRIPT und PlayVideo_Direct: open(FLAG_OnlyUrl, 'w').close() # Flag PlayVideo_Direct -> strm-Modul streamurl = PlayVideo_Direct(HLS_List, MP4_List, title_org, img, Plot) PLog("streamurl: " + streamurl) return streamurl
def middleware_convert_sub(response, **kwargs): data = response.stream.content.decode('utf8') reader = detect_format(data) if reader: data = WebVTTWriter().write(reader().read(data)) if ADDON_DEV: path = 'special://temp/convert_sub.middleware' real_path = xbmc.translatePath(path) with open(real_path, 'wb') as f: f.write(data.encode('utf8')) response.stream.content = data.encode('utf8') response.headers['content-type'] = 'text/vtt'
def exitCleanUp(self): if xbmc.Player().isPlayingVideo(): xbmc.Player().stop() self.renderstop = False while self.state == videoState.playing: xbmc.sleep(100) import glob fileNames = glob.glob(xbmc.translatePath('special://temp') + 'knew5/emulate*.png' ) for file in fileNames: try: os.remove(file) except: xbmc.log('Error deleting ' + file) self.exit = True self.close()
def getActivity(self, update=False): if update: url = self.base + '/activity?format=json&updates=1' + self.xnewa.client else: url = self.base + '/activity?format=json' + self.xnewa.client import json print (url) try: json_file = urlopen(url) jsonActivity = json.load(json_file) json_file.close() print(jsonActivity) #xbmc.log(jsonActivity) if 'url' in jsonActivity: import re if jsonActivity['url'] != '': self.nextUrl = re.sub('[^?&]*client[^&]+&*','',jsonActivity['url'],re.UNICODE) m = re.search('seek=(\d+)&', self.nextUrl) if m: seek = int(m.group(1)) self.nextUrl = re.sub('seek=(\d+)&','',self.nextUrl) if 'recording_resume' not in jsonActivity: if self.state == videoState.playing: xbmc.Player().seekTime(seek) return else: jsonActivity['recording_resume'] = seek self.nextUrl = unquote(self.nextUrl) if self.state == videoState.playing: self.skipStop = True self.quickPlayer(jsonActivity) elif 'playlist' in jsonActivity: self.quickPlayer(jsonActivity) elif 'action' in jsonActivity: if jsonActivity['action'] == 'exit': self.exit = True xbmc.sleep(250) import glob fileNames = glob.glob(xbmc.translatePath('special://temp') + 'knew5/emulate*.png' ) for file in fileNames: try: os.remove(file) except: xbmc.log('Leaving ' + file) self.close() return elif 'needsRendering' in jsonActivity: if jsonActivity['needsRendering'] == True: if isinstance(self.t1, Thread): if self.t1.is_alive() and self.state == videoState.playing: xbmc.log('player no render') self.renderstop = False else: self.renderstop = True else: self.renderstop = True self.InControl = False except URLError as err: print(err) self.exit = True self.close() except Exception as err: print(err)
def get_lib_path(self): return xbmc.translatePath( os.path.join(self.get_addon_path(), 'resources', 'lib'))
def get_qobuz_path(self): return xbmc.translatePath(os.path.join(self.get_lib_path(), 'qobuz'))
# -*- coding: utf-8 -*- from __future__ import unicode_literals import requests import requests.utils import urllib, os, re, json, uuid import urlresolver import HTMLParser from cookielib import LWPCookieJar from kodi_six import xbmc from urlresolver.plugins.lib import unwise from urlresolver.plugins.lib import jsunpack from operator import itemgetter from cachecontrol import CacheControl ADDON_FOLDER = xbmc.translatePath('special://home/addons') TMP_FOLDER = xbmc.translatePath('special://temp') WEB_CACHE = xbmc.translatePath(os.path.join(TMP_FOLDER, ".web_cache")) DEVICE_PATH = xbmc.translatePath('special://userdata') SEARCH_HISTORY_PATH = os.path.join(DEVICE_PATH, 'search.p') CID_PATH = os.path.join(DEVICE_PATH, 'cid') CHROME_DESKTOP_AGENTS = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" MOBILE_IOS_AGENTS = "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A366 Safari/600.1.4" DEFAULT_HEADERS = { "User-Agent": CHROME_DESKTOP_AGENTS, "Accept-Encoding": "gzip, deflate, sdch" } GA_MEDIA_TITLE_TEMPLATE = "[Browse MEDIA of] {title} ({quality}) [{mirror}] - Page {page}" GA_MIRROR_TITLE_TEMPLATE = "[Browse MIRROR of] {title} ({quality}) [{mirror}]" GA_EPS_TITLE_TEMPLATE = "[Browse EPS of] {title} ({quality}) [{mirror}]" GA_PLAY_TITLE_TEMPLATE = "[Play] {title} ({quality}) - Part {eps} [{mirror}]"
def LoadCookies(session, cookies_name="tmp_cookies"): try: path = xbmc.translatePath(os.path.join(TMP_FOLDER, cookies_name)) session.cookies.load(filename=path, ignore_discard=True, ignore_expires=True) except Exception as e: pass
def onAction(self, action): try: actionID = action.getId() buttonID = action.getButtonCode() except: return if buttonID & 0x1000000: #these are long presses if actionID not in CONTEXT_MENU and buttonID not in CONTEXT_MENU: return if actionID == ACTION_MOUSE_MOVE: return ignoreKeys = ( 61650, 61651, 127184, 127185, 323749, 323796 ) if buttonID in ignoreKeys: return if not self.ready or self.renderstop: return dt = datetime.datetime.now() now = int(time.mktime(dt.timetuple())) if now == self.recent[0]: if self.recent[1] == 2: xbmc.log('too fast') return self.recent[1] = self.recent[1] + 1 else: self.recent[0] = now self.recent[1] = 0 retval = self.onLiveAction(actionID,buttonID) xbmc.log(str(retval)) if retval == True: return self.renderstop = True self.inControl = True screenFile = xbmc.translatePath('special://temp') + 'knew5/emulate-'+ str(time.time()) + '.png' keyBase = self.base + '/control?time=' + str(now) + '&key=' url = None pauseActivity = True if actionID == ACTION_PLAYER_PLAY: url = keyBase + str(80|0x20000) elif actionID == ACTION_STOP: url = keyBase + str(83|0x20000) self.state = videoState.stopped elif actionID == ACTION_NEXT_ITEM: if buttonID & 0xf046 == 0xf046 : # NextPVR Ctrl-F url = keyBase + str(70|0x20000) else: url = keyBase + str(39|0x20000) elif actionID == ACTION_PREV_ITEM: if '/live?channel=' not in xbmc.Player().getPlayingFile(): url = keyBase + str(37|0x20000) else: # send ctrl-w url = keyBase + str(87|0x20000) elif actionID == ACTION_PLAYER_FORWARD: url = keyBase + str(70|0x20000) elif actionID == ACTION_PLAYER_REWIND: url = keyBase + str(82|0x20000) elif actionID == ACTION_FIRST_PAGE or actionID == ACTION_INFO: #home if self.state == videoState.playing: # send ctrl-b url = keyBase + str(66|0x20000) else: url = keyBase + '36' pauseActivity = False elif buttonID >= 0x2f041 and buttonID <= 0x2f05a: url = keyBase + str(buttonID&0xff) elif buttonID & 0x10000: ctrl = buttonID&0xff if ctrl == 0x50: url = keyBase + str(ctrl|0x20000) elif ctrl == 0x53: url = keyBase + str(ctrl|0x20000) self.renderstop = False xbmc.Player().stop() elif ctrl == 0x4b: url = keyBase + str(ctrl|0x20000) elif ctrl == 0x52: url = keyBase + str(ctrl|0x20000) elif ctrl == 0x82: url = keyBase + str(37|0x20000) elif ctrl == 0x83: url = keyBase + str(39|0x20000) elif ctrl == 0x42: url = keyBase + str(80|0x20000) elif ctrl == 0x46: url = keyBase + str(70|0x20000) elif ctrl == 0x57: url = keyBase + str(87|0x20000) elif ctrl == 0x47: url = keyBase + str(112) elif ctrl == 0x4d and buttonID & 0x30000: myKey = self.getContext() if myKey != None: url = keyBase + myKey elif ctrl == 0x4f: url = keyBase + str(119) elif ctrl == 0x54: url = keyBase + str(113) else: pass #print actionID, buttonID, hex(ctrl), hex(actionID) elif actionID == ACTION_RECORD or actionID == ACTION_QUEUE_ITEM: url = keyBase + str(75|0x20000) elif actionID == ACTION_PAUSE: url = keyBase + '32' elif buttonID == 0xf02e: url = keyBase + '46' elif actionID in MOVEMENT_LEFT: url = keyBase + '37' elif actionID in MOVEMENT_UP: url = keyBase + '38' if xbmc.Player().isPlayingVideo(): if '/live?channel=' not in xbmc.Player().getPlayingFile() and self.osdMode == False: url = keyBase + str(70|0x20000) else: pauseActivity = False elif actionID in MOVEMENT_RIGHT: url = keyBase + '39' elif actionID in MOVEMENT_DOWN or buttonID == 0xf064: url = keyBase + '40' if xbmc.Player().isPlayingVideo(): if '/live?channel=' not in xbmc.Player().getPlayingFile() and self.osdMode == False: url = keyBase + str(82|0x20000) else: pauseActivity = False elif actionID in MOVEMENT_SCROLL_UP: url = keyBase + '33' elif actionID in MOVEMENT_SCROLL_DOWN: url = keyBase + '34' elif actionID >= 58 and actionID <= 67: url = keyBase + str(actionID-10) elif actionID >= 142 and actionID <= 149: url = keyBase + str(actionID-92) elif actionID == ACTION_SELECT_ITEM: url = keyBase + '13' elif actionID == KEYBOARD_BACK or buttonID == 61575: url = keyBase + '8' elif actionID in EXIT_SCRIPT: url = keyBase + '27' elif actionID in CONTEXT_MENU or buttonID in CONTEXT_MENU or actionID == ACTION_MOUSE_DOUBLE_CLICK: myKey = self.getContext() if myKey != None: url = keyBase + myKey elif actionID == ACTION_TELETEXT_RED: url = keyBase + str(82|0x40000) elif actionID == ACTION_TELETEXT_GREEN: url = keyBase + str(71|0x40000) elif actionID == ACTION_TELETEXT_YELLOW: url = keyBase + str(89|0x40000) elif actionID == ACTION_TELETEXT_BLUE: url = keyBase + str(66|0x40000) elif buttonID >= 0xf030 and buttonID <= 0xf039: url = keyBase + str(buttonID-0xf030+48) elif buttonID >= 0xf041 and buttonID <= 0xf05a: if self.state == videoState.playing and buttonID == 0xf05a: buttonID = 118 url = keyBase + str(buttonID&0xff) elif buttonID >= 0xf090 and buttonID <= 0xf098: url = keyBase + str((buttonID&0xff)-32) elif buttonID == 0xf09b: #F12 exit self.exitCleanUp() elif buttonID == 0x4f092: #alt-f4' url = keyBase + str(0x40073) elif buttonID & 0x40000 or buttonID & 0x20000: buttonID = buttonID | 0x40000 url = keyBase + str(buttonID&0x400ff) elif actionID == 122 or actionID == 999 : if buttonID == 50: #guide url = keyBase + '112' elif buttonID == 49 or buttonID == 101: # recordings url = keyBase + '119' elif buttonID == 24: #live tv url = keyBase + '113' elif buttonID == 7: #my videos url = keyBase + '114' elif buttonID == 9: #my music url = keyBase + '115' elif buttonID == 6: #my pictures url = keyBase + '116' elif buttonID == 248: #my radio url = keyBase + '117' elif buttonID == 44: #subtitle xbmc.executebuiltin('Action( NextSubtitle )') elif buttonID == 196: # power off self.exitCleanUp() pass elif buttonID == 213: #display url = keyBase + '119' else: xbmc.log('remote action unsupported {0} {1}'.format(actionID, buttonID)) pass else: xbmc.log('action unsupported {0} {1}'.format(actionID, buttonID)) pass if url : url = url + self.xnewa.client #while self.rendering: # time.sleep(0.1) xbmc.log(url) try: jpgfile = urlopen(url) output = open(screenFile,'wb') output.write(jpgfile.read()) output.close() jpgfile.close() self.setOSDMode(True) self.image.setImage(screenFile,False) xbmc.sleep(25) except HTTPError as err: xbmc.log(str(err.code)) print(err) except URLError as err: print(err) self.exit = True self.close() except Exception as err: if err.errno != 104 and err.errno != 10054: print(err) self.exit = True self.close() else: xbmc.log('ignoring known error') if pauseActivity: self.getActivity() self.renderstop = False self.inControl = False self.ready = True
def render(self): fullRefresh = 0 while xbmc.abortRequested == False and self.exit == False: if not xbmc.Player().isPlayingVideo(): if self.state == videoState.started: if isinstance(self.t1, Thread): #print self.t1.is_alive(), self.renderstop, self.state, xbmc.Player().isPlayingVideo() if self.t1.isAlive() == False: self.state = videoState.error elif xbmc.Player().isPlayingAudio(): self.state = videoState.inactive if self.renderstop == False: fullRefresh += 1 if fullRefresh < 30 and self.state == videoState.inactive: if self.inControl == False and self.xnewa.sid != None: self.getActivity(True) if self.renderstop == True: self.renderstop = False self.getScreen() self.getActivity() else: fullRefresh = 0 import glob fileNames = glob.glob(xbmc.translatePath('special://temp') + 'knew5/emulate*.png' ) for file in fileNames: try: os.remove(file) except: xbmc.log('Error deleting ' + file) if self.state == videoState.playing or self.state == videoState.error or self.state == videoState.stopped: if self.sdlmode != SDL.disabled: if self.skipStop == False: try: url = self.base + '/control?media=stop' if self.state == videoState.error: url += '&message=Player%20error' url += self.xnewa.client screenFile1 = xbmc.translatePath('special://temp') + 'knew5/emulate-'+ str(time.time()) + '.png' xbmc.log(url) pngfile = urlopen(url) pngfile.close() except Exception as err: print(err) else: self.skipStop = False self.setOSDMode(True) self.sidUpdate() self.state = videoState.inactive url = self.base + '/control?key=131188' + self.xnewa.client xbmc.log(url) try: jpgfile = urlopen(url) screenFile = xbmc.translatePath('special://temp') + 'knew5/emulate-'+ str(time.time()) + '.png' output = open(screenFile,'wb') output.write(jpgfile.read()) output.close() self.image.setImage(screenFile,False) self.getActivity() except err: print(err) xbmc.sleep(1000) else: self.state = videoState.playing if self.sdlmode == SDL.full: if self.wasFullScreen: if xbmc.getCondVisibility('videoplayer.isfullscreen') == 0: self.wasFullScreen = False url = self.base + '/control?move=49x57' + self.xnewa.client screenFile1 = xbmc.translatePath('special://temp') + 'knew5/emulate-a'+ str(time.time()) + '.png' xbmc.log(url) try: pngfile = urlopen(url) output = open(screenFile1,'wb') output.write(pngfile.read()) output.close() pngfile.close() self.image.setImage(screenFile1,False) self.getActivity() except Exception as err: print(err) try: url = self.base + '/control?media=' + str(xbmc.Player().getTime()) + self.xnewa.client screenFile1 = xbmc.translatePath('special://temp') + 'knew5/emulate-'+ str(time.time()) + '.png' xbmc.log(url) request = Request(url) pngfile = urlopen(request) if pngfile.code == 200 and xbmc.getCondVisibility('videoplayer.isfullscreen') == 0: output = open(screenFile1,'wb') output.write(pngfile.read()) output.close() self.image.setImage(screenFile1,False) # needs rendering always true so just self.getActivity() elif pngfile.code == 204: self.setOSDMode(False) else: print(pngfile.code) pngfile.close() self.skipStop = False except Exception as err: print(err) pass xbmc.sleep(1000) return
def getScreen(self, force=False): self.rendering = True self.errors = 0 retval = True try: if force: if self.xnewa.AreYouThere(self.settings.usewol(), self.settings.NextPVR_MAC, self.settings.NextPVR_BROADCAST): url = self.base + '/control?size=' + self.settings.XNEWA_CLIENT_SIZE if self.settings.XNEWA_CLIENT_QUALITY == True: url += '&quality=high' url += self.xnewa.client xbmc.log(url) try: jpgfile = urlopen(url) jpgfile.close if self.sdlmode != SDL.disabled: try: url = self.base + '/control?media=stop' + self.xnewa.client xbmc.log(url) pngfile = urlopen(url) pngfile.close() except Exception as err: print(err) except HTTPError as e: print(e.code) if e.code == 404: xbmc.sleep(500) url = self.base + '/control?media=stop' + self.xnewa.client xbmc.log(url) pngfile = urlopen(url) pngfile.close() self.errors = self.errors + 1 elif e.code == 403: self.sidUpdate() self.getSid() self.errors = self.errors + 1 else: print(e) self.exit = True self.close() return False if self.errors < 3: self.getScreen(force) return False except URLError as err: print(err) self.exit = True self.close() else: self.exit = True self.close() return False screenFile = xbmc.translatePath('special://temp') + 'knew5/emulate-'+ str(time.time()) + '.png' url = self.base + '/control?format=json' + self.xnewa.client #xbmc.log(url) try: self.setOSDMode(True) jpgfile = urlopen(url) output = open(screenFile,'wb') output.write(jpgfile.read()) output.close() self.image.setImage(screenFile,False) except HTTPError as e: xbmc.log(url) xbmc.log(str(e.code)) retval = False except URLError as err: xbmc.log(url) print(err) xbmc.log('Abort emulation') self.exit = True self.close() retval = False except Exception as err: print(err) retval = False self.rendering = False return retval