From e175305d6eb330d439ba46523d2fbc9032d9092d Mon Sep 17 00:00:00 2001 From: ims Date: Tue, 29 Sep 2026 07:03:27 +0200 Subject: [PATCH] EPGSearch - add option to exclude Last Scanned bouquet and refresh search results when relevant settings change --- epgsearch/src/EPGSearch.py | 28 +++++++++++++++++- epgsearch/src/EPGSearchSetup.py | 51 +++++++++++++++++++-------------- epgsearch/src/__init__.py | 1 + 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/epgsearch/src/EPGSearch.py b/epgsearch/src/EPGSearch.py index 109c4438f..ceedbf07a 100644 --- a/epgsearch/src/EPGSearch.py +++ b/epgsearch/src/EPGSearch.py @@ -924,13 +924,37 @@ def ClearHistory(self): def setup(self): self.filter_type_before_setup = config.plugins.epgsearch.filter_type.value + self.search_settings_before_setup = self.getSearchSettings() self.session.openWithCallback(self.setupClosed, EPGSearchSetup) def setupClosed(self): - if self.do_filter is not None and self.filter_type_before_setup != config.plugins.epgsearch.filter_type.value: + epg = config.plugins.epgsearch + search_settings = self.getSearchSettings() + if self.currSearch and self.search_settings_before_setup != search_settings: + global BouquetChannelListList, IptvBouquetChannelListList + BouquetChannelListList = None + IptvBouquetChannelListList = None + self.searchEPG(self.currSearch, False) + elif self.do_filter is not None and self.filter_type_before_setup != epg.filter_type.value: self.hide_filter() self.show_filter() + # Track settings that affect EPG search results. + # Exclude unrelated settings to avoid unnecessary searches after closing setup. + # The result filter is handled separately without repeating the EPG search. + # New settings are included automatically unless explicitly excluded. + def getSearchSettings(self): + return { + name: item.value + for name, item in config.plugins.epgsearch.dict().items() + if name not in ( + "filter_type", "history", "history_length", + "add_search_to_epg", "type_button_blue", + "yellow_eventname", "picons", + "show_in_furtheroptionsmenu", "search_in_channelmenu" + ) + } + def blueButtonPressed(self): if len(config.plugins.epgsearch.history.value): history = [x for x in config.plugins.epgsearch.history.value] @@ -1088,6 +1112,8 @@ def getBouquetChannelList(self): for bouquet in bouquetlist: if not bouquet.valid(): continue + if config.plugins.epgsearch.bouquet.value and config.plugins.epgsearch.exclude_lastscanned.value and 'FROM BOUQUET "userbouquet.LastScanned.tv"' in bouquet.toString(): + continue if bouquet.flags & eServiceReference.isDirectory: services = serviceHandler.list(bouquet) if services: diff --git a/epgsearch/src/EPGSearchSetup.py b/epgsearch/src/EPGSearchSetup.py index 7b33632fa..7b98223c8 100644 --- a/epgsearch/src/EPGSearchSetup.py +++ b/epgsearch/src/EPGSearchSetup.py @@ -27,27 +27,8 @@ class EPGSearchSetup(Screen, ConfigListScreen): def __init__(self, session): Screen.__init__(self, session) self.title = _("EPGSearch Setup") - ConfigListScreen.__init__( - self, - [ - (_("Length of History"), config.plugins.epgsearch.history_length, _("How many entries to keep in the search history at most. 0 disables history entirely!")), - (_("Add \"Search\" Button to EPG"), config.plugins.epgsearch.add_search_to_epg, _("If this setting is enabled, the plugin adds a \"Search\" Button to the regular EPG.")), - (_("Type blue Button"), config.plugins.epgsearch.type_button_blue, _("Select type: 'Search and Select channel' or 'Search'.")), - (_("Use event name for yellow button search"), config.plugins.epgsearch.yellow_eventname, _("Use the current event name as the initial search text. An empty search field is used otherwise.")), - (_("Use Picons"), config.plugins.epgsearch.picons, _("If this setting is enabled, the plugin adds picons.")), - (_("Search type"), config.plugins.epgsearch.search_type, _("Select type for search, \"partial match\" for the most extensive search, \"partial description\" for the most description search.")), - (_("Search strictness"), config.plugins.epgsearch.search_case, _("Select whether or not you want to enforce case correctness.")), - (_("Add \"Search event in EPG\" to event menu"), config.plugins.epgsearch.show_in_furtheroptionsmenu, _("Adds \"Search event in EPG\" item into the event menu (needs restart GUI)")), - (_("Add \"Search event in EPG\" to channel menu"), config.plugins.epgsearch.search_in_channelmenu, _("Adds \"Search event in EPG\" item into the channel selection context menu (needs restart GUI)")), - (_("Search only bouquets"), config.plugins.epgsearch.bouquet, _("If this setting is enabled, searching EPG in only services in user bouquets.")), - (_("Include IPTV services"), config.plugins.epgsearch.include_iptv, _("Include IPTV services in search, in some cases slows down the searching.")), - (_("Display name service as in bouquets"), config.plugins.epgsearch.favorit_name, _("If 'Search only bouquets' is enabled, show service name as in bouquets for renamed services.")), - (_("Result filter"), config.plugins.epgsearch.filter_type, _("Use P+/- to filter result by short description or extended (only if short is missing). Partial: only items whose description is contained in selected event. Exact: only items with matching description. Full: identical whole description.")), - - - ], - session=session - ) + ConfigListScreen.__init__(self, [], session=session, on_change=self.changedEntry) + self.createSetup() self["config"].onSelectionChanged.append(self.updateHelp) @@ -63,6 +44,34 @@ def __init__(self, session): "save": self.save }, -2) + def createSetup(self): + menu = [] + menu.append((_("Length of History"), config.plugins.epgsearch.history_length, _("How many entries to keep in the search history at most. 0 disables history entirely!"))) + menu.append((_("Add \"Search\" Button to EPG"), config.plugins.epgsearch.add_search_to_epg, _("If this setting is enabled, the plugin adds a \"Search\" Button to the regular EPG."))) + menu.append((_("Type blue Button"), config.plugins.epgsearch.type_button_blue, _("Select type: 'Search and Select channel' or 'Search'."))) + menu.append((_("Use event name for yellow button search"), config.plugins.epgsearch.yellow_eventname, _("Use the current event name as the initial search text. An empty search field is used otherwise."))) + menu.append((_("Use Picons"), config.plugins.epgsearch.picons, _("If this setting is enabled, the plugin adds picons."))) + menu.append((_("Search type"), config.plugins.epgsearch.search_type, _("Select type for search, \"partial match\" for the most extensive search, \"partial description\" for the most description search."))) + menu.append((_("Search strictness"), config.plugins.epgsearch.search_case, _("Select whether or not you want to enforce case correctness."))) + menu.append((_("Add \"Search event in EPG\" to event menu"), config.plugins.epgsearch.show_in_furtheroptionsmenu, _("Adds \"Search event in EPG\" item into the event menu (needs restart GUI)"))) + menu.append((_("Add \"Search event in EPG\" to channel menu"), config.plugins.epgsearch.search_in_channelmenu, _("Adds \"Search event in EPG\" item into the channel selection context menu (needs restart GUI)"))) + menu.append((_("Search only bouquets"), config.plugins.epgsearch.bouquet, _("If this setting is enabled, searching EPG in only services in user bouquets."))) + if config.plugins.epgsearch.bouquet.value: + menu.append((4 * " " + _("Exclude Last Scanned"), config.plugins.epgsearch.exclude_lastscanned, _("Exclude the Last Scanned bouquet when searching only in bouquets."))) + menu.append((_("Include IPTV services"), config.plugins.epgsearch.include_iptv, _("Include IPTV services in search, in some cases slows down the searching."))) + menu.append((_("Display name service as in bouquets"), config.plugins.epgsearch.favorit_name, _("If 'Search only bouquets' is enabled, show service name as in bouquets for renamed services."))) + menu.append((_("Result filter"), config.plugins.epgsearch.filter_type, _("Use P+/- to filter result by short description or extended (only if short is missing). Partial: only items whose description is contained in selected event. Exact: only items with matching description. Full: identical whole description."))) + self["config"].list = menu + + def changedEntry(self): + current = self["config"].getCurrent() + if current[1].isChanged(): + if current not in self.manipulatedItems: + self.manipulatedItems.append(current) + elif current in self.manipulatedItems: + self.manipulatedItems.remove(current) + self.createSetup() + def updateHelp(self): cur = self["config"].getCurrent() if cur and len(cur) > 2: diff --git a/epgsearch/src/__init__.py b/epgsearch/src/__init__.py index b2f4d3509..edd30f9c5 100644 --- a/epgsearch/src/__init__.py +++ b/epgsearch/src/__init__.py @@ -28,6 +28,7 @@ def _(txt): config.plugins.epgsearch.type_button_blue = ConfigSelection([('0', _("only Search")), ('1', _("choice (Search and standard)"))], default='0') config.plugins.epgsearch.picons = ConfigYesNo(default=False) config.plugins.epgsearch.bouquet = ConfigYesNo(default=False) +config.plugins.epgsearch.exclude_lastscanned = ConfigYesNo(default=False) config.plugins.epgsearch.favorit_name = ConfigYesNo(default=False) config.plugins.epgsearch.include_iptv = ConfigYesNo(default=False) config.plugins.epgsearch.show_in_furtheroptionsmenu = ConfigYesNo(default=True)