Skip to content

Commit

Permalink
v.0.5.6q
Browse files Browse the repository at this point in the history
  • Loading branch information
Lunatixz committed Dec 15, 2024
1 parent 07af34a commit 4309ed9
Show file tree
Hide file tree
Showing 18 changed files with 61 additions and 41 deletions.
2 changes: 1 addition & 1 deletion addons.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addons>
<addon id="plugin.video.pseudotv.live" version="0.5.6p" name="PseudoTV Live" provider-name="Lunatixz">
<addon id="plugin.video.pseudotv.live" version="0.5.6q" name="PseudoTV Live" provider-name="Lunatixz">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="pvr.iptvsimple" version="21.8.0"/>
Expand Down
2 changes: 1 addition & 1 deletion addons.xml.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a3aa684a6c632ac9534b308a534e8838
9550523391d97a454e019fd66bb822a0
2 changes: 0 additions & 2 deletions language_report.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Language IDS w\empty strings: {
"30127": "",
"32024": "",
"32197": "",
"33130": ""
Expand Down Expand Up @@ -136,7 +135,6 @@ Language IDS not found in py files, possibly only in xml: {
"30117": "Remove Recording",
"30123": "Two Shows",
"30124": "Three Shows",
"30127": "",
"30128": "Searching for %s logo",
"30133": "Player",
"30135": "Include",
Expand Down
2 changes: 1 addition & 1 deletion plugin.video.pseudotv.live/addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.video.pseudotv.live" version="0.5.6p" name="PseudoTV Live" provider-name="Lunatixz">
<addon id="plugin.video.pseudotv.live" version="0.5.6q" name="PseudoTV Live" provider-name="Lunatixz">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="pvr.iptvsimple" version="21.8.0"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ msgid "Include Kodi Trailers"
msgstr ""

msgctxt "#30127"
msgid ""
msgid "Custom"
msgstr ""

msgctxt "#30128"
Expand Down
6 changes: 5 additions & 1 deletion plugin.video.pseudotv.live/resources/lib/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def __hasProgrammes(cacheResponse):
self.log('build, no verified channels found!')
return False, False

channels = sorted(self.verify(channels), key=itemgetter('number'))
channels = self.sortChannels(self.verify(channels))
now = getUTCstamp()
start = roundTimeDown(getUTCstamp(),offset=60)#offset time to start bottom of the hour
stopTimes = dict(self.xmltv.loadStopTimes(fallback=datetime.datetime.fromtimestamp(start).strftime(DTFORMAT)))
Expand Down Expand Up @@ -161,6 +161,10 @@ def __hasProgrammes(cacheResponse):
self.log('build, completeBuild = %s, updated = %s, saved = %s'%(self.completeBuild,bool(updated),self.saveChannelLineups()))
return self.completeBuild, bool(updated)


def sortChannels(self, channels: list) -> list:
return Channels().sortChannels(channels)


def getFileList(self, citem: dict, now: time, start: time) -> bool and list:
self.log('getFileList, [%s] start = %s'%(citem['id'],start))
Expand Down
9 changes: 7 additions & 2 deletions plugin.video.pseudotv.live/resources/lib/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ def _verify(self, channels: list=[]):


def _save(self, file=CHANNELFLEPATH) -> bool:
self.channelDATA['uuid'] = SETTINGS.getMYUUID()
self.channelDATA['channels'] = sorted(self.channelDATA['channels'], key=itemgetter('number'))
self.channelDATA['uuid'] = SETTINGS.getMYUUID()
self.channelDATA['channels'] = self.sortChannels(self.channelDATA['channels'])
self.log('_save, channels = %s'%(len(self.channelDATA['channels'])))
return setJSON(file,self.channelDATA)

Expand Down Expand Up @@ -83,6 +83,11 @@ def getType(self, type: str):
return list([citem for citem in self.getChannels() if citem.get('type') == type])


def sortChannels(self, channels: list) -> list:
try: return sorted(channels, key=itemgetter('number'))
except: return channels


def setChannels(self, channels: list=[]) -> bool:
if len(channels) == 0: channels = self.channelDATA['channels']
self.channelDATA['channels'] = channels
Expand Down
11 changes: 5 additions & 6 deletions plugin.video.pseudotv.live/resources/lib/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,16 @@ def KODI_LIVETV_SETTINGS(): #recommended Kodi LiveTV settings

def togglePVR(state=True, reverse=False, wait=FIFTEEN):
if SETTINGS.getSettingBool('Enable_PVR_RELOAD'):
isPlaying = BUILTIN.getInfoBool('Playing','Player')
isEnabled = BUILTIN.getInfoBool('AddonIsEnabled(%s)'%(PVR_CLIENT_ID),'System')
if (state and isEnabled) or (not state and not isEnabled): return
elif not isPlaying and not PROPERTIES.isRunning('togglePVR'):
elif not PROPERTIES.isRunning('togglePVR'):
with PROPERTIES.setRunning('togglePVR'):
log('globals: togglePVR, state = %s, reverse = %s, wait = %s'%(state,reverse,wait))
xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"Addons.SetAddonEnabled","params":{"addonid":"%s","enabled":%s}, "id": 1}'%(PVR_CLIENT_ID,str(state).lower()))
if reverse:
with BUILTIN.busy_dialog(isPlaying=BUILTIN.getInfoBool('Playing','Player')):
timerit(togglePVR)(wait,[not bool(state)])
DIALOG.notificationWait('%s: %s'%(PVR_CLIENT_NAME,LANGUAGE(32125)),wait=wait)
if not reverse: return
MONITOR().waitForAbort(1.0)
with BUILTIN.busy_dialog(): timerit(togglePVR)(wait,[not bool(state)])
DIALOG.notificationWait('%s: %s'%(PVR_CLIENT_NAME,LANGUAGE(32125)),wait=wait)
else: DIALOG.notificationWait(LANGUAGE(30023)%(PVR_CLIENT_NAME))

def isRadio(item):
Expand Down
13 changes: 9 additions & 4 deletions plugin.video.pseudotv.live/resources/lib/kodi.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,9 @@ def __getMeta(payload):
payload.pop('updated')
payload.pop('md5')
payload['m3u'] = M3U().getM3U()
payload['xmltv'] = {'stations':xmltv.getChannels(), 'recordings':xmltv.getRecordings(), 'programmes':[{'id':key,'end-time':datetime.datetime.fromtimestamp(time.time()).strftime(DTFORMAT)} for key, value in list(dict(xmltv.loadStopTimes()).items())]}
payload['xmltv'] = {'stations' :[{'id':station.get('id'),'display-name':station.get('display-name',[['','']])[0][0],'icon':station.get('icon',[{'src':LOGO}])[0].get('src',LOGO)} for station in xmltv.getChannels()],
'recordings':[{'id':recording.get('id'),'display-name':recording.get('display-name',[['','']])[0][0],'icon':recording.get('icon',[{'src':LOGO}])[0].get('src',LOGO)} for recording in xmltv.getRecordings()],
'programmes':[{'id':key,'end-time':datetime.datetime.fromtimestamp(time.time()).strftime(DTFORMAT)} for key, value in list(dict(xmltv.loadStopTimes()).items())]}
payload['library'] = Library().getLibrary()
payload['servers'] = Multiroom().getDiscovery()
del xmltv
Expand Down Expand Up @@ -1075,10 +1077,13 @@ def closeBusyDialog(self):


@contextmanager
def busy_dialog(self, isPlaying=False):
if not self.isBusyDialog() and not isPlaying:
def busy_dialog(self):
if not self.isBusyDialog() and not self.getInfoBool('Playing','Player'):
self.executebuiltin('ActivateWindow(busydialognocancel)')
try: yield
try:
if self.getInfoBool('Playing','Player'):
self.executebuiltin('Dialog.Close(busydialognocancel)')
yield
finally:
self.executebuiltin('Dialog.Close(busydialognocancel)')
else: yield
Expand Down
2 changes: 1 addition & 1 deletion plugin.video.pseudotv.live/resources/lib/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def _fill(type, func):
return items

if force: #clear library cache.
with BUILTIN.busy_dialog(isPlaying=BUILTIN.getInfoBool('Playing','Player')):
with BUILTIN.busy_dialog():
__clear()

complete = True
Expand Down
3 changes: 2 additions & 1 deletion plugin.video.pseudotv.live/resources/lib/m3u.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ def cleanSelf(self, items, key='id', slug='@%s'%(slugify(ADDON_NAME))): # remove


def sortStations(self, stations, key='number'):
return sorted(stations, key=itemgetter(key))
try: return sorted(stations, key=itemgetter(key))
except: return stations


def getM3U(self):
Expand Down
10 changes: 5 additions & 5 deletions plugin.video.pseudotv.live/resources/lib/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def __init__(self, *args, **kwargs):
self.eChannels = self.__loadChannels(SETTINGS.getSetting('Default_Channels'))
if self.eChannels is None: self.closeManager()
else:
self.channelList = sorted(self.createChannelList(self.buildArray(), self.eChannels), key=itemgetter('number'))
self.channelList = self.channels.sortChannels(self.createChannelList(self.buildArray(), self.eChannels))
self.newChannels = self.channelList.copy()

if self.startChannel == -1: self.startChannel = self.getFirstAvailChannel()
Expand Down Expand Up @@ -304,7 +304,7 @@ def __buildItem(key):
value = citem.get(key,' ')
if key in ["number","type","logo","id","catchup"]: return # keys to ignore, internal use only.
elif isinstance(value,(list,dict)):
if key == "group" : value = '|'.join(sorted(set(value)))
if key == "group" : value = ('|'.join(sorted(set(value))) or LANGUAGE(30127))
elif key == "path" : value = '|'.join(value)
elif key == "rules" : value = '|'.join([rule.name for key, rule in list(self.rule.loadRules([citem]).get(citem['id'],{}).items())])#todo load rule names
elif not isinstance(value,str): value = str(value)
Expand Down Expand Up @@ -417,8 +417,8 @@ def getPaths(self, citem: dict={}, paths: list=[]):
def getGroups(self, citem: dict={}, groups: list=[]):
groups = list([_f for _f in groups if _f])
ngroups = sorted([_f for _f in set(SETTINGS.getSetting('User_Groups').split('|') + GROUP_TYPES + groups) if _f])
if len(ngroups) > 0:
groups = [ngroups[idx] for idx in DIALOG.selectDialog(ngroups,header=LANGUAGE(32081),preselect=findItemsInLST(ngroups,groups),useDetails=False)]
if len(ngroups) > 0: groups = [ngroups[idx] for idx in DIALOG.selectDialog(ngroups,header=LANGUAGE(32081),preselect=findItemsInLST(ngroups,groups),useDetails=False)]
if not groups: groups = [LANGUAGE(30127)]
self.log('getGroups, groups = %s'%(groups))
return groups, citem

Expand Down Expand Up @@ -653,7 +653,7 @@ def _validate(citem):
if citem['number'] <= CHANNEL_LIMIT: citem['type'] = "Custom"
return self.setID(citem)

channelList = sorted([_f for _f in [_validate(channel) for channel in channelList] if _f], key=itemgetter('number'))
channelList = self.channels.sortChannels([_f for _f in [_validate(channel) for channel in channelList] if _f])
self.log('validateChannels, channelList = %s'%(len(channelList)))
return channelList

Expand Down
2 changes: 1 addition & 1 deletion plugin.video.pseudotv.live/resources/lib/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -1569,7 +1569,7 @@ def _buildSchedule(self, citem, fileList, builder):
self.log('_buildSchedule, id = %s, fileList = %s'%(citem.get('id'),len(fileList)))
return builder.buildCells(citem, duration=self._getTotDuration(fileList), entries=1, info={"title":'%s (%s)'%(citem.get('name'),LANGUAGE(32145)),
"episodetitle":'Updated: %s'%(datetime.datetime.fromtimestamp(time.time()).strftime(DTJSONFORMAT)),
"plot":'Size: %s videos\nTotal Runtime: %s hrs.'%(len(fileList),round(self._getTotDuration(fileList)//60//60)),
"plot":'Size: %s videos \nTotal Runtime: %s hrs.'%(len(fileList),round(self._getTotDuration(fileList)//60//60)),
"art":{"thumb":citem.get('logo',COLOR_LOGO),"fanart":FANART,"logo":citem.get('logo',LOGO),"icon":citem.get('logo',LOGO)}})

def runAction(self, actionid, citem, parameter, inherited):
Expand Down
1 change: 0 additions & 1 deletion plugin.video.pseudotv.live/resources/lib/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

class Player(xbmc.Player):
sysInfo = {}
isIdle = False
isPseudoTV = False
pendingStop = False
lastSubState = False
Expand Down
24 changes: 16 additions & 8 deletions plugin.video.pseudotv.live/resources/lib/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def chkPVRBackend(self):
self.log('chkPVRBackend')
if hasAddon(PVR_CLIENT_ID,True,True,True,True):
if not SETTINGS.hasPVRInstance():
with BUILTIN.busy_dialog(isPlaying=BUILTIN.getInfoBool('Playing','Player')):
with BUILTIN.busy_dialog():
SETTINGS.setPVRPath(USER_LOC, SETTINGS.getFriendlyName())


Expand Down Expand Up @@ -142,10 +142,10 @@ def _chkChannelUpdate(self):
id = PROPERTIES.getUpdateChannelID()
if id:
builder = Builder(self.service)
citem = [citem for citem in sorted(builder.verify(), key=itemgetter('number')) if citem.get('id') == id]
citem = builder.sortChannels([citem for citem in builder.verify() if citem.get('id') == id])
del builder
self.log('_chkChannelUpdate, id = %s, citem = %s'%(id,citem))
return self._que(self.chkChannels,citem)
return self._que(self.chkChannels,1,citem)


@cacheit(expiration=datetime.timedelta(minutes=10))
Expand Down Expand Up @@ -221,7 +221,7 @@ def chkChannels(self, channels: list=[]):
try:
builder = Builder(self.service)
if not channels:
channels = sorted(builder.verify(), key=itemgetter('number'))
channels = builder.sortChannels(builder.verify())
SETTINGS.setSetting('Select_Channels','[B]%s[/B] Channels'%(len(channels)))
PROPERTIES.setChannels(len(channels) > 0)
PROPERTIES.clearUpdateChannels() #updating all channels clear any pending individual channel updates
Expand Down Expand Up @@ -258,7 +258,15 @@ def chkJSONQUE(self):

def chkPVRRefresh(self):
self.log('chkPVRRefresh')
self._que(togglePVR,1,*(False,True))
self._que(self.chkPVRToggle,1)


def chkPVRToggle(self):
isIdle = self.service.monitor.isIdle
isPlaying = self.service.player.isPlaying()
self.log('chkPVRToggle, isIdle = %s, isPlaying = %s'%(isIdle,isPlaying))
if isIdle and not isPlaying: togglePVR(False,True)
else: self.chkPVRRefresh()


def chkFillers(self, channels=None):
Expand Down Expand Up @@ -312,7 +320,7 @@ def getGenreNames(self):
def getChannels(self):
try:
builder = Builder(self.service)
channels = sorted(builder.verify(), key=itemgetter('number'))
channels = builder.sortChannels(builder.verify())
del builder
self.log('getChannels, channels = %s'%(len(channels)))
return channels
Expand All @@ -325,7 +333,7 @@ def chkChannelChange(self, channels=[]):
nChannels = self.getChannels()
if channels != nChannels:
self.log('chkChannelChange, channels changed %s => %s: queueing chkChannels'%(len(channels),len(nChannels)))
self._que(self.chkChannels)
self._que(self.chkChannels,1,diffLSTDICT(channels,nChannels))
return nChannels
return channels

Expand All @@ -347,7 +355,7 @@ def setUserPath(self, old, new, overwrite=False):
with PROPERTIES.interruptActivity():
self.log('setUserPath, old = %s, new = %s'%(old,new))
dia = DIALOG.progressDialog(message='%s\n%s'%(LANGUAGE(32050),old))
with BUILTIN.busy_dialog(isPlaying=BUILTIN.getInfoBool('Playing','Player')):
with BUILTIN.busy_dialog():
fileItems = self.jsonRPC.walkListDirectory(old, depth=-1, appendPath=True)

cnt = 0
Expand Down
3 changes: 2 additions & 1 deletion plugin.video.pseudotv.live/resources/lib/xmltvs.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ def filterHoliday(program):


def sortChannels(self, channels: list) -> list:
return sorted(channels, key=itemgetter('display-name'))
try: return sorted(channels, key=itemgetter('display-name'))
except: return channels


def sortProgrammes(self, programmes: list) -> list:
Expand Down
8 changes: 4 additions & 4 deletions plugin.video.pseudotv.live/resources/lib/xsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,16 @@ def parseXSP(self, path: str, media: str='video', sort: dict={}, filter: dict={}
xml.close()

try: media = 'music' if dom.getElementsByTagName('smartplaylist')[0].attributes['type'].value.lower() in MUSIC_TYPES else 'video'
except Exception as e: self.log("parseXSP, parsing media failed! %s"%(e), xbmc.LOGDEBUG)
except Exception as e: self.log("parseXSP, no media type", xbmc.LOGDEBUG)

try: limit = (int(dom.getElementsByTagName('limit')[0].childNodes[0].nodeValue) or limit)
except Exception as e: self.log("parseXSP, no xsp limit set", xbmc.LOGDEBUG)
except Exception as e: self.log("parseXSP, no limit set", xbmc.LOGDEBUG)

try: sort.update({"method":dom.getElementsByTagName('order')[0].childNodes[0].nodeValue.lower()}) #todo pop rules to filter var.
except Exception as e: self.log("parseXSP, parsing method failed! %s"%(e), xbmc.LOGDEBUG)
except Exception as e: self.log("parseXSP, no sort method", xbmc.LOGDEBUG)

try: sort.update({"order":dom.getElementsByTagName('order')[0].getAttribute('direction').lower()})#todo pop rules to filter var.
except Exception as e: self.log("parseXSP, parsing order failed! %s"%(e), xbmc.LOGDEBUG)
except Exception as e: self.log("parseXSP, no sort direction", xbmc.LOGDEBUG)

try:
type = dom.getElementsByTagName('smartplaylist')[0].attributes['type'].value
Expand Down
Binary file not shown.

0 comments on commit 4309ed9

Please sign in to comment.