Skip to content

Commit

Permalink
v.0.4.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Lunatixz committed Oct 6, 2023
1 parent 32dd54e commit 05de835
Show file tree
Hide file tree
Showing 32 changed files with 518 additions and 368 deletions.
4 changes: 2 additions & 2 deletions addons.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addons>
<addon id="plugin.video.pseudotv.live" version="0.4.2k" name="PseudoTV Live" provider-name="Lunatixz">
<addon id="plugin.video.pseudotv.live" version="0.4.3" name="PseudoTV Live" provider-name="Lunatixz">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="pvr.iptvsimple" version="7.5.0"/>
<import addon="script.module.six" version="1.0.0"/>
<import addon="script.module.kodi-six" version="0.1.3.1"/>
<import addon="script.module.infotagger" version="0.0.5" />
Expand All @@ -11,7 +12,6 @@
<import addon="resource.images.studios.white" version="0.0.1"/>
<import addon="resource.images.musicgenreicons.text" version="0.0.1"/>
<import addon="resource.images.moviegenreicons.transparent" version="0.0.1"/>
<import addon="pvr.iptvsimple" optional="true" version="7.5.0"/>
<import addon="script.module.pil" optional="true" version="5.1.0"/>
</requires>
<extension point="xbmc.python.pluginsource" library="resources/lib/default.py">
Expand Down
2 changes: 1 addition & 1 deletion addons.xml.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f351ab486d57455e85735e7408cdb41b
a874e1c4ddf53dbb2ca37ea62f40c634
2 changes: 1 addition & 1 deletion plugin.video.pseudotv.live/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ If you want the exact channel numbers from PseudoTV Live to reflect onscreen, yo
- "Mixed" Content ie. TV & Movie Smartplaylists are unsupported in Kodi and its given type was designed for "Music" media. PseudoTV Live can use the "Mixed" type to allow mixed content. Create a "Mixed" type smartplaylist and select the `path, playlist or virtual folder` you'd like to use.

#### How-To Create Mixed Smartplaylist:
![How-To Create Mixed Smartplaylist](https://i.imgur.com/28mlM1P.gif)
![How-To Create Mixed Smartplaylist](https://i.imgur.com/MY7CO2p.mp4)

1. Open Smartplaylist editor, Select "Mixed" Type. Enter playlist name and when prompted save the file.

Expand Down
4 changes: 2 additions & 2 deletions plugin.video.pseudotv.live/addon.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.video.pseudotv.live" version="0.4.2k" name="PseudoTV Live" provider-name="Lunatixz">
<addon id="plugin.video.pseudotv.live" version="0.4.3" name="PseudoTV Live" provider-name="Lunatixz">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="pvr.iptvsimple" version="7.5.0"/>
<import addon="script.module.six" version="1.0.0"/>
<import addon="script.module.kodi-six" version="0.1.3.1"/>
<import addon="script.module.infotagger" version="0.0.5" />
Expand All @@ -10,7 +11,6 @@
<import addon="resource.images.studios.white" version="0.0.1"/>
<import addon="resource.images.musicgenreicons.text" version="0.0.1"/>
<import addon="resource.images.moviegenreicons.transparent" version="0.0.1"/>
<import addon="pvr.iptvsimple" optional="true" version="7.5.0"/>
<import addon="script.module.pil" optional="true" version="5.1.0"/>
</requires>
<extension point="xbmc.python.pluginsource" library="resources/lib/default.py">
Expand Down
6 changes: 6 additions & 0 deletions plugin.video.pseudotv.live/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v.0.4.4
-Added "Network Folder" clients ability to edit Autotuned channels on server (W.I.P).
-Moved "channels.json,library.json" files to "Centralized Folder" for network/client accessibility.
-Improved overlay functions to reduce memory overhead.
-Added "Show M3U/XMLTV" option to the utility Menu (Debugging tool).

v.0.4.3
-Added "Hack" method for automatically configuring IPTV-Simple (Manual configuration no longer necessary).
-Improved Usability/Notifications
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ msgid "Enable Nearest Holiday"
msgstr ""

msgctxt "#30069"
msgid "Third-Party (Settings)"
msgid "Third-Party"
msgstr ""

msgctxt "#30070"
msgid "Automatically Apply Recommended Third-Party plugin settings?"
msgid ""
msgstr ""

msgctxt "#30071"
Expand All @@ -310,11 +310,11 @@ msgid "Debugging"
msgstr ""

msgctxt "#30073"
msgid "Open Settings [IPTV Manager]"
msgid ""
msgstr ""

msgctxt "#30074"
msgid "Manually Apply Recommended Third-Party plugin settings."
msgid "Manually Apply Recommended PVR settings."
msgstr ""

msgctxt "#30075"
Expand Down Expand Up @@ -497,8 +497,9 @@ msgctxt "#30119"
msgid "Watch Later"
msgstr ""



msgctxt "#30120"
msgid "[COLOR=red][B]Warning!! [/B][/COLOR]%s\nAlready Exists, override it?."
msgstr ""



Expand Down Expand Up @@ -1018,7 +1019,7 @@ msgid "Reloading..."
msgstr ""

msgctxt "#32126"
msgid "Select Utility to perform"
msgid "Utility Menu"
msgstr ""

msgctxt "#32127"
Expand Down Expand Up @@ -1117,9 +1118,29 @@ msgctxt "#32150"
msgid "Run during playback"
msgstr ""

msgctxt "#32151"
msgid "Creating Backup"
msgstr ""

msgctxt "#32152"
msgid "Changes Applied!"
msgstr ""

msgctxt "#32153"
msgid "[COLOR=red][B]File migration required!![/B][/COLOR]\n[B]Moving File:[/B] %s\n[B]From:[/B] %s\n[B]To:[/B] %s"
msgstr ""

msgctxt "#32154"
msgid "Show M3U"
msgstr ""

msgctxt "#32155"
msgid "Show XMLTV"
msgstr ""

msgctxt "#32156"
msgid "Would you like to Install %s?"
msgstr ""


# Help - strings 33000 thru 33999 reserved for common strings used in add-ons
Expand Down Expand Up @@ -1277,7 +1298,7 @@ msgid "Allow PseudoTV Live to configure Third-Party plugins (IPTV Simple/IPTV Ma
msgstr ""

msgctxt "#33074"
msgid "Manually apply recommend settings to Third-Party plugins (IPTV Simple/IPTV Manager)"
msgid "Applying will override select user settings."
msgstr ""

msgctxt "#33078"
Expand Down
43 changes: 21 additions & 22 deletions plugin.video.pseudotv.live/resources/lib/autotune.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
class Autotune:
def __init__(self, sysARG=sys.argv, service=None):
self.log('__init__, sysARG = %s'%(sysARG))
self.sysARG = sysARG
self.sysARG = sysARG
self.library = Library(service)
self.channels = Channels()

#todo allow autotune lists shared with client for configuration, list via filesharing... library.json

def log(self, msg, level=xbmc.LOGDEBUG):
return log('%s: %s'%(self.__class__.__name__,msg),level)

Expand Down Expand Up @@ -62,7 +62,7 @@ def _runTune(self, samples=False, rebuild=False, dia=None):
rebuild = True

if samples or rebuild:
PROPERTIES.setEXTProperty('plugin.video.pseudotv.live.has.Predefined',True)
PROPERTIES.setEXTProperty('%s.has.Predefined'%(ADDON_ID),True)
for idx, ATtype in enumerate(AUTOTUNE_TYPES):
if samples and dia: dia = DIALOG.progressBGDialog(int((idx+1)*100//len(AUTOTUNE_TYPES)),dia,ATtype,'%s, %s'%(ADDON_NAME,'%s %s'%(LANGUAGE(32021),LANGUAGE(30038))))
self.selectAUTOTUNE(ATtype, autoSelect=samples, rebuildChannels=rebuild)
Expand All @@ -87,24 +87,23 @@ def _set(ATtype, selects=[]):
item['enabled'] = True
self.library.setLibrary(ATtype, items)

if not isClient():
items = self.library.getLibrary(ATtype)
if len(items) == 0 and (not rebuildChannels and not autoSelect):
return DIALOG.notificationDialog(LANGUAGE(32018)%(ATtype))

lizlst = [_build(item) for item in items]
if rebuildChannels:#rebuild channels.json entries
selects = list(_match(self.library.getEnabled(ATtype)))
elif autoSelect:#build sample channels
if len(items) >= AUTOTUNE_LIMIT:
selects = sorted(list(set(random.sample(list(set(range(0,len(items)))),AUTOTUNE_LIMIT))))
else:
selects = list(range(0,len(items)))
else:
selects = DIALOG.selectDialog(lizlst,LANGUAGE(32017)%(ATtype),preselect=list(_match(self.library.getEnabled(ATtype))))

if not selects is None: _set(ATtype, selects)
return self.buildAUTOTUNE(ATtype, self.library.getEnabled(ATtype))
items = self.library.getLibrary(ATtype)
if len(items) == 0 and (not rebuildChannels and not autoSelect):
return DIALOG.notificationDialog(LANGUAGE(32018)%(ATtype))

lizlst = [_build(item) for item in items]
if rebuildChannels:#rebuild channels.json entries
selects = list(_match(self.library.getEnabled(ATtype)))
elif autoSelect:#build sample channels
if len(items) >= AUTOTUNE_LIMIT:
selects = sorted(list(set(random.sample(list(set(range(0,len(items)))),AUTOTUNE_LIMIT))))
else:
selects = list(range(0,len(items)))
else:
selects = DIALOG.selectDialog(lizlst,LANGUAGE(32017)%(ATtype),preselect=list(_match(self.library.getEnabled(ATtype))))

if not selects is None: _set(ATtype, selects)
return self.buildAUTOTUNE(ATtype, self.library.getEnabled(ATtype))


def buildAUTOTUNE(self, ATtype, items):
Expand Down
48 changes: 26 additions & 22 deletions plugin.video.pseudotv.live/resources/lib/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
class Backup:
def __init__(self, sysARG=sys.argv):
self.sysARG = sysARG
self.channels = Channels()


def log(self, msg, level=xbmc.LOGDEBUG):
Expand All @@ -45,40 +44,42 @@ def getFileDate(self, file):
return LANGUAGE(32105) #Unknown


def hasBackup(self):
def hasBackup(self, file=CHANNELFLE_BACKUP):
with busy_dialog():
self.log('hasBackup')
if FileAccess.exists(CHANNELFLE_BACKUP) and not isClient():
PROPERTIES.setEXTProperty('plugin.video.pseudotv.live.has.Backup',"true")
backup_channel = (SETTINGS.getSetting('Backup_Channels') or 'Last Backup: Unknown')
if backup_channel == 'Last Backup: Unknown':
SETTINGS.setSetting('Backup_Channels' ,'%s: %s'%(LANGUAGE(32106),self.getFileDate(CHANNELFLE_BACKUP)))
if not SETTINGS.getSetting('Recover_Channels'):
SETTINGS.setSetting('Recover_Channels','%s [B]%s[/B] Channels?'%(LANGUAGE(32107),len(self.getChannels())))
if FileAccess.exists(file):
if file == CHANNELFLE_BACKUP:#main backup file, set meta.
PROPERTIES.setEXTProperty('%s.has.Backup'%(ADDON_ID),"true")
backup_channel = (SETTINGS.getSetting('Backup_Channels') or 'Last Backup: Unknown')
if backup_channel == 'Last Backup: Unknown':
SETTINGS.setSetting('Backup_Channels' ,'%s: %s'%(LANGUAGE(32106),self.getFileDate(file)))
if not SETTINGS.getSetting('Recover_Channels'):
SETTINGS.setSetting('Recover_Channels','%s [B]%s[/B] Channels?'%(LANGUAGE(32107),len(self.getChannels())))
return True
PROPERTIES.setEXTProperty('plugin.video.pseudotv.live.has.Backup',"false")
PROPERTIES.setEXTProperty('%s.has.Backup'%(ADDON_ID),"false")
SETTINGS.setSetting('Backup_Channels' ,'')
SETTINGS.setSetting('Recover_Channels' ,'')
return False


def getChannels(self, file=CHANNELFLE_BACKUP):
self.log('getChannels')
return self.channels._load(file).get('channels',[])


def backupChannels(self):
return Channels()._load(file).get('channels',[])
def backupChannels(self, file=CHANNELFLE_BACKUP):
self.log('backupChannels')
if isClient(): return DIALOG.notificationDialog(LANGUAGE(32058))
elif FileAccess.exists(CHANNELFLE_BACKUP):
elif FileAccess.exists(file):
if not DIALOG.yesnoDialog('%s\n%s?'%(LANGUAGE(32108),SETTINGS.getSetting('Backup_Channels'))):
return False

with busy_dialog():
if FileAccess.copy(CHANNELFLEPATH,CHANNELFLE_BACKUP):
PROPERTIES.setEXTProperty('plugin.video.pseudotv.live.has.Backup',"true")
SETTINGS.setSetting('Backup_Channels' ,'%s: %s'%(LANGUAGE(32106),datetime.datetime.now().strftime(BACKUP_TIME_FORMAT)))
SETTINGS.setSetting('Recover_Channels','%s [B]%s[/B] Channels?'%(LANGUAGE(32107),len(self.getChannels())))
if FileAccess.copy(CHANNELFLEPATH,file):
if file == CHANNELFLE_BACKUP: #main backup file, set meta.
PROPERTIES.setEXTProperty('%s.has.Backup'%(ADDON_ID),"true")
SETTINGS.setSetting('Backup_Channels' ,'%s: %s'%(LANGUAGE(32106),datetime.datetime.now().strftime(BACKUP_TIME_FORMAT)))
SETTINGS.setSetting('Recover_Channels','%s [B]%s[/B] Channels?'%(LANGUAGE(32107),len(self.getChannels())))
return DIALOG.notificationDialog('%s %s'%(LANGUAGE(32110),LANGUAGE(32025)))
return self.hasBackup()

Expand All @@ -94,6 +95,8 @@ def recoverChannels(self, file=CHANNELFLE_BACKUP):


def recoverChannelsFromBackup(self, file=CHANNELFLE_BACKUP):
FileAccess.copy(CHANNELFLEPATH,CHANNELFLE_RESTORE) #flex/temp backup existing channels prior to recover channels.
channels = Channels()
newChannels = self.getChannels()
difference = sorted(diffLSTDICT(self.getChannels(CHANNELFLE_DEFAULT),newChannels), key=lambda k: k['number'])
self.log('recoverChannelsFromBackup, file = %s, difference = %s'%(file,len(difference)))
Expand All @@ -105,11 +108,12 @@ def recoverChannelsFromBackup(self, file=CHANNELFLE_BACKUP):
pCount = int(((idx + 1)*100)//len(difference))
if citem in newChannels:
pDialog = DIALOG.progressDialog(pCount,pDialog,message="%s: %s"%(LANGUAGE(32113),citem.get('name')),header='%s, %s'%(ADDON_NAME,LANGUAGE(30338)))
self.channels.addChannel(citem)
channels.addChannel(citem)
else:
self.channels.delChannel(citem)
channels.delChannel(citem)
Library().resetLibrary()
return self.channels.setChannels()
return channels.setChannels()
del channels
return False


Expand Down
1 change: 1 addition & 0 deletions plugin.video.pseudotv.live/resources/lib/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(self):
self.channelDATA = getJSON(CHANNELFLE_DEFAULT)
self.channelTEMP = self.channelDATA.get('channels',[]).pop(0)
self.channelDATA.update(self._load())
self.setChannels()


def log(self, msg, level=xbmc.LOGDEBUG):
Expand Down
10 changes: 5 additions & 5 deletions plugin.video.pseudotv.live/resources/lib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
MEDIA_LOC = os.path.join(ADDON_PATH,'resources','skins','default','media')
SFX_LOC = os.path.join(MEDIA_LOC,'sfx')
BACKUP_LOC = os.path.join(SETTINGS_LOC,'backup')
CACHE_LOC = os.path.join(SETTINGS_LOC,'cache')
CACHE_LOC = os.path.join(SETTINGS_LOC,'cache') #default User_Folder path

#files
XMLTVFLE = '%s.xml'%('pseudotv')
Expand All @@ -125,17 +125,17 @@
TVGROUPFLE = 'tv_groups.xml'
RADIOGROUPFLE = 'radio_groups.xml'
PROVIDERFLE = 'providers.xml'
CHANNELBACKUPFLE = 'channels.backup'
CHANNELRESTOREFLE = 'channels.restore'

VIDEO_EXTS = xbmc.getSupportedMedia('video').split('|')
MUSIC_EXTS = xbmc.getSupportedMedia('music').split('|')
IMAGE_EXTS = xbmc.getSupportedMedia('picture').split('|')

#file paths
SETTINGS_FLE = os.path.join(SETTINGS_LOC,'settings.xml')
CHANNELFLE_BACKUP = os.path.join(SETTINGS_LOC,'channels.backup')
CHANNELFLE_RESTORE = os.path.join(SETTINGS_LOC,'channels.restore')
CHANNELFLEPATH = os.path.join(SETTINGS_LOC,CHANNELFLE)
LIBRARYFLEPATH = os.path.join(SETTINGS_LOC,LIBRARYFLE)
CHANNELFLE_BACKUP = os.path.join(BACKUP_LOC,CHANNELBACKUPFLE)
CHANNELFLE_RESTORE = os.path.join(BACKUP_LOC,CHANNELRESTOREFLE)

#sfx
BING_WAV = os.path.join(SFX_LOC,'bing.wav')
Expand Down
5 changes: 4 additions & 1 deletion plugin.video.pseudotv.live/resources/lib/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ def log(self, msg, level=xbmc.LOGDEBUG):
def _run(self):
self.log('_run, starting...')
while not self.service.monitor.abortRequested():
if self.service.monitor.chkInterrupt(1) or isClient():
if isClient():
self.log('_run, client break')
break
elif self.service.monitor.chkInterrupt(1):
self.log('_run, interrupted')
break
else:
Expand Down
15 changes: 5 additions & 10 deletions plugin.video.pseudotv.live/resources/lib/context_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(self, sysARG, writer):
if isinstance(path,list): path = path[0]

log('Browse: target = %s, path = %s'%(target,path))
BUILTIN.executebuiltin('ReplaceWindow(%s,%s,return)'%(target,path))
BUILTIN.executebuiltin('ReplaceWindow(%s,%s)'%(target,path))

class Match:
SEARCH_SCRIPT = None
Expand All @@ -62,24 +62,19 @@ def __init__(self, sysARG):
dbid = (writer.get('tvshowid') or writer.get('movieid'))
log('Match: __init__, sysARG = %s, title = %s, dbtype = %s, dbid = %s'%(sysARG,'%s - %s'%(title,name),dbtype,dbid))

if BUILTIN.getInfoBool('HasAddon(%s)'%(self.SIMILAR_SCRIPT),'System') and dbid:
if hasAddon(self.SIMILAR_SCRIPT,install=True) and dbid:
self.SEARCH_SCRIPT = self.SIMILAR_SCRIPT
elif BUILTIN.getInfoBool('HasAddon(%s)'%(self.GLOBAL_SCRIPT),'System'):
elif hasAddon(self.GLOBAL_SCRIPT,install=True):
self.SEARCH_SCRIPT = self.GLOBAL_SCRIPT
else: return DIALOG.notificationDialog(LANGUAGE(32000))
log('Match: SEARCH_SCRIPT = %s'%(self.SEARCH_SCRIPT))

if BUILTIN.getInfoBool('HasAddon(%s)'%(self.SEARCH_SCRIPT),'System'):
if not BUILTIN.getInfoBool('AddonIsEnabled(%s)'%(self.SEARCH_SCRIPT),'System'):
BUILTIN.executebuiltin('EnableAddon(%s)'%(self.SEARCH_SCRIPT))
else:
BUILTIN.executebuiltin('InstallAddon(%s)'%(self.SEARCH_SCRIPT))
hasAddon(self.SEARCH_SCRIPT,enable=True)

if self.SEARCH_SCRIPT == self.SIMILAR_SCRIPT:
# plugin://script.embuary.helper/?info=getsimilar&dbid=$INFO[ListItem.DBID]&type=tvshow&tag=HDR
# plugin://script.embuary.helper/?info=getsimilar&dbid=$INFO[ListItem.DBID]&type=movie&tag=HDR
# tag = optional, additional filter option to filter by library tag
BUILTIN.executebuiltin('ReplaceWindow(%s,%s,return)'%('%ss'%(writer.get('media','video')),'plugin://%s/?info=getsimilar&dbid=%d&type=%s'%(self.SEARCH_SCRIPT,dbid,dbtype)))
BUILTIN.executebuiltin('ReplaceWindow(%s,%s)'%('%ss'%(writer.get('media','video')),'plugin://%s/?info=getsimilar&dbid=%d&type=%s'%(self.SEARCH_SCRIPT,dbid,dbtype)))
else:
# - the addon is executed by another addon/skin: RunScript(script.globalsearch,searchstring=foo)
# You can specify which categories should be searched (this overrides the user preferences set in the addon settings):
Expand Down
Loading

0 comments on commit 05de835

Please sign in to comment.