fix crash when aborting import from epg
[enigma2-plugins.git] / epgsearch / src / EPGSearch.py
1 from enigma import eEPGCache, eServiceReference
2
3 from Screens.ChannelSelection import SimpleChannelSelection
4 from Screens.ChoiceBox import ChoiceBox
5 from Screens.EpgSelection import EPGSelection
6 from Screens.InputBox import InputBox
7 from Screens.Screen import Screen
8
9 from Components.ActionMap import ActionMap
10 from Components.Button import Button
11 from Components.config import config
12 from Components.TimerList import TimerList
13
14 class EPGSearch(EPGSelection):
15         def __init__(self, session):
16                 EPGSelection.__init__(self, session, '')  # Empty string serviceref so we get EPG_TYPE_SINGLE
17                 self.skinName = "EPGSelection"
18
19                 # XXX: we lose sort begin/end here
20                 self["key_yellow"].setText(_("New Search"))
21                 self["key_blue"].setText(_("History"))
22
23         def onCreate(self):
24                 l = self["list"]
25                 l.recalcEntrySize()
26                 l.list = []
27                 l.l.setList(l.list)
28
29         def closeScreen(self):
30                 # Save our history
31                 config.plugins.epgsearch.save()
32                 EPGSelection.closeScreen(self)
33
34         def yellowButtonPressed(self):
35                 self.session.openWithCallback(
36                         self.searchEPG,
37                         InputBox,
38                         title = _("Enter text to search for")
39                 )
40
41         def blueButtonPressed(self):
42                 options = [
43                         (_("From Timer"), "xxImportFromTimer"),
44                         (_("From EPG"), "xxImportFromEPG")
45                 ]
46                 options.extend([(x, x) for x in config.plugins.epgsearch.history.value])
47
48                 self.session.openWithCallback(
49                         self.searchEPGWrapper,
50                         ChoiceBox,
51                         title = _("Select text to search for"),
52                         list = options
53                 )
54
55         def searchEPGWrapper(self, ret):
56                 if ret:
57                         ret = ret[1]
58                         if ret is "xxImportFromTimer":
59                                 self.session.openWithCallback(
60                                         self.searchEPG,
61                                         EPGSearchTimerImport
62                                 )
63                         elif ret is "xxImportFromEPG":
64                                 self.session.openWithCallback(
65                                         self.searchEPG,
66                                         EPGSearchChannelSelection
67                                 )
68                         else:
69                                 self.searchEPG(ret)
70
71         def searchEPG(self, searchString = None):
72                 if searchString:
73                         # Maintain history
74                         history = config.plugins.epgsearch.history.value
75                         if searchString not in history:
76                                 history.insert(0, searchString)
77                                 if len(history) > 10:
78                                         history.pop(10)
79                         else:
80                                 history.remove(searchString)
81                                 history.insert(0, searchString)
82
83                         # Workaround to allow search for umlauts if we know the encoding (pretty bad, I know...)
84                         encoding = config.plugins.epgsearch.encoding.value
85                         if encoding != 'UTF-8':
86                                 try:
87                                         searchString = searchString.decode('UTF-8', 'replace').encode(encoding)
88                                 except UnicodeDecodeError:
89                                         pass
90
91                         # Search EPG, default to empty list
92                         epgcache = eEPGCache.getInstance() # XXX: the EPGList also keeps an instance of the cache but we better make sure that we get what we want :-)
93                         ret = epgcache.search(('RIBDT', 200, eEPGCache.PARTIAL_TITLE_SEARCH, searchString, eEPGCache.NO_CASE_CHECK)) or []
94                         ret.sort(key = lambda x: x[2]) # sort by time
95
96                         # Update List
97                         l = self["list"]
98                         l.recalcEntrySize()
99                         l.list = ret
100                         l.l.setList(ret)
101
102 class EPGSearchTimerImport(Screen):
103         def __init__(self, session):
104                 Screen.__init__(self, session)
105                 self.skinName = "TimerEditList"
106
107                 self.list = []
108                 self.fillTimerList()
109
110                 self["timerlist"] = TimerList(self.list)
111
112                 self["key_red"] = Button(_("Cancel"))
113                 self["key_green"] = Button(_("OK"))
114                 self["key_yellow"] = Button("")
115                 self["key_blue"] = Button("")
116
117                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
118                 {
119                         "ok": self.search,
120                         "cancel": self.cancel,
121                         "green": self.search,
122                         "red": self.cancel
123                 }, -1)
124                 self.onLayoutFinish.append(self.setCustomTitle)
125
126         def setCustomTitle(self):
127                 self.setTitle(_("Select a timer to search"))
128
129         def fillTimerList(self):
130                 l = self.list
131                 del l[:]
132
133                 for timer in self.session.nav.RecordTimer.timer_list:
134                         l.append((timer, False))
135
136                 for timer in self.session.nav.RecordTimer.processed_timers:
137                         l.append((timer, True))
138                 l.sort(key = lambda x: x[0].begin)
139
140         def search(self):
141                 cur = self["timerlist"].getCurrent()
142                 if cur:
143                         self.close(cur.name)
144
145         def cancel(self):
146                 self.close(None)
147
148 class EPGSearchChannelSelection(SimpleChannelSelection):
149         def __init__(self, session):
150                 SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
151                 self.skinName = "SimpleChannelSelection"
152
153                 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
154                         {
155                                 "showEPGList": self.channelSelected
156                         }
157                 )
158
159         def channelSelected(self):
160                 ref = self.getCurrentSelection()
161                 if (ref.flags & 7) == 7:
162                         self.enterPath(ref)
163                 elif not (ref.flags & eServiceReference.isMarker):
164                         self.session.openWithCallback(
165                                 self.epgClosed,
166                                 EPGSearchEPGSelection,
167                                 ref
168                         )
169
170         def epgClosed(self, ret = None):
171                 if ret:
172                         self.close(ret)
173
174 class EPGSearchEPGSelection(EPGSelection):
175         def __init__(self, session, ref):
176                 EPGSelection.__init__(self, session, ref)
177                 self.skinName = "EPGSelection"
178                 self["key_green"].setText(_("Search"))
179
180         def infoKeyPressed(self):
181                 self.timerAdd()
182
183         def timerAdd(self):
184                 cur = self["list"].getCurrent()
185                 evt = cur[0]
186                 sref = cur[1]
187                 if not evt: 
188                         return
189
190                 self.close(evt.getEventName())
191