Follow Enigma2 API change... its not allowed to directly access ConfigElement notifie...
[enigma2-plugins.git] / autotimer / src / AutoTimerResource.py
1 from AutoTimer import AutoTimer
2 from Components.config import config
3 from RecordTimer import AFTEREVENT
4 from twisted.web import http, resource
5 try:
6         from urllib import unquote
7 except ImportError as ie:
8         from urllib.parse import unquote
9 from enigma import eServiceReference
10 from . import _, iteritems
11 from . import plugin
12
13 API_VERSION = "1.0"
14
15 class AutoTimerBaseResource(resource.Resource):
16         _remove = False
17         def getAutoTimerInstance(self):
18                 if plugin.autotimer is None:
19                         self._remove = True
20                         autotimer = AutoTimer()
21                         try:
22                                 autotimer.readXml()
23                         except Exception:
24                                 # TODO: proper error handling
25                                 pass
26                         return autotimer
27                 self._remove = False
28                 return plugin.autotimer
29         def returnResult(self, req, state, statetext):
30                 req.setResponseCode(http.OK)
31                 req.setHeader('Content-type', 'application; xhtml+xml')
32                 req.setHeader('charset', 'UTF-8')
33
34                 return """<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
35 <e2simplexmlresult>
36         <e2state>%s</e2state>
37         <e2statetext>%s</e2statetext>
38 </e2simplexmlresult>""" % ('True' if state else 'False', statetext)
39
40
41 class AutoTimerDoParseResource(AutoTimerBaseResource):
42         def render(self, req):
43                 autotimer = self.getAutoTimerInstance()
44                 ret = autotimer.parseEPG()
45                 output = _("Found a total of %d matching Events.\n%d Timer were added and %d modified, %d conflicts encountered, %d similars added.") % (ret[0], ret[1], ret[2], len(ret[4]), len(ret[5]))
46
47                 if self._remove:
48                         autotimer.writeXml()
49
50                 return self.returnResult(req, True, output)
51
52 class AutoTimerListAutoTimerResource(AutoTimerBaseResource):
53         def render(self, req):
54                 autotimer = self.getAutoTimerInstance()
55
56                 # show xml
57                 req.setResponseCode(http.OK)
58                 req.setHeader('Content-type', 'application; xhtml+xml')
59                 req.setHeader('charset', 'UTF-8')
60                 return ''.join(autotimer.getXml())
61
62 class AutoTimerRemoveAutoTimerResource(AutoTimerBaseResource):
63         def render(self, req):
64                 autotimer = self.getAutoTimerInstance()
65
66                 id = req.args.get("id")
67                 if id:
68                         autotimer.remove(int(id[0]))
69                         if self._remove:
70                                 autotimer.writeXml()
71                         return self.returnResult(req, True, _("AutoTimer was removed"))
72                 else:
73                         return self.returnResult(req, False, _("missing parameter \"id\""))
74
75 class AutoTimerAddOrEditAutoTimerResource(AutoTimerBaseResource):
76         # TODO: recheck if we can modify regular config parser to work on this
77         # TODO: allow to edit defaults?
78         def render(self, req):
79                 autotimer = self.getAutoTimerInstance()
80                 def get(name, default=None):
81                         ret = req.args.get(name)
82                         return ret[0] if ret else default
83
84                 id = get("id")
85                 timer = None
86                 newTimer = True
87                 if id is None:
88                         id = autotimer.getUniqueId()
89                         timer = autotimer.defaultTimer.clone()
90                         timer.id = id
91                 else:
92                         id = int(id)
93                         for possibleMatch in autotimer.getTimerList():
94                                 if possibleMatch.id == id:
95                                         timer = possibleMatch
96                                         newTimer = False
97                                         break
98                         if timer is None:
99                                 return self.returnResult(req, False, _("unable to find timer with id %i" % (id,)))
100
101                 if id != -1:
102                         # Match
103                         timer.match = unquote(get("match", timer.match))
104                         if not timer.match:
105                                 return self.returnResult(req, False, _("autotimers need a match attribute"))
106
107                         # Name
108                         timer.name = unquote(get("name", timer.name)).strip()
109                         if not timer.name: timer.name = timer.match
110
111                         # Enabled
112                         enabled = get("enabled")
113                         if enabled is not None:
114                                 try: enabled = int(enabled)
115                                 except ValueError: enabled = enabled == "yes"
116                                 timer.enabled = enabled
117
118                         # Timeframe
119                         before = get("before")
120                         after = get("after")
121                         if before and after:
122                                 timer.timeframe = (int(after), int(before))
123                         elif before == '' or after == '':
124                                 timer.timeframe = None
125
126                 # Encoding
127                 timer.encoding = get("encoding", timer.encoding)
128
129                 # ...
130                 timer.searchType = get("searchType", timer.searchType)
131                 timer.searchCase = get("searchCase", timer.searchCase)
132
133                 # Alternatives
134                 timer.overrideAlternatives = int(get("overrideAlternatives", timer.overrideAlternatives))
135
136                 # Justplay
137                 justplay = get("justplay")
138                 if justplay is not None:
139                         try: justplay = int(justplay)
140                         except ValueError: justplay = justplay == "zap"
141                         timer.justplay = justplay
142
143                 # Timespan
144                 start = get("timespanFrom")
145                 end = get("timespanTo")
146                 if start and end:
147                         start = [int(x) for x in start.split(':')]
148                         end = [int(x) for x in end.split(':')]
149                         timer.timespan = (start, end)
150                 elif start == '' and end == '':
151                         timer.timespan = None
152
153                 # Services
154                 servicelist = get("services")
155                 if servicelist is not None:
156                         servicelist = unquote(servicelist).split(',')
157                         appendlist = []
158                         for value in servicelist:
159                                 myref = eServiceReference(str(value))
160                                 if not (myref.flags & eServiceReference.isGroup):
161                                         # strip all after last :
162                                         pos = value.rfind(':')
163                                         if pos != -1:
164                                                 if value[pos-1] == ':':
165                                                         pos -= 1
166                                                 value = value[:pos+1]
167
168                                 if myref.valid():
169                                         appendlist.append(value)
170                         timer.services = appendlist
171
172                 # Bouquets
173                 servicelist = get("bouquets")
174                 if servicelist is not None:
175                         servicelist = unquote(servicelist).split(',')
176                         while '' in servicelist: servicelist.remove('')
177                         timer.bouquets = servicelist
178
179                 # Offset
180                 offset = get("offset")
181                 if offset:
182                         offset = offset.split(',')
183                         if len(offset) == 1:
184                                 before = after = int(offset[0] or 0) * 60
185                         else:
186                                 before = int(offset[0] or 0) * 60
187                                 after = int(offset[1] or 0) * 60
188                         timer.offset = (before, after)
189                 elif offset == '':
190                         timer.offset = None
191
192                 # AfterEvent
193                 afterevent = get("afterevent")
194                 if afterevent:
195                         if afterevent == "default":
196                                 timer.afterevent = []
197                         else:
198                                 try: afterevent = int(afterevent)
199                                 except ValueError:
200                                         afterevent = {
201                                                 "nothing": AFTEREVENT.NONE,
202                                                 "deepstandby": AFTEREVENT.DEEPSTANDBY,
203                                                 "standby": AFTEREVENT.STANDBY,
204                                                 "auto": AFTEREVENT.AUTO
205                                         }.get(afterevent, AFTEREVENT.AUTO)
206                                 # TODO: add afterevent timespan
207                                 timer.afterevent = [(afterevent, None)]
208
209                 # Maxduration
210                 maxduration = get("maxduration")
211                 if maxduration:
212                         timer.maxduration = int(maxduration)*60
213                 elif maxduration == '':
214                         timer.maxduration = None
215
216                 # Includes
217                 title = req.args.get("title")
218                 shortdescription = req.args.get("shortdescription")
219                 description = req.args.get("description")
220                 dayofweek = req.args.get("dayofweek")
221                 if title or shortdescription or description or dayofweek:
222                         includes = timer.include
223                         title = [unquote(x) for x in title] if title else includes[0]
224                         shortdescription = [unquote(x) for x in shortdescription] if shortdescription else includes[1]
225                         description = [unquote(x) for x in description] if description else includes[2]
226                         dayofweek = [unquote(x) for x in dayofweek] if dayofweek else includes[3]
227                         while '' in title: title.remove('')
228                         while '' in shortdescription: shortdescription.remove('')
229                         while '' in description: description.remove('')
230                         while '' in dayofweek: dayofweek.remove('')
231                         timer.include = (title, shortdescription, description, dayofweek)
232
233                 # Excludes
234                 title = req.args.get("!title")
235                 shortdescription = req.args.get("!shortdescription")
236                 description = req.args.get("!description")
237                 dayofweek = req.args.get("!dayofweek")
238                 if title or shortdescription or description or dayofweek:
239                         excludes = timer.exclude
240                         title = [unquote(x) for x in title] if title else excludes[0]
241                         shortdescription = [unquote(x) for x in shortdescription] if shortdescription else excludes[1]
242                         description = [unquote(x) for x in description] if description else excludes[2]
243                         dayofweek = [unquote(x) for x in dayofweek] if dayofweek else excludes[3]
244                         while '' in title: title.remove('')
245                         while '' in shortdescription: shortdescription.remove('')
246                         while '' in description: description.remove('')
247                         while '' in dayofweek: dayofweek.remove('')
248                         timer.exclude = (title, shortdescription, description, dayofweek)
249
250                 tags = req.args.get("tag")
251                 if tags:
252                         while '' in tags: tags.remove('')
253                         timer.tags = [unquote(x) for x in tags]
254
255                 timer.matchCount = int(get("counter", timer.matchCount))
256                 timer.matchFormatString = get("counterFormat", timer.matchFormatString)
257                 if id != -1:
258                         matchLeft = get("left")
259                         timer.matchLeft = int(matchLeft) if matchLeft else (timer.matchCount if newTimer else timer.matchLeft)
260                         timer.matchLimit = get("lastActivation", timer.matchLimit)
261                         timer.lastBegin = int(get("lastBegin", timer.lastBegin))
262
263                 timer.avoidDuplicateDescription = int(get("avoidDuplicateDescription", timer.avoidDuplicateDescription))
264                 timer.destination = get("location", timer.destination) or None
265
266                 if newTimer:
267                         autotimer.add(timer)
268                         message = _("AutoTimer was added successfully")
269                 else:
270                         message = _("AutoTimer was changed successfully")
271
272                 # eventually save config
273                 if self._remove:
274                         autotimer.writeXml()
275
276                 return self.returnResult(req, True, message)
277
278 class AutoTimerChangeSettingsResource(AutoTimerBaseResource):
279         def render(self, req):
280                 for key, value in iteritems(req.args):
281                         value = value[0]
282                         if key == "autopoll":
283                                 config.plugins.autotimer.autopoll.value = True if value == "true" else False
284                         elif key == "interval":
285                                 config.plugins.autotimer.interval.value = int(value)
286                         elif key == "refresh":
287                                 config.plugins.autotimer.refresh.value = value
288                         elif key == "try_guessing":
289                                 config.plugins.autotimer.try_guessing.value = True if value == "true" else False
290                         elif key == "editor":
291                                 config.plugins.autotimer.editor.value = value
292                         elif key == "disabled_on_conflict":
293                                 config.plugins.autotimer.disabled_on_conflict.value = True if value == "true" else False
294                         elif key == "addsimilar_on_conflict":
295                                 config.plugins.autotimer.addsimilar_on_conflict.value = True if value == "true" else False
296                         elif key == "show_in_extensionsmenu":
297                                 config.plugins.autotimer.show_in_extensionsmenu.value = True if value == "true" else False
298                         elif key == "fastscan":
299                                 config.plugins.autotimer.fastscan.value = True if value == "true" else False
300                         elif key == "notifconflict":
301                                 config.plugins.autotimer.notifconflict.value = True if value == "true" else False
302                         elif key == "notifsimilar":
303                                 config.plugins.autotimer.notifsimilar.value = True if value == "true" else False
304
305                 if config.plugins.autotimer.autopoll.value:
306                         if plugin.autopoller is None:
307                                 from AutoPoller import AutoPoller
308                                 plugin.autopoller = AutoPoller()
309                         if plugin.autotimer is None:
310                                 plugin.autotimer = AutoTimer()
311                         plugin.autopoller.start(initial = False)
312                 else:
313                         if plugin.autopoller is not None:
314                                 plugin.autopoller.stop()
315                                 plugin.autopoller = None
316                         if plugin.autotimer is not None:
317                                 try: plugin.autotimer.readXml()
318                                 except Exception: pass
319                                 else: plugin.autotimer.writeXml()
320                                 plugin.autotimer = None
321
322                 return self.returnResult(req, True, _("config changed."))
323
324 class AutoTimerSettingsResource(resource.Resource):
325         def render(self, req):
326                 req.setResponseCode(http.OK)
327                 req.setHeader('Content-type', 'application; xhtml+xml')
328                 req.setHeader('charset', 'UTF-8')
329
330                 try:
331                         from Plugins.SystemPlugins.vps import Vps
332                 except ImportError as ie:
333                         hasVps = False
334                 else:
335                         hasVps = True
336
337                 return """<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
338 <e2settings>
339         <e2setting>
340                 <e2settingname>config.plugins.autotimer.autopoll</e2settingname>
341                 <e2settingvalue>%s</e2settingvalue>
342         </e2setting>
343         <e2setting>
344                 <e2settingname>config.plugins.autotimer.interval</e2settingname>
345                 <e2settingvalue>%d</e2settingvalue>
346         </e2setting>
347         <e2setting>
348                 <e2settingname>config.plugins.autotimer.refresh</e2settingname>
349                 <e2settingvalue>%s</e2settingvalue>
350         </e2setting>
351         <e2setting>
352                 <e2settingname>config.plugins.autotimer.try_guessing</e2settingname>
353                 <e2settingvalue>%s</e2settingvalue>
354         </e2setting>
355         <e2setting>
356                 <e2settingname>config.plugins.autotimer.editor</e2settingname>
357                 <e2settingvalue>%s</e2settingvalue>
358         </e2setting>
359         <e2setting>
360                 <e2settingname>config.plugins.autotimer.disabled_on_conflict</e2settingname>
361                 <e2settingvalue>%s</e2settingvalue>
362         </e2setting>
363         <e2setting>
364                 <e2settingname>config.plugins.autotimer.addsimilar_on_conflict</e2settingname>
365                 <e2settingvalue>%s</e2settingvalue>
366         </e2setting>
367         <e2setting>
368                 <e2settingname>config.plugins.autotimer.show_in_extensionsmenu</e2settingname>
369                 <e2settingvalue>%s</e2settingvalue>
370         </e2setting>
371         <e2setting>
372                 <e2settingname>config.plugins.autotimer.fastscan</e2settingname>
373                 <e2settingvalue>%s</e2settingvalue>
374         </e2setting>
375         <e2setting>
376                 <e2settingname>config.plugins.autotimer.notifconflict</e2settingname>
377                 <e2settingvalue>%s</e2settingvalue>
378         </e2setting>
379         <e2setting>
380                 <e2settingname>config.plugins.autotimer.notifsimilar</e2settingname>
381                 <e2settingvalue>%s</e2settingvalue>
382         </e2setting>
383         <e2setting>
384                 <e2settingname>hasVps</e2settingname>
385                 <e2settingvalue>%s</e2settingvalue>
386         </e2setting>
387 </e2settings>""" % (
388                                 config.plugins.autotimer.autopoll.value,
389                                 config.plugins.autotimer.interval.value,
390                                 config.plugins.autotimer.refresh.value,
391                                 config.plugins.autotimer.try_guessing.value,
392                                 config.plugins.autotimer.editor.value,
393                                 config.plugins.autotimer.addsimilar_on_conflict,
394                                 config.plugins.autotimer.disabled_on_conflict.value,
395                                 config.plugins.autotimer.show_in_extensionsmenu.value,
396                                 config.plugins.autotimer.fastscan.value,
397                                 config.plugins.autotimer.notifconflict.value,
398                                 config.plugins.autotimer.notifsimilar.value,
399                                 hasVps,
400                         )