Skip to content

Commit

Permalink
v.0.4.5b
Browse files Browse the repository at this point in the history
  • Loading branch information
Lunatixz committed Jan 25, 2024
1 parent 6a33c54 commit 059c70f
Show file tree
Hide file tree
Showing 17 changed files with 162 additions and 151 deletions.
3 changes: 1 addition & 2 deletions 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.4.5a" name="PseudoTV Live" provider-name="Lunatixz">
<addon id="plugin.video.pseudotv.live" version="0.4.5b" name="PseudoTV Live" provider-name="Lunatixz">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="pvr.iptvsimple" version="7.5.0"/>
Expand All @@ -13,7 +13,6 @@
<import addon="resource.images.musicgenreicons.text" version="0.0.1"/>
<import addon="resource.images.moviegenreicons.transparent" version="0.0.1"/>
<import addon="script.module.pil" optional="true" version="5.1.0"/>

</requires>
<extension point="xbmc.python.pluginsource" library="resources/lib/default.py">
<provides>video</provides>
Expand Down
2 changes: 1 addition & 1 deletion addons.xml.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
aaeaccee130840fdeb3bc2bc232b5ac4
c3e878aa86e205046aa264dc97d59067
3 changes: 1 addition & 2 deletions 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.4.5a" name="PseudoTV Live" provider-name="Lunatixz">
<addon id="plugin.video.pseudotv.live" version="0.4.5b" name="PseudoTV Live" provider-name="Lunatixz">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="pvr.iptvsimple" version="7.5.0"/>
Expand All @@ -12,7 +12,6 @@
<import addon="resource.images.musicgenreicons.text" version="0.0.1"/>
<import addon="resource.images.moviegenreicons.transparent" version="0.0.1"/>
<import addon="script.module.pil" optional="true" version="5.1.0"/>

</requires>
<extension point="xbmc.python.pluginsource" library="resources/lib/default.py">
<provides>video</provides>
Expand Down
227 changes: 107 additions & 120 deletions plugin.video.pseudotv.live/resources/lib/builder.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions plugin.video.pseudotv.live/resources/lib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
OVERLAY_DELAY = 15 #secs
DTFORMAT = '%Y%m%d%H%M%S'
DTZFORMAT = '%Y%m%d%H%M%S +%z'
DTJSONFORMAT = '%Y-%m-%d %H:%M:%S'
LANG = 'en' #todo parse kodi region settings
DEFAULT_ENCODING = "utf-8"
PROMPT_DELAY = 4000 #msecs
Expand Down
2 changes: 1 addition & 1 deletion plugin.video.pseudotv.live/resources/lib/context_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __init__(self, sysARG, writer):
with busy_dialog():
target = '%ss'%(writer.get('media','video'))
orgpath = writer.get('originalpath','')
citem = Builder().getProvisional(writer.get('citem',{}))
citem = Builder().buildProvisional(writer.get('citem',{}))

if '?xsp=' in orgpath:
path, params = orgpath.split('?xsp=')
Expand Down
6 changes: 3 additions & 3 deletions plugin.video.pseudotv.live/resources/lib/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
from globals import *
from plugin import Plugin

def run(sysARG):
def run(sysARG):
params = dict(urllib.parse.parse_qsl(sysARG[2][1:].replace('.pvr','')))
name = (unquoteString(params.get("name",'')) or None)
channel = (params.get("channel",'') or None)
url = (params.get("url",'') or None)
id = (params.get("id",'') or None)
starttime = (params.get("starttime",'') or None)
endtime = (params.get("endtime",'') or None)
mode = (params.get("mode",'') or 'guide')
radio = (params.get("radio",'') or 'False').lower() == "true"
log("Default: run, params = %s"%(params))
Expand All @@ -42,7 +42,7 @@ def run(sysARG):
elif mode == 'vod':
threadit(Plugin(sysARG).playVOD)(name,id)
elif mode == 'broadcast':
threadit(Plugin(sysARG).playVOD)(name,id)
threadit(Plugin(sysARG).playBroadcast)(name,channel,datetime.datetime.fromtimestamp((datetime.datetime.timestamp(strpTime(endtime, DTJSONFORMAT)) - getTimeoffset())).strftime(DTJSONFORMAT))
elif mode == 'play':
if radio: threadit(Plugin(sysARG).playRadio)(name,channel)
else: threadit(Plugin(sysARG).playChannel)(name,channel,bool(SETTINGS.getSettingInt('Playback_Method')))
Expand Down
24 changes: 17 additions & 7 deletions plugin.video.pseudotv.live/resources/lib/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ def escapeString(text, table=HTML_ESCAPE):
def unescapeString(text, table=HTML_ESCAPE):
return unescape(text,{v:k for k, v in list(table.items())})


def getJSON(file):
fle = (FileAccess.open(file, 'r') or '')
try: data = loadJSON(fle.read())
Expand Down Expand Up @@ -278,21 +277,32 @@ def pagination(list, end):
for start in range(0, len(list), end):
yield seq[start:start+end]

def roundTimeDown(thetime, offset=30): # round the given time down to the nearest
n = datetime.datetime.fromtimestamp(thetime)
def roundTimeDown(dt, offset=30): # round the given time down to the nearest
n = datetime.datetime.fromtimestamp(dt)
delta = datetime.timedelta(minutes=offset)
if n.minute > (offset-1): n = n.replace(minute=offset, second=0, microsecond=0)
else: n = n.replace(minute=0, second=0, microsecond=0)
return time.mktime(n.timetuple())

def strpTime(datestring, format='%Y-%m-%d %H:%M:%S'): #convert json pvr datetime string to datetime obj, thread safe!
def roundTimeUp(dt=None, roundTo=60):
if dt == None : dt = datetime.datetime.now()
seconds = (dt.replace(tzinfo=None) - dt.min).seconds
rounding = (seconds+roundTo/2) // roundTo * roundTo
return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)

def strpTime(datestring, format=DTJSONFORMAT): #convert json pvr datetime string to datetime obj, thread safe!
try: return datetime.datetime.strptime(datestring, format)
except TypeError: return datetime.datetime.fromtimestamp(time.mktime(time.strptime(datestring, format)))
except: return ''

def getLocalTime():
offset = (datetime.datetime.utcnow() - datetime.datetime.now())
return time.time() + offset.total_seconds() #returns timestamp
def getTimeoffset():
return (int((datetime.datetime.now() - datetime.datetime.utcnow()).days * 86400 + round((datetime.datetime.now() - datetime.datetime.utcnow()).seconds, -1)))

def getUTCstamp():
return time.time() - getTimeoffset()

def getGMTstamp():
return time.time()

def randomShuffle(items=[]):
if len(items) > 0:
Expand Down
4 changes: 2 additions & 2 deletions plugin.video.pseudotv.live/resources/lib/jsonrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,15 +453,15 @@ def buildWebBase(self, local=False):

@cacheit(checksum=getInstanceID())
def buildProvisionalPaths(self, value, type):
self.log('buildProvisional, value = %s, type = %s'%(value,type))
self.log('buildProvisionalPaths, value = %s, type = %s'%(value,type))
paths = []
for request in PROVISIONAL_TYPES.get(type,{}).get('path',[]):
items = self.getDirectory(param={"directory":request}, cache=False).get('files',[])
for item in items:
if item.get('label') == value:
paths.append(item['file'])
break
self.log('buildProvisional, return paths = %s'%(paths))
self.log('buildProvisionalPaths, return paths = %s'%(paths))
return paths


Expand Down
3 changes: 1 addition & 2 deletions plugin.video.pseudotv.live/resources/lib/m3u.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def _save(self, file=M3UFLEPATH):

opts = list(self.getMitem().keys())
mins = [opts.pop(opts.index(key)) for key in list(M3U_MIN.keys()) if key in opts] #min required m3u entries.
line = '#EXTINF:-1 tvg-chno="%s" tvg-id="%s" tvg-name="%s" tvg-logo="%s" group-title="%s" radio="%s" catchup="%s" catchup-source="%s" %s,%s\n'
line = '#EXTINF:-1 tvg-chno="%s" tvg-id="%s" tvg-name="%s" tvg-logo="%s" group-title="%s" radio="%s" catchup="%s" %s,%s\n'
self.M3UDATA['stations'] = self.sortStations(self.M3UDATA.get('stations',[]))
self.M3UDATA['recordings'] = self.sortStations(self.M3UDATA.get('recordings',[]))
self.log('_save, saving %s stations and %s recordings to %s'%(len(self.M3UDATA['stations']),len(self.M3UDATA['recordings']),file))
Expand All @@ -229,7 +229,6 @@ def _save(self, file=M3UFLEPATH):
';'.join(station['group']),
station['radio'],
station['catchup'],
station['catchup-source'],
optional,
station['label']))

Expand Down
28 changes: 22 additions & 6 deletions plugin.video.pseudotv.live/resources/lib/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def _matchJSON():

@timeit
def matchChannel(self, chname, id, radio=False, isPlaylist=False):
self.log('matchChannel, id = %s, radio = %s, isPlaylist = %s'%(id,radio,isPlaylist))
self.log('matchChannel, id = %s, chname = %s, radio = %s, isPlaylist = %s'%(id,chname,radio,isPlaylist))
def _match():
channels = self.jsonRPC.getPVRChannels(radio)
for channel in channels:
Expand All @@ -143,7 +143,7 @@ def _match():
return self.playError(pvritem)

try: pvritem['epgurl'] = 'pvr://guide/%s/{starttime}.epg'%(re.compile('pvr://guide/(.*)/', re.IGNORECASE).search(self.sysInfo.get('path')).group(1))
except: pvritem['epgurl'] = ''#"pvr://guide/1197/2022-02-14 18:22:24.epg"
except: pvritem['epgurl'] = self.sysInfo.get('path','')#"pvr://guide/1197/2022-02-14 18:22:24.epg"
if isPlaylist and not radio: pvritem = self.extendProgrammes(pvritem)
PROPERTIES.setEXTProperty('%s.pendingPVRITEM.%s'%(ADDON_ID,pvritem.get('channelid','-1')),dumpJSON(pvritem))
cacheResponse = self.cache.set(cacheName, pvritem, checksum=getInstanceID(), expiration=datetime.timedelta(seconds=OVERLAY_DELAY), json_data=True)
Expand Down Expand Up @@ -175,10 +175,26 @@ def playVOD(self, name, url):
self.resolveURL(True, liz)


def playBroadcast(self, name, id):
self.log('playBroadcast, id = %s'%(id))


def playBroadcast(self, name, id, endtime):
self.log('playBroadcast, id = %s, endtime = %s'%(id, endtime))
with preparingPlayback():
nowitem = {}
found = False
listitems = [xbmcgui.ListItem()] #empty listitem required to pass failed playback.
pvritem = self.matchChannel(name,id,False,True)
if pvritem:
nextitems = [pvritem.get('broadcastnow',{})]
nextitems.extend(pvritem.get('broadcastnext',[]))
for nowitem in nextitems:
if nowitem.get('endtime') == endtime:
found = True
liz = LISTITEMS.buildItemListItem(decodeWriter(nowitem.get('writer',{})))
liz.setProperty('pvritem',dumpJSON(pvritem))
listitems = [liz]
break
self.resolveURL(found, listitems[0])


def playChannel(self, name, id, isPlaylist=False):
self.log('playChannel, id = %s, isPlaylist = %s'%(id,isPlaylist))
with preparingPlayback():
Expand Down
8 changes: 4 additions & 4 deletions plugin.video.pseudotv.live/resources/lib/xmltvs.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def loadProgrammes(self, file=XMLTVFLEPATH):
def loadStopTimes(self, channels=None, programmes=None, fallback=None):
if channels is None: channels = self.getChannels()
if programmes is None: programmes = self.getProgrammes()
if fallback is None: fallback = datetime.datetime.fromtimestamp(roundTimeDown(getLocalTime(),offset=60)).strftime(DTFORMAT)
if fallback is None: fallback = datetime.datetime.fromtimestamp(roundTimeDown(getUTCstamp(),offset=60)).strftime(DTFORMAT)

for channel in channels:
try:
Expand Down Expand Up @@ -186,7 +186,7 @@ def cleanChannels(self, channels, programmes): # remove stations with no guideda

def cleanProgrammes(self, programmes): # remove expired content, ignore "recordings" ie. media=True
try:
now = (datetime.datetime.fromtimestamp(float(getLocalTime())) - datetime.timedelta(days=MIN_GUIDEDAYS)) #allow some old programmes to avoid empty cells.
now = (datetime.datetime.fromtimestamp(float(getUTCstamp())) - datetime.timedelta(days=MIN_GUIDEDAYS)) #allow some old programmes to avoid empty cells.
tmpProgrammes = [program for program in programmes if (strpTime(program['stop'].rstrip(),DTFORMAT) > now)]
except Exception as e:
self.log("cleanProgrammes, Failed! %s"%(e), xbmc.LOGERROR)
Expand Down Expand Up @@ -239,7 +239,7 @@ def addRecording(self, ritem, fitem):
else:
self.XMLTVDATA['recordings'][idx] = sitem # replace existing channel meta

fitem['start'] = getLocalTime()
fitem['start'] = getUTCstamp()
fitem['stop'] = fitem['start'] + fitem['duration']
if self.addProgram(ritem['id'],self.getProgramItem(ritem,fitem)):
return self._save()
Expand Down Expand Up @@ -383,7 +383,7 @@ def matchChannel(channel, channels, programmes):
def chkImport(self, channels, programmes): # parse for empty programmes, inject single cell entry.
try:
def addSingleEntry(channel, start=None, length=10800): #create a single entry with min. channel meta, use as a filler.
if start is None: start = datetime.datetime.fromtimestamp(roundTimeDown(getLocalTime(),offset=60))
if start is None: start = datetime.datetime.fromtimestamp(roundTimeDown(getUTCstamp(),offset=60))
pitem = {'channel' : channel.get('id'),
'title' : [(channel.get('display-name',[{'',LANG}])[0][0], LANG)],
'desc' : [(xbmc.getLocalizedString(161), LANG)],
Expand Down
2 changes: 1 addition & 1 deletion plugin.video.pseudotv.live/resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@
</setting>
<setting id="Duration_Type" type="integer" label="30049" help="33049">
<level>2</level>
<default>0</default>
<default>1</default>
<constraints>
<options>
<option label="30050">0</option>
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 059c70f

Please sign in to comment.