def reset(self, filters=None, silent=False): '''reset skin settings''' log_msg("filters: %s" % filters) if silent or (not silent and xbmcgui.Dialog().yesno( heading=self.addon.getLocalizedString(32010), message=self.addon.getLocalizedString(32011))): if filters: # only restore specific settings skinsettings = self.get_skinsettings(filters) for setting in skinsettings: xbmc.executebuiltin( try_encode("Skin.Reset(%s)" % setting[1])) else: # restore all skin settings xbmc.executebuiltin( "RunScript(script.skinshortcuts,type=resetall&warning=false)" ) xbmc.sleep(250) xbmc.executebuiltin("Skin.ResetSettings") xbmc.sleep(250) xbmc.executebuiltin("ReloadSkin") # fix default settings and labels xbmc.sleep(1500) xbmc.executebuiltin( "RunScript(script.skin.helper.service,action=checkskinsettings)" )
def daynightthemes(self, dayornight): '''allow user to set a specific theme during day/night time''' if dayornight not in ["day", "night"]: log_msg( "Invalid parameter for day/night theme - must be day or night") return # show listing with themes listitems = self.get_skin_colorthemes() listitems += self.get_user_colorthemes() header = self.addon.getLocalizedString(32031) curvalue = xbmc.getInfoLabel( "Skin.String(SkinHelper.ColorTheme.%s.theme)" % dayornight).decode("utf-8") dialog = DialogSelect("DialogSelect.xml", "", windowtitle=header, richlayout=True, listing=listitems, autofocus=curvalue) dialog.doModal() result = dialog.result del dialog if result: themefile = result.getfilename().decode("utf-8") themename = result.getLabel().decode("utf-8") self.set_day_night_theme(dayornight, themename, themefile)
def get_imdb_id(win, metadatautils): '''get imdbnumber for listitem''' content_type = win.getProperty("contenttype") imdb_id = try_decode(xbmc.getInfoLabel("ListItem.IMDBNumber")) if not imdb_id: imdb_id = try_decode( xbmc.getInfoLabel("ListItem.Property(IMDBNumber)")) if imdb_id and not imdb_id.startswith("tt"): imdb_id = "" if not imdb_id: year = try_decode(xbmc.getInfoLabel("ListItem.Year")) title = try_decode( xbmc.getInfoLabel("ListItem.Title")).split(",")[0].split("(")[0] if content_type in ["episodes", "seasons"]: title = try_decode(xbmc.getInfoLabel("ListItem.TvShowTitle")) if title: log_msg( "Animated Art: lookup imdbid by title and year: (%s - %s)" % (title, year), xbmc.LOGNOTICE) imdb_id = metadatautils.get_omdb_info("", title, year, content_type).get( "imdbnumber", "") if not imdb_id: return title return imdb_id
def fuzz(): ''' Get and call all fuzz modules ''' # Get test directory in addon folder test_path = xbmc.translatePath( 'special://home/addons/script.library.integration.tool/resources/test/' ) # Add all test modules to fuzz suite loader = unittest.TestLoader() suite = unittest.TestSuite() suite.addTests( loader.discover(os.path.dirname(__file__), pattern='fuzz_*.py')) utils.log_msg('All fuzz tests: %s' % suite) # Run all unit tests and save to text file log_file = os.path.join(test_path, 'fuzz_report.txt') with open(log_file, "w") as f: result = unittest.TextTestRunner(f, verbosity=2).run(suite) if result.wasSuccessful(): utils.notification('Fuzz successful') else: utils.notification('Fuzz failed') utils.log_msg('Fuzz result: %s' % result)
def onDatabaseUpdated(self, database): '''builtin function for the xbmc.Monitor class''' log_msg("Kodi_Monitor: %s database updated" % database) if database == "music": self.refresh_music_widgets("") else: self.refresh_video_widgets("")
def onNotification(self, sender, method, data): '''builtin function for the xbmc.Monitor class''' try: log_msg("Kodi_Monitor: sender %s - method: %s - data: %s" % (sender, method, data)) if sys.version_info.major == 3: data = json.loads(data) else: data = json.loads(data.decode('utf-8')) mediatype = "" if data and isinstance(data, dict): if data.get("item"): mediatype = data["item"].get("type", "") elif data.get("type"): mediatype = data["type"] if method == "VideoLibrary.OnUpdate": if not mediatype: mediatype = self.last_mediatype # temp hack self.refresh_video_widgets(mediatype) if method == "AudioLibrary.OnUpdate": self.refresh_music_widgets(mediatype) if method == "Player.OnStop": self.last_mediatype = mediatype if mediatype in ["movie", "episode", "musicvideo"]: if self.addon.getSetting("aggresive_refresh") == "true": self.refresh_video_widgets(mediatype) except Exception as exc: log_msg("Exception in KodiMonitor: %s" % exc, xbmc.LOGERROR)
def selectimage(self): skinsettings = SkinSettings() skinstring = self.params.get('skinstring', '') skinshortcutsprop = self.params.get('skinshortcutsproperty', '') current_value = self.params.get('currentvalue', '') resource_addon = self.params.get('resourceaddon', '') allow_multi = self.params.get('allowmulti', 'false') == 'true' windowheader = self.params.get('header', '') label, value = skinsettings.select_image(skinstring, allow_multi=allow_multi, windowheader=windowheader, resource_addon=resource_addon, current_value=current_value) log_msg('selectimage 3') if label: if skinshortcutsprop: # write value to skinshortcuts prop from .skinshortcuts import set_skinshortcuts_property set_skinshortcuts_property(skinshortcutsprop, value, label) else: # write the values to skin strings if value.startswith("$INFO"): # we got an dynamic image from window property skinsettings.set_skin_variable(skinstring, value) value = '$VAR[%s]' % skinstring xbmc.executebuiltin('Skin.SetString(%s.label,%s)' % (skinstring, label)) xbmc.executebuiltin('Skin.SetString(%s.name,%s)' % (skinstring, label)) xbmc.executebuiltin('Skin.SetString(%s,%s)' % (skinstring, value)) xbmc.executebuiltin('Skin.SetString(%s.path,%s)' % (skinstring, value)) del skinsettings
def check_screensaver(self): '''Allow user to disable screensaver on fullscreen music playback''' if getCondVisibility( "Window.IsActive(visualisation) + Skin.HasSetting(SkinHelper.DisableScreenSaverOnFullScreenMusic)" ): if not self.screensaver_disabled: # disable screensaver when fullscreen music active self.screensaver_disabled = True screensaver_setting = kodi_json( 'Settings.GetSettingValue', '{"setting":"screensaver.mode"}') if screensaver_setting: self.screensaver_setting = screensaver_setting kodi_json('Settings.SetSettingValue', { "setting": "screensaver.mode", "value": None }) log_msg( "Disabled screensaver while fullscreen music playback - previous setting: %s" % self.screensaver_setting, xbmc.LOGINFO) elif self.screensaver_disabled and self.screensaver_setting: # enable screensaver again after fullscreen music playback was ended kodi_json('Settings.SetSettingValue', { "setting": "screensaver.mode", "value": self.screensaver_setting }) self.screensaver_disabled = False self.screensaver_setting = None log_msg( "fullscreen music playback ended - restoring screensaver: %s" % self.screensaver_setting, xbmc.LOGINFO)
def favourites_widgets(): '''widgets from favourites''' favourites = kodi_json( 'Favourites.GetFavourites', { "type": None, "properties": ["path", "thumbnail", "window", "windowparameter"] }) widgets = [] if favourites: for fav in favourites: if "windowparameter" in fav: content = fav["windowparameter"] # check if this is a valid path with content if ("script://" not in content.lower() and "mode=9" not in content.lower() and "search" not in content.lower() and "play" not in content.lower()): label = fav["title"] log_msg("skinshortcuts widgets processing favourite: %s" % label) mutils = MetadataUtils() mediatype = mutils.detect_plugin_content(content) del mutils if mediatype and mediatype != "empty": widgets.append([label, content, mediatype]) return widgets
def recent(self): ''' get recently added episodes ''' log_msg("recent widget", xbmc.LOGINFO) tvshow_episodes = {} total_count = 0 unique_count = 0 filters = [] if self.options["hide_watched"]: filters.append(kodi_constants.FILTER_UNWATCHED) if self.options.get("tag"): filters.append({ "operator": "contains", "field": "tag", "value": self.options["tag"] }) if self.options.get("path"): filters.append({ "operator": "startswith", "field": "path", "value": self.options["path"] }) while unique_count < self.options["limit"]: recent_episodes = self.metadatautils.kodidb.episodes( sort=kodi_constants.SORT_DATEADDED, filters=filters, limits=(total_count, self.options["limit"] + total_count)) log_msg("Check grouping setting", xbmc.LOGINFO) if not self.options["group_episodes"]: # grouping is not enabled, just return the result log_msg("Grouping not enabled, return normal result", xbmc.LOGINFO) return recent_episodes if len(recent_episodes) < self.options["limit"]: # break the loop if there are no more episodes unique_count = self.options["limit"] # if multiple episodes for the same show with same addition date, we combine them into one # to do that we build a dict with recent episodes for all episodes of the same season added on the same date for episode in recent_episodes: total_count += 1 unique_key = "%s-%s-%s" % (episode["tvshowid"], episode["dateadded"].split(" ")[0], episode["season"]) log_msg("Unique %s" % unique_key, xbmc.LOGINFO) if unique_key not in tvshow_episodes: tvshow_episodes[unique_key] = [] unique_count += 1 tvshow_episodes[unique_key].append(episode) log_msg("Return entries sorted by dateadded", xbmc.LOGINFO) # create our entries and return the result sorted by dateadded if sys.version_info.major == 3: all_items = self.metadatautils.process_method_on_list( self.create_grouped_entry, tvshow_episodes.values()) else: all_items = self.metadatautils.process_method_on_list( self.create_grouped_entry, tvshow_episodes.itervalues()) return sorted(all_items, key=itemgetter("dateadded"), reverse=True)[:self.options["limit"]]
def show_info_panel(self): '''feature to auto show the OSD infopanel for X seconds''' try: sec_to_display = int( xbmc.getInfoLabel( "Skin.String(SkinHelper.ShowInfoAtPlaybackStart)")) except Exception: return if sec_to_display > 0 and not self.infopanelshown: retries = 0 log_msg("Show OSD Infopanel - number of seconds: %s" % sec_to_display) self.infopanelshown = True if self.win.getProperty("VideoScreensaverRunning") != "true": while retries != 50 and getCondVisibility("!Player.ShowInfo"): xbmc.sleep(100) if getCondVisibility( "!Player.ShowInfo + Window.IsActive(fullscreenvideo)" ): xbmc.executebuiltin('Action(info)') retries += 1 # close info again after given amount of time xbmc.Monitor().waitForAbort(sec_to_display) if getCondVisibility( "Player.ShowInfo + Window.IsActive(fullscreenvideo)"): xbmc.executebuiltin('Action(info)')
def __init__(self): self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.metadatautils = MetadataUtils() self.addonname = try_decode(self.addon.getAddonInfo('name')) self.addonversion = try_decode(self.addon.getAddonInfo('version')) self.kodimonitor = KodiMonitor(metadatautils=self.metadatautils, win=self.win) self.listitem_monitor = ListItemMonitor( metadatautils=self.metadatautils, win=self.win, monitor=self.kodimonitor) self.webservice = WebService(self.metadatautils) self.win.clearProperty("SkinHelperShutdownRequested") # start the extra threads self.listitem_monitor.start() self.webservice.start() log_msg('%s version %s started' % (self.addonname, self.addonversion), xbmc.LOGINFO) # run as service, check skin every 10 seconds and keep the other threads alive while not self.kodimonitor.abortRequested(): # check skin version info self.check_skin_version() # sleep for 10 seconds self.kodimonitor.waitForAbort(10) # Abort was requested while waiting. We should exit self.close()
def load_widget(self): '''legacy entrypoint called (widgets are moved to seperate addon), start redirect...''' action = self.params.get("action", "") newaddon = "script.skin.helper.widgets" log_msg( "Deprecated method: %s. Please reassign your widgets to get rid of this message. -" "This automatic redirect will be removed in the future" % (action), xbmc.LOGWARNING) paramstring = "" if sys.version_info.major == 3: for key, value in self.params.items(): paramstring += ",%s=%s" % (key, value) else: for key, value in self.params.iteritems(): paramstring += ",%s=%s" % (key, value) if getCondVisibility("System.HasAddon(%s)" % newaddon): # TEMP !!! for backwards compatability reasons only - to be removed in the near future!! import imp addon = xbmcaddon.Addon(newaddon) addon_path = try_decode(addon.getAddonInfo('path')) imp.load_source('plugin', os.path.join(addon_path, "plugin.py")) from plugin import main main.Main() del addon else: # trigger install of the addon if KODI_VERSION > 16: xbmc.executebuiltin("InstallAddon(%s)" % newaddon) else: xbmc.executebuiltin("RunPlugin(plugin://%s)" % newaddon)
def onNotification(self, sender, method, data): '''builtin function for the xbmc.Monitor class''' try: log_msg("Kodi_Monitor: sender %s - method: %s - data: %s" % (sender, method, data)) data = json.loads(try_decode(data)) mediatype = "" dbid = 0 transaction = False if data and isinstance(data, dict): if data.get("item"): mediatype = data["item"].get("type", "") dbid = data["item"].get("id", 0) elif data.get("type"): mediatype = data["type"] dbid = data.get("id", 0) if data.get("transaction"): transaction = True if method == "System.OnQuit": self.win.setProperty("SkinHelperShutdownRequested", "shutdown") if method == "VideoLibrary.OnUpdate": self.process_db_update(mediatype, dbid, transaction) if method == "AudioLibrary.OnUpdate": self.process_db_update(mediatype, dbid, transaction) if method == "Player.OnStop": self.monitoring_stream = False self.infopanelshown = False self.win.clearProperty("Skinhelper.PlayerPlaying") self.win.clearProperty("TrailerPlaying") self.reset_win_props() if method == "Player.OnPlay": if not self.monitoring_stream and not getCondVisibility( "Player.DisplayAfterSeek"): self.reset_win_props() if self.wait_for_player(): if getCondVisibility("Player.HasAudio"): if getCondVisibility("Player.IsInternetStream"): self.monitor_radiostream() else: self.set_music_properties() if getCondVisibility("Pvr.IsPlayingRadio"): if getCondVisibility("!Player.IsInternetStream"): self.monitor_radiostream() else: self.set_music_properties() elif getCondVisibility( "VideoPlayer.Content(livetv) | String.StartsWith(Player.FileNameAndPath,pvr://)" ): self.monitor_livetv() else: self.set_video_properties(mediatype, dbid) self.show_info_panel() except Exception as exc: log_exception(__name__, exc)
def getpvrthumb(self, **kwargs): '''get pvr images''' log_msg("webservice.getpvrthumb called with args: %s" % kwargs) title = kwargs.get("title", "") channel = kwargs.get("channel", "") genre = kwargs.get("genre", "") artwork = self.__mutils.get_pvr_artwork(title, channel, genre) return self.handle_artwork(artwork, kwargs)
def widgets(self): '''called from skinshortcuts to retrieve listing of all widgetss''' log_msg("skinhelperservice plugin allwidgets function", xbmc.LOGWARNING) if sys.version_info.major == 3: from . import skinshortcuts else: import skinshortcuts skinshortcuts.get_widgets(self.params.get("path", ""), self.params.get("sublevel", ""))
def stop(self): '''called when the thread has to stop working''' log_msg("ListItemMonitor - stop called") self.exit = True self.cache.close() self.event.set() self.event.clear() self.join(1)
def getmusicart(self, **kwargs): '''get pvr images''' log_msg("webservice.getmusicart called with args: %s" % kwargs) artist = kwargs.get("artist", "") album = kwargs.get("album", "") track = kwargs.get("track", "") artwork = self.__mutils.get_music_artwork(artist, album, track) return self.handle_artwork(artwork, kwargs)
def refresh_music_widgets(self, media_type): '''refresh music widgets''' log_msg("Music database changed - type: %s - refreshing widgets...." % media_type) timestr = time.strftime("%Y%m%d%H%M%S", time.gmtime()) self.win.setProperty("widgetreload-music", timestr) self.win.setProperty("widgetreloadmusic", timestr) if media_type: self.win.setProperty("widgetreload-%ss" % media_type, timestr)
def main(): ''' Main entrypoint for module. Update log and call other functions to update files ''' utils.log_msg('Updating pickle files...', xbmc.LOGNOTICE) update_managed() update_staged() update_synced() update_blocked() utils.log_msg('Pickle files updated.', xbmc.LOGNOTICE)
def plugin_widgetlisting(pluginpath, sublevel=""): '''get all nodes in a plugin listing''' widgets = [] if sublevel: media_array = kodi_json('Files.GetDirectory', { "directory": pluginpath, "media": "files" }) else: if not getCondVisibility("System.HasAddon(%s)" % pluginpath): return [] media_array = kodi_json('Files.GetDirectory', { "directory": "plugin://%s" % pluginpath, "media": "files" }) for item in media_array: log_msg("skinshortcuts widgets processing: %s" % (item["file"])) content = item["file"] label = item["label"] # extendedinfo has some login-required widgets, skip those if ("script.extendedinfo" in pluginpath and not EXTINFO_CREDS and ("info=starred" in content or "info=rated" in content or "info=account" in content)): continue if item.get("filetype", "") == "file": continue mutils = MetadataUtils() media_type = mutils.detect_plugin_content(item["file"]) del mutils if media_type == "empty": continue if media_type == "folder": content = "plugin://script.skin.helper.service?action=widgets&path=%s&sublevel=%s" % ( urlencode(item["file"]), label) # add reload param for widgets if "reload=" not in content: if "movies" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-movies)]" elif "episodes" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-episodes)]" elif "tvshows" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-tvshows)]" elif "musicvideos" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-musicvideos)]" elif "albums" in content or "songs" in content or "artists" in content: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload-music)]" else: reloadstr = "&reload=$INFO[Window(Home).Property(widgetreload)]"\ "$INFO[Window(Home).Property(widgetreload2)]" content = content + reloadstr content = content.replace("&limit=100", "&limit=25") widgets.append([label, content, media_type]) if pluginpath == "script.extendedinfo" and not sublevel: # some additional entrypoints for extendedinfo... widgets += extendedinfo_youtube_widgets() return widgets
def refresh_video_widgets(self, media_type): '''refresh video widgets''' log_msg("Video database changed - type: %s - refreshing widgets...." % media_type) timestr = time.strftime("%Y%m%d%H%M%S", time.gmtime()) self.win.setProperty("widgetreload", timestr) if media_type: self.win.setProperty("widgetreload-%ss" % media_type, timestr) if "episode" in media_type: self.win.setProperty("widgetreload-tvshows", timestr)
def check_autobackup(self): if self.addon.getSetting("auto_backups") == "true": cur_date = datetime.now().strftime('%Y-%m-%d') last_backup = self.addon.getSetting("last_backup") if cur_date != last_backup and self.addon.getSetting("backup_path"): log_msg("Performing auto backup of skin settings...") backupfile = self.get_backupfilename() self.backup(backup_file=backupfile, silent=True) self.addon.setSetting("last_backup", cur_date) self.clean_oldbackups()
def extraposter(self): '''helper to display extraposter in multiimage control in the skin''' log_msg("skinhelperservice plugin extraposter function", xbmc.LOGWARNING) posters = eval(self.params["posters"]) # process extraposters for count, item in enumerate(posters): listitem = xbmcgui.ListItem("poster%s" % count, path=item) listitem.setProperty('mimetype', 'image/jpeg') xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=item, listitem=listitem) xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
def run(self): log_msg("Starting WebService on port %s" % PORT, xbmc.LOGINFO) conf = { 'global': { 'server.socket_host': '0.0.0.0', 'server.socket_port': PORT }, '/': {} } cherrypy.quickstart(self.__root, '/', conf)
def getthumb(self, **kwargs): '''get generic thumb image from google/youtube''' log_msg("webservice.getthumb called with args: %s" % kwargs) title = kwargs.get("title", "") preferred_types, is_json_request, fallback = self.get_common_params( kwargs) image = self.__mutils.google.search_image(title) if not image: image = fallback return self.handle_image(image)
def run(self): '''called to start our background service ''' log_msg("BackgroundsUpdater - started", xbmc.LOGINFO) self.winpropcache() self.get_config() backgrounds_task_interval = 0 walls_task_interval = 0 delayed_task_interval = 112 while not self.exit: # Process backgrounds only if we're not watching fullscreen video if xbmc.getCondVisibility( "![Window.IsActive(fullscreenvideo) | Window.IsActive(script.pseudotv.TVOverlay.xml) | " "Window.IsActive(script.pseudotv.live.TVOverlay.xml)] | " "Window.IsActive(script.pseudotv.live.EPG.xml)"): # background stuff like reading the skin settings and generating smart shortcuts if delayed_task_interval >= 120: delayed_task_interval = 0 self.get_config() self.report_allbackgrounds() self.smartshortcuts.build_smartshortcuts() self.report_allbackgrounds() self.winpropcache(True) if self.exit: break # force refresh smart shortcuts on request if self.win.getProperty("refreshsmartshortcuts"): self.win.clearProperty("refreshsmartshortcuts") self.smartshortcuts.build_smartshortcuts() # Update home backgrounds every interval (if enabled by skinner) if self.backgrounds_delay and backgrounds_task_interval >= self.backgrounds_delay: backgrounds_task_interval = 0 self.update_backgrounds() if self.exit: break # Update wall images every interval (if enabled by skinner) if self.enable_walls and self.walls_delay and ( walls_task_interval >= self.walls_delay): walls_task_interval = 0 _thread.start_new_thread( self.wallimages.update_wallbackgrounds, ()) self.wallimages.update_manualwalls() self.kodimonitor.waitForAbort(1) backgrounds_task_interval += 1 walls_task_interval += 1 delayed_task_interval += 1
def test(): ''' Get and call all test modules and find coverage ''' # Get test directory in addon folder test_path = xbmc.translatePath( 'special://home/addons/script.library.integration.tool/resources/test/' ) # Add all test modules to suite loader = unittest.TestLoader() suite = unittest.TestSuite() suite.addTests( loader.discover(os.path.dirname(__file__), pattern='test_*.py')) utils.log_msg('All unit tests: %s' % suite) # Attempt to load and start coverage module try: sys.path.append( '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages' ) import coverage except ImportError: test_coverage = False utils.log_msg('Coverage module not available.', xbmc.LOGWARNING) else: test_path_wildcard = os.path.join(test_path, '*') cov = coverage.Coverage(omit=test_path_wildcard) cov.start() test_coverage = True utils.log_msg('Coverage module loaded.') # Run all unit tests and save to text file log_file = os.path.join(test_path, 'test_report.txt') with open(log_file, 'w') as f: result = unittest.TextTestRunner(f, verbosity=2).run(suite) # Stop coverage and save output if test_coverage: cov.stop() cov_folder = os.path.join(test_path, 'coverage') cov.html_report(directory=cov_folder) cov_txt_file = os.path.join(test_path, 'coverage.txt') with open(cov_txt_file, 'w') as f: cov.report(file=f) cov_xml_file = os.path.join(test_path, 'coverage.xml') cov.xml_report(outfile=cov_xml_file) utils.log_msg('Test coverage complete.') if result.wasSuccessful(): utils.notification('Tests successful') else: utils.notification('Tests failed') utils.log_msg('Test result: %s' % result)
def restore(self): '''restore skin settings from file''' backuprestore = BackupRestore() silent = self.params.get("SILENT", "") if silent and not xbmcvfs.exists(silent): log_msg( "ERROR while restoring backup ! --> Filename invalid." "Make sure you provide the FULL path, for example special://skin/extras/mybackup.zip", xbmc.LOGERROR) return backuprestore.restore(silent)
def add_to_library(self): # TODO: add a return value so Staged will know if episode wasn't added # and can display a relevant notification # Rename episode if metadata is available self.rename_using_metadata() # Don't add episodes that don't have episode id in name if not re.match('.*[0-9]+x[0-9].*|.*[Ss][0-9].*[Ee][0-9].*', self.clean_title): utils.log_msg('No episode number detected for {0}. Not adding to library...'\ .format(self.clean_title), xbmc.LOGNOTICE) return # Check if tvshow folder already exists if not os.path.isdir(self.managed_dir): # If not, create folder in ManagedTV utils.fs.mkdir(self.managed_dir) if os.path.isdir(self.metadata_dir): # Link tvshow.nfo and artwork now, if self.metadata_dir exists files = os.listdir(self.metadata_dir) for fname in files: if not (re.match( '.*[0-9]+x[0-9].*|.*[Ss][0-9].*[Ee][0-9].*', fname) or '.strm' in fname): utils.fs.softlink_file( os.path.join(self.metadata_dir, fname), os.path.join(self.managed_dir, fname)) # Create stream file filepath = os.path.join(self.managed_dir, self.clean_title + '.strm') utils.fs.create_stream_file(self.path, filepath) # Link metadata for episode if it exists if os.path.isdir(self.metadata_dir): # Link nfo file for episode nfo_path = os.path.join(self.metadata_dir, self.clean_title + '.nfo') if os.path.exists(nfo_path): utils.fs.softlink_file(nfo_path, self.managed_dir) # Link thumbnail for episode meta_thumb_path = os.path.join(self.metadata_dir, self.clean_title + '-thumb.jpg') managed_thumb_path = os.path.join(self.managed_dir, self.clean_title + '-thumb.jpg') if os.path.exists(meta_thumb_path): utils.fs.softlink_file(meta_thumb_path, managed_thumb_path) elif utils.USE_SHOW_ARTWORK: # Try show landscape or fanart (since Kodi can't generate thumb for strm) landscape_path = os.path.join(self.metadata_dir, 'landscape.jpg') fanart_path = os.path.join(self.metadata_dir, 'fanart.jpg') if os.path.exists(landscape_path): utils.fs.softlink_file(landscape_path, managed_thumb_path) elif os.path.exists(fanart_path): utils.fs.softlink_file(fanart_path, managed_thumb_path) resources.lib.database_handler.DatabaseHandler().update_content( self.path, status='managed')
script.skin.helper.widgets Main service entry point ''' from resources.lib.utils import log_msg, ADDON_ID from resources.lib.kodi_monitor import KodiMonitor import xbmc import xbmcgui import xbmcaddon import time TASK_INTERVAL = 520 WIN = xbmcgui.Window(10000) ADDON = xbmcaddon.Addon(ADDON_ID) MONITOR = KodiMonitor(win=WIN, addon=ADDON) log_msg('Backgroundservice started', xbmc.LOGNOTICE) # keep the kodi monitor alive which processes database updates to refresh widgets while not MONITOR.abortRequested(): # set generic widget reload if TASK_INTERVAL >= 300: WIN.setProperty("widgetreload2", time.strftime("%Y%m%d%H%M%S", time.gmtime())) TASK_INTERVAL = 0 else: TASK_INTERVAL += 10 # sleep for 10 seconds MONITOR.waitForAbort(10) del MONITOR