Skip to content

Commit

Permalink
AutoTimer
Browse files Browse the repository at this point in the history
New search type: description match
Search for a part within the event description
Specify a channel or bouquet filter will decrease the execution time
Tested with Enigma2 single and multi bouquet configuration
  • Loading branch information
betonme committed Dec 1, 2011
1 parent 834d73d commit 4e6f2c0
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 10 deletions.
86 changes: 83 additions & 3 deletions autotimer/src/AutoTimer.py
Expand Up @@ -44,7 +44,8 @@ def getTimeDiff(timer, begin, end):

typeMap = {
"exact": eEPGCache.EXAKT_TITLE_SEARCH,
"partial": eEPGCache.PARTIAL_TITLE_SEARCH
"partial": eEPGCache.PARTIAL_TITLE_SEARCH,
"description": "AUTOTIMER_CUSTOM_DESCRIPTION_SEARCH"
}

caseMap = {
Expand Down Expand Up @@ -213,8 +214,87 @@ def parseEPG(self, simulateOnly = False):
except UnicodeDecodeError:
pass

# Search EPG, default to empty list
epgmatches = epgcache.search(('RITBDSE', 1000, typeMap[timer.searchType], match, caseMap[timer.searchCase])) or []
if timer.searchType == "description":
test = []
epgmatches = []

casesensitive = timer.searchCase == "sensitive"
if not casesensitive:
match = match.lower()

#if timer.services or timer.bouquets:
# Service filter defined
# Search only using the specified services
for service in timer.services:
test.append( (service, 0, -1, -1 ) )
mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
for bouquet in timer.bouquets:
services = serviceHandler.list(eServiceReference(bouquet))
if not services is None:
while True:
service = services.getNext()
if not service.valid(): #check end of list
break
if not (service.flags & mask):
test.append( (service.toString(), 0, -1, -1 ) )

if not test:
#else:
# No service filter defined
# Search within all services - could be very slow

# Get all bouquets
bouquetlist = []
refstr = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"bouquets.tv\" ORDER BY bouquet'
bouquetroot = eServiceReference(refstr)
mask = eServiceReference.isDirectory
if config.usage.multibouquet.value:
bouquets = serviceHandler.list(bouquetroot)
if bouquets:
while True:
s = bouquets.getNext()
if not s.valid():
break
if s.flags & mask:
info = serviceHandler.info(s)
if info:
bouquetlist.append((info.getName(s), s))
else:
info = serviceHandler.info(bouquetroot)
if info:
bouquetlist.append((info.getName(bouquetroot), bouquetroot))

# Get all services
mask = (eServiceReference.isMarker | eServiceReference.isDirectory)
for name, bouquet in bouquetlist:
if not bouquet.valid(): #check end of list
break
if bouquet.flags & eServiceReference.isDirectory:
services = serviceHandler.list(bouquet)
if not services is None:
while True:
service = services.getNext()
if not service.valid(): #check end of list
break
if not (service.flags & mask):
test.append( (service.toString(), 0, -1, -1 ) )

if test:
# Get all events
# eEPGCache.lookupEvent( [ format of the returned tuples, ( service, 0 = event intersects given start_time, start_time -1 for now_time), ] )
test.insert(0, 'RITBDSE')
allevents = epgcache.lookupEvent( test ) or []

# Filter events
for serviceref, eit, name, begin, duration, shortdesc, extdesc in allevents:
if ( shortdesc if casesensitive else shortdesc.lower() ).find(match) > -1 \
or ( extdesc if casesensitive else extdesc.lower() ).find(match) > -1:
epgmatches.append( (serviceref, eit, name, begin, duration, shortdesc, extdesc) )

else:
# Search EPG, default to empty list
epgmatches = epgcache.search( ('RITBDSE', 1000, typeMap[timer.searchType], match, caseMap[timer.searchCase]) ) or []

# Sort list of tuples by begin time 'B'
epgmatches.sort(key=itemgetter(3))

Expand Down
2 changes: 1 addition & 1 deletion autotimer/src/AutoTimerComponent.py
Expand Up @@ -148,7 +148,7 @@ def setSearchCase(self, case):
searchCase = property(lambda self: self._searchCase, setSearchCase)

def setSearchType(self, type):
assert type in ("exact", "partial"), "search type must be exact or partial"
assert type in ("exact", "partial", "description"), "search type must be exact, partial or description"
self._searchType = type

searchType = property(lambda self: self._searchType, setSearchType)
Expand Down
8 changes: 4 additions & 4 deletions autotimer/src/AutoTimerConfiguration.py
Expand Up @@ -540,8 +540,8 @@ def buildConfig(defaultTimer, timers, webif = False):
if defaultTimer.encoding != defaultEncoding or webif:
extend((' encoding="', str(defaultTimer.encoding), '"'))

# Only display searchType if exact
if defaultTimer.searchType == "exact":
# SearchType
if defaultTimer.searchType:
extend((' searchType="', str(defaultTimer.searchType), '"'))

# Only display searchCase if sensitive
Expand Down Expand Up @@ -674,8 +674,8 @@ def buildConfig(defaultTimer, timers, webif = False):
if timer.encoding != defaultEncoding or webif:
extend((' encoding="', str(timer.encoding), '"'))

# Only display searchType if exact
if timer.searchType == "exact":
# SearchType
if timer.searchType:
extend((' searchType="', str(timer.searchType), '"'))

# Only display searchCase if sensitive
Expand Down
4 changes: 2 additions & 2 deletions autotimer/src/AutoTimerEditor.py
Expand Up @@ -184,7 +184,7 @@ def createSetup(self, timer):
self.encoding = NoSave(ConfigSelection(choices = selection, default = default))

# ...
self.searchType = NoSave(ConfigSelection(choices = [("partial", _("partial match")), ("exact", _("exact match"))], default = timer.searchType))
self.searchType = NoSave(ConfigSelection(choices = [("partial", _("partial match")), ("exact", _("exact match")), ("description", _("description match"))], default = timer.searchType))
self.searchCase = NoSave(ConfigSelection(choices = [("sensitive", _("case-sensitive search")), ("insensitive", _("case-insensitive search"))], default = timer.searchCase))

# Alternatives override
Expand Down Expand Up @@ -489,7 +489,7 @@ def initHelpTexts(self):
self.name: _("This is a name you can give the AutoTimer. It will be shown in the Overview and the Preview."),
self.match: _("This is what will be looked for in event titles. Note that looking for e.g. german umlauts can be tricky as you have to know the encoding the channel uses."),
self.encoding: _("Encoding the channel uses for it's EPG data. You only need to change this if you're searching for special characters like the german umlauts."),
self.searchType: _("Select \"exact match\" to enforce \"Match title\" to match exactly or \"partial match\" if you only want to search for a part of the event title."),
self.searchType: _("Select \"exact match\" to enforce \"Match title\" to match exactly, \"partial match\" if you only want to search for a part of the event title or \"description match\" if you only want to search for a part of the event description"),
self.searchCase: _("Select whether or not you want to enforce case correctness."),
self.justplay: _("Add zap timer instead of record timer?"),
self.overrideAlternatives: _("With this option enabled the channel to record on can be changed to a alternative service it is restricted to."),
Expand Down

0 comments on commit 4e6f2c0

Please sign in to comment.