[WebInterface] - forward opener for externals to have access to functions of WebInterface
[enigma2-plugins.git] / autotimer / src / AutoTimerResource.py
1 # -*- coding: UTF-8 -*-
2 from AutoTimer import AutoTimer
3 from AutoTimerConfiguration import CURRENT_CONFIG_VERSION
4 from RecordTimer import AFTEREVENT
5 from twisted.internet import reactor
6 from twisted.web import http, resource, server
7 import threading
8 try:
9         from urllib import unquote
10 except ImportError as ie:
11         from urllib.parse import unquote
12 from ServiceReference import ServiceReference
13 from Tools.XMLTools import stringToXML
14 from enigma import eServiceReference
15 from . import config, iteritems, plugin
16 from plugin import autotimer, AUTOTIMER_VERSION
17
18 API_VERSION = "1.6"
19
20 class AutoTimerBaseResource(resource.Resource):
21         def returnResult(self, req, state, statetext):
22                 req.setResponseCode(http.OK)
23                 req.setHeader('Content-type', 'application/xhtml+xml')
24                 req.setHeader('charset', 'UTF-8')
25
26                 return """<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
27 <e2simplexmlresult>
28         <e2state>%s</e2state>
29         <e2statetext>%s</e2statetext>
30 </e2simplexmlresult>""" % ('True' if state else 'False', statetext)
31
32 class AutoTimerBackgroundThread(threading.Thread):
33         def __init__(self, req, fnc):
34                 threading.Thread.__init__(self)
35                 self._req = req
36                 if hasattr(req, 'notifyFinish'):
37                         req.notifyFinish().addErrback(self.connectionLost)
38                 self._stillAlive = True
39                 self._fnc = fnc
40                 self.start()
41
42         def connectionLost(self, err):
43                 self._stillAlive = False
44
45         def run(self):
46                 req = self._req
47                 code = http.OK
48                 try: ret = self._fnc(req)
49                 except Exception as e:
50                         ret = str(e)
51                         code = http.INTERNAL_SERVER_ERROR
52                 def finishRequest():
53                         req.setResponseCode(code)
54                         if code == http.OK:
55                                 req.setHeader('Content-type', 'application/xhtml+xml')
56                         req.setHeader('charset', 'UTF-8')
57                         req.write(ret)
58                         req.finish()
59                 if self._stillAlive:
60                         reactor.callFromThread(finishRequest)
61
62 class AutoTimerBackgroundingResource(AutoTimerBaseResource, threading.Thread):
63         def render(self, req):
64                 AutoTimerBackgroundThread(req, self.renderBackground)
65                 return server.NOT_DONE_YET
66
67         def renderBackground(self, req):
68                 pass
69
70 class AutoTimerDoParseResource(AutoTimerBaseResource):
71         def render(self, req):
72                 self._req = req
73                 self._stillAlive = True
74                 if hasattr(req, 'notifyFinish'):
75                         req.notifyFinish().addErrback(self.connectionLost)
76
77                 d = autotimer.parseEPGAsync().addCallback(self.epgCallback).addErrback(self.epgErrback)
78                 def timeout():
79                         if not d.called and self._stillAlive:
80                                 reactor.callFromThread(lambda: req.write("<ignore />"))
81                                 reactor.callLater(50, timeout)
82                 reactor.callLater(50, timeout)
83
84                 req.setResponseCode(http.OK)
85                 req.setHeader('Content-type', 'application/xhtml+xml')
86                 req.setHeader('charset', 'UTF-8')
87                 req.write("""<?xml version=\"1.0\" encoding=\"UTF-8\" ?><e2simplexmlresult>""")
88                 return server.NOT_DONE_YET
89
90         def connectionLost(self, err):
91                 self._stillAlive = False
92
93         def epgCallback(self, ret):
94                 if self._stillAlive:
95                         ret = """<e2state>True</e2state>
96         <e2statetext>"""+ \
97         _("Found a total of %(matches)d matching Events.\n%(timer)d Timer were added and\n%(modified)d modified,\n%(conflicts)d conflicts encountered,\n%(similars)d similars added.") % \
98         {"matches":ret[0], "timer":ret[1], "modified":ret[2], "conflicts":len(ret[4]), "similars":len(ret[5])} \
99         + "</e2statetext></e2simplexmlresult>"
100                         def finishRequest():
101                                 self._req.write(ret)
102                                 self._req.finish()
103                         reactor.callFromThread(finishRequest)
104
105         def epgErrback(self, failure):
106                 if self._stillAlive:
107                         ret = """<e2state>False</e2state>
108         <e2statetext>"""+ _("AutoTimer failed with error %s") % (str(failure),) + "</e2statetext></e2simplexmlresult>"
109                         def finishRequest():
110                                 self._req.write(ret)
111                                 self._req.finish()
112                         reactor.callFromThread(finishRequest)
113
114 class AutoTimerSimulateBackgroundThread(AutoTimerBackgroundThread):
115         def run(self):
116                 req = self._req
117                 if self._stillAlive:
118                         req.setResponseCode(http.OK)
119                         req.setHeader('Content-type', 'application/xhtml+xml')
120                         req.setHeader('charset', 'UTF-8')
121                         reactor.callFromThread(lambda: req.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<e2autotimersimulate api_version=\"" + str(API_VERSION) + "\">\n"))
122
123                 def finishRequest():
124                         req.write('</e2autotimersimulate>')
125                         req.finish()
126
127                 try: autotimer.parseEPG(simulateOnly=True, callback=self.intermediateWrite)
128                 except Exception as e:
129                         def finishRequest():
130                                 req.write('<exception>'+str(e)+'</exception><|PURPOSEFULLYBROKENXML<')
131                                 req.finish()
132
133                 if self._stillAlive:
134                         reactor.callFromThread(finishRequest)
135
136         def intermediateWrite(self, timers, conflicting, similar, skipped):
137                 returnlist = []
138                 extend = returnlist.extend
139
140                 for (name, begin, end, serviceref, autotimername, message) in timers:
141                         ref = ServiceReference(str(serviceref))
142                         extend((
143                                 '<e2simulatedtimer>\n'
144                                 '   <e2servicereference>', stringToXML(serviceref), '</e2servicereference>\n',
145                                 '   <e2servicename>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n',
146                                 '   <e2name>', stringToXML(name), '</e2name>\n',
147                                 '   <e2timebegin>', str(begin), '</e2timebegin>\n',
148                                 '   <e2timeend>', str(end), '</e2timeend>\n',
149                                 '   <e2autotimername>', stringToXML(autotimername), '</e2autotimername>\n'
150                                 '</e2simulatedtimer>\n'
151                         ))
152
153                 if self._stillAlive:
154                         reactor.callFromThread(lambda: self._req.write(''.join(returnlist)))
155
156 class AutoTimerTestBackgroundThread(AutoTimerBackgroundThread):
157         def run(self):
158                 req = self._req
159                 if self._stillAlive:
160                         req.setResponseCode(http.OK)
161                         req.setHeader('Content-type', 'application/xhtml+xml')
162                         req.setHeader('charset', 'UTF-8')
163                         reactor.callFromThread(lambda: req.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<e2autotimersimulate api_version=\"" + str(API_VERSION) + "\">\n"))
164
165                 def finishRequest():
166                         req.write('</e2autotimersimulate>')
167                         req.finish()
168
169                 id = req.args.get("id")
170                 if id:
171                         self.id = int(id[0])
172                 else:
173                         self.id = None
174                 
175                 try: autotimer.parseEPG(simulateOnly=True, uniqueId=self.id, callback=self.intermediateWrite)
176                 except Exception as e:
177                         def finishRequest():
178                                 req.write('<exception>'+str(e)+'</exception><|PURPOSEFULLYBROKENXML<')
179                                 req.finish()
180
181                 if self._stillAlive:
182                         reactor.callFromThread(finishRequest)
183
184         def intermediateWrite(self, timers, conflicting, similar, skipped):
185                 returnlist = []
186                 extend = returnlist.extend
187
188                 for (name, begin, end, serviceref, autotimername, message) in timers:
189                         ref = ServiceReference(str(serviceref))
190                         extend((
191                                 '<e2simulatedtimer>\n'
192                                 '   <e2servicereference>', stringToXML(serviceref), '</e2servicereference>\n',
193                                 '   <e2servicename>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n',
194                                 '   <e2name>', stringToXML(name), '</e2name>\n',
195                                 '   <e2timebegin>', str(begin), '</e2timebegin>\n',
196                                 '   <e2timeend>', str(end), '</e2timeend>\n',
197                                 '   <e2autotimername>', stringToXML(autotimername), '</e2autotimername>\n',
198                                 '   <e2state>OK</e2state>\n'
199                                 '   <e2message>', stringToXML(message), '</e2message>\n'
200                                 '</e2simulatedtimer>\n'
201                         ))
202
203                 if skipped:
204                         for (name, begin, end, serviceref, autotimername, message) in skipped:
205                                 ref = ServiceReference(str(serviceref))
206                                 extend((
207                                         '<e2simulatedtimer>\n'
208                                         '   <e2servicereference>', stringToXML(serviceref), '</e2servicereference>\n',
209                                         '   <e2servicename>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n',
210                                         '   <e2name>', stringToXML(name), '</e2name>\n',
211                                         '   <e2timebegin>', str(begin), '</e2timebegin>\n',
212                                         '   <e2timeend>', str(end), '</e2timeend>\n',
213                                         '   <e2autotimername>', stringToXML(autotimername), '</e2autotimername>\n',
214                                         '   <e2state>Skip</e2state>\n'
215                                         '   <e2message>', stringToXML(message), '</e2message>\n'
216                                         '</e2simulatedtimer>\n'
217                                 ))
218                 
219                 if self._stillAlive:
220                         reactor.callFromThread(lambda: self._req.write(''.join(returnlist)))
221
222 class AutoTimerSimulateResource(AutoTimerBaseResource):
223         def render(self, req):
224                 AutoTimerSimulateBackgroundThread(req, None)
225                 return server.NOT_DONE_YET
226
227 class AutoTimerTestResource(AutoTimerBaseResource):
228         def render(self, req):
229                 AutoTimerTestBackgroundThread(req, None)
230                 return server.NOT_DONE_YET
231
232 class AutoTimerListAutoTimerResource(AutoTimerBaseResource):
233         def render(self, req):
234                 # We re-read the config so we won't display empty or wrong information
235                 try:
236                         autotimer.readXml()
237                 except Exception as e:
238                         return self.returnResult(req, False, _("Couldn't load config file!") + '\n' + str(e))
239                 webif = True
240                 p = req.args.get('webif')
241                 if p:
242                         webif = not(p[0] == "false")
243                 # show xml
244                 req.setResponseCode(http.OK)
245                 req.setHeader('Content-type', 'application/xhtml+xml')
246                 req.setHeader('charset', 'UTF-8')
247                 return ''.join(autotimer.getXml(webif))
248
249 class AutoTimerRemoveAutoTimerResource(AutoTimerBaseResource):
250         def render(self, req):
251                 id = req.args.get("id")
252                 if id:
253                         autotimer.remove(int(id[0]))
254                         
255                         # Save modified xml
256                         if config.plugins.autotimer.always_write_config.value:
257                                 autotimer.writeXml()
258                         
259                         return self.returnResult(req, True, _("AutoTimer was removed"))
260                 else:
261                         return self.returnResult(req, False, _("missing parameter \"id\""))
262                         
263 class AutoTimerAddXMLAutoTimerResource(AutoTimerBaseResource):
264         def render_POST(self, req):
265                 req.setResponseCode(http.OK)
266                 req.setHeader('Content-type', 'application/xhtml+xml;' )
267                 req.setHeader('charset', 'UTF-8')
268                 autotimer.readXml() # read current timers to ensure autotimer.timers is populated with current autotimers
269                 autotimer.readXmlTimer(req.args['xml'][0])
270                 if config.plugins.autotimer.always_write_config.value:
271                         autotimer.writeXml()
272                 return self.returnResult(req, True, _("AutoTimer was added successfully"))
273                 
274 class AutoTimerUploadXMLConfigurationAutoTimerResource(AutoTimerBaseResource):
275         def render_POST(self, req):
276                 req.setResponseCode(http.OK)
277                 req.setHeader('Content-type', 'application/xhtml+xml;' )
278                 req.setHeader('charset', 'UTF-8')       
279                 autotimer.readXml(xml_string=req.args['xml'][0])
280                 if config.plugins.autotimer.always_write_config.value:
281                         autotimer.writeXml()
282                 return self.returnResult(req, True, _("AutoTimers were changed successfully"))  
283
284 class AutoTimerAddOrEditAutoTimerResource(AutoTimerBaseResource):
285         # TODO: recheck if we can modify regular config parser to work on this
286         # TODO: allow to edit defaults?
287         def render(self, req):
288                 def get(name, default=None):
289                         ret = req.args.get(name)
290                         return ret[0] if ret else default
291
292                 id = get("id")
293                 timer = None
294                 newTimer = True
295                 if id is None:
296                         id = autotimer.getUniqueId()
297                         timer = autotimer.defaultTimer.clone()
298                         timer.id = id
299                 else:
300                         id = int(id)
301                         for possibleMatch in autotimer.getTimerList():
302                                 if possibleMatch.id == id:
303                                         timer = possibleMatch
304                                         newTimer = False
305                                         break
306                         if timer is None:
307                                 return self.returnResult(req, False, _("unable to find timer with id %i" % (id,)))
308
309                 if id != -1:
310                         # Match
311                         timer.match = unquote(get("match", timer.match))
312                         if not timer.match:
313                                 return self.returnResult(req, False, _("autotimers need a match attribute"))
314
315                         # Name
316                         timer.name = unquote(get("name", timer.name)).strip()
317                         if not timer.name: timer.name = timer.match
318
319                         # Enabled
320                         enabled = get("enabled")
321                         if enabled is not None:
322                                 try: enabled = int(enabled)
323                                 except ValueError: enabled = enabled == "yes"
324                                 timer.enabled = enabled
325
326                         # Timeframe
327                         before = get("before")
328                         after = get("after")
329                         if before and after:
330                                 timer.timeframe = (int(after), int(before))
331                         elif before == '' or after == '':
332                                 timer.timeframe = None
333
334                 # ...
335                 timer.searchType = get("searchType", timer.searchType)
336                 timer.searchCase = get("searchCase", timer.searchCase)
337
338                 # Alternatives
339                 timer.overrideAlternatives = int(get("overrideAlternatives", timer.overrideAlternatives))
340
341                 # Justplay
342                 justplay = get("justplay")
343                 if justplay is not None:
344                         try: justplay = int(justplay)
345                         except ValueError: justplay = justplay == "zap"
346                         timer.justplay = justplay
347                 setEndtime = get("setEndtime")
348                 if setEndtime is not None:
349                         timer.setEndtime = int(setEndtime)
350
351                 # Timespan
352                 start = get("timespanFrom")
353                 end = get("timespanTo")
354                 if start and end:
355                         start = [int(x) for x in start.split(':')]
356                         end = [int(x) for x in end.split(':')]
357                         timer.timespan = (start, end)
358                 elif start == '' and end == '':
359                         timer.timespan = None
360
361                 # Services
362                 servicelist = get("services")
363                 if servicelist is not None:
364                         servicelist = unquote(servicelist).split(',')
365                         appendlist = []
366                         for value in servicelist:
367                                 myref = eServiceReference(str(value))
368                                 if not (myref.flags & eServiceReference.isGroup):
369                                         # strip all after last :
370                                         pos = value.rfind(':')
371                                         if pos != -1:
372                                                 if value[pos-1] == ':':
373                                                         pos -= 1
374                                                 value = value[:pos+1]
375
376                                 if myref.valid():
377                                         appendlist.append(value)
378                         timer.services = appendlist
379
380                 # Bouquets
381                 servicelist = get("bouquets")
382                 if servicelist is not None:
383                         servicelist = unquote(servicelist).split(',')
384                         while '' in servicelist: servicelist.remove('')
385                         timer.bouquets = servicelist
386
387                 # Offset
388                 offset = get("offset")
389                 if offset:
390                         offset = offset.split(',')
391                         if len(offset) == 1:
392                                 before = after = int(offset[0] or 0) * 60
393                         else:
394                                 before = int(offset[0] or 0) * 60
395                                 after = int(offset[1] or 0) * 60
396                         timer.offset = (before, after)
397                 elif offset == '':
398                         timer.offset = None
399
400                 # AfterEvent
401                 afterevent = get("afterevent")
402                 if afterevent:
403                         if afterevent == "default":
404                                 timer.afterevent = []
405                         else:
406                                 try: afterevent = int(afterevent)
407                                 except ValueError:
408                                         afterevent = {
409                                                 "nothing": AFTEREVENT.NONE,
410                                                 "deepstandby": AFTEREVENT.DEEPSTANDBY,
411                                                 "standby": AFTEREVENT.STANDBY,
412                                                 "auto": AFTEREVENT.AUTO
413                                         }.get(afterevent, AFTEREVENT.AUTO)
414                                 start = get("aftereventFrom")
415                                 end = get("aftereventTo")
416                                 if start and end:
417                                         start = [int(x) for x in start.split(':')]
418                                         end = [int(x) for x in end.split(':')]
419                                         timer.afterevent = [(afterevent, (start, end))]
420                                 else:
421                                         timer.afterevent = [(afterevent, None)]
422
423                 # Maxduration
424                 maxduration = get("maxduration")
425                 if maxduration:
426                         timer.maxduration = int(maxduration)*60
427                 elif maxduration == '':
428                         timer.maxduration = None
429
430                 # Includes
431                 title = req.args.get("title")
432                 shortdescription = req.args.get("shortdescription")
433                 description = req.args.get("description")
434                 dayofweek = req.args.get("dayofweek")
435                 if title or shortdescription or description or dayofweek:
436                         includes = timer.include
437                         title = [unquote(x) for x in title] if title else includes[0]
438                         shortdescription = [unquote(x) for x in shortdescription] if shortdescription else includes[1]
439                         description = [unquote(x) for x in description] if description else includes[2]
440                         dayofweek = [unquote(x) for x in dayofweek] if dayofweek else includes[3]
441                         while '' in title: title.remove('')
442                         while '' in shortdescription: shortdescription.remove('')
443                         while '' in description: description.remove('')
444                         while '' in dayofweek: dayofweek.remove('')
445                         timer.include = (title, shortdescription, description, dayofweek)
446
447                 # Excludes
448                 title = req.args.get("!title")
449                 shortdescription = req.args.get("!shortdescription")
450                 description = req.args.get("!description")
451                 dayofweek = req.args.get("!dayofweek")
452                 if title or shortdescription or description or dayofweek:
453                         excludes = timer.exclude
454                         title = [unquote(x) for x in title] if title else excludes[0]
455                         shortdescription = [unquote(x) for x in shortdescription] if shortdescription else excludes[1]
456                         description = [unquote(x) for x in description] if description else excludes[2]
457                         dayofweek = [unquote(x) for x in dayofweek] if dayofweek else excludes[3]
458                         while '' in title: title.remove('')
459                         while '' in shortdescription: shortdescription.remove('')
460                         while '' in description: description.remove('')
461                         while '' in dayofweek: dayofweek.remove('')
462                         timer.exclude = (title, shortdescription, description, dayofweek)
463
464                 tags = req.args.get("tag")
465                 if tags:
466                         while '' in tags: tags.remove('')
467                         timer.tags = [unquote(x) for x in tags]
468
469                 timer.matchCount = int(get("counter", timer.matchCount))
470                 timer.matchFormatString = get("counterFormat", timer.matchFormatString)
471                 if id != -1:
472                         matchLeft = get("left")
473                         timer.matchLeft = int(matchLeft) if matchLeft else (timer.matchCount if newTimer else timer.matchLeft)
474                         timer.matchLimit = get("lastActivation", timer.matchLimit)
475                         timer.lastBegin = int(get("lastBegin", timer.lastBegin))
476
477                 timer.avoidDuplicateDescription = int(get("avoidDuplicateDescription", timer.avoidDuplicateDescription))
478                 timer.searchForDuplicateDescription = int(get("searchForDuplicateDescription", timer.searchForDuplicateDescription))
479                 timer.destination = get("location", timer.destination) or None
480
481                 # vps
482                 enabled = get("vps_enabled")
483                 if enabled is not None:
484                         try: enabled = int(enabled)
485                         except ValueError: enabled = enabled == "yes"
486                         timer.vps_enabled = enabled
487                 vps_overwrite = get("vps_overwrite")
488                 if vps_overwrite is not None:
489                         try: vps_overwrite = int(vps_overwrite)
490                         except ValueError: vps_overwrite = vps_overwrite == "yes"
491                         timer.vps_overwrite = vps_overwrite
492                 if not timer.vps_enabled and timer.vps_overwrite:
493                         timer.vps_overwrite = False
494
495                 # SeriesPlugin
496                 series_labeling = get("series_labeling")
497                 if series_labeling is not None:
498                         try: series_labeling = int(series_labeling)
499                         except ValueError: series_labeling = series_labeling == "yes"
500                         timer.series_labeling = series_labeling
501                 series_save_filter = get("series_save_filter")
502                 if series_save_filter is not None:
503                         try: series_save_filter = int(series_save_filter)
504                         except ValueError: series_save_filter = series_save_filter == "yes"
505                         timer.series_save_filter = series_save_filter
506                 if not timer.series_labeling and timer.series_save_filter:
507                         timer.series_save_filter = False
508
509                 if newTimer:
510                         autotimer.add(timer)
511                         message = _("AutoTimer was added successfully")
512                 else:
513                         message = _("AutoTimer was changed successfully")
514                 
515                 # Save modified xml
516                 if config.plugins.autotimer.always_write_config.value:
517                         autotimer.writeXml()
518
519                 return self.returnResult(req, True, message)
520
521 class AutoTimerChangeSettingsResource(AutoTimerBaseResource):
522         def render(self, req):
523                 for key, value in iteritems(req.args):
524                         value = value[0]
525                         if key == "autopoll":
526                                 config.plugins.autotimer.autopoll.value = True if value == "true" else False
527                         elif key == "interval":
528                                 config.plugins.autotimer.interval.value = int(value)
529                         elif key == "refresh":
530                                 config.plugins.autotimer.refresh.value = value
531                         elif key == "try_guessing":
532                                 config.plugins.autotimer.try_guessing.value = True if value == "true" else False
533                         elif key == "editor":
534                                 config.plugins.autotimer.editor.value = value
535                         elif key == "disabled_on_conflict":
536                                 config.plugins.autotimer.disabled_on_conflict.value = True if value == "true" else False
537                         elif key == "addsimilar_on_conflict":
538                                 config.plugins.autotimer.addsimilar_on_conflict.value = True if value == "true" else False
539                         elif key == "show_in_extensionsmenu":
540                                 config.plugins.autotimer.show_in_extensionsmenu.value = True if value == "true" else False
541                         elif key == "fastscan":
542                                 config.plugins.autotimer.fastscan.value = True if value == "true" else False
543                         elif key == "notifconflict":
544                                 config.plugins.autotimer.notifconflict.value = True if value == "true" else False
545                         elif key == "notifsimilar":
546                                 config.plugins.autotimer.notifsimilar.value = True if value == "true" else False
547                         elif key == "maxdaysinfuture":
548                                 config.plugins.autotimer.maxdaysinfuture.value = int(value)
549                         elif key == "add_autotimer_to_tags":
550                                 config.plugins.autotimer.add_autotimer_to_tags.value = True if value == "true" else False
551                         elif key == "add_name_to_tags":
552                                 config.plugins.autotimer.add_name_to_tags.value = True if value == "true" else False
553                         elif key == "timeout":
554                                 config.plugins.autotimer.timeout.value = int(value)
555                         elif key == "delay":
556                                 config.plugins.autotimer.delay.value = int(value)
557                         elif key == "editdelay":
558                                 config.plugins.autotimer.editdelay.value = int(value)
559                         elif key == "skip_during_records":
560                                 config.plugins.autotimer.skip_during_records.value = True if value == "true" else False
561                         elif key == "skip_during_epgrefresh":
562                                 config.plugins.autotimer.skip_during_epgrefresh.value = True if value == "true" else False
563
564                 if config.plugins.autotimer.autopoll.value:
565                         if plugin.autopoller is None:
566                                 from AutoPoller import AutoPoller
567                                 plugin.autopoller = AutoPoller()
568                         plugin.autopoller.start(initial = False)
569                 else:
570                         if plugin.autopoller is not None:
571                                 plugin.autopoller.stop()
572                                 plugin.autopoller = None
573
574                 return self.returnResult(req, True, _("config changed."))
575
576 class AutoTimerSettingsResource(resource.Resource):
577         def render(self, req):
578                 req.setResponseCode(http.OK)
579                 req.setHeader('Content-type', 'application/xhtml+xml')
580                 req.setHeader('charset', 'UTF-8')
581
582                 try:
583                         from Plugins.SystemPlugins.vps import Vps
584                 except ImportError as ie:
585                         hasVps = False
586                 else:
587                         hasVps = True
588
589                 try:
590                         from Plugins.Extensions.SeriesPlugin.plugin import Plugins
591                 except ImportError as ie:
592                         hasSeriesPlugin = False
593                 else:
594                         hasSeriesPlugin = True
595
596                 return """<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
597 <e2settings>
598         <e2setting>
599                 <e2settingname>config.plugins.autotimer.autopoll</e2settingname>
600                 <e2settingvalue>%s</e2settingvalue>
601         </e2setting>
602         <e2setting>
603                 <e2settingname>config.plugins.autotimer.interval</e2settingname>
604                 <e2settingvalue>%d</e2settingvalue>
605         </e2setting>
606         <e2setting>
607                 <e2settingname>config.plugins.autotimer.refresh</e2settingname>
608                 <e2settingvalue>%s</e2settingvalue>
609         </e2setting>
610         <e2setting>
611                 <e2settingname>config.plugins.autotimer.try_guessing</e2settingname>
612                 <e2settingvalue>%s</e2settingvalue>
613         </e2setting>
614         <e2setting>
615                 <e2settingname>config.plugins.autotimer.editor</e2settingname>
616                 <e2settingvalue>%s</e2settingvalue>
617         </e2setting>
618         <e2setting>
619                 <e2settingname>config.plugins.autotimer.disabled_on_conflict</e2settingname>
620                 <e2settingvalue>%s</e2settingvalue>
621         </e2setting>
622         <e2setting>
623                 <e2settingname>config.plugins.autotimer.addsimilar_on_conflict</e2settingname>
624                 <e2settingvalue>%s</e2settingvalue>
625         </e2setting>
626         <e2setting>
627                 <e2settingname>config.plugins.autotimer.show_in_extensionsmenu</e2settingname>
628                 <e2settingvalue>%s</e2settingvalue>
629         </e2setting>
630         <e2setting>
631                 <e2settingname>config.plugins.autotimer.fastscan</e2settingname>
632                 <e2settingvalue>%s</e2settingvalue>
633         </e2setting>
634         <e2setting>
635                 <e2settingname>config.plugins.autotimer.notifconflict</e2settingname>
636                 <e2settingvalue>%s</e2settingvalue>
637         </e2setting>
638         <e2setting>
639                 <e2settingname>config.plugins.autotimer.notifsimilar</e2settingname>
640                 <e2settingvalue>%s</e2settingvalue>
641         </e2setting>
642         <e2setting>
643                 <e2settingname>config.plugins.autotimer.maxdaysinfuture</e2settingname>
644                 <e2settingvalue>%s</e2settingvalue>
645         </e2setting>
646         <e2setting>
647                 <e2settingname>config.plugins.autotimer.add_autotimer_to_tags</e2settingname>
648                 <e2settingvalue>%s</e2settingvalue>
649         </e2setting>
650         <e2setting>
651                 <e2settingname>config.plugins.autotimer.add_name_to_tags</e2settingname>
652                 <e2settingvalue>%s</e2settingvalue>
653         </e2setting>
654         <e2setting>
655                 <e2settingname>config.plugins.autotimer.timeout</e2settingname>
656                 <e2settingvalue>%s</e2settingvalue>
657         </e2setting>
658         <e2setting>
659                 <e2settingname>config.plugins.autotimer.delay</e2settingname>
660                 <e2settingvalue>%s</e2settingvalue>
661         </e2setting>
662         <e2setting>
663                 <e2settingname>config.plugins.autotimer.editdelay</e2settingname>
664                 <e2settingvalue>%s</e2settingvalue>
665         </e2setting>
666         <e2setting>
667                 <e2settingname>config.plugins.autotimer.skip_during_records</e2settingname>
668                 <e2settingvalue>%s</e2settingvalue>
669         </e2setting>
670         <e2setting>
671                 <e2settingname>config.plugins.autotimer.skip_during_epgrefresh</e2settingname>
672                 <e2settingvalue>%s</e2settingvalue>
673         </e2setting>
674         <e2setting>
675                 <e2settingname>hasVps</e2settingname>
676                 <e2settingvalue>%s</e2settingvalue>
677         </e2setting>
678         <e2setting>
679                 <e2settingname>hasSeriesPlugin</e2settingname>
680                 <e2settingvalue>%s</e2settingvalue>
681         </e2setting>
682         <e2setting>
683                 <e2settingname>version</e2settingname>
684                 <e2settingvalue>%s</e2settingvalue>
685         </e2setting>
686         <e2setting>
687                 <e2settingname>api_version</e2settingname>
688                 <e2settingvalue>%s</e2settingvalue>
689         </e2setting>
690         <e2setting>
691                 <e2settingname>autotimer_version</e2settingname>
692                 <e2settingvalue>%s</e2settingvalue>
693         </e2setting>
694 </e2settings>""" % (
695                                 config.plugins.autotimer.autopoll.value,
696                                 config.plugins.autotimer.interval.value,
697                                 config.plugins.autotimer.refresh.value,
698                                 config.plugins.autotimer.try_guessing.value,
699                                 config.plugins.autotimer.editor.value,
700                                 config.plugins.autotimer.addsimilar_on_conflict.value,
701                                 config.plugins.autotimer.disabled_on_conflict.value,
702                                 config.plugins.autotimer.show_in_extensionsmenu.value,
703                                 config.plugins.autotimer.fastscan.value,
704                                 config.plugins.autotimer.notifconflict.value,
705                                 config.plugins.autotimer.notifsimilar.value,
706                                 config.plugins.autotimer.maxdaysinfuture.value,
707                                 config.plugins.autotimer.add_autotimer_to_tags.value,
708                                 config.plugins.autotimer.add_name_to_tags.value,
709                                 config.plugins.autotimer.timeout.value,
710                                 config.plugins.autotimer.delay.value,
711                                 config.plugins.autotimer.editdelay.value,
712                                 config.plugins.autotimer.skip_during_records.value,
713                                 config.plugins.autotimer.skip_during_epgrefresh.value,
714                                 hasVps,
715                                 hasSeriesPlugin,
716                                 CURRENT_CONFIG_VERSION,
717                                 API_VERSION,
718                                 AUTOTIMER_VERSION
719                         )