def remLoginData(info=True): for fn in xbmcvfs.listdir(g.DATA_PATH)[1]: if py2_decode(fn).startswith('cookie'): xbmcvfs.delete(OSPJoin(g.DATA_PATH, fn)) writeConfig('accounts', '') writeConfig('login_name', '') writeConfig('login_pass', '') if info: writeConfig('accounts.lst', '') g.addon.setSetting('login_acc', '') g.dialog.notification(g.__plugin__, getString(30211), xbmcgui.NOTIFICATION_INFO)
def saveUserCookies(cookieJar, cachedUsers=None): if not cookieJar: return cur_user = py2_decode(g.addon.getSetting('login_acc')) users = cachedUsers if cachedUsers else loadUsers() user = [i for i in users if cur_user == i['name']] if not user: return user = user[0] from requests.utils import dict_from_cookiejar as dfcj user['cookie'] = dfcj(cookieJar) saveUsers(users)
def Tivi_Search(query=None, title='Search', pagenr=''): PLog("Tivi_Search:") if query == '': query = ardundzdf.get_query(channel='ZDF') PLog(query) if query == None or query.strip() == '': return "" query_org = query query=py2_decode(query) # decode, falls erf. (1. Aufruf) PLog('Tivi_Search:'); PLog(query); PLog(pagenr); ID='Search' Tivi_Search_PATH = 'https://www.zdf.de/suche?q=%s&from=&to=&sender=ZDFtivi&attrs=&contentTypes=episode&sortBy=date&page=%s' if pagenr == '': # erster Aufruf muss '' sein pagenr = 1 path = Tivi_Search_PATH % (query, pagenr) PLog(path) page, msg = get_page(path=path) searchResult = stringextract('data-loadmore-result-count="', '"', page) # Anzahl Ergebnisse PLog("searchResult: " + searchResult) li = xbmcgui.ListItem() li = home(li, ID='Kinderprogramme') # Home-Button # Der Loader in ZDF-Suche liefert weitere hrefs, auch wenn weitere Ergebnisse fehlen - # dto ZDFtivi if searchResult == '0' or 'class="artdirect"' not in page: query = (query.replace('%252B', ' ').replace('+', ' ')) # quotiertes ersetzen msg1 = 'Keine Ergebnisse (mehr) zu: %s' % query MyDialog(msg1, '', '') return li # anders als bei den übrigen ZDF-'Mehr'-Optionen gibt der Sender Suchergebnisse bereits # seitenweise aus, hier umgesetzt mit pagenr - offset entfällt li, page_cnt = ardundzdf.ZDF_get_content(li=li, page=page, ref_path=path, ID=ID) PLog('li, page_cnt: %s, %s' % (li, page_cnt)) if page_cnt == 'next': # mehr Seiten (Loader erreicht) pagenr = int(pagenr) + 1 query = query_org.replace('+', ' ') path = Tivi_Search_PATH % (query, pagenr) # Debug PLog(pagenr); PLog(path) title = "Mehr Ergebnisse in ZDFtivi suchen zu: >%s<" % query query_org=py2_encode(query_org); fparams="&fparams={'query': '%s', 'pagenr': '%s'}" %\ (quote(query_org), pagenr) addDir(li=li, label=title, action="dirList", dirID="resources.lib.childs.Tivi_Search", fanart=R(ICON_MEHR), thumb=R(ICON_MEHR), fparams=fparams) xbmcplugin.endOfDirectory(HANDLE, cacheToDisc=True)
def __getattr__(self, name): if name in ['MOVIE_PATH', 'TV_SHOWS_PATH']: export = self._g.DATA_PATH if self._gs('enablelibraryfolder') == 'true': export = py2_decode(xbmc.translatePath(self._gs('customlibraryfolder'))) export = OSPJoin(export, 'Movies' if 'MOVIE_PATH' == name else 'TV') return export + '\\' if '\\' in export else export + '/' elif 'Language' == name: # Language settings l = jsonRPC('Settings.GetSettingValue', param={'setting': 'locale.audiolanguage'}) l = xbmc.convertLanguage(l['value'], xbmc.ISO_639_1) l = l if l else xbmc.getLanguage(xbmc.ISO_639_1, False) return l if l else 'en' elif 'playMethod' == name: return int(self._gs('playmethod')) elif 'browser' == name: return int(self._gs('browser')) elif 'MaxResults' == name: return int(self._gs('items_perpage')) elif 'tvdb_art' == name: return self._gs('tvdb_art') elif 'tmdb_art' == name: return self._gs('tmdb_art') elif 'showfanart' == name: return self._gs('useshowfanart') == 'true' elif 'dispShowOnly' == name: return self._gs('disptvshow') == 'true' elif 'payCont' == name: return self._gs('paycont') == 'true' elif 'verbLog' == name: return self._gs('logging') == 'true' elif 'useIntRC' == name: return self._gs('remotectrl') == 'true' elif 'RMC_vol' == name: return self._gs('remote_vol') == 'true' elif 'ms_mov' == name: ms_mov = self._gs('mediasource_movie'); return ms_mov if ms_mov else 'Amazon Movies' elif 'ms_tv' == name: ms_tv = self._gs('mediasource_tv'); return ms_tv if ms_tv else 'Amazon TV' elif 'multiuser' == name: return self._gs('multiuser') == 'true' elif 'DefaultFanart' == name: return OSPJoin(self._g.PLUGIN_PATH, 'fanart.png') elif 'ThumbIcon' == name: return OSPJoin(self._g.PLUGIN_PATH, 'resources', 'thumb.png') elif 'NextIcon' == name: return OSPJoin(self._g.PLUGIN_PATH, 'resources', 'next.png') elif 'HomeIcon' == name: return OSPJoin(self._g.PLUGIN_PATH, 'resources', 'home.png') elif 'wl_order' == name: return ['DATE_ADDED_DESC', 'TITLE_DESC', 'TITLE_ASC'][int('0' + self._gs('wl_order'))] elif 'verifySsl' == name: return self._gs('ssl_verif') == 'false' elif 'OfferGroup' == name: return '' if self.payCont else '&OfferGroups=B0043YVHMY' elif 'wl_export' == name: return self._gs('wl_export') == 'true' elif 'region' == name: return int(self._gs('region')) elif 'proxyaddress' == name: return getConfig('proxyaddress') elif 'subtitleStretch' == name: return self._gs('sub_stretch') == 'true' elif 'subtitleStretchFactor' == name: return [24 / 23.976, 23.976 / 24, 25 / 23.976, 23.976 / 25, 25.0 / 24.0, 24.0 / 25.0][int(self._gs('sub_stretch_factor'))] elif 'audioDescriptions' == name: return self._gs('audio_description') == 'true' elif 'removePosters' == name: return self._gs('pv_episode_thumbnails') == 'true' elif 'useEpiThumbs' == name: return self._gs('tld_episode_thumbnails') == 'true' elif 'bypassProxy' == name: return self._gs('proxy_mpdalter') == 'false' elif 'uhdAndroid' == name: return self._gs('uhd_android') == 'true' elif 'skip_scene' == name: return int('0' + self._gs('skip_scene')) elif 'pagination' == name: return { 'all': self._gs('paginate_everything') == 'true', 'watchlist': self._gs('paginate_watchlist') == 'true', 'collections': self._gs('paginate_collections') == 'true', 'search': self._gs('paginate_search') == 'true' }
def make_filenames(title): PLog('make_filenames:') # erzeugt - hoffentlich - sichere Dateinamen (ohne Extension) # zugeschnitten auf Titelerzeugung in meinen Plugins title = py2_decode(title) fname = transl_umlaute(title) # Umlaute valid_chars = "-_ %s%s" % (string.ascii_letters, string.digits) fname = ''.join(c for c in fname if c in valid_chars) fname = fname.replace(u' ', u'_') return fname
def addLink(name, url, mode, art, plot, genre, date, showcontext, playlist, regexs, total, setCookie='', type=None, year=None): addon_log('addLink: {0}'.format(py2_decode(name))) u = '{0}?{1}'.format( sys.argv[0], urllib.urlencode({ 'url': url, 'name': py2_encode(name), 'fanart': art.get('fanart', ''), 'type': type, 'year': year })) contextMenu = [] liz = xbmcgui.ListItem(name) liz.setInfo(type='Video', infoLabels={ 'Title': name, 'Plot': plot, 'Genre': genre, 'dateadded': date }) liz.setArt(art) liz.setProperty('IsPlayable', 'true') if type == 'movie': contextMenu.append( (getString(39101, globals.addon), 'RunPlugin({0}&mode={1}&filetype=file)'.format(u, 200))) xbmcplugin.setContent(int(sys.argv[1]), 'movies') else: contextMenu.append( (getString(39100, globals.addon), 'RunPlugin({0}&mode={1}&filetype=file)'.format(u, 200))) liz.addContextMenuItems(contextMenu) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url='{0}&mode={1}'.format(u, mode), listitem=liz, totalItems=total)
def _is_remote_filesystem(path): from .utils import log from watchdog.utils import platform if not platform.is_linux(): return False remote_fs_types = ['cifs', 'smbfs', 'nfs', 'nfs4'] escaped_path = encode_path(path.rstrip('/').replace(' ', '\\040')) try: with open('/proc/mounts', 'r') as f: for line in f: _, mount_point, fstype = line.split()[:3] if mount_point == escaped_path: log("[fstype] type is \"%s\" '%s' " % (fstype, py2_decode(path))) return fstype in remote_fs_types log("[fstype] path not in /proc/mounts '%s' " % py2_decode(escaped_path)) return False except (IOError, ValueError) as e: log("[fstype] failed to read /proc/mounts. %s, %s" % (type(e), e)) return False
def getEventPlayInfo(self, event_id, epg_channel_id): # If not Sky news then get details id else use hardcoded playinfo_url if epg_channel_id != '17': r = requests.get('{0}/epgd{1}/web/eventDetail/{2}/{3}/'.format(self.baseUrl, self.baseServicePath, event_id, epg_channel_id)) event_details_link = json.loads(py2_decode(r.text))['detailPage'] # Extract id from details link p = re.compile('/([0-9]*)\.html', re.IGNORECASE) m = re.search(p, event_details_link) playlist_id = m.group(1) playinfo_url = '{0}{1}/multiplatform/web/xml/player_playlist/asset/{2}.xml'.format(self.baseUrl, self.baseServicePath, playlist_id) else: playinfo_url = '{0}{1}/multiplatform/web/xml/player_playlist/ssn/127.xml'.format(self.baseUrl, self.baseServicePath) return self.getPlayInfo(url=playinfo_url)
def arte_Search(query='', nextpage=''): PLog("arte_Search:") if query == '': query = ardundzdf.get_query(channel='phoenix') # unbehandelt PLog(query) query = py2_decode(query) if query == None or query == '': return "" query=py2_encode(query); if nextpage == '': nextpage = '1' path = 'https://www.arte.tv/guide/api/emac/v3/de/web/data/SEARCH_LISTING/?imageFormats=landscape&mainZonePage=1&query=%s&page=%s&limit=20' %\ (quote(query), nextpage) page, msg = get_page(path=path, do_safe=False) # ohne quote in get_page (api-Call) if page == '': msg1 = 'Fehler in Suche: %s' % query msg2 = msg MyDialog(msg1, msg2, '') return li PLog(len(page)) li = xbmcgui.ListItem() li = home(li, ID='arte') # Home-Button PLog(len(page)) # page = page.replace('\\u002F', '/') # hier nicht erf. page = page.replace('\\"', '*') # Bsp. "\"Brisant\"" nexturl = stringextract('nextPage":', ',', page) # letzte Seite: "", auch "null," möglich nextpage = stringextract('page=', '&', nexturl) PLog("nextpage: " + nextpage) li = GetContent(li, page, ID='SEARCH') if nextpage: img = R(ICON_MEHR) title = u"Weitere Beiträge" tag = u"weiter zu Seite %s" % nextpage query=py2_encode(query); fparams="&fparams={'query': '%s', 'nextpage': '%s'}" % (quote(query), nextpage) addDir(li=li, label=title, action="dirList", dirID="resources.lib.arte.arte_Search", fanart=img, thumb=img, fparams=fparams, tagline=tag) xbmcplugin.endOfDirectory(HANDLE, cacheToDisc=True)
def get_setting(key, converter=str, choices=None): value = ADDON.getSetting(id=key) if converter is six.text_type or converter is str: return py2_decode(value) elif converter is bool: return value == 'true' elif converter is int: return int(value) elif isinstance(choices, (list, tuple)): return choices[int(value)] else: raise TypeError('Acceptable converters are str, unicode, bool and ' 'int. Acceptable choices are instances of list ' ' or tuple.')
def warning(text, title='Zattoo Live TV', time=4500, exit=False): import xbmc import xbmcaddon import os.path icon = py2_decode( os.path.join( xbmc.translatePath( xbmcaddon.Addon('plugin.video.zattoo_com').getAddonInfo( 'path')), 'icon.png')) xbmc.executebuiltin('Notification(%s, %s, %d, %s)' % (title, text, time, icon)) if exit: import sys sys.exit(0)
def add_to_search_history(self, itm): cur = self.db.cursor() self.log("Database: add " + itm + " to search_history") try: cur.execute( "INSERT INTO search_history(search_query) VALUES (?)", (py2_decode(itm), ), ) self.db.commit() return True except Exception: self.log("Add to search history WARNING: " + traceback.format_exc()) return False
def getPlayInfo(self, id='', url=''): ns = {'media': 'http://search.yahoo.com/mrss/', 'skyde': 'http://sky.de/mrss_extensions/'} # If no url is given we assume that the url hast to be build with the id if url == '': url = '{0}{1}/multiplatform/web/xml/player_playlist/asset/{2}.xml'.format(self.baseUrl, self.baseServicePath, id) r = requests.get(url) tree = ET.ElementTree(ET.fromstring(py2_decode(r.text))) root = tree.getroot() manifest_url = root.find('channel/item/media:content', ns).attrib['url'] apix_id = root.find('channel/item/skyde:apixEventId', ns).text package_code = root.find('channel/item/skyde:packageCode', ns).text return {'manifestUrl': manifest_url, 'apixId': apix_id, 'duration': 0, 'package_code': package_code}
def onNotification(self, sender, method, data): log.debug('{0}.onNotification({1}, {2}, {3})'.format( self, sender, method, py2_decode(data))) if PY2: data_base64 = base64.b64encode(data) else: data_base64 = base64.b64encode(data.encode("utf-8")) try: urllib_request.urlopen( "%s/notification?sender=%s&method=%s&data=%s" % (ELEMENTUMD_HOST, sender, method, data_base64)) except: pass
def build_textlist(PLAYLIST): PLog('build_textlist:') new_list = [] cnt = 1 save_new = False # altes Format überschreiben for item in PLAYLIST: title, url, thumb, Plot, status = item.split('###') Plot = py2_decode(Plot) title = py2_decode(title) my_line = u"%s. %s.." % (str(cnt).zfill(3), title[:60] ) # Color in Textviewer o. Wirkung if Plot: my_line = u"%s | %s.." % (my_line, Plot[:60]) my_line = "%s | Status: %s" % (my_line, status) my_line = my_line.replace('|||', ' | ') my_line = my_line.replace('| |', ' | ') my_line = cleanmark(my_line) new_list.append(my_line) cnt = cnt + 1 new_list = "\n".join(new_list) new_list = py2_encode(new_list) return new_list
def getCurrentEvent(self, epg_channel_id): # Save date for fure use now = datetime.datetime.now() current_date = now.strftime('%d.%m.%Y') # Get Epg information xbmc.log('[Sky Go] eventlisturl = {0}/epgd{1}/web/eventList/{2}/{3}/'.format(self.baseUrl, self.baseServicePath, current_date, epg_channel_id)) r = requests.get('{0}/epgd{1}/web/eventList/{2}/{3}/'.format(self.baseUrl, self.baseServicePath, current_date, epg_channel_id)) events = json.loads(py2_decode(r.text))[epg_channel_id] for event in events: start_date = datetime.datetime(*('{0} {1}'.format(time.strptime(event['startDate'], event['startTime'], '%d.%m.%Y %H:%M')[0:6]))) end_date = datetime.datetime(*('{0} {1}'.format(time.strptime(event['endDate'], event['endTime'], '%d.%m.%Y %H:%M')[0:6]))) # Check if event is running event if start_date < now < end_date: return event # Return False if no current running event return False
def decrypt_credential_v1(self, enc): try: enc = Util.base64dec_bytes(enc) iv = enc[:AES.block_size] cipher = AES.new(self.get_device_id_v1(), AES.MODE_CBC, iv) if sys.version_info < (3, 0): return py2_decode( Padding.unpad(padded_data=cipher.decrypt( enc[AES.block_size:]), block_size=32)) return Padding.unpad(padded_data=cipher.decrypt( enc[AES.block_size:]), block_size=32).decode('utf8') except Exception: self.log("Decrypt credentials error: " + traceback.format_exc()) return None
def loadUser(key='', empty=False, cachedUsers=None): cur_user = py2_decode(g.addon.getSetting('login_acc')) users = cachedUsers if cachedUsers else loadUsers() user = None if empty else [i for i in users if cur_user == i['name']] if user: user = user[0] if key and key not in user.keys(): user = getTerritory(user) if False is user[1]: g.dialog.notification(g.__plugin__, getString(30219), xbmcgui.NOTIFICATION_ERROR) user = user[0] addUser(user) return user.get(key, user) else: return def_keys.get(key, def_keys)
def sendLogin(self, username, password): # Try to login if not re.match(r'^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$', username): loginKey = 'customerCode' else: loginKey = 'email' r = self.session.get('https://www.skygo.sky.de/SILK/services/public/session/login?{0}'.format(urlencode({ 'version': '12354', 'platform': 'web', 'product': 'SG', loginKey: username, 'password': self.decode(password), 'remMe': True }))) # Parse json return json.loads(py2_decode(r.text[3:-1]))
def _ParseBaseRequest(self, method): """Return path, headers and post data commonly required by all methods""" try: from urllib.parse import unquote, urlparse, parse_qsl except ImportError: from urlparse import unquote, urlparse, parse_qsl path = py2_decode(urlparse(self.path).path[1:]) # Get URI without the trailing slash path = path.split('/') # license/<asin>/<ATV endpoint> Log('[PS] Requested {} path {}'.format(method, path), Log.DEBUG) # Retrieve headers and data headers = {k: self.headers[k] for k in self.headers if k not in ['host', 'content-length']} data_length = self.headers.get('content-length') data = {k: v for k, v in parse_qsl(self.rfile.read(int(data_length)))} if data_length else None return (path, headers, data)
def transl_json(line): # json-Umlaute übersetzen # Vorkommen: Loader-Beiträge ZDF/3Sat (ausgewertet als Strings) # Recherche Bsp.: https://www.compart.com/de/unicode/U+00BA # line= py2_decode(line) for r in ((u'\\u00E4', u"ä"), (u'\\u00C4', u"Ä"), (u'\\u00F6', u"ö") , (u'\\u00C6', u"Ö"), (u'\\u00D6', u"Ö"),(u'\\u00FC', u"ü"), (u'\\u00DC', u'Ü') , (u'\\u00DF', u'ß'), (u'\\u0026', u'&'), (u'\\u00AB', u'"') , (u'\\u00BB', u'"') , (u'\xc3\xa2', u'*') # a mit Circumflex: â<U+0088><U+0099> bzw. \xc3\xa2 , (u'u00B0', u' Grad') # u00BA -> Grad (3Sat, 37 Grad) , (u'u00EA', u'e') # 3Sat: Fête , (u'u00E9', u'e') # 3Sat: Fabergé , (u'u00E6', u'ae')): # 3Sat: Kjaerstad line = line.replace(*r) return line
def listPath(self, path): page = {} # path = path.replace('ipad', 'web') r = self.skygo.session.get('{0}{1}'.format(self.skygo.baseUrl, path)) if self.common.get_dict_value(r.headers, 'content-type').startswith('application/json'): page = loads(py2_decode(r.text)) else: xbmcplugin.endOfDirectory(self.common.addon_handle, cacheToDisc=True) return False if 'sort_by_lexic_p' in path: url = self.common.build_url({'action': 'listPage', 'path': '{0}header.json'.format(path[0:path.index('sort_by_lexic_p')])}) self.addDir('[A-Z]', url) listitems = self.parseListing(page, path) self.listAssets(listitems) xbmcplugin.endOfDirectory(self.common.addon_handle, cacheToDisc=True)
def getLocalizedLabel(label): try: if "LOCALIZE" not in label: return label if ";;" not in label and label.endswith(']'): return getLocalizedString(int(label[9:-1])) else: parts = label.split(";;") translation = getLocalizedString(int(parts[0][9:14])) for i, part in enumerate(parts[1:]): if part[0:8] == "LOCALIZE": parts[i + 1] = getLocalizedString(int(part[9:14])) return (py2_encode( py2_decode(translation, 'utf-8', 'replace') % tuple(parts[1:]), 'utf-8', 'ignore')) except: return label
def listEpisodesFromSeason(self, series_id, season_id): url = '{0}{1}/multiplatform/ipad/json/details/series/{2}_global.json'.format(self.skygo.baseUrl, self.skygo.baseServicePath, series_id) r = self.skygo.session.get(url) if self.common.get_dict_value(r.headers, 'content-type').startswith('application/json'): data = loads(py2_decode(r.text))['serieRecap']['serie'] xbmcplugin.setContent(self.common.addon_handle, 'episodes') for season in data['seasons']['season']: if str(season['id']) == str(season_id): for episode in season['episodes']['episode']: # Check Altersfreigabe / Jugendschutzeinstellungen parental_rating = 0 if 'parental_rating' in episode: parental_rating = episode['parental_rating']['value'] if self.js_showall == 'false': if not self.skygo.parentalCheck(parental_rating, play=False): continue li = xbmcgui.ListItem() li.setProperty('IsPlayable', 'true') li.addContextMenuItems([ ('Aktualisieren', 'RunPlugin({0})'.format(self.common.build_url({'action': 'refresh'}))), self.getWatchlistContextItem({'type': 'Episode', 'data': episode}) ], replaceItems=False) info, episode = self.getInfoLabel('Episode', episode) li.setInfo('video', info) li.setLabel(episode.get('li_label') if episode.get('li_label', None) else info['title']) # li = self.addStreamInfo(li, episode) if episode.get('webplayer_config', {}).get('assetThumbnail'): thumb = episode.get('webplayer_config', {}).get('assetThumbnail') else: thumb = episode.get('main_picture').get('picture')[len(episode.get('main_picture').get('picture')) - 1] thumb = '{0}/{1}'.format(thumb.get('path'), thumb.get('file')) art = {'poster': '{0}{1}|User-Agent={2}'.format(self.skygo.baseUrl, season['path'], self.skygo.user_agent), 'fanart': self.getHeroImage(data), 'thumb': '{0}{1}|User-Agent={2}'.format(self.skygo.baseUrl, thumb, self.skygo.user_agent) } li.setArt(art) url = self.common.build_url({'action': 'playVod', 'vod_id': episode['id'], 'infolabels': info, 'parental_rating': parental_rating, 'art': art}) xbmcplugin.addDirectoryItem(handle=self.common.addon_handle, url=url, listitem=li, isFolder=False) xbmcplugin.addSortMethod(self.common.addon_handle, sortMethod=xbmcplugin.SORT_METHOD_EPISODE) xbmcplugin.endOfDirectory(self.common.addon_handle, cacheToDisc=True)
def delStream(path, provider, isShow): streams = [] addon_log('delStream: path = {0}, provider = {1}, isShow = {2}'.format(py2_decode(path), py2_decode(provider), isShow)) try: args = {'sqliteDB': settings.DATABASE_SQLLITE_OSMOSIS_MOVIE_FILENAME_AND_PATH, 'mysqlDBType': 'Movies'} if not isShow \ else {'sqliteDB': settings.DATABASE_SQLLITE_OSMOSIS_TVSHOW_FILENAME_AND_PATH, 'mysqlDBType': 'TVShows'} con, cursor = openDB(**args) path = invCommas(path) if isShow == False: query = 'SELECT movies.title FROM movies WHERE movies.id IN (SELECT stream_ref.mov_id FROM stream_ref WHERE stream_ref.mov_id IN (SELECT movies.id FROM movies WHERE movies.filePath like \'{0}\') and stream_ref.provider like \'{1}\');' else: query = 'SELECT stream_ref.seasonEpisode FROM stream_ref WHERE stream_ref.show_id IN (SELECT shows.id FROM shows WHERE shows.filePath like \'{0}\') and stream_ref.provider like \'{1}\';' args = [path, provider] addon_log('delStream: query = {0}'.format(query.format(*args))) cursor.execute(query.format(*args)) streams_delete = cursor.fetchall() if isShow == False: query = 'DELETE FROM stream_ref WHERE stream_ref.mov_id IN (SELECT movies.id FROM movies WHERE movies.filePath like \'{0}\') and stream_ref.provider like \'{1}\';' else: query = 'DELETE FROM stream_ref WHERE stream_ref.show_id IN (SELECT shows.id FROM shows WHERE shows.filePath like \'{0}\') and stream_ref.provider like \'{1}\';' addon_log('delStream: query = {0}'.format(query.format(*args))) cursor.execute(query.format(*args)) con.commit() if isShow == False: query = 'SELECT movies.title FROM movies WHERE movies.id IN (SELECT stream_ref.mov_id FROM stream_ref WHERE stream_ref.mov_id IN (SELECT movies.id FROM movies WHERE movies.filePath like \'{0}\'));' else: query = 'SELECT stream_ref.seasonEpisode FROM stream_ref WHERE stream_ref.show_id IN (SELECT shows.id FROM shows WHERE shows.filePath like \'{0}\');' addon_log('delStream: query = {0}'.format(query.format(*args))) cursor.execute(query.format(*args)) streams_keep = cursor.fetchall() streams = [s for s in streams_delete if s not in streams_keep] except: streams = [] finally: cursor.close() con.close() return streams
def deleteFromWatchlist(self, asset_id): url = '{0}delete?{1}'.format( self.base_url, urlencode({ 'assetId': asset_id, 'version': '12354', 'platform': 'web', 'product': 'SG', 'catalog': 'sg' })) r = self.skygo.session.get(url) res = json.loads(py2_decode(r.text[3:len(r.text) - 1])) if res['resultMessage'] == 'OK': xbmc.executebuiltin('Container.Refresh') else: xbmcgui.Dialog().notification( 'Sky Go: Merkliste', 'Eintrag konnte nicht von der Merkliste entfernt werden', xbmcgui.NOTIFICATION_ERROR, 2000, True)
def unescape(line): # HTML-Escapezeichen in Text entfernen, bei Bedarf erweitern. ARD auch ' statt richtig ' # # s.a. ../Framework/api/utilkit.py # # Ev. erforderliches Encoding vorher durchführen - Achtung in Kodis # # Python-Version v2.26.0 'ascii'-codec-Error bei mehrfachem decode # # PLog(type(line)) if line == None or line == '': return '' line = py2_decode(line) for r in ( (u"&", u"&"), (u"<", u"<"), (u">", u">"), (u"'", u"'"), (u"'", u"'"), (u""", u'"'), (u"'", u"'"), (u"ö", u"ö"), (u"ä", u"ä"), (u"ü", u"ü"), (u"ß", u"ß"), (u"Ö", u"Ö"), (u"Ä", u"Ä"), (u"Ü", u"Ü"), (u"'", u"'"), (u" | ", u""), (u" ", u""), # Spezialfälle: # https://stackoverflow.com/questions/20329896/python-2-7-character-u2013 # "sächsischer Genetiv", Bsp. Scott's # Carriage Return (Cr) (u"–", u"-"), (u"'", u"'"), (u"
", u""), (u"\xc2\xb7", u"-"), (u'undoacute;', u'o'), (u'é', u'e'), (u'è', u'e'), (u'ã', u'a')): line = line.replace(*r) return line
def delStream(path, provider, isShow): streams = [] utils.addon_log('delStream: path = {0}, provider = {1}, isShow = {2}'.format(py2_decode(path), py2_decode(provider), isShow)) try: args = {'sqliteDB': MODBPATH, 'mysqlDB': 'Movies'} if not isShow or isShow == False else {'sqliteDB': SHDBPATH, 'mysqlDB': 'TVShows'} con, cursor = openDB(**args) path = stringUtils.invCommas(path) if isShow == False: query = 'SELECT movies.title FROM movies WHERE movies.id IN (SELECT stream_ref.mov_id FROM stream_ref WHERE stream_ref.mov_id IN (SELECT movies.id FROM movies WHERE movies.filePath like \'{0}\') and stream_ref.provider like \'{1}\');' else: query = 'SELECT stream_ref.seasonEpisode FROM stream_ref WHERE stream_ref.show_id IN (SELECT shows.id FROM shows WHERE shows.filePath like \'{0}\') and stream_ref.provider like \'{1}\';' args = [path, provider] utils.addon_log('delStream: query{0} = {1}'.format('{args}', query.format(*args))) cursor.execute(query.format(*args)) streams_delete = cursor.fetchall() if isShow == False: query = 'DELETE FROM stream_ref WHERE stream_ref.mov_id IN (SELECT movies.id FROM movies WHERE movies.filePath like \'{0}\') and stream_ref.provider like \'{1}\';' else: query = 'DELETE FROM stream_ref WHERE stream_ref.show_id IN (SELECT shows.id FROM shows WHERE shows.filePath like \'{0}\') and stream_ref.provider like \'{1}\';' utils.addon_log('delStream: query{0} = {1}'.format('{args}', query.format(*args))) cursor.execute(query.format(*args)) con.commit() if isShow == False: query = 'SELECT movies.title FROM movies WHERE movies.id IN (SELECT stream_ref.mov_id FROM stream_ref WHERE stream_ref.mov_id IN (SELECT movies.id FROM movies WHERE movies.filePath like \'{0}\'));' else: query = 'SELECT stream_ref.seasonEpisode FROM stream_ref WHERE stream_ref.show_id IN (SELECT shows.id FROM shows WHERE shows.filePath like \'{0}\');' utils.addon_log('delStream: query{0} = {1}'.format('{args}', query.format(*args))) cursor.execute(query.format(*args)) streams_keep = cursor.fetchall() streams = [s for s in streams_delete if s not in streams_keep] except: streams = [] finally: cursor.close() con.close() return streams
def getClipToken(self, content): clipType = 'FREE' if content == 'ENTITLED USER' or content == 'SUBSCRIBED USER': clipType = 'NOTFREE' timestamp = str(time.time()).replace('.', '') url = 'https://www.skygo.sky.de/SILK/services/public/clipToken?{0}'.format( urlencode({ 'clipType': clipType, 'version': '12354', 'platform': 'web', 'product': 'SG' })) url = '{0}&_{1}'.format(timestamp) r = self.skygo.session.get(url) if common.get_dict_value( r.headers, 'content-type').startswith('application/json'): return json.loads(py2_decode(r.text[3:len(r.text) - 1])) else: None
def listWatchlist(self, asset_type, page=0): self.skygo.login() url = '{0}get?{1}'.format( self.base_url, urlencode({ 'type': asset_type, 'page': page, 'pageSize': 8 })) r = self.skygo.session.get(url) data = json.loads(py2_decode(r.text[3:len(r.text) - 1])) listitems = [] if data.get('watchlist'): for item in data.get('watchlist'): if item.get('assetId'): asset = self.nav.getAssetDetailsFromCache( item.get('assetId')) if len(asset) > 0: for asset_details in self.nav.getAssets([asset]): listitems.append(asset_details) else: xbmc.log( '[Sky Go] watchlist details could not be found for item {0}' .format(item)) if data['hasNext']: url = self.common.build_url({ 'action': 'watchlist', 'list': asset_type, 'page': page + 1 }) listitems.append({ 'type': 'path', 'label': 'Mehr...', 'url': url }) self.nav.listAssets(listitems, isWatchlist=True) xbmcplugin.endOfDirectory(self.common.addon_handle, cacheToDisc=False)
def quickPlayer (self,activity): from . import details #print self.nextUrl Audio = False self.wasFullScreen = True windowed = self.settings.XNEWA_LIVE_SKIN if 'playlist' in activity: import os import re dd = {} xbmc.PlayList(0).clear() for playlist in activity['playlist']: nextUrl = re.sub('[^?&]*client[^&]+&*','',playlist['url'].encode('utf-8')) xbmc.log(nextUrl) url = nextUrl.split('=',1)[1] if url[0:2]=='\\\\': url = 'smb:'+ url.replace('\\','/') if xbmcvfs.exists(url) == False: s = self.base + playlist['url'].replace(' ','+').replace('&f=','&mode=http&f=') xbmc.log(s) xbmc.PlayList(0).add(s) else: xbmc.PlayList(0).add(url) dd['movie'] = False dd['playlist'] = xbmc.PlayList(0) windowed = False elif self.nextUrl.startswith('/live?channel'): try: #v5 if self.settings.XNEWA_INTERFACE == 'XML' or self.settings.XNEWA_INTERFACE == 'Version5': url = self.base + '/services?method=channel.listings.current' + self.xnewa.client + '&channel_id=' + str (activity['channel_id']) xbmc.log(url) dd1 = self.xnewa._progs2array_xml(url) else: url = self.base + '/public/GuideService/Listing' + self.xnewa.jsid + '&channelId=' + str (activity['channel_id']) xbmc.log(url) dd1 = self.xnewa._progs2array_json(url) dd = dd1[0]['progs'][0] dd['program_oid'] = dd['oid'] #dd['season'] = 0 except Exception as err: print(err) dd = {} dd['program_oid'] = 12346 dd['title'] = activity['channel_name'] dd['subtitle'] = str(activity['channel_number']) dd['end'] = '' dd['season'] = 0 dd['desc'] = '' dd['channel_oid'] = activity['channel_id'] channel = {} channel[0] = activity['channel_name'] channel[1] = activity['channel_number'] channel[2] = '0' self.prev_channel = self.channel_number self.channel_number = activity['channel_number'] dd['channel'] = channel dd['bookmarkSecs'] = 0 dd['movie'] = False elif self.nextUrl.startswith('/stream?'): dd = {} dd['title'] = 'title' dd['movie'] = False dd['filename'] = py2_decode(self.nextUrl.split('=',1)[1]).replace('http://plugin','plugin') dd['season'] = 0 if 'duration' in activity: dd['library_duration'] = activity['duration'] else: import re m = re.search('.*_(\d{2})(\d{2})(\d{2})(\d{2})(-\d)\.ts', dd['filename']) if m: start = int(m.group(1)) * 60 + int(m.group(2)) end = int(m.group(3)) * 60 + int(m.group(4)) #print start #print end if start > end: dd['library_duration'] = (start + end - 1440) * 60 else: dd['library_duration'] = (end - start) * 60 dd['filename'] = dd['filename'].replace('127.0.0.1',self.xnewa.ip) #self.getPlaybackPosition(dd['filename']) dd['nextUrl'] = self.nextUrl if 'recording_description' in activity: dd['desc'] = activity['recording_description'] elif 'description' in activity: dd['desc'] = activity['description'] else: dd['desc'] = '' if 'recording_title' in activity: dd['title'] = activity['recording_title'] elif dd['filename'].startswith('http:'): if '.m3u8' not in dd['filename']: Audio = True elif 'title' in activity: dd['title'] = activity['title'] if 'recording_subtitle' in activity: dd['subtitle'] = activity['recording_subtitle'] elif 'subtitle' in activity: dd['subtitle'] = activity['subtitle'] else: dd['subtitle'] = None if 'recording_resume' in activity: dd['bookmarkSecs'] = activity['recording_resume'] dd['resume'] = activity['recording_resume'] else: dd['bookmarkSecs'] = 0 if 'album' in activity: Audio = True if 'recording_id' in activity: dd['recording_oid'] = activity['recording_id'] dd['nextUrl'] = '/live?recording=' + dd['recording_oid'] if self.settings.NextPVR_ICON_DL == 'Yes' and self.xnewa.getShowIcon(dd['title']) is None: self.xnewa.getDetails(self.settings.NextPVR_USER,self.settings.NextPVR_PW,dd['recording_oid'],'R','Yes') else: dd['recording_oid'] = 0 if 'Genres' in activity: dd['genres'] = activity['Genres'] for genre in dd['Genres']: if genre == "Movie" or genre == "Movies" or genre == "Film": dd['movie'] = True break detailDialog = details.DetailDialog("nextpvr_recording_details.xml", WHERE_AM_I,self.settings.XNEWA_SKIN, xnewa=self.xnewa, settings=self.settings, oid=123, epg=True, type="R") xbmc.log(str(windowed)) if self.sdlmode == SDL.disabled: self.setOSDMode(False) windowed = False if isinstance(self.t1, Thread): xbmc.Player().stop() while self.t1.is_alive(): xbmc.sleep(100) self.renderstop = False self.t1 = Thread(target=detailDialog._myPlayer, args=(dd,None,windowed,Audio,False)) self.t1.start() self.state = videoState.started #xbmc.executebuiltin('XBMC.ActivateWindow(25)') #self.player = detailDialog.getPlayer() #self.player.overlay = self #xbmc.executebuiltin('ActivateWindow(visualisation)') #xbmc.executebuiltin('ActivateWindow(musicosd)') return
def smartUTF8(s): return py2_decode(smartUnicode(s))