diff --git a/addons.xml b/addons.xml index a6b4bc61..ef5b033c 100644 --- a/addons.xml +++ b/addons.xml @@ -1,6 +1,6 @@ - + diff --git a/addons.xml.md5 b/addons.xml.md5 index d6c82830..5a0b0aa1 100644 --- a/addons.xml.md5 +++ b/addons.xml.md5 @@ -1 +1 @@ -7ba6383b3801a48849929f7a94b16ac2 \ No newline at end of file +836fbdc58ebbb216068953a36651d863 \ No newline at end of file diff --git a/plugin.video.pseudotv.live/addon.xml b/plugin.video.pseudotv.live/addon.xml index 7fa25013..4ff931a7 100644 --- a/plugin.video.pseudotv.live/addon.xml +++ b/plugin.video.pseudotv.live/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/plugin.video.pseudotv.live/resources/language/resource.language.en_gb/strings.po b/plugin.video.pseudotv.live/resources/language/resource.language.en_gb/strings.po index 8ce8a5e1..f3c4541f 100644 --- a/plugin.video.pseudotv.live/resources/language/resource.language.en_gb/strings.po +++ b/plugin.video.pseudotv.live/resources/language/resource.language.en_gb/strings.po @@ -130,19 +130,19 @@ msgid "Logo Resource" msgstr "" msgctxt "#30028" -msgid "Ratings" +msgid "Ratings Resource" msgstr "" msgctxt "#30029" -msgid "Bumpers" +msgid "Bumpers Resource" msgstr "" msgctxt "#30030" -msgid "Adverts" +msgid "Adverts Resource" msgstr "" msgctxt "#30031" -msgid "Trailers" +msgid "Trailers Resource" msgstr "" msgctxt "#30032" @@ -1287,7 +1287,7 @@ msgid "Please wait for announcements to finish, Try again later..." msgstr "" msgctxt "#32149" -msgid "[COLOR=orange]Idle[/COLOR]" +msgid "[COLOR=orange][B]Idle[/B][/COLOR]" msgstr "" msgctxt "#32150" @@ -1323,7 +1323,7 @@ msgid "Pending Changes..." msgstr "" msgctxt "#32158" -msgid "[COLOR=yellow]Waiting for pairing (%s)[/COLOR]" +msgid "[COLOR=yellow]Waiting for pairing ([B]%s[/B])[/COLOR]" msgstr "" msgctxt "#32159" @@ -1762,5 +1762,5 @@ msgid "Force Autotune to run." msgstr "" msgctxt "#33182" -msgid "When [COLOR=orange]Idle[/COLOR] click to begin beacon; Within 15mins start another Kodi instance w/PseudoTV Live installed\nThe two instances will pair, enabled in Select Server list." +msgid "When [COLOR=orange][B]Idle[/B][/COLOR] click to begin beacon; Within 15mins start another Kodi instance w/PseudoTV Live installed\nThe two instances will pair, enabled in Select Server list." msgstr "" diff --git a/plugin.video.pseudotv.live/resources/lib/backup.py b/plugin.video.pseudotv.live/resources/lib/backup.py index 2f6aa55e..aaf011c2 100644 --- a/plugin.video.pseudotv.live/resources/lib/backup.py +++ b/plugin.video.pseudotv.live/resources/lib/backup.py @@ -34,7 +34,7 @@ def log(self, msg, level=xbmc.LOGDEBUG): def getFileDate(self, file: str) -> str: - try: return datetime.datetime.fromtimestamp(pathlib.Path(xbmcvfs.translatePath(file)).stat().st_mtime).strftime(BACKUP_TIME_FORMAT) + try: return datetime.datetime.fromtimestamp(pathlib.Path(FileAccess.translatePath(file)).stat().st_mtime).strftime(BACKUP_TIME_FORMAT) except: return LANGUAGE(32105) #Unknown diff --git a/plugin.video.pseudotv.live/resources/lib/builder.py b/plugin.video.pseudotv.live/resources/lib/builder.py index 24cb1e2b..f12443ba 100644 --- a/plugin.video.pseudotv.live/resources/lib/builder.py +++ b/plugin.video.pseudotv.live/resources/lib/builder.py @@ -383,7 +383,7 @@ def buildList(self, citem: dict, path: str, media: str='video', page: int=SETTIN item['art'] = (item.get('art',{}) or dirItem.get('art',{})) item.get('art',{})['icon'] = citem['logo'] - if item.get('trailer') and self.bctTypes['trailers'].get('enabled',False) and self.bctTypes['trailers'].get('incKODI',False): + if item.get('trailer') and self.bctTypes['trailers'].get('enabled',False): titem = item.copy() tdur = self.jsonRPC.getDuration(titem.get('trailer'), accurate=True, save=False) if tdur > 0: diff --git a/plugin.video.pseudotv.live/resources/lib/cache.py b/plugin.video.pseudotv.live/resources/lib/cache.py index 82d37a5f..b9ff2b19 100644 --- a/plugin.video.pseudotv.live/resources/lib/cache.py +++ b/plugin.video.pseudotv.live/resources/lib/cache.py @@ -88,7 +88,7 @@ def get(self, name, checksum=ADDON_VERSION, json_data=False): def clear(self, name, wait=15): import sqlite3 self.log('clear, name = %s'%self.getname(name)) - sc = xbmcvfs.translatePath(xbmcaddon.Addon(id='script.module.simplecache').getAddonInfo('profile')) + sc = FileAccess.translatePath(xbmcaddon.Addon(id='script.module.simplecache').getAddonInfo('profile')) dbpath = os.path.join(sc, 'simplecache.db') connection = sqlite3.connect(dbpath, timeout=wait, isolation_level=None) try: diff --git a/plugin.video.pseudotv.live/resources/lib/channels.py b/plugin.video.pseudotv.live/resources/lib/channels.py index 89c9865c..0ce8aafd 100644 --- a/plugin.video.pseudotv.live/resources/lib/channels.py +++ b/plugin.video.pseudotv.live/resources/lib/channels.py @@ -113,7 +113,7 @@ def delChannel(self, citem: dict={}) -> bool: def addChannel(self, citem: dict={}) -> bool: - idx, channel = self.findChannel(citem) + idx, channel = self.findChannel(citem) if idx is not None: for key in ['id','rules','number','favorite','logo']: if channel.get(key): citem[key] = channel[key] # existing id found, reuse channel meta. diff --git a/plugin.video.pseudotv.live/resources/lib/cqueue.py b/plugin.video.pseudotv.live/resources/lib/cqueue.py index 57f7a27f..6d1801f9 100644 --- a/plugin.video.pseudotv.live/resources/lib/cqueue.py +++ b/plugin.video.pseudotv.live/resources/lib/cqueue.py @@ -62,7 +62,8 @@ def __start(self): def __run(self, func, args=(), kwargs=None): self.log("__run, func = %s"%(func.__name__)) - try: return func(*args, **kwargs) + try: return executeit(func)(*args, **kwargs) + #return func(*args, **kwargs) except Exception as e: self.log("__run, func = %s failed! %s"%(func.__name__,e), xbmc.LOGERROR) @@ -72,6 +73,7 @@ def __exists(self, package): if epackage == package[2]: if epriority <= package[1]: return True else: + self.log("__exists, pop func = %s"%(epackage[0].__name__)) self.min_heap.pop(idx) return False return False @@ -81,7 +83,7 @@ def _push(self, package: tuple, priority: int=0, delay: int=0): self.log("_push, func = %s"%(package[0].__name__)) node = LlNode(package, priority, delay) if self.__exists((1,priority,package)): - self.log("_push, exists... ignoring package") + self.log("_push, %s exists; ignoring package"%(package[2])) return elif self.priority: self.qsize += 1 @@ -114,11 +116,10 @@ def __pop(self): self.log("__pop, The queue is empty!") break - if self.priority: + elif self.priority: if not self.min_heap: self.log("__pop, The priority queue is empty!") break - min_num, _, package = heapq.heappop(self.min_heap) self.qsize -= 1 self.__run(*package) @@ -135,8 +136,7 @@ def __pop(self): if self.fifo: self.head = next_node else: self.tail = next_node - if not self.delay: - package, self.__run(*package) + if not self.delay: package, self.__run(*package) else: popTimer = Timer(curr_node.wait, *package) if popTimer.is_alive(): popTimer.join() diff --git a/plugin.video.pseudotv.live/resources/lib/fileaccess.py b/plugin.video.pseudotv.live/resources/lib/fileaccess.py index bd5f6dbf..f63518fa 100644 --- a/plugin.video.pseudotv.live/resources/lib/fileaccess.py +++ b/plugin.video.pseudotv.live/resources/lib/fileaccess.py @@ -50,6 +50,7 @@ def listdir(path): @staticmethod def translatePath(path): + if '@' in path: path = path.split('@')[1] return xbmcvfs.translatePath(path) diff --git a/plugin.video.pseudotv.live/resources/lib/fillers.py b/plugin.video.pseudotv.live/resources/lib/fillers.py index eacb7b7c..9e59eced 100644 --- a/plugin.video.pseudotv.live/resources/lib/fillers.py +++ b/plugin.video.pseudotv.live/resources/lib/fillers.py @@ -67,7 +67,7 @@ def _parseLocal(path): if FileAccess.exists(path): return self.jsonRPC.walkListDirectory(path,exts=VIDEO_EXTS,depth=CHANNEL_LIMIT,chkDuration=True) def _parseVFS(path): - if hasAddon(id, install=True): return self.jsonRPC.walkFileDirectory(path,depth=CHANNEL_LIMIT,chkDuration=True,retItem=True) + if hasAddon(path, install=True): return self.jsonRPC.walkFileDirectory(path,depth=CHANNEL_LIMIT,chkDuration=True,retItem=True) def _parseResource(id): if hasAddon(id, install=True): return self.jsonRPC.walkListDirectory(os.path.join('special://home/addons/%s'%id,'resources'),exts=VIDEO_EXTS,depth=CHANNEL_LIMIT,checksum=self.jsonRPC.getAddonDetails(id).get('version',ADDON_VERSION),expiration=datetime.timedelta(days=MAX_GUIDEDAYS)) @@ -78,11 +78,11 @@ def __sortItems(data, stype='folder'): for path, files in list(data.items()): key = (os.path.basename(os.path.normpath(path)).replace('\\','/').strip('/').split('/')[-1:][0]).lower() for file in files: - if stype == 'plugin': [tmpDCT.setdefault(key,[]).append(file) for key in (file.get('genre',[]) or ['resources'])] + if stype == 'plugin': [tmpDCT.setdefault(key.lower(),[]).append(file) for key in (file.get('genre',[]) or ['resources'])] else: if stype == 'file': key = file.split('.')[0].lower() dur = self.jsonRPC.getDuration(os.path.join(path,file), accurate=True) - if dur > 0: tmpDCT.setdefault(key,[]).append({'file':os.path.join(path,file),'duration':dur,'label':'%s - %s'%(path.strip('/').split('/')[-1:][0],file.split('.')[0])}) + if dur > 0: tmpDCT.setdefault(key.lower(),[]).append({'file':os.path.join(path,file),'duration':dur,'label':'%s - %s'%(path.strip('/').split('/')[-1:][0],file.split('.')[0])}) return tmpDCT try: @@ -179,19 +179,21 @@ def injectBCTs(self, citem, fileList): # post roll - adverts/trailers if len(postFileList) > 0: self.log('injectBCTs, post-roll current runtime %s, available runtime %s, available content %s'%(runtime, postFillRuntime,len(postFileList))) - while not self.builder.service.monitor.abortRequested() and postFillRuntime > 0 and len(postFileList) > 0 and postFillCount > 0: + while not self.builder.service.monitor.abortRequested() and postFillRuntime > 0 and postFillCount > 0: if self.builder.service._interrupt(): break - item = postFileList.pop(0) - if (item.get('duration') or 0) == 0: continue - elif postFillRuntime <= 0: break - elif postFillRuntime >= item.get('duration'): - postFillRuntime -= item.get('duration') - self.log('injectBCTs, adding post-roll %s - %s'%(item.get('duration'),item.get('file'))) - if self.builder.pDialog: self.builder.pDialog = DIALOG.progressBGDialog(self.builder.pCount, self.builder.pDialog, message='Filling Post-Rolls',header='%s, %s'%(ADDON_NAME,self.builder.pMSG)) - item.update({'title':'Post-Roll','episodetitle':item.get('label'),'genre':['Post-Roll'],'plot':item.get('plot',item.get('file')),'path':item.get('file')}) - nfileList.append(self.builder.buildCells(citem,item.get('duration'),entries=1,info=item)[0]) - elif postFillRuntime < item.get('duration'): - postFillCount -= 1 - postFileList.append(item) - self.log('injectBCTs, unused post roll runtime %s'%(postFillRuntime)) + elif len(postFileList) == 0: break + else: + item = postFileList.pop(0) + if (item.get('duration') or 0) == 0: continue + elif postFillRuntime <= 0: break + elif postFillRuntime >= item.get('duration'): + postFillRuntime -= item.get('duration') + self.log('injectBCTs, adding post-roll %s - %s'%(item.get('duration'),item.get('file'))) + if self.builder.pDialog: self.builder.pDialog = DIALOG.progressBGDialog(self.builder.pCount, self.builder.pDialog, message='Filling Post-Rolls',header='%s, %s'%(ADDON_NAME,self.builder.pMSG)) + item.update({'title':'Post-Roll','episodetitle':item.get('label'),'genre':['Post-Roll'],'plot':item.get('plot',item.get('file')),'path':item.get('file')}) + nfileList.append(self.builder.buildCells(citem,item.get('duration'),entries=1,info=item)[0]) + elif postFillRuntime < item.get('duration'): + postFillCount -= 1 + postFileList.append(item) + if (self.builder.bctTypes['adverts']['auto'] and self.builder.bctTypes['trailers']['auto']): self.log('injectBCTs, unused post roll runtime %s'%(postFillRuntime)) return nfileList \ No newline at end of file diff --git a/plugin.video.pseudotv.live/resources/lib/globals.py b/plugin.video.pseudotv.live/resources/lib/globals.py index b1353094..e2999404 100644 --- a/plugin.video.pseudotv.live/resources/lib/globals.py +++ b/plugin.video.pseudotv.live/resources/lib/globals.py @@ -206,7 +206,7 @@ def hasFile(file): else: return FileAccess.exists(file) def hasAddon(id, install=False, enable=False, force=False, notify=False): - id = getIDbyPath(id) + if '://' in id: id = getIDbyPath(id) if BUILTIN.getInfoBool('HasAddon(%s)'%(id),'System'): if BUILTIN.getInfoBool('AddonIsEnabled(%s)'%(id),'System'): return True elif enable: @@ -328,7 +328,7 @@ def cleanLabel(text): def cleanImage(image=LOGO): if not image: image = LOGO if not image.startswith(('image://','resource://','special://','smb://','nfs://','https://','http://')): - realPath = xbmcvfs.translatePath('special://home/addons/') + realPath = FileAccess.translatePath('special://home/addons/') if image.startswith(realPath):# convert real path. to vfs image = image.replace(realPath,'special://home/addons/').replace('\\','/') elif image.startswith(realPath.replace('\\','/')): @@ -366,7 +366,7 @@ def getIDbyPath(url): try: if url.startswith('special://'): return re.compile('special://home/addons/(.*?)/resources', re.IGNORECASE).search(url).group(1) elif url.startswith('plugin://'): return re.compile('plugin://(.*?)/', re.IGNORECASE).search(url).group(1) - except Exception as e: log('Globals: getIDbyPath failed! %s'%(e), xbmc.LOGERROR) + except Exception as e: log('Globals: getIDbyPath failed! url = %s, %s'%(url,e), xbmc.LOGERROR) return url def combineDicts(dict1={}, dict2={}): diff --git a/plugin.video.pseudotv.live/resources/lib/json2table.py b/plugin.video.pseudotv.live/resources/lib/json2table.py index 9f890f9b..ed85aedd 100644 --- a/plugin.video.pseudotv.live/resources/lib/json2table.py +++ b/plugin.video.pseudotv.live/resources/lib/json2table.py @@ -86,9 +86,9 @@ def convert(self, json_input): """ html_output = self._table_opening_tag if self._build_top_to_bottom: - html_output += self._markup_header_row(json_input.keys()) + html_output += self._markup_header_row(list(json_input.keys())) html_output += "" - for value in json_input.values(): + for value in list(json_input.values()): if isinstance(value, list): # check if all keys in the list are identical # and group all values under a common column @@ -98,7 +98,7 @@ def convert(self, json_input): html_output += self._markup_table_cell(value) html_output += "" else: - for key, value in iter(json_input.items()): + for key, value in iter(list(json_input.items())): html_output += "{:s}".format(self._markup(key)) if isinstance(value, list): html_output += self._maybe_club(value) @@ -161,7 +161,7 @@ def _dict_to_html_attributes(d): if d is None: return "" - return "".join(" {}=\"{}\"".format(key, value) for key, value in iter(d.items())) + return "".join(" {}=\"{}\"".format(key, value) for key, value in iter(list(d.items()))) @staticmethod def _list_of_dicts_to_column_headers(list_of_dicts): @@ -183,9 +183,9 @@ def _list_of_dicts_to_column_headers(list_of_dicts): if len(list_of_dicts) < 2 or not all(isinstance(item, dict) for item in list_of_dicts): return None - column_headers = list_of_dicts[0].keys() + column_headers = list(list_of_dicts[0].keys()) for d in list_of_dicts[1:]: - if len(d.keys()) != len(column_headers) or not all(header in d for header in column_headers): + if len(list(d.keys())) != len(column_headers) or not all(header in d for header in column_headers): return None return column_headers diff --git a/plugin.video.pseudotv.live/resources/lib/jsonrpc.py b/plugin.video.pseudotv.live/resources/lib/jsonrpc.py index e4226c06..c154f744 100644 --- a/plugin.video.pseudotv.live/resources/lib/jsonrpc.py +++ b/plugin.video.pseudotv.live/resources/lib/jsonrpc.py @@ -353,15 +353,13 @@ def queDuration(self, item={}, duration=0, runtime=0): 'song' : {"method":"AudioLibrary.SetSongDetails" ,"params":{"songid" :item.get('id',-1) ,"runtime": runtime,"resume": {"position": item.get('position',0.0),"total": duration}}}, 'songs' : {"method":"AudioLibrary.SetSongDetails" ,"params":{"songid" :item.get('songid',-1) ,"runtime": runtime,"resume": {"position": item.get('position',0.0),"total": duration}}}} try: - if 'type' in item: - params = param[item['type']] - if -1 in params: raise Exception('no dbid found') - elif params: - if duration == 0: param['params'].pop('resume') - elif runtime == 0: param['params'].pop('runtime') - id = (item.get('id') or item.get('movieid') or item.get('episodeid') or item.get('musicvideoid') or item.get('songid')) - self.log('queDuration, id = %s, media = %s, duration = %s, runtime = %s'%(id,item['type'],duration,runtime)) - self.queueJSON(params) + params = param.get(item.get('type')) + if params: + if duration == 0: param['params'].pop('resume') + elif runtime == 0: param['params'].pop('runtime') + id = (item.get('id') or item.get('movieid') or item.get('episodeid') or item.get('musicvideoid') or item.get('songid')) + self.log('queDuration, id = %s, media = %s, duration = %s, runtime = %s'%(id,item['type'],duration,runtime)) + self.queueJSON(params) except Exception as e: self.log("queDuration, failed! %s\nitem = %s"%(e,item), xbmc.LOGERROR) @@ -377,9 +375,8 @@ def quePlaycount(self, item): 'songs' : {"method":"AudioLibrary.SetSongDetails" ,"params":{"songid" :item.get('songid',-1) ,"playcount": item.get('playcount',0),"resume": {"position": item.get('position',0.0),"total": item.get('total',0.0)}}}} try: if not item.get('file','').startswith(tuple(VFS_TYPES)): - params = param[item['type']] - if -1 in params: raise Exception('no dbid found') - elif params: + params = param.get(item.get('type')) + if params: id = (item.get('id') or item.get('movieid') or item.get('episodeid') or item.get('musicvideoid') or item.get('songid')) self.log('quePlaycount, id = %s, media = %s, playcount = %s, resume = %s'%(id,item['type'],item.get('playcount',0),item.get('resume',{}))) self.queueJSON(params) @@ -522,18 +519,18 @@ def padItems(self, files, page=SETTINGS.getSettingInt('Page_Limit')): @cacheit(expiration=datetime.timedelta(seconds=EPOCH_TIMER),json_data=False) - def getFriendlyName(self): + def InputFriendlyName(self): with PROPERTIES.suspendActivity(): fn = self.getSettingValue("services.devicename") - self.log("getFriendlyName, name = %s"%(fn)) + self.log("InputFriendlyName, name = %s"%(fn)) if not fn or fn.lower() == 'kodi': if DIALOG.okDialog(LANGUAGE(32132)%(fn)): input = DIALOG.inputDialog(LANGUAGE(30122), fn) if not input or input.lower() == 'kodi': - return self.getFriendlyName() + return self.InputFriendlyName() else: self.setSettingValue("services.devicename",input) - self.log('getFriendlyName, setting device name = %s'%(input)) + self.log('InputFriendlyName, setting device name = %s'%(input)) return input return fn diff --git a/plugin.video.pseudotv.live/resources/lib/kodi.py b/plugin.video.pseudotv.live/resources/lib/kodi.py index 30cc889b..40083df3 100644 --- a/plugin.video.pseudotv.live/resources/lib/kodi.py +++ b/plugin.video.pseudotv.live/resources/lib/kodi.py @@ -238,9 +238,11 @@ def getSettingDict(self, key): return loadJSON(decodeString(self.getSetting(key))) - def getCacheSetting(self, key, checksum=1, json_data=False): - return self.cache.get(key, checksum, json_data) - + def getCacheSetting(self, key, checksum=1, json_data=False, revive=True): + if revive: return self.setCacheSetting(key, self.cache.get(key, checksum, json_data), checksum, json_data=json_data) + else: return self.cache.get(key, checksum, json_data) + + #SET def _setSetting(self, func, key, value): try: @@ -316,6 +318,7 @@ def setEXTSetting(self, id, key, value): def hasAutotuned(self): + if self.property.getEXTProperty('%s.has.Channels'%(ADDON_ID)) != "true" and self.property.getEXTProperty('%s.has.Enabled_Servers'%(ADDON_ID)) != "true": return False return self.getCacheSetting('hasAutotuned') @@ -328,7 +331,7 @@ def getFriendlyName(self): if not friendly: from jsonrpc import JSONRPC jsonRPC = JSONRPC() - friendly = self.setCacheSetting('Friendly_Name',jsonRPC.getFriendlyName()) + friendly = self.setCacheSetting('Friendly_Name',jsonRPC.InputFriendlyName()) del jsonRPC return friendly @@ -909,12 +912,12 @@ def closeBusyDialog(self): @contextmanager def busy_dialog(self, isPlaying=False): - if not self.isBusyDialog() and not isPlaying : - self.executebuiltin('ActivateWindow(busydialognocancel)') - try: yield - finally: self.executebuiltin('Dialog.Close(busydialognocancel)') - else: yield - + if not self.isBusyDialog() and not isPlaying: + xbmc.executebuiltin('ActivateWindow(busydialognocancel)') + try: yield + finally: + xbmc.executebuiltin('Dialog.Close(busydialognocancel)') + def getInfoLabel(self, key, param='ListItem', default=''): value = (xbmc.getInfoLabel('%s.%s'%(param,key)) or default) @@ -1026,7 +1029,7 @@ def __init__(self, *args, **kwargs): self.header = kwargs["header"] self.image = kwargs["image"] self.text = kwargs["text"] - self.autoclose = kwargs["atclose"] + self.acThread = Timer(kwargs["atclose"], self.onClose) def onInit(self): @@ -1034,20 +1037,32 @@ def onInit(self): self.getControl(40001).setImage(self.image) self.getControl(40002).setText(self.text) self.getControl(40003).setLabel(LANGUAGE(32062)) - if self.autoclose > 0: timerit(self.close)(self.autoclose) self.setFocus(self.getControl(40003)) + self.acThread.name = "acThread" + self.acThread.daemon=True + self.acThread.start() def onClick(self, controlId): if controlId == 40003: - self.close() + self.onClose() + + + def onClose(self): + try: + if self.acThread.is_alive(): + self.acThread.cancel() + self.acThread.join() + except: pass + self.close() + with self.builtin.busy_dialog(): - imagefile = os.path.join(xbmcvfs.translatePath(TEMP_LOC),'%s.png'%(getMD5(str(url.split('/')[-1])))) + imagefile = os.path.join(FileAccess.translatePath(TEMP_LOC),'%s.png'%(getMD5(str(url.split('/')[-1])))) if not FileAccess.exists(imagefile): qrIMG = pyqrcode.create(url) qrIMG.png(imagefile, scale=10) - + qr = QRCode( "plugin.video.pseudotv.live.qrcode.xml" , ADDON_PATH, "default", image=imagefile, text=msg, header=heading, atclose=autoclose) qr.doModal() del qr @@ -1167,49 +1182,49 @@ def inputDialog(self, message, default='', key=xbmcgui.INPUT_ALPHANUM, opt=0, cl return xbmcgui.Dialog().input(message, default, key, opt, close) - def browseDialog(self, type=0, heading=ADDON_NAME, default='', shares='', mask='', options=None, useThumbs=True, treatAsFolder=False, prompt=True, multi=False, monitor=False): + def browseDialog(self, type=0, heading=ADDON_NAME, default='', shares='', mask='', options=[], include=None, useThumbs=True, treatAsFolder=False, prompt=True, multi=False, monitor=False): + self.log('browseDialog, type = %s, heading= %s, shares= %s, useThumbs= %s, treatAsFolder= %s, default= %s\nmask= %s, options= %s, include= %s'%(type,heading,shares,useThumbs,treatAsFolder,default,mask,options,include)) def buildMenuItem(option): return self.listitems.buildMenuListItem(option['label'],option['label2'],DUMMY_ICON.format(text=getAbbr(option['label']))) if prompt: - optTMP = [] - proOpt = [{"label":"Video Playlists" , "label2":"special://profile/playlists/video/" , "default":"special://profile/playlists/video/" , "mask":".xsp" , "type":1 , "multi":False}, - {"label":"Music Playlists" , "label2":"special://profile/playlists/music/" , "default":"special://profile/playlists/music/" , "mask":".xsp" , "type":1 , "multi":False}, - {"label":"Mixed Playlists" , "label2":"special://profile/playlists/mixed/" , "default":"special://profile/playlists/mixed/" , "mask":".xsp" , "type":1 , "multi":False}, - {"label":"Dynamic Playlist", "label2":"Create Dynamic Smartplaylist" , "default":"" , "mask":"" , "type":1 , "multi":False}, - {"label":"Video" , "label2":"library://video/" , "default":"library://video/" , "mask":xbmc.getSupportedMedia('video') , "type":0 , "multi":False}, - {"label":"Music" , "label2":"library://music/" , "default":"library://music/" , "mask":xbmc.getSupportedMedia('music') , "type":0 , "multi":False}, - {"label":"Files" , "label2":"All Folders & Files" , "default":"" , "mask":mask , "type":type , "multi":False}, - {"label":"Local" , "label2":"Local Folders & Files" , "default":"" , "mask":mask , "type":type , "multi":False}, - {"label":"Network" , "label2":"Local Drives and Network Share" , "default":"" , "mask":mask , "type":type , "multi":False}, - {"label":"Pictures" , "label2":"Picture Sources" , "default":"" , "mask":xbmc.getSupportedMedia('picture') , "type":1 , "multi":False}, - {"label":"Resources" , "label2":"Resource Plugins" , "default":"resource://" , "mask":mask , "type":type , "multi":False} + proOpt = [{"label":"Video Playlists" , "label2":"special://profile/playlists/video/" , "default":"special://profile/playlists/video/" , "mask":".xsp" , "type":1 , "multi":multi}, + {"label":"Music Playlists" , "label2":"special://profile/playlists/music/" , "default":"special://profile/playlists/music/" , "mask":".xsp" , "type":1 , "multi":multi}, + {"label":"Mixed Playlists" , "label2":"special://profile/playlists/mixed/" , "default":"special://profile/playlists/mixed/" , "mask":".xsp" , "type":1 , "multi":multi}, + {"label":"Dynamic Playlist", "label2":"Create Dynamic Smartplaylist" , "default":"" , "mask":"" , "type":1 , "multi":multi}, + {"label":"Video" , "label2":"library://video/" , "default":"library://video/" , "mask":xbmc.getSupportedMedia('video') , "type":0 , "multi":multi}, + {"label":"Music" , "label2":"library://music/" , "default":"library://music/" , "mask":xbmc.getSupportedMedia('music') , "type":0 , "multi":multi}, + {"label":"Files" , "label2":"All Folders & Files" , "default":"" , "mask":mask , "type":type , "multi":multi}, + {"label":"Local" , "label2":"Local Folders & Files" , "default":"" , "mask":mask , "type":type , "multi":multi}, + {"label":"Network" , "label2":"Local Drives and Network Share" , "default":"" , "mask":mask , "type":type , "multi":multi}, + {"label":"Pictures" , "label2":"Picture Sources" , "default":"" , "mask":xbmc.getSupportedMedia('picture') , "type":1 , "multi":multi}, + {"label":"Resources" , "label2":"Resource Plugins" , "default":"resource://" , "mask":mask , "type":type , "multi":multi} ] - if isinstance(options,list): [optTMP.append(proOpt[idx]) for idx in options] - else: optTMP = proOpt + if isinstance(include,list): [options.append(proOpt[idx]) for idx in include] + elif len(options) > 0: options.extend(proOpt) + else: options = proOpt if default: default, file = os.path.split(default) if file: type = 1 else: type = 0 - optTMP.insert(0,{"label":"Current Path", "label2":default, "default":default , "mask":mask, "type":type, "multi":multi}) + options.insert(0,{"label":"Current Path", "label2":default, "default":default , "mask":mask, "type":type, "multi":multi}) with self.builtin.busy_dialog(): - lizLST = poolit(buildMenuItem)(optTMP) + lizLST = poolit(buildMenuItem)(options) select = self.selectDialog(lizLST, LANGUAGE(32089), multi=False) - if optTMP[select].get('label') == "Dynamic Playlist": return self.buildDXSP(default) - elif optTMP[select].get('label') == "Resource Plugins": return self.buildResource(default, mask) + if options[select].get('label') == "Dynamic Playlist": return self.buildDXSP(default) + elif options[select].get('label') == "Resource Plugins": return self.buildResource(default, mask) elif select is not None: - shares = optTMP[select]['label'].lower().replace("network","") - mask = optTMP[select]['mask'] - type = optTMP[select]['type'] - multi = optTMP[select]['multi'] - default = optTMP[select]['default'] + shares = options[select]['label'].lower().replace("network","") + mask = options[select]['mask'] + type = options[select]['type'] + multi = options[select]['multi'] + default = options[select]['default'] else: return - - self.log('browseDialog, type = %s, heading= %s, shares= %s, useThumbs= %s, treatAsFolder= %s, default= %s\nmask= %s'%(type, heading, shares, useThumbs, treatAsFolder, default, mask)) + if monitor: self.toggleInfoMonitor(True) if multi == True: ## https://codedocs.xyz/xbmc/xbmc/group__python___dialog.html#ga856f475ecd92b1afa37357deabe4b9e4 diff --git a/plugin.video.pseudotv.live/resources/lib/manager.py b/plugin.video.pseudotv.live/resources/lib/manager.py index 2735a217..b4991a3d 100644 --- a/plugin.video.pseudotv.live/resources/lib/manager.py +++ b/plugin.video.pseudotv.live/resources/lib/manager.py @@ -383,7 +383,9 @@ def getPaths(self, citem: dict={}, paths: list=[]): key, path = lizLST[select].getProperty('key'), lizLST[select].getPath() if key == 'add': with self.toggleSpinner(self.itemList): - npath, citem = self.validatePath(DIALOG.browseDialog(heading=LANGUAGE(32080),monitor=True), citem) + # opts = [{"label":"STRM Playlist","label2":"STRM containing directories.","default":"","mask":".strm","type":1,"multi":False}] + opts = [] + npath, citem = self.validatePath(DIALOG.browseDialog(heading=LANGUAGE(32080),options=opts,monitor=True),citem) pathLST.append(npath) elif key == 'save': paths = pathLST diff --git a/plugin.video.pseudotv.live/resources/lib/multiroom.py b/plugin.video.pseudotv.live/resources/lib/multiroom.py index b77f8355..7d72001c 100644 --- a/plugin.video.pseudotv.live/resources/lib/multiroom.py +++ b/plugin.video.pseudotv.live/resources/lib/multiroom.py @@ -97,8 +97,9 @@ def sendResponse(self, payload): def hasServers(self, servers={}): if not servers: servers = self.getDiscovery() self.log('hasServers, servers = %s'%(len(servers))) - SETTINGS.setSetting('Select_server','|'.join(['[COLOR=%s]%s[/COLOR]'%({True:'green',False:'red'}[v.get('online',False)],v.get('name')) for v in [v for v in servers.values() if v.get('enabled',False)]])) + SETTINGS.setSetting('Select_server','|'.join(['[COLOR=%s][B]%s[/B][/COLOR]'%({True:'green',False:'red'}[v.get('online',False)],v.get('name')) for v in [v for v in list(servers.values()) if v.get('enabled',False)]])) PROPERTIES.setEXTProperty('%s.has.Servers'%(ADDON_ID),str(len(servers) > 0).lower()) + PROPERTIES.setEXTProperty('%s.has.Enabled_Servers'%(ADDON_ID),str(len([v for v in list(servers.values()) if v.get('enabled',False)]) > 0).lower()) def getDiscovery(self): @@ -139,46 +140,49 @@ def addServer(self, payload={}): def delServer(self): self.log('delServer') def _build(payload): - return LISTITEMS.buildMenuListItem(payload['name'],'%s - %s'%(payload['host'],{"True":"[COLOR=green]Online[/COLOR]","False":"[COLOR=red]Offline[/COLOR]"}[str(payload.get('online',False))]),url=dumpJSON(payload)) + return LISTITEMS.buildMenuListItem(payload['name'],'[B]%s[/B] - %s: Channels (%s)'%({"True":"[COLOR=green]Online[/COLOR]","False":"[COLOR=red]Offline[/COLOR]"}[str(payload.get('online',False))],payload['host'],len(payload.get('channels',[])))) with BUILTIN.busy_dialog(): servers = self.getDiscovery() lizlst = poolit(_build)(list(servers.values())) - selects = DIALOG.selectDialog(lizlst,LANGUAGE(32183)) - if not selects is None: - [servers.pop(liz.getLabel()) for idx, liz in enumerate(lizlst) if idx in selects] - if self.setDiscovery(servers): - return DIALOG.notificationDialog(LANGUAGE(30046)) + + selects = DIALOG.selectDialog(lizlst,LANGUAGE(32183)) + if not selects is None: + [servers.pop(liz.getLabel()) for idx, liz in enumerate(lizlst) if idx in selects] + if self.setDiscovery(servers): + return DIALOG.notificationDialog(LANGUAGE(30046)) def selServer(self): self.log('selServer') def __chkSettings(settings): - for k,v in settings.items(): + for k,v in list(settings.items()): if v.startswith(('resource','plugin')): hasAddon(v,install=True,enable=True) def __build(payload): - return LISTITEMS.buildMenuListItem(payload['name'],'%s - %s'%(payload['host'],{"True":"[COLOR=green]Online[/COLOR]","False":"[COLOR=red]Offline[/COLOR]"}[str(payload.get('online',False))]),url=dumpJSON(payload)) + return LISTITEMS.buildMenuListItem(payload['name'],'[B]%s[/B] - %s: Channels (%s)'%({"True":"[COLOR=green]Online[/COLOR]","False":"[COLOR=red]Offline[/COLOR]"}[str(payload.get('online',False))],payload['host'],len(payload.get('channels',[])))) with BUILTIN.busy_dialog(): servers = self.getDiscovery() lizlst = poolit(__build)(list(servers.values())) - selects = DIALOG.selectDialog(lizlst,LANGUAGE(30130),preselect=[idx for idx, listitem in enumerate(lizlst) if loadJSON(listitem.getPath()).get('enabled',False)]) - if not selects is None: - for idx, liz in enumerate(lizlst): - instancePath = SETTINGS.hasPVRInstance(liz.getLabel()) - if idx in selects: - if not servers.get(liz.getLabel()).get('enabled',False): - DIALOG.notificationDialog(LANGUAGE(30099)%(liz.getLabel())) - servers.get(liz.getLabel()).update({'enabled':True}) - __chkSettings(servers.get(liz.getLabel()).get('settings',{})) - if not instancePath: SETTINGS.setPVRRemote(servers.get(liz.getLabel()).get('host'),liz.getLabel()) - else: - if servers.get(liz.getLabel()).get('enabled',False): DIALOG.notificationDialog(LANGUAGE(30100)%(liz.getLabel())) - servers.get(liz.getLabel()).update({'enabled':False}) - if instancePath: FileAccess.delete(instancePath) - if self.setDiscovery(servers): - return PROPERTIES.setEXTProperty('%s.chkDiscovery'%(ADDON_ID),'true') + + selects = DIALOG.selectDialog(lizlst,LANGUAGE(30130),preselect=[idx for idx, listitem in enumerate(lizlst) if loadJSON(listitem.getPath()).get('enabled',False)]) + if not selects is None: + for idx, liz in enumerate(lizlst): + instancePath = SETTINGS.hasPVRInstance(liz.getLabel()) + if idx in selects: + if not servers[liz.getLabel()].get('enabled',False): + DIALOG.notificationDialog(LANGUAGE(30099)%(liz.getLabel())) + servers[liz.getLabel()]['enabled'] = True + __chkSettings(servers[liz.getLabel()].get('settings',{})) + if not instancePath: SETTINGS.setPVRRemote(servers[liz.getLabel()].get('host'),liz.getLabel()) + else: + if servers[liz.getLabel()].get('enabled',False): + DIALOG.notificationDialog(LANGUAGE(30100)%(liz.getLabel())) + servers[liz.getLabel()]['enabled'] = False + if instancePath: FileAccess.delete(instancePath) + if self.setDiscovery(servers): + return PROPERTIES.setEXTProperty('%s.chkDiscovery'%(ADDON_ID),'true') def run(self): diff --git a/plugin.video.pseudotv.live/resources/lib/overlay.py b/plugin.video.pseudotv.live/resources/lib/overlay.py index 80efa12a..0686fe67 100644 --- a/plugin.video.pseudotv.live/resources/lib/overlay.py +++ b/plugin.video.pseudotv.live/resources/lib/overlay.py @@ -71,7 +71,7 @@ def onInit(self): self.setFocusId(40001) except Exception as e: log("Replay: onInit, failed! %s\ncitem = %s"%(e,self.myPlayer.sysInfo), xbmc.LOGERROR) - self._onClose() + self.onClose() def _progressLoop(self, control, wait=OVERLAY_DELAY): @@ -82,7 +82,7 @@ def _progressLoop(self, control, wait=OVERLAY_DELAY): prog = int((abs(wait-tot)*100)//tot) if prog > 0: control.setAnimations([('Conditional', 'effect=zoom start=%s,100 end=%s,100 time=1000 center=%s,100 condition=True'%((prog-20),(prog),xpos))]) wait -= 1 - self._onClose() + self.onClose() def onAction(self, act): @@ -98,10 +98,10 @@ def onAction(self, act): elif actionId == ACTION_MOVE_UP: BUILTIN.executebuiltin('AlarmClock(up,Action(up),time,100,true,false)') elif actionId == ACTION_MOVE_DOWN: BUILTIN.executebuiltin('AlarmClock(down,Action(down),time,100,true,false)') elif actionId in ACTION_PREVIOUS_MENU: BUILTIN.executebuiltin('AlarmClock(back,Action(back),time,100,true,false)') - self._onClose() + self.onClose() - def _onClose(self): + def onClose(self): log("Replay: onClose") self._closing = True self.close() @@ -233,7 +233,7 @@ def close(self): self._cancelChannelBug() self.runActions(RULES_ACTION_OVERLAY_CLOSE, self.player.sysInfo.get('citem',{}), inherited=self) for control, visible in list(self.controlManager.items()): self._removeControl(control) - + def _cancelOnNext(self): self.log('_cancelOnNext') @@ -245,7 +245,7 @@ def _cancelOnNext(self): def _cancelChannelBug(self): self.log('_cancelChannelBug') - self._setImage(self._channelBug,'None') + self._setImage(self._channelBug,' ') self._setVisible(self._channelBug,False) if self._channelBugThread.is_alive(): self._channelBugThread.cancel() @@ -348,7 +348,7 @@ def getOnNextInterval(interval=3): remaining = floor(self.player.getTimeLabel('TimeRemaining')) showTime = (abs(totalTime - (totalTime * .75)) - (OVERLAY_DELAY * interval)) intTime = roundupDIV(showTime,interval) - showOnNext = remaining <= showTime and totalTime > SELECT_DELAY and not BUILTIN.getInfoLabel('NextGenre','VideoPlayer') in FILLER_TYPE and int((BUILTIN.getInfoLabel('Duration','VideoPlayer') or '0')) > self.minDuration + showOnNext = remaining <= showTime and totalTime > SELECT_DELAY and not BUILTIN.getInfoLabel('NextGenre','VideoPlayer') in FILLER_TYPE and self.player.getPlayerTime() > self.minDuration if remaining < intTime: return getOnNextInterval(interval + 1) self.log('toggleOnNext, totalTime = %s, interval = %s, remaining = %s, intTime = %s, showOnNext = %s'%(totalTime,interval,remaining,intTime,showOnNext)) diff --git a/plugin.video.pseudotv.live/resources/lib/resources.py b/plugin.video.pseudotv.live/resources/lib/resources.py index 02b4b0aa..791cc82c 100644 --- a/plugin.video.pseudotv.live/resources/lib/resources.py +++ b/plugin.video.pseudotv.live/resources/lib/resources.py @@ -163,7 +163,7 @@ def isMono(self, file: str) -> bool: elif hasAddon('script.module.pil'): try: from PIL import Image, ImageStat - file = unquoteString(file.replace('resource://','special://home/addons/').replace('image://','')).replace('\\','/') + file = FileAccess.translatePath(unquoteString(file.replace('resource://','special://home/addons/').replace('image://','')).replace('\\','/')) mono = reduce(lambda x, y: x and y < 0.005, ImageStat.Stat(Image.open(FileAccess.open(file,'rb'))).var, True) self.log('isMono, mono = %s, file = %s'%(mono,file)) return mono diff --git a/plugin.video.pseudotv.live/resources/lib/rules.py b/plugin.video.pseudotv.live/resources/lib/rules.py index b106bb28..60ea499f 100644 --- a/plugin.video.pseudotv.live/resources/lib/rules.py +++ b/plugin.video.pseudotv.live/resources/lib/rules.py @@ -278,9 +278,9 @@ def onActionSelect(self, optionindex, header=ADDON_NAME, preselect=-1, useDetail self.optionValues[optionindex] = self.selectBoxOptions[optionindex][select] - def onActionBrowse(self, optionindex, type=0, heading=ADDON_NAME, shares='', mask='', options=None, useThumbs=True, treatAsFolder=False, prompt=True, multi=False, monitor=False): + def onActionBrowse(self, optionindex, type=0, heading=ADDON_NAME, shares='', mask='', options=[], include=None, useThumbs=True, treatAsFolder=False, prompt=True, multi=False, monitor=False): log("onActionBrowse") - info = self.dialog.browseDialog(type, heading, self.optionValues[optionindex].replace('None',''), shares, mask, options, useThumbs, treatAsFolder, prompt, multi, monitor) + info = self.dialog.browseDialog(type, heading, self.optionValues[optionindex].replace('None',''), shares, mask, options, include, useThumbs, treatAsFolder, prompt, multi, monitor) if info is not None: self.optionValues[optionindex] = info @@ -442,7 +442,7 @@ def getImage(self, image='None'): def onAction(self, optionindex): if optionindex == 0: self.onActionToggleBool(optionindex) - elif optionindex == 1: self.onActionBrowse(optionindex, type=1, heading=self.optionLabels[1], mask=xbmc.getSupportedMedia('picture'), options=list(range(6,11))) + elif optionindex == 1: self.onActionBrowse(optionindex, type=1, heading=self.optionLabels[1], mask=xbmc.getSupportedMedia('picture'), include=list(range(6,11))) elif optionindex == 2: self.getPosition(optionindex) return self.optionValues[optionindex] diff --git a/plugin.video.pseudotv.live/resources/lib/server.py b/plugin.video.pseudotv.live/resources/lib/server.py index f07c514b..a5201197 100644 --- a/plugin.video.pseudotv.live/resources/lib/server.py +++ b/plugin.video.pseudotv.live/resources/lib/server.py @@ -142,48 +142,55 @@ def do_POST(self): def do_GET(self): self.log('do_GET, incoming path = %s'%(self.path)) - if self.path.lower().startswith('/remote.json'): - content = "application/json" - chunk = dumpJSON(SETTINGS.getPayload(inclMeta=True),idnt=4).encode(encoding=DEFAULT_ENCODING) - self._set_headers(content,chunk) - self.log('do_GET, sending = remote payload, size = %s'%(len(chunk))) - self.wfile.write(chunk) - self.wfile.close() - return + if self.path.lower().startswith('/remote'): + path = self.path.lower() + if self.path.lower().endswith('.json'): + content = "application/json" + chunk = dumpJSON(SETTINGS.getPayload(inclMeta=True),idnt=4).encode(encoding=DEFAULT_ENCODING) + elif self.path.lower().endswith('.html'): + from json2table import convert + content = "text/html" + chunk = convert(SETTINGS.getPayload(inclMeta=True),build_direction="LEFT_TO_RIGHT",table_attributes={"style":"width:25%","class":"table-dark"}).encode(encoding=DEFAULT_ENCODING) + else: self.send_error(404, "Not found") elif self.path.lower() == '/%s'%(M3UFLE.lower()): - path = M3UFLEPATH content = "application/vnd.apple.mpegurl" + path = M3UFLEPATH elif self.path.lower() == '/%s'%(XMLTVFLE.lower()): - path = XMLTVFLEPATH content = "text/xml" + path = XMLTVFLEPATH elif self.path.lower() == '/%s'%(GENREFLE.lower()): - path = GENREFLEPATH content = "text/plain" + path = GENREFLEPATH elif self.path.lower().startswith("/images/"): path = os.path.join(LOGO_LOC,unquoteString(self.path.replace('/images/',''))) content = mimetypes.guess_type(self.path[1:])[0] else: self.send_error(404, "Not found") - - if FileAccess.exists(path): + + if not path: return + elif path.endswith(('.json','.html')): self.log('do_GET, outgoing path = %s, content = %s'%(path, content)) + self._set_headers(content,chunk) + self.log('do_GET, sending = remote payload, size = %s'%(len(chunk))) + self.wfile.write(chunk) + self.wfile.close() + elif FileAccess.exists(path): if self.path.lower() == '/%s'%(XMLTVFLE.lower()): self.log('do_GET, sending = %s'%(path)) - with FileLock(): - fle = FileAccess.open(path, "r") - if 'gzip' in self.headers.get('accept-encoding'): - self.log('do_GET, gzip compressing') - data = self._gzip_encode(fle.read().encode(encoding=DEFAULT_ENCODING)) - self._set_headers(content,data,True) - self.wfile.write(data) - else: - self._set_headers(content) - while not self.monitor.abortRequested(): - chunk = fle.read(64 * 1024).encode(encoding=DEFAULT_ENCODING) - if not chunk or self.monitor.myService._interrupt(.001): break - self.send_header('content-length', len(content)) - self.wfile.write(chunk) - self.wfile.close() - fle.close() + fle = FileAccess.open(path, "r") + if 'gzip' in self.headers.get('accept-encoding'): + self.log('do_GET, gzip compressing') + data = self._gzip_encode(fle.read().encode(encoding=DEFAULT_ENCODING)) + self._set_headers(content,data,True) + self.wfile.write(data) + else: + self._set_headers(content) + while not self.monitor.abortRequested(): + chunk = fle.read(64 * 1024).encode(encoding=DEFAULT_ENCODING) + if not chunk or self.monitor.myService._interrupt(.001): break + self.send_header('content-length', len(content)) + self.wfile.write(chunk) + self.wfile.close() + fle.close() elif self.path.lower().startswith("/images/"): fle = FileAccess.open(path, "rb") chunk = fle.readBytes() @@ -254,7 +261,7 @@ def _start(self): self._httpd_thread = Thread(target=self._server.serve_forever) self._httpd_thread.daemon=True self._httpd_thread.start() - SETTINGS.setSetting('Remote_Status',{'True':'[COLOR=green]Online[/COLOR]','False':'[COLOR=red]Offline[/COLOR]'}[str(self.isRunning)]) + SETTINGS.setSetting('Remote_Status',{'True':'[COLOR=green][B]Online[/B][/COLOR]','False':'[COLOR=red][B]Offline[/B][/COLOR]'}[str(self.isRunning)]) except Exception as e: self.log("_start, Failed! %s"%(e), xbmc.LOGERROR) diff --git a/plugin.video.pseudotv.live/resources/lib/service.py b/plugin.video.pseudotv.live/resources/lib/service.py index 7edbaf31..04fda82b 100644 --- a/plugin.video.pseudotv.live/resources/lib/service.py +++ b/plugin.video.pseudotv.live/resources/lib/service.py @@ -69,13 +69,13 @@ def onPlayBackStarted(self): def onAVChange(self): self.log('onAVChange') + self.isIdle = self.myService.monitor.chkIdle() if self.isPseudoTV: self.lastSubState = BUILTIN.isSubtitle() self.disableTrakt = SETTINGS.getSettingBool('Disable_Trakt') #todo adv. rule opt self.rollbackPlaycount = SETTINGS.getSettingBool('Rollback_Watched')#todo adv. rule opt self.restartPercentage = SETTINGS.getSettingInt('Restart_Percentage') self.saveDuration = SETTINGS.getSettingBool('Store_Duration') - self.isIdle = self.myService.monitor.chkIdle() def onAVStarted(self): @@ -282,7 +282,7 @@ def log(self, msg, level=xbmc.LOGDEBUG): def getIdle(self): try: idleTime = (int(xbmc.getGlobalIdleTime()) or 0) except: #Kodi raises error after sleep. - self.log('getIdleTime, Kodi waking up from sleep...') + self.log('getIdle, Kodi waking up from sleep...') idleTime = 0 idleState = (idleTime > OVERLAY_DELAY) return idleState, idleTime diff --git a/plugin.video.pseudotv.live/resources/lib/tasks.py b/plugin.video.pseudotv.live/resources/lib/tasks.py index 52aac417..863f17be 100644 --- a/plugin.video.pseudotv.live/resources/lib/tasks.py +++ b/plugin.video.pseudotv.live/resources/lib/tasks.py @@ -101,7 +101,7 @@ def chkPVRBackend(self): if hasAddon(PVR_CLIENT_ID,True,True,True,True): if not SETTINGS.hasPVRInstance(): with BUILTIN.busy_dialog(isPlaying=BUILTIN.getInfoBool('Playing','Player')): - SETTINGS.setPVRPath(USER_LOC, validString(SETTINGS.getFriendlyName())) + SETTINGS.setPVRPath(USER_LOC, SETTINGS.getFriendlyName()) def _chkQueTimer(self): @@ -213,6 +213,7 @@ def chkChannels(self): if PROPERTIES.hasFirstrun(): self._que(self.chkChannels,2) else: self.service.currentChannels = list(channels) + PROPERTIES.setEXTProperty('%s.has.Channels'%(ADDON_ID),str(len(self.service.currentChannels) > 0).lower()) if updated: PROPERTIES.setEXTProperty('%s.chkPVRRefresh'%(ADDON_ID),'true') if not PROPERTIES.hasFirstrun(): PROPERTIES.setFirstrun(state=True) except Exception as e: diff --git a/plugin.video.pseudotv.live/resources/lib/utilities.py b/plugin.video.pseudotv.live/resources/lib/utilities.py index 1b933592..92b3bf6a 100644 --- a/plugin.video.pseudotv.live/resources/lib/utilities.py +++ b/plugin.video.pseudotv.live/resources/lib/utilities.py @@ -99,7 +99,7 @@ def qrSupport(self): def qrRemote(self): - DIALOG.qrDialog('http://%s/%s'%(PROPERTIES.getRemoteURL(),REMOTEFLE), 'PseudoTV Live Remote Status') + DIALOG.qrDialog('http://%s/%s'%(PROPERTIES.getRemoteURL(),'remote.html'), 'PseudoTV Live Remote Status') def userGroups(self): @@ -207,7 +207,7 @@ def run(self): with BUILTIN.busy_dialog(): from jsonrpc import JSONRPC jsonRPC = JSONRPC() - if SETTINGS.setPVRPath(USER_LOC,validString(SETTINGS.getFriendlyName()),prompt=True,force=True): + if SETTINGS.setPVRPath(USER_LOC,SETTINGS.getFriendlyName(),prompt=True,force=True): DIALOG.notificationDialog(LANGUAGE(32152)) else: DIALOG.notificationDialog(LANGUAGE(32165)) del jsonRPC diff --git a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.background.xml b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.background.xml index 99eb919e..827ab07a 100644 --- a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.background.xml +++ b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.background.xml @@ -4,7 +4,19 @@ SetProperty(plugin.video.pseudotv.live.OVERLAY_BACKGROUND,true,10000) SetProperty(plugin.video.pseudotv.live.OVERLAY_BACKGROUND,false,10000) + + + + + + + + + + + + 0 0 Background !Playing diff --git a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.channelbug.xml b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.channelbug.xml index bb36cd32..68e85dce 100644 --- a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.channelbug.xml +++ b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.channelbug.xml @@ -4,7 +4,19 @@ SetProperty(plugin.video.pseudotv.live.OVERLAY_CHANNELBUG_RUNNING,true,10000) SetProperty(plugin.video.pseudotv.live.OVERLAY_CHANNELBUG_RUNNING,false,10000) + + + + + + + + + + + + 0 0 @@ -29,33 +41,33 @@ scale backgrounds/ratio.png - - - 200 - 35 - 1000 - 80 - 10 - horizontal - true - WindowOpen - - 50 - 80 - left - center - buttons/dpad.png - keep - - - left - center - auto + + 200 + 35 + 1000 80 - font32_title - ffffffff - ff000000 - + 10 + horizontal + true + WindowOpen + + 50 + 80 + left + center + buttons/dpad.png + keep + + + left + center + auto + 80 + font32_title + ffffffff + ff000000 + + diff --git a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.manager.xml b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.manager.xml index ab2a1f08..4cae2833 100644 --- a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.manager.xml +++ b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.manager.xml @@ -3,7 +3,7 @@ 0x00000000 SetProperty(plugin.video.pseudotv.live.OVERLAY_MANAGER,true,10000) SetProperty(plugin.video.pseudotv.live.OVERLAY_MANAGER,false,10000) - + @@ -13,13 +13,13 @@ - 90 - 50% - 1820 + 90 + 50% + 1820 -2000 -2000 diff --git a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.qrcode.xml b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.qrcode.xml index 814e3efb..2a8e4724 100644 --- a/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.qrcode.xml +++ b/plugin.video.pseudotv.live/resources/skins/default/1080i/plugin.video.pseudotv.live.qrcode.xml @@ -13,13 +13,13 @@ - 270 - 480 - 960 + 270 + 480 + 960 80 480 diff --git a/zips/plugin.video.pseudotv.live/plugin.video.pseudotv.live-0.5.4o.zip b/zips/plugin.video.pseudotv.live/plugin.video.pseudotv.live-0.5.4o.zip index 32d67c22..deec21d5 100644 Binary files a/zips/plugin.video.pseudotv.live/plugin.video.pseudotv.live-0.5.4o.zip and b/zips/plugin.video.pseudotv.live/plugin.video.pseudotv.live-0.5.4o.zip differ diff --git a/zips/plugin.video.pseudotv.live/plugin.video.pseudotv.live-0.5.4p.zip b/zips/plugin.video.pseudotv.live/plugin.video.pseudotv.live-0.5.4p.zip new file mode 100644 index 00000000..e4efa3ac Binary files /dev/null and b/zips/plugin.video.pseudotv.live/plugin.video.pseudotv.live-0.5.4p.zip differ