SeriesPlugin 1.2.8: Fixed multiple timer / movie handling
[enigma2-plugins.git] / seriesplugin / src / Identifiers / Wunschliste.py
1 # by betonme @2012
2
3 # Imports
4 from Components.config import config
5
6 from Tools.BoundFunction import boundFunction
7
8 from urllib import urlencode
9
10 from HTMLParser import HTMLParser
11
12 from datetime import datetime
13
14 import re
15 from sys import maxint
16
17 # Internal
18 from Plugins.Extensions.SeriesPlugin.IdentifierBase import IdentifierBase
19 from Plugins.Extensions.SeriesPlugin.Channels import compareChannels
20 from Plugins.Extensions.SeriesPlugin.Logger import splog
21
22 from iso8601 import parse_date
23
24 # Constants
25 SERIESLISTURL     = "http://www.wunschliste.de/ajax/search_dropdown.pl?"
26 EPISODEIDURLPRINT = "http://www.wunschliste.de/epg_print.pl?"
27
28 # (Season.Episode) - EpisodeTitle
29 # (21.84) Folge 4985
30 # (105) Folge 105
31 # (4.11/4.11) Mama ist die Beste/Rund um die Uhr
32 # Galileo: Die schaerfste Chili der Welt
33 # Galileo: Jumbo auf Achse: Muelltonnenkoch
34 # Gute Zeiten, schlechte Zeiten: Folgen 4985 - 4988 (21.84) - Sa 05.05., 11.00:00 Uhr / RTL
35 #CompiledRegexpPrintTitle = re.compile( '(\(.*\) )?(.+)')
36
37 CompiledRegexpEpisode = re.compile( '((\d+)[\.x])?(\d+)')
38
39 class WLPrintParser(HTMLParser):
40         def __init__(self):
41                 HTMLParser.__init__(self)
42                 self.tr= False
43                 self.td= False
44                 self.data = []
45                 self.list = []
46
47         def handle_starttag(self, tag, attributes):
48                 if tag == 'td':
49                         self.td= True
50                 elif tag == 'tr':
51                         self.tr= True
52
53         def handle_endtag(self, tag):
54                 if tag == 'td':
55                         self.td= False
56                 elif tag == 'tr':
57                         self.tr= False
58                         self.list.append(self.data)
59                         self.data= []
60
61         def handle_data(self, data):
62                 if self.tr and self.td:
63                         self.data.append(data)
64
65
66 class Wunschliste(IdentifierBase):
67         def __init__(self):
68                 IdentifierBase.__init__(self)
69
70         @classmethod
71         def knowsToday(cls):
72                 return True
73
74         @classmethod
75         def knowsFuture(cls):
76                 return True
77
78         def getEpisode(self, name, begin, end=None, service=None, channels=[]):
79                 # On Success: Return a single season, episode, title tuple
80                 # On Failure: Return a empty list or String or None
81                 
82                 self.begin = begin
83                 self.end = end
84                 self.service = service
85                 self.channels = channels
86                 
87                 self.knownids = []
88                 self.returnvalue = None
89                 
90                 # Check preconditions
91                 if not name:
92                         splog(_("Skip Wunschliste: No show name specified"))
93                         return _("Skip Wunschliste: No show name specified")
94                 if not begin:
95                         splog(_("Skip Wunschliste: No begin timestamp specified"))
96                         return _("Skip Wunschliste: No begin timestamp specified")
97                 
98                 splog("WunschlistePrint getEpisode")
99                 
100                 while name:     
101                         ids = self.getSeries(name)
102                         
103                         while ids:
104                                 idserie = ids.pop()
105                                 
106                                 if idserie and len(idserie) == 2:
107                                         id, self.series = idserie
108                                         
109                                         result = self.getNextPage( id )
110                                         if result:
111                                                 return result
112                                         
113                         else:
114                                 name = self.getAlternativeSeries(name)
115                 
116                 else:
117                         return ( self.returnvalue or _("No matching series found") )
118
119         def getSeries(self, name):
120                 url = SERIESLISTURL + urlencode({ 'q' : re.sub("[^a-zA-Z0-9-*]", " ", name) })
121                 data = self.getPage( url )
122                 
123                 if data and isinstance(data, basestring):
124                         data = self.parseSeries(data)
125                         self.doCache(url, data)
126                 
127                 if data and isinstance(data, list):
128                         splog("WunschlistePrint ids", data)
129                         return self.filterKnownIds(data)
130
131         def parseSeries(self, data):
132                 serieslist = []
133                 for line in data.splitlines():
134                         values = line.split("|")
135                         if len(values) == 4:
136                                 idname, countryyear, id, temp = values
137                                 splog(id, idname)
138                                 serieslist.append( (id, idname) )
139                         else:
140                                 splog("WunschlistePrint: ParseError: " + str(line))
141                 serieslist.reverse()
142                 return serieslist
143
144         def parseNextPage(self, data):
145                 # Handle malformed HTML issues
146                 #data = data.replace('"','&')
147                 data = data.replace('&','&')
148                 parser = WLPrintParser()
149                 parser.feed(data)
150                 #splog(parser.list)
151                 return parser.list
152
153         def getNextPage(self, id):
154                 splog("WunschlistePrint getNextPage")
155                 
156                 url = EPISODEIDURLPRINT + urlencode({ 's' : id })
157                 data = self.getPage( url )
158                 
159                 if data and isinstance(data, basestring):
160                         data = self.parseNextPage(data)
161                         self.doCache(url, data)
162                 
163                 if data and isinstance(data, list):
164                         trs = data
165                         
166                         yepisode = None
167                         ydelta = maxint
168                         year = str(datetime.today().year)
169                         
170                         for tds in trs:
171                                 if tds and len(tds) >= 5:
172                                         #print tds
173                                         xchannel, xday, xdate, xbegin, xend = tds[:5]
174                                         xtitle = "".join(tds[4:])
175                                         xbegin   = datetime.strptime( xdate+year+xbegin, "%d.%m.%Y%H.%M Uhr" )
176                                         #xend     = datetime.strptime( xdate+xend, "%d.%m.%Y%H.%M Uhr" )
177                                         #splog(xchannel, xdate, xbegin, xend, xtitle)
178                                         #splog(datebegin, xbegin, abs((datebegin - xbegin)))
179                                         
180                                         #Py2.6
181                                         delta = abs(self.begin - xbegin)
182                                         delta = delta.seconds + delta.days * 24 * 3600
183                                         #Py2.7 delta = abs(self.begin - xbegin).total_seconds()
184                                         splog(self.begin, xbegin, delta, int(config.plugins.seriesplugin.max_time_drift.value)*60)
185                                         
186                                         if delta <= int(config.plugins.seriesplugin.max_time_drift.value) * 60:
187                                                 
188                                                 if compareChannels(self.channels, xchannel, self.service):
189                                                 
190                                                         if delta < ydelta:
191                                                                 
192                                                                 print len(tds), tds
193                                                                 if len(tds) >= 7:
194                                                                         xepisode, xtitle = tds[5:7]
195                                                                 
196                                                                         if xepisode:
197                                                                                 result = CompiledRegexpEpisode.search(xepisode)
198                                                                                 
199                                                                                 if result and len(result.groups()) >= 3:
200                                                                                         xseason = result and result.group(2) or "1"
201                                                                                         xepisode = result and result.group(3) or "0"
202                                                                                 else:
203                                                                                         xseason = "1"
204                                                                                         xepisode = "0"
205                                                                         else:
206                                                                                 xseason = "1"
207                                                                                 xepisode = "0"
208                                                                 
209                                                                 elif len(tds) == 6:
210                                                                         xtitle = tds[5]
211                                                                         xseason = "0"
212                                                                         xepisode = "0"
213                                                                 
214                                                                 yepisode = (xseason, xepisode, xtitle.decode('ISO-8859-1').encode('utf8'), self.series.decode('ISO-8859-1').encode('utf8'))
215                                                                 ydelta = delta
216                                                         
217                                                         else: #if delta >= ydelta:
218                                                                 break
219                                                 
220                                                 else:
221                                                         self.returnvalue = _("Check the channel name")
222                                                 
223                                         elif yepisode:
224                                                 break
225                         
226                         if yepisode:
227                                 return ( yepisode )