TEXT   1

Amélioration et modification du script initial

Par arnonymous
le 14 August 2025

  1. # -*- coding: utf-8 -*-
  2.  
  3. '''
  4.     TvSkipIntro Add-on
  5.     Copyright (C) 2018 aenema
  6.     Amélioration et modification de ce script.
  7.  
  8.     This program is free software: you can redistribute it and/or modify
  9.     it under the terms of the GNU General Public License as published by
  10.     the Free Software Foundation, either version 3 of the License, or
  11.     (at your option) any later version.
  12.    
  13.     This program is distributed in the hope that it will be useful,
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16.     GNU General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program. If not, see .
  20. '''
  21.  
  22. import xbmcvfs, xbmc, xbmcaddon, json, os, xbmcgui, time, re
  23.  
  24. # --- Initialisation de l'add-on et des chemins ---
  25. KODI_VERSION = int(xbmc.getInfoLabel("System.BuildVersion").split(".")[0])
  26. addonInfo = xbmcaddon.Addon().getAddonInfo
  27. settings = xbmcaddon.Addon().getSetting
  28. profilePath = xbmcvfs.translatePath(addonInfo('profile'))
  29. addonPath = xbmcvfs.translatePath(addonInfo('path'))
  30. skipFile = os.path.join(profilePath, 'skipintro.json')
  31. defaultSkip = settings('default.skip')
  32.  
  33. if not os.path.exists(profilePath):
  34.     xbmcvfs.mkdir(profilePath)
  35.  
  36. # --- Fonctions utilitaires de gestion des données (réglagles améliorées) ---
  37.  
  38. def load_skip_data():
  39.     """Charge les données de saut d'intro depuis le fichier JSON."""
  40.     if not os.path.exists(skipFile):
  41.         return []
  42.     try:
  43.         with open(skipFile, 'r') as f:
  44.             return json.load(f)
  45.     except (IOError, json.JSONDecodeError):
  46.         # En cas d'erreur de lecture ou de fichier corrompu, on renvoie une liste vide
  47.         return []
  48.  
  49. def save_skip_data(data):
  50.     """Sauvegarde des données de saut d'intro dans le fichier JSON."""
  51.     try:
  52.         with open(skipFile, 'w') as f:
  53.             json.dump(data, f, indent=2)
  54.     except IOError:
  55.         pass # Gérer silencieusement les erreurs d'écriture
  56.  
  57. # --- Fonctions principales de l'add-on ---
  58.  
  59. def cleantitle(title):
  60.     if title is None:
  61.         return
  62.     # Utilisation d'une expression régulière plus concise pour nettoyer le titre
  63.     title = title.lower()
  64.     title = re.sub('&#\d+;', '', title)
  65.     title = re.sub(r'(\[.*?\]|\(.*?\))', '', title)
  66.     title = re.sub(r'[^a-z0-9]', '', title)
  67.     return title
  68.  
  69. def updateSkip(title, seconds=defaultSkip, start=0, service=True):
  70.     data = load_skip_data()
  71.     found = False
  72.     for item in data:
  73.         if cleantitle(item['title']) == cleantitle(title):
  74.             item['service'] = service
  75.             item['skip'] = seconds
  76.             item['start'] = start
  77.             found = True
  78.             break
  79.     if not found:
  80.         # Si le titre n'est pas trouvé, l'ajoute comme si c'était un nouveau
  81.         newskip(title, seconds, start, service)
  82.     else:
  83.         save_skip_data(data)
  84.  
  85. def newskip(title, seconds=None, start=0, service=True):
  86.     if seconds is None or seconds == '':
  87.         seconds = defaultSkip
  88.    
  89.     data = load_skip_data()
  90.    
  91.     # Vérification si le titre existe déjà pour éviter les doublons
  92.     if not any(cleantitle(item['title']) == cleantitle(title) for item in data):
  93.         newIntro = {'title': title, 'service': service, 'skip': seconds, 'start': start}
  94.         data.append(newIntro)
  95.         save_skip_data(data)
  96.  
  97. def getSkip(title):
  98.     data = load_skip_data()
  99.     skip = [i['skip'] for i in data if cleantitle(i['title']) == cleantitle(title) and i['service'] is True]
  100.     if skip:
  101.         return skip[0]
  102.     else:
  103.         newskip(title, defaultSkip)
  104.         return defaultSkip
  105.  
  106. def checkService(title):
  107.     data = load_skip_data()
  108.     service_status = [i['service'] for i in data if cleantitle(i['title']) == cleantitle(title)]
  109.     return service_status[0] if service_status else True
  110.  
  111. def checkStartTime(title):
  112.     data = load_skip_data()
  113.     start_time = [i['start'] for i in data if cleantitle(i['title']) == cleantitle(title)]
  114.     return start_time[0] if start_time else 0
  115.  
  116. # --- Vérification initiale du fichier au démarrage ---
  117. if not os.path.exists(skipFile):
  118.     newskip('default', defaultSkip)
  119.  
  120. # --- Classe de service Kodi ---
  121. class Service():
  122.     WINDOW = xbmcgui.Window(10000)
  123.  
  124.     def __init__(self, *args):
  125.         self.skipped = False
  126.         self.currentShow = None
  127.  
  128.     def ServiceEntryPoint(self):
  129.         monitor = xbmc.Monitor()
  130.  
  131.         while not monitor.abortRequested():
  132.             if monitor.waitForAbort(1): # Réduction du délai d'attente à 1s pour une meilleure réactivité
  133.                 break
  134.  
  135.             if xbmc.Player().isPlaying():
  136.                 try:
  137.                     current_show = xbmc.getInfoLabel("VideoPlayer.TVShowTitle")
  138.                     if current_show and current_show != self.currentShow:
  139.                         self.currentShow = current_show
  140.                         self.skipped = False  # Réinitialise pour une nouvelle série
  141.                        
  142.                     if self.currentShow and not self.skipped:
  143.                         self.SkipIntro(self.currentShow)
  144.                 except Exception as e:
  145.                     xbmc.log(f"Erreur dans le service de saut d'intro : {e}", xbmc.LOGINFO)
  146.             else:
  147.                 self.skipped = False
  148.                 self.currentShow = None
  149.                
  150.     def SkipIntro(self, tvshow):
  151.         try:
  152.             if not xbmc.Player().isPlayingVideo():
  153.                 return
  154.            
  155.             timeNow = xbmc.Player().getTime()
  156.             status = checkService(tvshow)
  157.  
  158.             if not status:
  159.                 self.skipped = True
  160.                 return
  161.            
  162.             startTime = checkStartTime(tvshow)
  163.            
  164.             if int(startTime) >= int(timeNow):
  165.                 return
  166.            
  167.             # --- Utilisation d'un dialogue pour l'utilisateur ---
  168.             dialog = CustomDialog('script-dialog.xml', addonPath, tvshow)
  169.             dialog.doModal()
  170.             self.skipped = True
  171.             del dialog
  172.         except Exception as e:
  173.             xbmc.log(f"Erreur dans SkipIntro: {e}", xbmc.LOGINFO)
  174.  
  175.  
  176. # --- Classe pour le dialogue de l'interface graphique (GUI) ---
  177. OK_BUTTON = 201
  178. NEW_BUTTON = 202
  179. DISABLE_BUTTON = 210
  180. ACTION_PREVIOUS_MENU = 10
  181. ACTION_BACK = 92
  182. INSTRUCTION_LABEL = 203
  183. AUTHCODE_LABEL = 204
  184. WARNING_LABEL = 205
  185. CENTER_Y = 6
  186. CENTER_X = 2
  187.  
  188. class CustomDialog(xbmcgui.WindowXMLDialog):
  189.     def __init__(self, xmlFile, resourcePath, show):
  190.         self.tvshow = show
  191.  
  192.     def onInit(self):
  193.         self.skipValue = int(getSkip(self.tvshow))
  194.         skipLabel = 'SKIP INTRO: %s' % self.skipValue
  195.         skipButton = self.getControl(OK_BUTTON)
  196.         skipButton.setLabel(skipLabel)
  197.  
  198.     def onAction(self, action):
  199.         if action in [ACTION_PREVIOUS_MENU, ACTION_BACK]:
  200.             self.close()
  201.  
  202.     def onControl(self, control):
  203.         pass
  204.  
  205.     def onFocus(self, control):
  206.         pass
  207.  
  208.     def onClick(self, control):
  209.         if control == OK_BUTTON:
  210.             timeNow = xbmc.Player().getTime()
  211.             skipTotal = int(timeNow) + int(self.skipValue)
  212.             xbmc.Player().seekTime(int(skipTotal))
  213.  
  214.         elif control == NEW_BUTTON:
  215.             dialog = xbmcgui.Dialog()
  216.             d = dialog.input('Skip Value (seconds)', type=xbmcgui.INPUT_NUMERIC)
  217.             if d is None or d == '':
  218.                 self.close()
  219.                 return
  220.  
  221.             d2 = dialog.input('Prompt At (seconds)', type=xbmcgui.INPUT_NUMERIC)
  222.             if d2 is None or d2 == '':
  223.                 d2 = 0
  224.            
  225.             if str(d) != '0':
  226.                 newskip(self.tvshow, d, start=d2)
  227.  
  228.         elif control == DISABLE_BUTTON:
  229.             updateSkip(self.tvshow, seconds=self.skipValue, service=False)
  230.  
  231.         if control in [OK_BUTTON, NEW_BUTTON, DISABLE_BUTTON]:
  232.             self.close()
  233.  
  234. # Démarrage du service
  235. Service().ServiceEntryPoint()

Modifier ce paste:


<b><a class="btn btn-default" data-target="#signin" data-toggle="modal" href="#">CONNEXION</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class="btn btn-default" data-target="#signup" data-toggle="modal" href="#">INSCRIPTION</a></b>