Files
XoséandClaude Opus 5.5 b62bf07a2b 1.0.0+kodimov.14: guide reload no longer skipped while the remote is in use; remove empty instances
- .190 on 2026-11-13: the box came on with an old epg.xml, Kodi stored it
  (no current programmes for 124 channels) and doesn't ask again for up to
  an hour. KodiMov+ wrote a new guide two minutes later, but the reload
  waited for 30 s without a key press and gave up after 10 minutes, while
  the guide was being browsed. It now waits for a 10 s pause, for as long
  as Kodi runs.
- Instances with no channel list (the "Migrated Add-on Config" Kodi makes
  when IPTV Simple is installed again) are removed once KodiMov+'s own
  instance exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 15:35:56 +01:00

87 lines
3.7 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import time
import xbmc
import xbmcgui
from resources.lib.proxy import Proxy
from resources.lib.addon import *
from resources.lib.log import LOG
from resources.lib import kodimov
def file_age(filename):
"""Seconds since the file was last written (or found unchanged)."""
try:
return time.time() - os.path.getmtime(filename)
except OSError:
return float('inf')
if __name__ == '__main__':
LOG('Service started')
proxy = Proxy()
proxy.start()
LOG('proxy_address: {}'.format(proxy.proxy_address))
# Refreshes the TV guide channel list (new channels, new numbers) and the
# programme guide a minute after Kodi starts and then every 6 hours; a
# refresh that failed is tried again half an hour later. Opening the add-on
# also renews the 10-day Movistar login.
started = time.time()
next_check = started + 60
max_age = 0 # always refresh once after Kodi starts
new_api_retries = 6
try:
pvr_dir = translatePath(xbmcaddon.Addon('pvr.iptvsimple').getAddonInfo('profile'))
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
restart_iptv = False
# A changed instance file needs IPTV Simple restarted. The guide reload
# after start (below) restarts it anyway, so that one is left to do it;
# this is only the fallback, 10 minutes later, if it didn't happen.
restart_after = started + 10 * 60
monitor = xbmc.Monitor()
while not monitor.abortRequested():
if monitor.waitForAbort(1):
break
if restart_iptv and kodimov.last_iptv_restart() > started:
restart_iptv = False
if restart_iptv and time.time() >= restart_after and kodimov.is_idle():
restart_iptv = False
kodimov.restart_iptv_simple()
if time.time() >= next_check:
next_check = time.time() + 30 * 60
exporting = False
# Movistar's channel numbers in Kodi's TV section, also when another
# add-on (Radios de Vigo) adds its own IPTV Simple instance
if pvr_dir and kodimov.has_iptv_instance(pvr_dir, 'kodimovplus'):
kodimov.ensure_channel_numbers(os.path.join(profile_dir, 'numbers-set'))
age_limit, max_age = max_age, 6 * 3600 - 120
# After Kodi starts (or this add-on updates) also get the new guide into Kodi now
reload_guide = '&reload_guide=1' if age_limit == 0 else ''
if restart_iptv: reload_guide = '&reload_guide=force' # also for the changed instance files
# The new servers failed (they at times refuse everything for minutes):
# the list lacks LALIGA, DAZN LALIGA, Liga de Campeones. Try again in
# half an hour, a few times, instead of in 6 hours.
if new_api_retries and kodimov.new_api_failed(profile_dir):
new_api_retries -= 1
age_limit = 0
reload_guide = reload_guide or '&reload_guide=1'
if addon.getSettingBool('auto_export_epg'): # channels + programme guide
if file_age(os.path.join(profile_dir, 'epg.xml')) > age_limit:
exporting = True
xbmc.executebuiltin('RunPlugin(plugin://plugin.video.kodimovplus/?action=export_epg_now&quiet=1' + reload_guide + ')')
elif addon.getSettingBool('export_channels'):
if file_age(os.path.join(profile_dir, 'channels.m3u8')) > age_limit:
exporting = True
xbmc.executebuiltin('RunPlugin(plugin://plugin.video.kodimovplus/?action=export_channels_now)')
if not exporting:
# Keeps the pass for the LALIGA / Liga de Campeones streams fresh
xbmc.executebuiltin('RunPlugin(plugin://plugin.video.kodimovplus/?action=new_api_keep_warm)')
proxy.stop()