PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/plugin.video.willowtv/default.py

http://apple-tv2-xbmc.googlecode.com/
Python | 1098 lines | 1078 code | 16 blank | 4 comment | 18 complexity | f1b3081ca27266383d5515ebd49fc819 MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. import urllib,urllib2,urlparse,re,sys,xbmcplugin,xbmcgui
  2. import cookielib,os,string,cookielib,StringIO
  3. import os,time,base64,logging,calendar
  4. import xbmcaddon
  5. from xml.dom.minidom import parse, parseString
  6. #Willow TV
  7. wtv=xbmcaddon.Addon(id='plugin.video.willowtv')
  8. addonPath=wtv.getAddonInfo('path')
  9. artPath=addonPath+'/resources/art'
  10. defaultIconImg=os.path.join(xbmc.translatePath( artPath ), "cricket-icon.png")
  11. login = 'https://www.willow.tv/EventMgmt/UserMgmt/Login.asp'
  12. backup_login = 'https://live.willow.tv/EventMgmt/Login.asp'
  13. hostname='http://www.willow.tv'
  14. backup_hostname='http://live.willow.tv'
  15. youtubeChannel='willow'
  16. maxLinksPerPageOption = [15,25,50]
  17. def loginWillowTV(url):
  18. try:
  19. print url
  20. cookiejar = cookielib.LWPCookieJar()
  21. cookiejar = urllib2.HTTPCookieProcessor(cookiejar)
  22. opener = urllib2.build_opener(cookiejar)
  23. urllib2.install_opener(opener)
  24. email = wtv.getSetting('email')
  25. pwd = wtv.getSetting('password')
  26. values = {'Email': email,'Password': pwd, 'KeepSigned': 'true', 'LoginFormSubmit': 'true'}
  27. headers = { 'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3' }
  28. data = urllib.urlencode(values)
  29. req = urllib2.Request(url, data, headers)
  30. response = urllib2.urlopen(req)
  31. link=response.read()
  32. response.close()
  33. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"')
  34. match=re.compile('Error: Your email or password is incorrect').findall(web)
  35. if(len(match)>0):
  36. d = xbmcgui.Dialog()
  37. d.ok('Login Failed', 'Error: Your email or password is incorrect.','Please verify your login details.')
  38. return False
  39. else:
  40. return True
  41. except:
  42. d = xbmcgui.Dialog()
  43. d.ok('LOGIN Failed', 'Its not your fault. BREAK TIME!','Please go out of Willow TV and try again.')
  44. return False
  45. def HOME():
  46. addDir('My Packages','willow.tv',6,'http://i3.ytimg.com/i/2V_LHwvaNS2XWZ5l8x3jLQ/1.jpg?v=c12daa','')
  47. addDir('YouTube Channel','willow',20,'http://i3.ytimg.com/i/2V_LHwvaNS2XWZ5l8x3jLQ/1.jpg?v=c12daa','')
  48. def MYPACKAGES(url, name):
  49. try:
  50. loginCheck = loginWillowTV(login)
  51. if(loginCheck == False):
  52. return False
  53. xbmc.executebuiltin("XBMC.Notification(Willow TV,Account Login Sucessful,5000,)")
  54. #LOGIN SUCCESS. Show My Packages.
  55. url = 'http://www.willow.tv/EventMgmt/UserMgmt/MyPackages.asp'
  56. req = urllib2.Request(url)
  57. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  58. response = urllib2.urlopen(req)
  59. link=response.read()
  60. response.close()
  61. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"')
  62. match=re.compile('<table cellspacing=0 cellpadding=0 width="100%"><tr><td><table class="matchListBgClr fontSize80" width=100% cellspacing=1 cellpadding=5><tr><td (.+?)="20%">Event</td><td>(.+?)</td></tr><tr class=MainRow><td>Package</td><td>(.+?)</td></tr><tr class=MainRow><td>Purchase Date</td><td class=MainRow>(.+?)</td></tr><tr><td colspan=2><div id=ShowHideMsg(.+?) align=right><a class=TableLink href=(.+?)><strong>Click here</strong></a> to see Matches included in this Package</div><DIV style="display:none" id=MatchList(.+?)></div></td></tr></table></td></tr><tr><td align=right>Click here to <a class=TableLink href="..(.+?)"><strong>WATCH</strong></a> this event.<br><br></td></tr></table>').findall(web)
  63. for tmp,event,package,purchaseDate,extra1,extra2,extra3,urlParam in match:
  64. iconImg = ''
  65. fanart = ''
  66. if(event=='ICC World Cup 2011'):
  67. fanart=os.path.join(xbmc.translatePath( artPath ), "worldCup2011_fanart1.jpg")
  68. addDirWithOption(package,'http://www.willow.tv/EventMgmt'+urlParam,'FALSE',1,iconImg,fanart)
  69. xbmc.executebuiltin("XBMC.Notification(Willow TV,Account Packages Loaded,5000,)")
  70. except:
  71. raise
  72. xbmc.executebuiltin("XBMC.Notification(Willow TV is DOWN,Please use WILLOW TV [BACKUP PLAN],5000,)")
  73. fanart=os.path.join(xbmc.translatePath( addonPath ), "fanart.jpg")
  74. #addDirWithOption('Willow TV [BACKUP PLAN. Use this if failed to see other your Packages]','http://live.willow.tv/EventMgmt/UserMgmt/MatchList.asp','TRUE',1,iconImg,fanart)
  75. def MATCHES(url,name, isBackupPlan):
  76. if(isBackupPlan == 'TRUE'):
  77. loginCheck = loginWillowTV(backup_login)
  78. if(loginCheck == False):
  79. return
  80. xbmc.executebuiltin("XBMC.Notification(BACKTUP Willow TV,Account Login Sucessful,5000,)")
  81. req = urllib2.Request(url)
  82. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  83. response = urllib2.urlopen(req)
  84. link=response.read()
  85. response.close()
  86. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"').replace('style="display:none;"','')
  87. match=re.compile('<tr class="SeriesMatchRow_(.+?)" ><td class="matchListDataBgClr"><SCRIPT>CXWriteLocalDateTime(.+?);</SCRIPT></td><td class="matchListDataBgClr">(.+?)</td><td class="matchListDataBgClr">(.+?)</tr>').findall(web)
  88. if len(match) > 0:
  89. for id, matchDate, matchName, matchURL in match:
  90. datetime_obj = time.strptime(matchDate, '("%m/%d/%Y %H:%M:%S %Z")')
  91. localMatchDate = time.strftime('(%a, %b %d %Y %I:%M %p)', time.localtime(calendar.timegm(datetime_obj)))
  92. addDirWithOption(localMatchDate + ' - [B]' + matchName + '[/B]',matchURL,isBackupPlan,2,'','')
  93. else:
  94. UPCOMING_MATCH_LIST('http://www.willow.tv/EventMgmt/UserMgmt/FixtureArchiveHelper.asp?eid=160&target=upcoming')
  95. ARCHIVE_MATCH_LIST('http://www.willow.tv/EventMgmt/UserMgmt/FixtureArchiveHelper.asp?eid=160&target=concluded')
  96. #xbmc.executebuiltin("XBMC.Notification("+name+",Match List Loaded,5000,)")
  97. def UPCOMING_MATCH_LIST(url,name='', isBackupPlan='FALSE'):
  98. req = urllib2.Request(url)
  99. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  100. response = urllib2.urlopen(req)
  101. link=response.read()
  102. response.close()
  103. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"')
  104. print web
  105. match=re.compile('<tr toggler="yes" (.+?)CXGetLocalDateTime(.+?);</SCRIPT></a><td class="matchListDataBgClr">(.+?)</td><td class="matchListDataBgClr">(.+?)</td>').findall(web)
  106. for temp, matchDate, matchName, matchCategories in match:
  107. datetime_obj = time.strptime(matchDate, '("%m/%d/%Y %H:%M:%S %Z")')
  108. localMatchDate = time.strftime('(%a, %b %d %Y %I:%M %p)', time.localtime(calendar.timegm(datetime_obj)))
  109. addDirWithOption(localMatchDate + ' - [B] UPCOMING or LIVE :: ' + matchName + '[/B]',matchCategories,isBackupPlan,13,'','')
  110. def UPCOMING_SECTIONS(url,name,isBackupPlan='FALSE'):
  111. newMatch = re.compile('<a class="TableLink" href="(.+?)">(.+?)</a>').findall(url)
  112. for videoURL,videoDesc in newMatch:
  113. if not re.search('scorecard',videoDesc,re.I):
  114. videoLabel = ''
  115. if re.search('live',videoDesc,re.I):
  116. videoLabel = 'LIVE'
  117. elif re.search('highlight',videoDesc,re.I):
  118. videoLabel = 'Highlights'
  119. elif re.search('replay',videoDesc,re.I):
  120. videoLabel = 'Replay'
  121. if(isBackupPlan == 'TRUE'):
  122. addDirWithOption(videoLabel,backup_hostname+unescape(videoURL.replace(backup_hostname,'')),isBackupPlan,3,'','')
  123. else:
  124. addDirWithOption(videoLabel,hostname+unescape(videoURL.replace(hostname,'')),isBackupPlan,3,'','')
  125. def ARCHIVE_MATCH_LIST(url,name='', isBackupPlan='FALSE'):
  126. req = urllib2.Request(url)
  127. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  128. response = urllib2.urlopen(req)
  129. link=response.read()
  130. response.close()
  131. print 'MATCHES link == '+url
  132. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"')
  133. match=re.compile('<tr class="(.+?)"><td style="text-align:left!important;" id="concludedDateField_(.+?)"><script type="text/javascript">document.getElementById\("concludedDateField_(.+?)"\).innerHTML = CXGetLocalDateTime(.+?);</script></td><td style="text-align:left!important;">(.+?)</td><td style="text-align: right">(.+?)</td></tr>').findall(web)
  134. for className, id, id2, matchDate, matchName, matchURL in match:
  135. datetime_obj = time.strptime(matchDate, '("%d %b %Y %H:%M %Z")')
  136. localMatchDate = time.strftime('(%a, %b %d %Y %I:%M %p)', time.localtime(calendar.timegm(datetime_obj)))
  137. addDirWithOption(localMatchDate + ' - [B]' + matchName + '[/B]',matchURL,isBackupPlan,12,'','')
  138. def ARCHIVE_SECTIONS(url,name, isBackupPlan):
  139. newMatch = re.compile('<a href="(.+?)" style="(.+?)"><img src="(.+?)" alt="(.+?)" title="(.+?)" />').findall(url)
  140. for videoURL,videoStyle,videoImg,videoAlt,videoType in newMatch:
  141. if(videoAlt != 'Video Scorecard'):
  142. if(isBackupPlan == 'TRUE'):
  143. addDirWithOption(videoAlt,backup_hostname+unescape(videoURL.replace(backup_hostname,'')),isBackupPlan,3,'','')
  144. else:
  145. addDirWithOption(videoAlt,hostname+unescape(videoURL.replace(hostname,'')),isBackupPlan,3,'','')
  146. def SECTIONS(url,name, isBackupPlan):
  147. newMatch = re.compile('<a class="TableLink" href="(.+?)">(.+?)</a>').findall(url)
  148. for videoURL,videoType in newMatch:
  149. if(videoType != '(Video Scorecard)'):
  150. if(isBackupPlan == 'TRUE'):
  151. addDirWithOption(videoType,backup_hostname+unescape(videoURL.replace(backup_hostname,'')),isBackupPlan,3,'','')
  152. else:
  153. addDirWithOption(videoType,hostname+unescape(videoURL.replace(hostname,'')),isBackupPlan,3,'','')
  154. def STREAMS(url, name, isBackupPlan):
  155. loginCheck = False
  156. if(isBackupPlan == 'TRUE'):
  157. loginCheck = loginWillowTV(backup_login)
  158. else:
  159. loginCheck = loginWillowTV(login)
  160. if(loginCheck == False):
  161. return
  162. #xbmc.executebuiltin("XBMC.Notification(LOADING..,Retreiving available video streams,5000,)")
  163. req = urllib2.Request(url)
  164. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  165. response = urllib2.urlopen(req)
  166. link=response.read()
  167. response.close()
  168. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"')
  169. match = re.compile('var playlistLength = (.+?);').findall(web)
  170. option = 1
  171. if(len(match)==0):
  172. #addDirWithOption('STREAM VIDEO LINK',url,str(option),4,'','')
  173. VIDEOLINKS(url,'VIDEO STREAM LINK',str(option), 1)
  174. else:
  175. days = re.compile('document.getElementById\("StreamingTitleIndex"\).value=').findall(web)
  176. totalOptions=int(match[0])
  177. day = 1
  178. if len(days) == 0:
  179. LOAD_VIDEOLINKS(url, option, totalOptions, web, 1)
  180. else:
  181. totalDays = len(days)
  182. while day <= totalDays:
  183. addDirWithOption('Match DAY - '+str(day), url, str(option)+'&AJ;'+str(totalOptions)+'&AJ;'+web+'&AJ;'+str(day), 5, '', '')
  184. day = day + 1
  185. def DAY_VIDEOLINKS(url, option, totalOptions, web, day, isBackupPlan='FALSE'):
  186. loginCheck = False
  187. if(isBackupPlan == 'TRUE'):
  188. loginCheck = loginWillowTV(backup_login)
  189. else:
  190. loginCheck = loginWillowTV(login)
  191. if(loginCheck == False):
  192. return
  193. #xbmc.executebuiltin("XBMC.Notification(LOADING..,Retreiving available video streams,5000,)")
  194. LOAD_VIDEOLINKS(url, option, totalOptions, web, day)
  195. def LOAD_VIDEOLINKS(url, option, totalOptions, web, day):
  196. print 'Total Streaming Options = '+str(totalOptions)
  197. web = web.replace('"','')
  198. match = re.compile('<button onclick=document.getElementById\(StreamingServer\).value=(.+?);document.URLOptionsForm.submit\(\); id=(.+?) name=(.+?) class=buttonEnabled type=button>(.+?)</button>').findall(web)
  199. if(totalOptions == len(match)):
  200. for streamOption, temp1, temp2, streamName in match:
  201. iconImg=os.path.join(xbmc.translatePath( artPath ), "stream_icon.png")
  202. VIDEOLINKS(url,'VIDEO STREAM LINK - '+streamOption+' ['+streamName+']',streamOption, day)
  203. else:
  204. while(option <= totalOptions):
  205. iconImg=os.path.join(xbmc.translatePath( artPath ), "stream_icon.png")
  206. VIDEOLINKS(url,'VIDEO PART - '+str(option),option, day)
  207. option = option+1
  208. def VIDEOLINKS(url,name, option, day):
  209. print url
  210. link = ''
  211. try:
  212. values = {'StreamingServer': option, 'StreamingTitleIndex': day}
  213. headers = { 'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3' }
  214. data = urllib.urlencode(values)
  215. req = urllib2.Request(url, data, headers)
  216. response = urllib2.urlopen(req)
  217. link=response.read()
  218. response.close()
  219. #print link
  220. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"')
  221. iconImg=os.path.join(xbmc.translatePath( artPath ), "playnow_icon.png")
  222. #playVideo('PLAY NOW', url, web, iconImg)
  223. #xbmc.executebuiltin("XBMC.Notification("+name+",Select PLAY NOW to watch video,5000,)")
  224. playVideo(name, url, web, iconImg)
  225. except:
  226. if re.search('YouTube', link):
  227. xbmc.executebuiltin("XBMC.Notification(REDIRECTING to YouTube,Using your YouTube user details,2000,)")
  228. YouTube_CHANNEL_CONTENT('willow','willow')
  229. else:
  230. xbmc.executebuiltin("XBMC.Notification(STREAM LINK FAILED,Fail to load stream link. Try other links,2000,)")
  231. return False
  232. def playVideo(name, url, web, iconimage):
  233. ok=True
  234. flashvarsMatch=re.compile('var flashvars = {};(.+?)var params = {};').findall(web)
  235. if(len(flashvarsMatch) == 0):
  236. rtmp_path=re.compile('src: "(.+?)"').findall(web)[0].replace('%26','&')
  237. print rtmp_path
  238. #SWFObject=re.compile('plugin_llnwStreamingPlugin: "(.+?)"').findall(web)[0]
  239. SWFObject = 'http://willow.tv/EventMgmt/scripts/StrobeMediaPlayback.swf'
  240. print SWFObject
  241. streamURL = rtmp_path + " swfUrl="+SWFObject + " swfVfy=true" + " live=true"
  242. if(rtmp_path != ''):
  243. addLink(name, streamURL, iconimage, '')
  244. else:
  245. d = xbmcgui.Dialog()
  246. d.ok('PLAYBACK Failed', 'Connection URL not found.','Please try again later or check logs.')
  247. else:
  248. flashvars=re.compile('flashvars.(.+?) = "(.+?)";').findall(flashvarsMatch[0])
  249. flashvarsComment=re.compile('//flashvars.(.+?) = "(.+?)";').findall(flashvarsMatch[0])
  250. streamURL = ''
  251. for fname,fvalue in flashvars:
  252. for fnameC, fvalueC in flashvarsComment:
  253. if(fname != fnameC):
  254. print fname +'='+ fvalue
  255. if(fname == 'File'):
  256. streamURL=fvalue.replace('%26','&')
  257. break
  258. if(streamURL != ''):
  259. addLink(name, streamURL, iconimage, '')
  260. else:
  261. d = xbmcgui.Dialog()
  262. d.ok('PLAYBACK Failed', 'Connection URL not found.','Please try again later or check logs.')
  263. #YouTube Channel
  264. def YouTube_CHANNEL_PLAYLISTS(url, name):
  265. urlContent = url.split('&AJ;')
  266. playListId = urlContent[0]
  267. ifTitleContains=''
  268. ifTitleNotContains=''
  269. if(len(urlContent) > 1):
  270. searchCriterias = urlContent[1].split('&JA;')
  271. ifTitleContains = searchCriterias[0]
  272. ifTitleNotContains = searchCriterias[1]
  273. retrieve_YT_UserPlaylists(playListId, name, 1, 50, 1, ifTitleContains, ifTitleNotContains)
  274. def YouTube_CHANNEL_PLAYLIST_VIDEOS(url, name):
  275. retrieve_YT_PlaylistVideoLinks(url, name)
  276. def YouTube_CHANNEL_UPLOADS(url, name, lastPageNbr):
  277. linksPerPage = maxLinksPerPageOption[int(wtv.getSetting('linksPerPage'))]
  278. startIndex = 1
  279. if lastPageNbr > 0:
  280. startIndex = (lastPageNbr * linksPerPage) + 1
  281. retrieve_YT_UserUploads(url, name, startIndex, linksPerPage, lastPageNbr+1)
  282. def YouTube_CHANNEL_LIVE(url, name):
  283. try:
  284. req = urllib2.Request('http://www.youtube.com/'+url)
  285. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  286. response = urllib2.urlopen(req)
  287. link=response.read()
  288. response.close()
  289. web = ''.join(link.splitlines()).replace('\t','').replace('\'','"')
  290. #print web
  291. activeEventsCount = int(re.compile('<div class="title">Active Events \((.+?)\)</div>').findall(web)[0])
  292. eventCount = 1
  293. print activeEventsCount
  294. events = re.compile('id="playnav-event-title-play-live_streaming-0-(.+?)"><span dir="ltr" class="yt-www-ls-event-title">(.+?)</span>').findall(web)
  295. for id, title in events:
  296. videoUrl = 'http://www.youtube.com/watch?v='+id
  297. imgUrl = 'http://i2.ytimg.com/vi/'+id+'/default.jpg'
  298. print title
  299. #print eventCount
  300. addYTPlayableMovieLink(title,videoUrl,33,imgUrl)
  301. eventCount = eventCount + 1
  302. if(eventCount > activeEventsCount):
  303. break
  304. except:
  305. d = xbmcgui.Dialog()
  306. d.ok('No ACTIVE live events', 'There are no active LIVE events','Try schedule and check again.')
  307. return False
  308. def YouTube_CHANNEL_CONTENT(url, name):
  309. d = xbmcgui.Dialog()
  310. index = d.select('Select Category:', ['Uploads','Playlists','LIVE'])
  311. if index == 0:
  312. YouTube_CHANNEL_UPLOADS(url, 'Uploads', 0)
  313. elif index == 1:
  314. YouTube_CHANNEL_PLAYLISTS(url, 'Playlists')
  315. elif index == 2:
  316. YouTube_CHANNEL_LIVE(url, 'LIVE')
  317. #######YOUTUBE APIs############
  318. def retrieve_YT_UserInfo(YouTubeUserId):
  319. url='http://gdata.youtube.com/feeds/api/users/'+YouTubeUserId
  320. #url='http://gdata.youtube.com/feeds/api/videos/yrvUcOiPb1g'
  321. req = urllib2.Request(url)
  322. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  323. response = urllib2.urlopen(req)
  324. link=response.read()
  325. response.close()
  326. domObj = parseString(link)
  327. #print domObj.toprettyxml()
  328. entry = domObj.getElementsByTagName("entry")[0]
  329. userInfo = {}
  330. userInfo['title'] = getText(entry.getElementsByTagName("title")[0].childNodes)
  331. userInfo['thumbnail'] = entry.getElementsByTagName("media:thumbnail")[0].getAttribute('url')
  332. return userInfo
  333. def retrieve_YT_UserUploads(YouTubeUserId, name='', startIndex=1, maxCount=50, pageNbr=0):
  334. url='http://gdata.youtube.com/feeds/api/users/'+YouTubeUserId+'/uploads?v=2&max-results='+str(maxCount) + '&start-index='+str(startIndex)
  335. req = urllib2.Request(url)
  336. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  337. response = urllib2.urlopen(req)
  338. link=response.read()
  339. response.close()
  340. domObj = parseString(link)
  341. #print domObj.toprettyxml()
  342. videos=domObj.getElementsByTagName("entry")
  343. imgUrl = 'http://i.ytimg.com/vi/'+YouTubeUserId+'/default.jpg'
  344. matchCount = len(videos)
  345. if(matchCount == 1):
  346. videoID=getText(videos[0].getElementsByTagName("yt:videoid")[0].childNodes)
  347. try:
  348. addYTPlayableMovieLink(getText(videos[0].getElementsByTagName("title")[0].childNodes),videoID,31,'http://i.ytimg.com/vi/'+videoID+'/default.jpg')
  349. except KeyError: pass
  350. elif(matchCount > 1):
  351. for video in videos:
  352. videoTitle = getText(video.getElementsByTagName("title")[0].childNodes)
  353. videoID = getText(video.getElementsByTagName("yt:videoid")[0].childNodes)
  354. try:
  355. addYTPlayableMovieLink(videoTitle,videoID,31,'http://i.ytimg.com/vi/'+videoID+'/default.jpg')
  356. except KeyError: pass
  357. currCountOfVideo = len(videos)
  358. if(currCountOfVideo == maxCount):
  359. addYTDirWithLastPageNbr('[B]NEXT PAGE >>[/B]',YouTubeUserId,22,os.path.join(xbmc.translatePath( artPath ), "next-icon.png"), pageNbr)
  360. if(pageNbr > 1):
  361. addYTDirWithLastPageNbr('[B]<< PREVIOUS PAGE[/B]',YouTubeUserId,22,os.path.join(xbmc.translatePath( artPath ), "prev-icon.png"), pageNbr-2)
  362. def retrieve_YT_PlaylistVideoLinks(playlistID, playlistTitle='', startIndex=1, maxCount=50, playList='',playListLinksCount=0):
  363. url='http://gdata.youtube.com/feeds/api/playlists/'+playlistID+'?v=2&max-results='+str(maxCount) + '&start-index='+str(startIndex)
  364. req = urllib2.Request(url)
  365. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  366. response = urllib2.urlopen(req)
  367. link=response.read()
  368. response.close()
  369. domObj = parseString(link)
  370. #print domObj.toprettyxml()
  371. videos=domObj.getElementsByTagName("entry")
  372. imgUrl = 'http://i.ytimg.com/vi/'+playlistID+'/default.jpg'
  373. i = 1
  374. matchCount = len(videos)
  375. if playListLinksCount == 0:
  376. playListLinksCount = matchCount
  377. else:
  378. playListLinksCount = playListLinksCount + matchCount
  379. if(matchCount == 1):
  380. videoID=getText(videos[0].getElementsByTagName("yt:videoid")[0].childNodes)
  381. addYTPlayableMovieLink(getText(videos[0].getElementsByTagName("title")[0].childNodes),videoID,31,'http://i.ytimg.com/vi/'+videoID+'/default.jpg')
  382. elif(matchCount > 1):
  383. for video in videos:
  384. videoTitle = getText(video.getElementsByTagName("title")[0].childNodes)
  385. videoID = getText(video.getElementsByTagName("yt:videoid")[0].childNodes)
  386. addYTPlayableMovieLink(videoTitle,videoID,31,'http://i.ytimg.com/vi/'+videoID+'/default.jpg')
  387. playList = playList + videoID
  388. if(i < matchCount or matchCount == maxCount):
  389. playList = playList + ':;'
  390. i = i + 1
  391. if(matchCount == maxCount):
  392. retrieve_YT_PlaylistVideoLinks(playlistID, playlistTitle, startIndex+maxCount, maxCount, playList, playListLinksCount)
  393. elif(playListLinksCount > 0):
  394. addYTPlayListLink('[B]Direct PLAY - ' + playlistTitle + '[/B] [I]Playlist of above ' + str(playListLinksCount) + ' videos[/I]',playList,32,imgUrl)
  395. def retrieve_YT_UserPlaylists(YouTubeUserId, name='', startIndex=1, maxCount=50, pageNbr=0, ifTitleContains='', ifTitleNotContains=''):
  396. url='http://gdata.youtube.com/feeds/api/users/'+YouTubeUserId+'/playlists?v=2&max-results='+str(maxCount) + '&start-index='+str(startIndex)
  397. req = urllib2.Request(url)
  398. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  399. response = urllib2.urlopen(req)
  400. link=response.read()
  401. response.close()
  402. domObj = parseString(link)
  403. #print domObj.toprettyxml()
  404. playlists=domObj.getElementsByTagName("entry")
  405. for playlist in playlists:
  406. playListTitle = unicode(getText(playlist.getElementsByTagName("title")[0].childNodes)).encode("utf-8")
  407. playlistID = getText(playlist.getElementsByTagName("yt:playlistId")[0].childNodes)
  408. print playListTitle
  409. if ifTitleContains != '' and not re.search(ifTitleContains, playListTitle):
  410. continue
  411. elif ifTitleNotContains != '' and re.search(ifTitleNotContains, playListTitle):
  412. continue
  413. addDir(playListTitle, playlistID,21,'','')
  414. print len(playlists)
  415. currCountOfPlayList = len(playlists)
  416. print maxCount
  417. if(currCountOfPlayList == maxCount):
  418. retrieve_YT_UserPlaylists(YouTubeUserId, name, startIndex+maxCount, maxCount, pageNbr, ifTitleContains, ifTitleNotContains)
  419. # addYTDirWithLastPageNbr('[B]NEXT PAGE >>[/B]',YouTubeUserId+'&AJ;'+ifTitleContains+'&AJ;'+ifTitleNotContains,61,os.path.join(xbmc.translatePath( artPath ), "next-icon.png"), pageNbr)
  420. #if(pageNbr > 1):
  421. # addYTDirWithLastPageNbr('[B]<< PREVIOUS PAGE[/B]',YouTubeUserId+'&AJ;'+ifTitleContains+'&AJ;'+ifTitleNotContains,61,os.path.join(xbmc.translatePath( artPath ), "prev-icon.png"), pageNbr-2)
  422. def retrieve_YT_UserLiveEvents(YouTubeUserId):
  423. url='http://gdata.youtube.com/feeds/api/users/'+YouTubeUserId+'/live/events?v=2'
  424. req = urllib2.Request(url)
  425. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  426. response = urllib2.urlopen(req)
  427. link=response.read()
  428. response.close()
  429. domObj = parseString(link)
  430. #print domObj.toprettyxml()
  431. playlists=domObj.getElementsByTagName("entry")
  432. for playlist in playlists:
  433. title = unicode(getText(playlist.getElementsByTagName("title")[0].childNodes)).encode("utf-8")
  434. videoID = getText(playlist.getElementsByTagName("yt:videoid")[0].childNodes)
  435. status = getText(playlist.getElementsByTagName("yt:status")[0].childNodes)
  436. imgUrl = 'http://i.ytimg.com/vi/'+videoID+'/default.jpg'
  437. if status == 'active':
  438. title = '[B]ACTIVE[/B] '+title
  439. elif status == 'pending':
  440. title = '[B]UPCOMING[/B] '+title
  441. else:
  442. continue
  443. addYTPlayableMovieLink(title,'http://www.youtube.com/watch?v='+videoID,33,imgUrl)
  444. def YouTube_PLAY_PLAYLIST(url,name):
  445. #xbmc.executebuiltin("XBMC.Notification(PLease Wait!,Loading video links into XBMC Media Player,5000)")
  446. ok=True
  447. playList = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
  448. playList.clear()
  449. #time.sleep(2)
  450. links = url.split(':;')
  451. pDialog = xbmcgui.DialogProgress()
  452. ret = pDialog.create('Loading playlist...')
  453. totalLinks = len(links)
  454. loadedLinks = 0
  455. remaining_display = 'Videos loaded :: [B]'+str(loadedLinks)+' / '+str(totalLinks)+'[/B] into XBMC player playlist.'
  456. pDialog.update(0,'Please wait for the process to retrieve video link.',remaining_display)
  457. for videoLink in links:
  458. load_YT_Video(videoLink,name,True,True)
  459. loadedLinks = loadedLinks + 1
  460. percent = (loadedLinks * 100)/totalLinks
  461. #print percent
  462. remaining_display = 'Videos loaded :: [B]'+str(loadedLinks)+' / '+str(totalLinks)+'[/B] into XBMC player playlist.'
  463. pDialog.update(percent,'Please wait for the process to retrieve video link.',remaining_display)
  464. if (pDialog.iscanceled()):
  465. return False
  466. xbmcPlayer = xbmc.Player()
  467. xbmcPlayer.play(playList)
  468. if not xbmcPlayer.isPlayingVideo():
  469. d = xbmcgui.Dialog()
  470. d.ok('INVALID VIDEO PLAYLIST', 'The playlist videos were removed due to copyright issue.','Check other links.')
  471. return ok
  472. def YouTube_PLAY_VIDEO(url,name):
  473. ok=True
  474. print url
  475. videoUrl = load_YT_Video(url,name,True,False)
  476. if videoUrl == None:
  477. d = xbmcgui.Dialog()
  478. d.ok('VIDEO UNAVAILABLE', 'This video is not available to view through this add-on.','Try to access link directly.')
  479. return False
  480. xbmcPlayer = xbmc.Player()
  481. xbmcPlayer.play(videoUrl)
  482. return ok
  483. def YouTube_PLAY_LIVE_VIDEO(url, name):
  484. req = urllib2.Request(url)
  485. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  486. response = urllib2.urlopen(req)
  487. link=response.read()
  488. response.close()
  489. #print link
  490. #videoUrl = load_YT_Video(url,name,True,False)
  491. loginUrl = re.compile('href="https://accounts.google.com/ServiceLogin(.+?)">Sign In</a>').findall(link)[0]
  492. loginCookie = loginYouTube('https://accounts.google.com/ServiceLogin'+loginUrl.replace('&amp;','&'))
  493. videoUrl = None
  494. videoUrl_sec = None
  495. if loginCookie != None:
  496. req = urllib2.Request(url)
  497. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  498. response = urllib2.urlopen(req)
  499. link=response.read()
  500. response.close()
  501. link = link.replace('\\u0026','&')
  502. #print link
  503. if re.search('url_encoded_fmt_stream_map', link):
  504. map = None
  505. match=re.compile('url_encoded_fmt_stream_map=(.+?)&').findall(link)
  506. if len(match) == 0:
  507. map=(re.compile('url_encoded_fmt_stream_map": "(.+?)"').findall(link)[0]).replace('\\/', '/').split('url=')
  508. else:
  509. map=urllib.unquote(match[0]).decode('utf8').split('url=')
  510. videoUrl = resolve_YT_Video(map, name, True, False,'',True)
  511. else:
  512. map = None
  513. match=re.compile('fmt_stream_map=(.+?)&').findall(link)
  514. if len(match) == 0:
  515. map=(re.compile('fmt_stream_map": "(.+?)"').findall(link)[0]).replace('\\/', '/').split('url=')
  516. else:
  517. map=urllib.unquote(match[0]).decode('utf8').split('url=')
  518. videoUrl = resolve_YT_Video(map, name, True, False,'',True)
  519. #print videoUrl
  520. if videoUrl == None and videoUrl_sec == None:
  521. d = xbmcgui.Dialog()
  522. d.ok('VIDEO UNAVAILABLE', 'This video is not available to view through this add-on.','Try to access link directly.')
  523. return False
  524. cookies = ''
  525. for cookie in loginCookie:
  526. #print cookie.name
  527. #print cookie.value
  528. cookies = cookies + cookie.name + '=' + cookie.value + '; '
  529. #print 'FINAL COOKIE' + cookies
  530. xbmcPlayer = xbmc.Player(xbmc.PLAYER_CORE_AUTO)
  531. xbmcPlayer.play(videoUrl+'|User-Agent='+urllib.quote_plus('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')+'&Referer='+urllib.quote_plus(url)+'&Cookie='+urllib.quote_plus(cookies))
  532. def loginYouTube(url):
  533. try:
  534. email = wtv.getSetting('yt_email')
  535. pwd = wtv.getSetting('yt_password')
  536. if (not email or email == '') or (not pwd or pwd == ''):
  537. d = xbmcgui.Dialog()
  538. d.ok('Provide YouTube account details', 'To watch LIVE CRICKET on your favorite Willow TV,','please provide your login details for YouTube account linked to Willow TV.')
  539. wtv.openSettings(sys.argv[ 0 ])
  540. email = wtv.getSetting('yt_email')
  541. pwd = wtv.getSetting('yt_password')
  542. from mechanize import ParseResponse
  543. cookiejar = cookielib.LWPCookieJar()
  544. http_cookiejar = urllib2.HTTPCookieProcessor(cookiejar)
  545. opener = urllib2.build_opener(http_cookiejar)
  546. urllib2.install_opener(opener)
  547. req = urllib2.Request(url)
  548. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  549. urllib2.HTTPSHandler(debuglevel=1)
  550. response = urllib2.urlopen(req)
  551. forms = ParseResponse(response, backwards_compat=False)
  552. response.close()
  553. form = forms[0]
  554. form['Passwd'] = pwd
  555. form['Email'] = email
  556. req = form.click()
  557. response = urllib2.urlopen(req)
  558. web = response.read()
  559. if re.search('Enter the verification code',web,re.I):
  560. response = urllib2.urlopen(req)
  561. forms = ParseResponse(response, backwards_compat=False)
  562. response.close()
  563. form = forms[0]
  564. keyb = xbmc.Keyboard()
  565. keyb.setHeading('Please provide 2-step verification PIN:')
  566. keyb.doModal()
  567. code = None
  568. if (keyb.isConfirmed()):
  569. code = keyb.getText()
  570. if code is None:
  571. d = xbmcgui.Dialog()
  572. d.ok('YouTube login failed', 'Cannot proceed without verification code.','Process has been cancelled by user.')
  573. return None
  574. form["smsUserPin"] = code
  575. req = form.click()
  576. response = urllib2.urlopen(req)
  577. forms = ParseResponse(response, backwards_compat=False)
  578. response.close()
  579. form = forms[0]
  580. req = form.click()
  581. response = urllib2.urlopen(req)
  582. web = response.read()
  583. while re.search('<title>Redirecting</title>', web):
  584. redirect_re = re.compile('<meta http-equiv="refresh" content="0; url=\&\#39;(.+?)\&\#39;"')
  585. # check for redirect meta tag
  586. match = redirect_re.search(web)
  587. if match:
  588. url = redirect_re.findall(web)[0].replace('&amp;','&')
  589. else:
  590. url = None
  591. break
  592. req = urllib2.Request(url)
  593. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  594. response = urllib2.urlopen(req)
  595. web=response.read()
  596. response.close()
  597. return cookiejar
  598. except:
  599. raise
  600. d = xbmcgui.Dialog()
  601. d.ok('YouTube login failed', 'Please opt for 2-step authentication method of google','You should check if you have provided correct username and password')
  602. return None
  603. def load_YT_Video(code,name,isRequestForURL,isRequestForPlaylist):
  604. print 'YT VIDEO ID = '+ code
  605. #YOUTUBE
  606. try:
  607. linkImage = 'http://i.ytimg.com/vi/'+code+'/default.jpg'
  608. req = urllib2.Request('http://www.youtube.com/watch?v='+code+'&fmt=18')
  609. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  610. response = urllib2.urlopen(req)
  611. link=response.read()
  612. response.close()
  613. if len(re.compile('shortlink" href="http://youtu.be/(.+?)"').findall(link)) == 0:
  614. if len(re.compile('\'VIDEO_ID\': "(.+?)"').findall(link)) == 0:
  615. req = urllib2.Request('http://www.youtube.com/get_video_info?video_id='+code+'&asv=3&el=detailpage&hl=en_US')
  616. req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3')
  617. response = urllib2.urlopen(req)
  618. link=response.read()
  619. response.close()
  620. map = None
  621. link = link.replace('\\u0026','&')
  622. match=re.compile('url_encoded_fmt_stream_map=(.+?)&').findall(link)
  623. if len(match) == 0:
  624. map=(re.compile('url_encoded_fmt_stream_map": "(.+?)"').findall(link)[0]).replace('\\/', '/').split('url=')
  625. else:
  626. map=urllib.unquote(match[0]).decode('utf8').split('url=')
  627. if re.search('status=fail', link):
  628. return
  629. if map == None:
  630. return
  631. #print map
  632. return resolve_YT_Video(map, name,isRequestForURL,isRequestForPlaylist,linkImage)
  633. except: pass
  634. def resolve_YT_Video(map, name,isRequestForURL,isRequestForPlaylist,linkImage,selectVideoQual=False):
  635. try:
  636. highResoVid = ''
  637. youtubeVideoQual = wtv.getSetting('videoQual')
  638. #print map
  639. videoQuals = []
  640. videoLinks = []
  641. for attr in map:
  642. if attr == '':
  643. continue
  644. parts = attr.split('&qual')
  645. url = urllib.unquote(parts[0]).decode('utf8')
  646. qual = re.compile('&itag=(\d*)').findall(url)[0]
  647. print qual
  648. if(qual == '13'):
  649. if(selectVideoQual):
  650. videoQuals.append('LOW 3GP')
  651. videoLinks.append(url)
  652. elif(not(isRequestForURL)):
  653. addLink ('PLAY 3GP Low Quality - 176x144',url,linkImage)
  654. elif(highResoVid == ''):
  655. highResoVid = url
  656. elif(qual == '17'):
  657. if(selectVideoQual):
  658. videoQuals.append('SD 3GP')
  659. videoLinks.append(url)
  660. elif(not(isRequestForURL)):
  661. addLink ('PLAY 3GP Medium Quality - 176x144',url,linkImage)
  662. elif(highResoVid == ''):
  663. highResoVid = url
  664. elif(qual == '36'):
  665. if(selectVideoQual):
  666. videoQuals.append('HD 3GP')
  667. videoLinks.append(url)
  668. elif(not(isRequestForURL)):
  669. addLink ('PLAY 3GP High Quality - 320x240',url,linkImage)
  670. elif(highResoVid == ''):
  671. highResoVid = url
  672. elif(qual == '5'):
  673. if(selectVideoQual):
  674. videoQuals.append('LOW FLV')
  675. videoLinks.append(url)
  676. elif(not(isRequestForURL)):
  677. addLink ('PLAY FLV Low Quality - 400\\327226',url,linkImage)
  678. elif(highResoVid == ''):
  679. highResoVid = url
  680. elif(qual == '34'):
  681. if(selectVideoQual):
  682. videoQuals.append('SD 480p FLV')
  683. videoLinks.append(url)
  684. elif(not(isRequestForURL)):
  685. addLink ('PLAY FLV Medium Quality - 480x360',url,linkImage)
  686. elif(highResoVid == ''):
  687. highResoVid = url
  688. elif(qual == '6'):
  689. if(selectVideoQual):
  690. videoQuals.append('SD 640p FLV')
  691. videoLinks.append(url)
  692. elif(not(isRequestForURL)):
  693. addLink ('PLAY FLV Medium Quality - 640\\327360',url,linkImage)
  694. elif(highResoVid == ''):
  695. highResoVid = url
  696. elif(qual == '35'):
  697. if(selectVideoQual):
  698. videoQuals.append('SD FLV')
  699. videoLinks.append(url)
  700. elif(not(isRequestForURL)):
  701. addLink ('PLAY FLV High Quality - 854\\327480',url,linkImage)
  702. else:
  703. highResoVid = url
  704. elif(qual == '18'):
  705. if(selectVideoQual):
  706. videoQuals.append('SD 480p MP4')
  707. videoLinks.append(url)
  708. elif(not(isRequestForURL)):
  709. addLink ('PLAY MP4 High Quality - 480x360',url,linkImage)
  710. else:
  711. highResoVid = url
  712. elif(qual == '22'):
  713. if(selectVideoQual):
  714. videoQuals.append('HD 720p MP4')
  715. videoLinks.append(url)
  716. elif(not(isRequestForURL)):
  717. addLink ('PLAY MP4 High Quality - 1280x720',url,linkImage)
  718. else:
  719. highResoVid = url
  720. if youtubeVideoQual == '1' or youtubeVideoQual == '2':
  721. break
  722. elif(qual == '37'):
  723. if(selectVideoQual):
  724. videoQuals.append('HD 1080p MP4')
  725. videoLinks.append(url)
  726. elif(not(isRequestForURL)):
  727. addLink ('PLAY MP4 High-2 Quality - 1920x1080',url,linkImage)
  728. else:
  729. highResoVid = url
  730. if youtubeVideoQual == '2':
  731. break
  732. elif(qual == '38'):
  733. if(selectVideoQual):
  734. videoQuals.append('HD 4096p WEBM')
  735. videoLinks.append(url)
  736. elif(not(isRequestForURL)):
  737. addLink ('PLAY MP4 Epic Quality - 4096\\3272304',url,linkImage)
  738. else:
  739. highResoVid = url
  740. if youtubeVideoQual == '2':
  741. break
  742. elif(qual == '43'):
  743. if(selectVideoQual):
  744. videoQuals.append('HD 4096p WEBM')
  745. videoLinks.append(url)
  746. elif(not(isRequestForURL)):
  747. addLink ('PLAY WEBM Medium Quality - 4096\\3272304',url,linkImage)
  748. else:
  749. highResoVid = url
  750. elif(qual == '44'):
  751. if(selectVideoQual):
  752. videoQuals.append('HD 4096p WEBM')
  753. videoLinks.append(url)
  754. elif(not(isRequestForURL)):
  755. addLink ('PLAY WEBM High Quality - 4096\\3272304',url,linkImage)
  756. else:
  757. highResoVid = url
  758. if youtubeVideoQual == '1' or youtubeVideoQual == '2':
  759. break
  760. elif(qual == '45'):
  761. if(selectVideoQual):
  762. videoQuals.append('HD 4096p WEBM')
  763. videoLinks.append(url)
  764. elif(not(isRequestForURL)):
  765. addLink ('PLAY WEBM High-2 Quality - 4096\\3272304',url,linkImage)
  766. else:
  767. highResoVid = url
  768. if youtubeVideoQual == '2':
  769. break
  770. elif(qual == '120'):
  771. if(selectVideoQual):
  772. videoQuals.append('HD 720p Fast')
  773. videoLinks.append(url)
  774. elif(not(isRequestForURL)):
  775. addLink ('PLAY HD Video Quality',url,linkImage)
  776. else:
  777. highResoVid = url
  778. if youtubeVideoQual == '1' or youtubeVideoQual == '2':
  779. break
  780. if(selectVideoQual):
  781. d = xbmcgui.Dialog()
  782. index = d.select('Select video quality:', videoQuals)
  783. if index == -1:
  784. return None
  785. highResoVid = videoLinks[index]
  786. if(isRequestForURL):
  787. if(isRequestForPlaylist):
  788. liz = xbmcgui.ListItem('VIDEO PART', thumbnailImage=linkImage)
  789. xbmc.PlayList(xbmc.PLAYLIST_VIDEO).add(url = highResoVid, listitem=liz)
  790. return highResoVid
  791. else:
  792. return highResoVid
  793. except: pass
  794. #YOUTUBE
  795. def getVideoTitle(video):
  796. return getText(video.getElementsByTagName("title")[0].childNodes)
  797. def getVideoID(video):
  798. return getText(video.getElementsByTagName("yt:videoid")[0].chi

Large files files are truncated, but you can click here to view the full file