fix possible crash while getting the video url
[enigma2-plugins.git] / mytube / src / MyTubeService.py
1 # -*- coding: iso-8859-1 -*-
2 from __init__ import _
3 import gdata.youtube
4 import gdata.youtube.service
5 from gdata.service import BadAuthentication
6 from Tools.LoadPixmap import LoadPixmap
7 from Components.config import config, Config, ConfigSelection, ConfigText, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigIP, ConfigNumber
8 from Components.ConfigList import ConfigListScreen
9 from Components.config import KEY_DELETE, KEY_BACKSPACE, KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT
10
11 from twisted.web import client
12 from twisted.internet import reactor
13 from urllib2 import Request, URLError, HTTPError
14 from socket import gaierror,error
15 import re, os, sys, socket
16 import urllib
17 from urllib import FancyURLopener, quote
18 import cookielib
19 from httplib import HTTPConnection,CannotSendRequest,BadStatusLine
20 HTTPConnection.debuglevel = 1
21
22 #config.plugins.mytube = ConfigSubsection()
23 #config.plugins.mytube.general = ConfigSubsection()
24 #config.plugins.mytube.general.useHTTPProxy = ConfigYesNo(default = False)
25 #config.plugins.mytube.general.ProxyIP = ConfigIP(default=[0,0,0,0])
26 #config.plugins.mytube.general.ProxyPort = ConfigNumber(default=8080)
27
28 class MyOpener(FancyURLopener):
29         version = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12'
30
31
32 class GoogleSuggestions():
33         def __init__(self, callback, ds = None, json = None, hl = None):
34                 self.callback = callback
35                 self.conn = HTTPConnection("google.com")
36                 self.prepQuerry = "/complete/search?"
37                 if ds is not None:
38                         self.prepQuerry = self.prepQuerry + "ds=" + ds + "&"
39                 if json is not None:
40                         self.prepQuerry = self.prepQuerry + "json=" + json + "&"
41                 if hl is not None:
42                         self.prepQuerry = self.prepQuerry + "hl=" + hl + "&"
43                 self.prepQuerry = self.prepQuerry + "jsonp=self.gotSuggestions&q="
44
45         def gotSuggestions(self, suggestslist):
46                 self.callback(suggestslist)
47
48         def getSuggestions(self, querryString):
49                 if querryString is not "":
50                         querry = self.prepQuerry + quote(querryString)
51                         try:
52                                 self.conn.request("GET", querry)
53                         except (CannotSendRequest, gaierror, error):
54                                 print "[YTB] Can not send request for suggestions"
55                                 self.callback(None)
56                         else:
57                                 try:
58                                         response = self.conn.getresponse()
59                                 except BadStatusLine:
60                                         print "[YTB] Can not get a response from google"
61                                         self.callback(None)
62                                 else:
63                                         if response.status == 200:
64                                                 data = response.read()
65                                                 exec data
66                                         else:
67                                                 self.callback(None)
68                         self.conn.close()
69                 else:
70                         self.callback(None)
71
72
73 class MyTubeFeedEntry():
74         def __init__(self, feed, entry, favoritesFeed = False):
75                 self.feed = feed
76                 self.entry = entry
77                 self.favoritesFeed = favoritesFeed
78                 self.thumbnail = {}
79                 self.myopener = MyOpener()
80                 urllib.urlopen = MyOpener().open
81                 """if config.plugins.mytube.general.useHTTPProxy.value is True:
82                         proxy = {'http': 'http://'+str(config.plugins.mytube.general.ProxyIP.getText())+':'+str(config.plugins.mytube.general.ProxyPort.value)}
83                         self.myopener = MyOpener(proxies=proxy)
84                         urllib.urlopen = MyOpener(proxies=proxy).open
85                 else:
86                         self.myopener = MyOpener()
87                         urllib.urlopen = MyOpener().open"""
88                 
89         def isPlaylistEntry(self):
90                 return False
91
92         def getTubeId(self):
93                 #print "[MyTubeFeedEntry] getTubeId"
94                 ret = None
95                 if self.entry.media.player:
96                         ret = self.entry.media.player.url.split("=").pop()
97                 return ret
98
99         def getTitle(self):
100                 #print "[MyTubeFeedEntry] getTitle",self.entry.media.title.text
101                 return self.entry.media.title.text
102
103         def getDescription(self):
104                 #print "[MyTubeFeedEntry] getDescription"
105                 if self.entry.media is not None and self.entry.media.description is not None:
106                         return self.entry.media.description.text
107                 return "not vailable"
108
109         def getThumbnailUrl(self, index = 0):
110                 #print "[MyTubeFeedEntry] getThumbnailUrl"
111                 if index < len(self.entry.media.thumbnail):
112                         return self.entry.media.thumbnail[index].url
113                 return None
114
115         def getPublishedDate(self):
116                 if self.entry.published is not None:
117                         return self.entry.published.text
118                 return "unknown"
119
120         def getViews(self):
121                 if self.entry.statistics is not None:
122                         return self.entry.statistics.view_count
123                 return "not available"
124         
125         def getDuration(self):
126                 if self.entry.media is not None and self.entry.media.duration is not None:
127                         return self.entry.media.duration.seconds
128                 else:
129                         return 0
130
131         def getRatingAverage(self):
132                 if self.entry.rating is not None:
133                         return self.entry.rating.average
134                 return 0
135
136
137         def getNumRaters(self):
138                 if self.entry.rating is not None:
139                         return self.entry.rating.num_raters
140                 return ""       
141
142         def getAuthor(self):
143                 authors = []
144                 for author in self.entry.author:
145                         authors.append(author.name.text)
146                 author = ", ".join(authors)
147                 return author
148
149         def PrintEntryDetails(self):
150                 EntryDetails = { 'Title': None, 'TubeID': None, 'Published': None, 'Published': None, 'Description': None, 'Category': None, 'Tags': None, 'Duration': None, 'Views': None, 'Rating': None, 'Thumbnails': None}
151                 EntryDetails['Title'] = self.entry.media.title.text
152                 EntryDetails['TubeID'] = self.getTubeId()
153                 EntryDetails['Description'] = self.getDescription()
154                 EntryDetails['Category'] = self.entry.media.category[0].text
155                 EntryDetails['Tags'] = self.entry.media.keywords.text
156                 EntryDetails['Published'] = self.getPublishedDate()
157                 EntryDetails['Views'] = self.getViews()
158                 EntryDetails['Duration'] = self.getDuration()
159                 EntryDetails['Rating'] = self.getNumRaters()
160                 EntryDetails['RatingAverage'] = self.getRatingAverage()
161                 EntryDetails['Author'] = self.getAuthor()
162                 # show thumbnails
163                 list = []
164                 for thumbnail in self.entry.media.thumbnail:
165                         print 'Thumbnail url: %s' % thumbnail.url
166                         list.append(str(thumbnail.url))
167                 EntryDetails['Thumbnails'] = list
168                 #print EntryDetails
169                 return EntryDetails
170
171
172         def getVideoUrl(self):
173                 mrl = None
174                 isHDAvailable = False
175                 req = "http://www.youtube.com/watch?v=" + str(self.getTubeId())
176                 try:
177                         response = urllib.urlopen(req)
178                         """if config.plugins.mytube.general.useHTTPProxy.value is True:
179                                 proxy = {'http': str(config.plugins.mytube.general.ProxyIP.getText())+':'+str(config.plugins.mytube.general.ProxyPort.value)}
180                                 print "USING PRXY---->",proxy
181                                 response = urllib.urlopen(req,proxies=proxy)
182                         else:
183                                 response = urllib.urlopen(req)"""
184                 except HTTPError, e:
185                         print "[MyTube] The server coundn't fulfill the request."
186                         print "[MyTube] Error code: ", e.code
187                 except URLError, e:
188                         print "[MyTube] We failed to reach a server."
189                         print "[MyTube] Reason: ", e.reason
190                 except IOError, e:
191                         print "[MyTube] We failed to reach a server."
192                         print "[MyTube] Reason: ", e
193                 else:
194                         m = None
195                         while not None:
196                                 data = response.readline()
197                                 if data == "":
198                                         break
199
200                                 if "isHDAvailable = true" in data:
201                                         isHDAvailable = True
202                                         print "HD AVAILABLE"
203                                 else:
204                                         pass
205                                 m = re.search("watch_fullscreen\\?(?P<vid_query>.*?)&title=(?P<name>.*)';\n", data)
206                                 if m:
207                                         break
208                         response.close
209                         if m:
210                                 t= re.match (".*[?&]t=([^&]+)", m.group('vid_query')).groups()[0]
211                                 if isHDAvailable is True:
212                                         mrl = "http://www.youtube.com/get_video?video_id=" + quote(self.getTubeId()) + "&t=" + t + "&fmt=22"
213                                         print "[MyTube] GOT HD URL: ", mrl
214                                 else:
215                                         mrl = "http://www.youtube.com/get_video?video_id=" + quote(self.getTubeId()) + "&t=" + t + "&fmt=18"
216                                         print "[MyTube] GOT SD URL: ", mrl
217
218                         else:
219                                 print "[MyTube] No valid mp4-url found"
220                 #self.myopener = MyOpener()
221                 #urllib.urlopen = MyOpener().open
222                 return mrl
223
224         def getRelatedVideos(self):
225                 print "[MyTubeFeedEntry] getResponseVideos()"
226                 for link in self.entry.link:
227                         #print "Related link: ", link.rel.endswith
228                         if link.rel.endswith("video.related"):
229                                 print "Found Related: ", link.href
230                                 return link.href
231
232         def getResponseVideos(self):
233                 print "[MyTubeFeedEntry] getResponseVideos()"
234                 for link in self.entry.link:
235                         #print "Responses link: ", link.rel.endswith
236                         if link.rel.endswith("video.responses"):
237                                 print "Found Responses: ", link.href
238                                 return link.href
239
240 class MyTubePlayerService():
241 #       Do not change the client_id and developer_key in the login-section!
242 #       ClientId: ytapi-dream-MyTubePlayer-i0kqrebg-0
243 #       DeveloperKey: AI39si4AjyvU8GoJGncYzmqMCwelUnqjEMWTFCcUtK-VUzvWygvwPO-sadNwW5tNj9DDCHju3nnJEPvFy4WZZ6hzFYCx8rJ6Mw
244         def __init__(self):
245                 print "[MyTube] MyTubePlayerService - init"
246                 self.feedentries = []
247                 self.feed = None
248                 
249         def startService(self):
250                 print "[MyTube] MyTubePlayerService - startService"
251                 self.yt_service = gdata.youtube.service.YouTubeService()
252                 self.yt_service.developer_key = 'AI39si4AjyvU8GoJGncYzmqMCwelUnqjEMWTFCcUtK-VUzvWygvwPO-sadNwW5tNj9DDCHju3nnJEPvFy4WZZ6hzFYCx8rJ6Mw'
253                 self.yt_service.client_id = 'ytapi-dream-MyTubePlayer-i0kqrebg-0'
254                 self.loggedIn = False
255                 #os.environ['http_proxy'] = 'http://169.229.50.12:3128'
256                 #proxy = os.environ.get('http_proxy')
257                 #print "FOUND ENV PROXY-->",proxy
258                 #for a in os.environ.keys():
259                 #       print a
260
261         def stopService(self):
262                 print "[MyTube] MyTubePlayerService - stopService"
263                 del self.ytService
264                 self.loggedIn = False
265
266         def isLoggedIn(self):
267                 return self.loggedIn
268
269         def getFeed(self, url):
270                 print "[MyTube] MyTubePlayerService - getFeed:",url
271                 self.feedentries = []
272                 self.feed = self.yt_service.GetYouTubeVideoFeed(url)
273                 for entry in self.feed.entry:
274                         MyFeedEntry = MyTubeFeedEntry(self, entry)
275                         self.feedentries.append(MyFeedEntry)
276                 return self.feed                        
277
278         def search(self, searchTerms, startIndex = 1, maxResults = 25,
279                                         orderby = "relevance", racy = "include", 
280                                         author = "", lr = "", categories = "", sortOrder = "ascending"):
281                 print "[MyTube] MyTubePlayerService - search()"
282                 self.feedentries = []
283                 query = gdata.youtube.service.YouTubeVideoQuery()
284                 query.vq = searchTerms
285                 query.orderby = orderby
286                 query.racy = racy
287                 query.sortorder = sortOrder
288                 if lr is not None:
289                         query.lr = lr
290                 if categories[0] is not None:
291                         query.categories = categories
292                 query.start_index = startIndex
293                 query.max_results = maxResults
294                 try:
295                         feed = self.yt_service.YouTubeQuery(query)
296                 except gaierror:
297                         feed = None
298                 if feed is not None:
299                         self.feed = feed
300                         for entry in self.feed.entry:
301                                 MyFeedEntry = MyTubeFeedEntry(self, entry)
302                                 self.feedentries.append(MyFeedEntry)
303                 return self.feed                
304
305         def getTitle(self):
306                 return self.feed.title.text
307
308         def getEntries(self):
309                 return self.feedentries
310
311         def itemCount(self):
312                 return self.feed.items_per_page.text
313
314         def getTotalResults(self):
315                 return self.feed.total_results.text
316         
317         def getNextFeedEntriesURL(self):
318                 for link in self.feed.link:
319                         if link.rel == "next":
320                                 return link.href
321                 return None
322
323
324 myTubeService = MyTubePlayerService()