SeriesPlugin 1.0: First public version
[enigma2-plugins.git] / seriesplugin / src / IdentifierBase.py
1 # by betonme @2012
2
3 from collections import defaultdict
4
5 from thread import start_new_thread
6
7 #TODO Implement Twisted handler
8 #Twisted 12.x
9 #from twisted.web.client import getPage as twGetPage
10 #Twisted 8.x
11 #from twisted.web.client import _parse, HTTPClientFactory
12 #from twisted.internet import reactor
13 #Twisted All
14 #from twisted.python.failure import Failure
15
16 from time import sleep
17 import socket
18
19 #import urllib2
20 from urllib import urlencode
21 from urllib2 import urlopen, URLError, Request, build_opener, HTTPCookieProcessor
22
23 from Components.config import config
24 from Tools.BoundFunction import boundFunction
25
26 # Internal
27 from ModuleBase import ModuleBase
28 from Cacher import Cacher, INTER_QUERY_TIME
29 from Logger import splog
30 from Analytics import Analytics
31
32 import recipeMemUse as MemoryUsage
33
34
35 class MyException(Exception):
36     pass
37
38 class IdentifierBase(ModuleBase, Cacher, Analytics):
39         def __init__(self):
40                 ModuleBase.__init__(self)
41                 Cacher.__init__(self)
42                 Analytics.__init__(self)
43                 
44                 socket.setdefaulttimeout(5)
45                 
46                 self.name = ""
47                 self.begin = None
48                 self.end = None
49                 self.channel = ""
50                 self.ids = []
51                 
52                 self.returnvalue = None
53                 
54                 self.search_depth = 0;
55
56         ################################################
57         # Helper function
58         def getAlternativeSeries(self, name):
59                 
60                 self.search_depth += 1
61                 if( self.search_depth < config.plugins.seriesplugin.search_depths.value ):
62                         return " ".join(name.split(" ")[:-1])
63                 else:
64                         return ""
65
66
67         ################################################
68         # URL functions
69         def getPage(self, url, headers={}, expires=INTER_QUERY_TIME, counter=0):
70                 response = None
71                 
72                 splog("SSBase getPage", url)
73                 
74                 #TEST other solutions
75                 #http://de.softuses.com/28672
76                 #http://code.google.com/p/psutil/
77                 #VmSize = MemoryUsage.memory()
78                 #splog("SP VmSize: "+str(VmSize/1024/1024)+" Mb" )
79                 #VmRSS  = MemoryUsage.resident()
80                 #splog("SP VmRSS:  "+str(VmRSS/1024/1024)+" Mb" )
81                 #VmStk  = MemoryUsage.stacksize()
82                 #splog("SP VmStk:  "+str(VmStk/1024/1024)+" Mb" )
83                 
84                 cached = self.getCached(url, expires)
85                 
86                 self.sendAnalytics(url, True if cached else False)
87                 
88                 if cached:
89                         splog("SSBase cached")
90                         response = cached
91                 
92                 else:
93                         splog("SSBase not cached")
94                         
95                         try:
96                                 req = Request(url, headers=headers)
97                                 response = urlopen(req, timeout=15).read()
98                                 
99                                 #splog("SSBase response to cache: ", response) 
100                                 if response:
101                                         self.doCacheInternal(url, response)
102                         
103                         except URLError as e:
104                                  # For Python 2.6
105                                 if counter > 2:
106                                         splog("SSBase URLError counter > 2")
107                                         raise MyException("There was an URLError: %r" % e)
108                                 elif hasattr(e, "code"):
109                                         splog("SSBase URLError code")
110                                         print e.code, e.msg, counter
111                                         sleep(2)
112                                         return self.getPage(url, headers, expires, counter+1)
113                                 else:
114                                         splog("SSBase URLError else")
115                                         raise MyException("There was an URLError: %r" % e)
116                         
117                         except socket.timeout as e:
118                                  # For Python 2.7
119                                 if counter > 2:
120                                         splog("SSBase URLError counter > 2")
121                                         raise MyException("There was an SocketTimeout: %r" % e)
122                                 elif hasattr(e, "code"):
123                                         splog("SSBase URLError code")
124                                         print e.code, e.msg, counter
125                                         sleep(2)
126                                         return self.getPage(url, headers, expires, counter+1)
127                                 else:
128                                         splog("SSBase URLError else")
129                                         raise MyException("There was an SocketTimeout: %r" % e)
130                         
131                 splog("SSBase success")
132                 return response
133         
134         ################################################
135         # Service prototypes
136         @classmethod
137         def knowsElapsed(cls):
138                 # True: Service knows elapsed air dates
139                 # False: Service doesn't know elapsed air dates
140                 return False
141
142         @classmethod
143         def knowsToday(cls):
144                 # True: Service knows today air dates
145                 # False: Service doesn't know today air dates
146                 return False
147
148         @classmethod
149         def knowsFuture(cls):
150                 # True: Service knows future air dates
151                 # False: Service doesn't know future air dates
152                 return False
153
154         ################################################
155         # To be implemented by subclass
156         def getEpisode(self, name, begin, end, service, channels):
157                 # On Success: Return a single season, episode, title tuple
158                 # On Failure: Return a empty list or String or None
159                 return None