diff --git a/README.md b/README.md index 2342c37..dc32b4c 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ What it adds: - **One IPTV Simple instance per channel list**: the TV guide setup rewrites the instance that already reads KodiMov+'s list (one set up with the original add-on, or by hand) instead of adding `instance-settings-91.xml` next to it, and the service deletes any extra one at Kodi start (keeping the one that isn't 91, which holds what was watched): two of them showed every channel twice. - Fixes the programme guide export of upstream 1.0.0 (the amazon.tv guide is a flat list). - Its own proxy port (57031), so it can run next to the original. After an update the new proxy waits for the old one to free the port instead of moving to a random one, so the channel being watched keeps playing (upstream sets `allow_reuse_address` and `SO_REUSEADDR` too late to take effect). -- **Restarts IPTV Simple only while idle**: nothing playing and no key pressed for 30 seconds (a channel opened during a restart fails). After start or update a single guide reload also picks up changed instance files. +- **Restarts IPTV Simple only while idle**: nothing playing and no key pressed for 10 seconds (a channel opened during a restart fails). It waits for that as long as Kodi runs: after the box was off, Kodi first loads the old guide file and keeps it (no current programmes) until the reload. After start or update a single guide reload also picks up changed instance files. +- **Removes empty IPTV Simple instances** (no channel list, like the "Migrated Add-on Config" Kodi creates when IPTV Simple is installed again) once KodiMov+'s own instance is there. --- diff --git a/addon.xml b/addon.xml index 745af6f..a76a7ac 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ @@ -21,7 +21,8 @@ Movistar+ para Kodi, con inicio de sesión automático desde la red de Movistar Fork of Paco8's Movistar+ add-on (plugin.video.movistarplus). Logs in by itself from the Movistar home network, keeps the channel list and numbers up to date, plays the LALIGA, DAZN LALIGA and Liga de Campeones channels through Movistar's new servers (from the Movistar home network), hides the channels it can't play, adds free Galician channels (TVG2, TeleVigo) and writes a programme guide for every channel. Requires a Movistar+ subscription. Fork del addon Movistar+ de Paco8 (plugin.video.movistarplus). Inicia sesión solo desde la red de Movistar, mantiene la lista y los números de los canales al día, reproduce los canales de LALIGA, DAZN LALIGA y Liga de Campeones a través de los servidores nuevos de Movistar (desde la red de Movistar de casa), oculta los canales que no puede reproducir, añade canales gallegos gratuitos (TVG2, TeleVigo) y genera la guía de programación de todos los canales. Se necesita estar abonado a Movistar+. - 1.0.0+kodimov.13: updating the add-on no longer stops the channel being watched (the proxy got a new port and the stream lost it). IPTV Simple is restarted only while nothing plays and nobody has used the remote for 30 seconds, and fewer times after an update. + 1.0.0+kodimov.14: the programme guide is no longer left empty for most channels after the box was off for a while and the remote is in use: the guide reload now waits for a 10-second pause instead of 30 seconds and doesn't give up after 10 minutes. Empty IPTV Simple instances ("Migrated Add-on Config", left when IPTV Simple is installed again) are removed. +1.0.0+kodimov.13: updating the add-on no longer stops the channel being watched (the proxy got a new port and the stream lost it). IPTV Simple is restarted only while nothing plays and nobody has used the remote for 30 seconds, and fewer times after an update. 1.0.0+kodimov.12: no more channels twice in the TV guide on boxes where the TV guide setup was run over an existing setup (the extra IPTV Simple instance is removed, and the setup now rewrites the existing one). LALIGA, DAZN LALIGA and Liga de Campeones no longer go missing for 6 hours when Movistar's new servers refuse the box's registration as a web player once: it is tried again, and the TV guide list is rewritten half an hour later. 1.0.0+kodimov.11: Movistar's channel numbers also show on boxes with more than one IPTV Simple instance (Radios de Vigo, a leftover empty one), where Kodi had refused the setting and numbered the channels 1, 2, 3...; existing TV guide setups are put right by themselves. KodiMov+ and Radios de Vigo no longer restart IPTV Simple at the same time. 1.0.0+kodimov.10: the LALIGA, DAZN LALIGA and Liga de Campeones channels are back, live and catch-up, on boxes connected to the Movistar home network (their streams are now served only through Movistar's new servers). New setting to always play at the best quality, up to 1080p, instead of the 576p Kodi stays at on automatic (off by default). The "Error 4027" message no longer pops up when the add-on recovers from it by itself. diff --git a/resources/lib/kodimov.py b/resources/lib/kodimov.py index a69e6f8..1aff445 100644 --- a/resources/lib/kodimov.py +++ b/resources/lib/kodimov.py @@ -493,7 +493,7 @@ def reload_iptv_guide(pvr_dir, addon_id): nothing if something is playing.""" import xbmc monitor = xbmc.Monitor() - if not wait_until_idle(timeout=600): return + if not wait_until_idle(): return if not set_iptv_refresh(pvr_dir, addon_id, 1): return try: restart_iptv_simple() @@ -504,15 +504,18 @@ def reload_iptv_guide(pvr_dir, addon_id): restart_iptv_simple() -def is_idle(seconds=30): - """Nothing playing and nobody pressed a key for a while. Restarting IPTV - Simple stops live TV, and a channel opened while it restarts fails.""" +def is_idle(seconds=10): + """Nothing playing and nobody pressed a key for a few seconds. Restarting + IPTV Simple stops live TV, and a channel opened while it restarts fails. + Short on purpose: the reload is most needed right when someone is + browsing a TV guide with missing programmes.""" import xbmc return not xbmc.Player().isPlaying() and xbmc.getGlobalIdleTime() >= seconds def wait_until_idle(timeout=None): - """Waits until is_idle(). False if Kodi is closing or the timeout ran out.""" + """Waits until is_idle(), by default for as long as Kodi runs. False if + Kodi is closing or the timeout ran out.""" import xbmc monitor = xbmc.Monitor() end = time.time() + timeout if timeout else None @@ -592,20 +595,43 @@ def has_iptv_instance(pvr_dir, addon_id): return bool(iptv_instance_files(pvr_dir, addon_id)) -def remove_duplicate_instances(pvr_dir, addon_id): +def _empty_instance_files(pvr_dir): + """Instances with no channel list at all, like the "Migrated Add-on Config" + Kodi creates when IPTV Simple is installed again. They show nothing and + count as a second PVR instance (see ensure_channel_numbers).""" + import glob + import re + def value(content, setting): + match = re.search(r']*?(?:/>|>([^<]*))'.format(setting), content) + return ((match and match.group(1)) or '').strip() + res = [] + for filename in glob.glob(os.path.join(pvr_dir, 'instance-settings-*.xml')): + try: + with io.open(filename, 'r', encoding='utf-8') as f: + content = f.read() + except (IOError, OSError): + continue + if not value(content, 'm3uPath') and not value(content, 'm3uUrl'): res.append(filename) + return res + + +def remove_extra_instances(pvr_dir, addon_id): """Two instances reading the same channel list put every channel twice in the TV guide. That happened when the TV guide setup (instance 91) was run on a box already set up with another instance. Keeps one and deletes the - others. Returns True if a file was deleted (IPTV Simple must be restarted - to drop it).""" + others, and deletes empty instances (no channel list) once this add-on's + is there. Returns True if a file was deleted (IPTV Simple must be + restarted to drop it).""" + ours = iptv_instance_files(pvr_dir, addon_id) + if not ours: return False removed = False - for filename in iptv_instance_files(pvr_dir, addon_id)[1:]: + for filename in ours[1:] + _empty_instance_files(pvr_dir): try: os.remove(filename) - LOG('remove_duplicate_instances: removed {}'.format(filename)) + LOG('remove_extra_instances: removed {}'.format(filename)) removed = True except OSError as e: - LOG('remove_duplicate_instances: {}: {}'.format(filename, e)) + LOG('remove_extra_instances: {}: {}'.format(filename, e)) return removed diff --git a/service.py b/service.py index acf1c0f..f1c62ad 100644 --- a/service.py +++ b/service.py @@ -35,7 +35,7 @@ if __name__ == '__main__': new_api_retries = 6 try: pvr_dir = translatePath(xbmcaddon.Addon('pvr.iptvsimple').getAddonInfo('profile')) - restart_iptv = kodimov.remove_duplicate_instances(pvr_dir, 'kodimovplus') + restart_iptv = kodimov.remove_extra_instances(pvr_dir, 'kodimovplus') restart_iptv = kodimov.set_iptv_refresh(pvr_dir, 'kodimovplus') or restart_iptv except RuntimeError: # IPTV Simple not installed or disabled pvr_dir = None