PageRenderTime 102ms CodeModel.GetById 29ms RepoModel.GetById 9ms app.codeStats 1ms

/IPTVPlayer/hosts/hoststreamcomplet.py

https://gitlab.com/zatoshi/iptvplayer-for-e2
Python | 344 lines | 308 code | 19 blank | 17 comment | 12 complexity | 7ed7615d8d9fe5dd3deb9ec7f0cf4f03 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. ###################################################
  3. # LOCAL import
  4. ###################################################
  5. from Plugins.Extensions.IPTVPlayer.components.iptvplayerinit import TranslateTXT as _, SetIPTVPlayerLastHostError
  6. from Plugins.Extensions.IPTVPlayer.components.ihost import CHostBase, CBaseHostClass, CDisplayListItem, RetHost, CUrlItem, ArticleContent
  7. from Plugins.Extensions.IPTVPlayer.tools.iptvtools import printDBG, printExc, CSearchHistoryHelper, remove_html_markup, GetLogoDir, GetCookieDir, byteify
  8. from Plugins.Extensions.IPTVPlayer.libs.pCommon import common, CParsingHelper
  9. import Plugins.Extensions.IPTVPlayer.libs.urlparser as urlparser
  10. from Plugins.Extensions.IPTVPlayer.libs.youtube_dl.utils import clean_html
  11. from Plugins.Extensions.IPTVPlayer.tools.iptvtypes import strwithmeta
  12. ###################################################
  13. ###################################################
  14. # FOREIGN import
  15. ###################################################
  16. import copy
  17. import re
  18. import urllib
  19. import base64
  20. try: import json
  21. except: import simplejson as json
  22. from datetime import datetime
  23. from Components.config import config, ConfigSelection, ConfigYesNo, ConfigText, getConfigListEntry
  24. ###################################################
  25. ###################################################
  26. # E2 GUI COMMPONENTS
  27. ###################################################
  28. from Plugins.Extensions.IPTVPlayer.components.asynccall import MainSessionWrapper
  29. from Screens.MessageBox import MessageBox
  30. ###################################################
  31. ###################################################
  32. # Config options for HOST
  33. ###################################################
  34. def GetConfigList():
  35. optionList = []
  36. return optionList
  37. ###################################################
  38. def gettytul():
  39. return 'http://streamcomplet.com/'
  40. class StreamComplet(CBaseHostClass):
  41. MAIN_URL = 'http://www.streamcomplet.com/'
  42. SRCH_URL = MAIN_URL + '?s='
  43. DEFAULT_ICON_URL = 'http://streamcomplet.com/wp-content/themes/streaming/logo/logo.png'
  44. MAIN_CAT_TAB = [{'category':'categories', 'title': _('Categories'), 'icon':DEFAULT_ICON_URL, 'filters':{}},
  45. {'category':'search', 'title': _('Search'), 'icon':DEFAULT_ICON_URL, 'search_item':True},
  46. {'category':'search_history', 'title': _('Search history'), 'icon':DEFAULT_ICON_URL }
  47. ]
  48. def __init__(self):
  49. CBaseHostClass.__init__(self, {'history':'StreamComplet', 'cookie_type':'MozillaCookieJar', 'cookie':'StreamComplet.cookie'})
  50. self.cacheFilters = {}
  51. self.USER_AGENT = "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; androVM for VirtualBox ('Tablet' version with phone caps) Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30"
  52. self.USER_AGENT2 = "Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20150101 Firefox/44.0 (Chrome)"
  53. self.HEADER = {'User-Agent': self.USER_AGENT, 'Accept': 'text/html'}
  54. self.defaultParams = {'use_cookie': True, 'load_cookie': True, 'save_cookie': True, 'cookiefile': self.COOKIE_FILE}
  55. def _getFullUrl(self, url):
  56. mainUrl = self.MAIN_URL
  57. if 0 < len(url) and not url.startswith('http'):
  58. url = mainUrl + url
  59. if not mainUrl.startswith('https://'):
  60. url = url.replace('https://', 'http://')
  61. return url
  62. def listsTab(self, tab, cItem, type='dir'):
  63. printDBG("StreamComplet.listsTab")
  64. for item in tab:
  65. params = dict(cItem)
  66. params.update(item)
  67. params['name'] = 'category'
  68. if type == 'dir':
  69. self.addDir(params)
  70. else: self.addVideo(params)
  71. def listCategories(self, cItem, category):
  72. printDBG("StreamComplet.listCategories")
  73. sts, data = self.cm.getPage(self.MAIN_URL)
  74. if not sts: return
  75. data = self.cm.ph.getDataBeetwenMarkers(data, '<ul id="menu-menu" class="menu">', '</ul>', False)[1]
  76. data = re.compile('<a href="([^"]+?)"[^>]*?>([^<]+?)<').findall(data)
  77. for item in data:
  78. params = dict(cItem)
  79. params.update({'category':category, 'title':item[1].strip(), 'url':self._getFullUrl(item[0])})
  80. self.addDir(params)
  81. def listItems(self, cItem):
  82. printDBG("StreamComplet.listItems")
  83. tmp = cItem['url'].split('?')
  84. url = tmp[0]
  85. if len(tmp) > 1:
  86. arg = tmp[1]
  87. else: arg = ''
  88. page = cItem.get('page', 1)
  89. if page > 1:
  90. url += 'page/%s/' % page
  91. if '' != arg:
  92. url += '?' + arg
  93. sts, data = self.cm.getPage(url)
  94. if not sts: return
  95. nextPage = False
  96. if ('/page/%s/' % (page+1)) in data:
  97. nextPage = True
  98. m1 = '<div class="moviefilm">'
  99. data = self.cm.ph.getDataBeetwenMarkers(data, m1, '<div class="filmborder">', False)[1]
  100. data = data.split(m1)
  101. for item in data:
  102. params = dict(cItem)
  103. params = dict(cItem)
  104. url = self.cm.ph.getSearchGroups(item, 'href="([^"]+?)"')[0]
  105. title = self.cm.ph.getSearchGroups(item, 'alt="([^"]+?)"')[0]
  106. title = self.cleanHtmlStr( title )
  107. if title == '': continue
  108. icon = self.cm.ph.getSearchGroups(item, 'src="([^"]+?)"')[0]
  109. desc = self.cleanHtmlStr( item )
  110. params.update({'title':title, 'icon':self._getFullUrl(icon), 'desc':desc, 'url':self._getFullUrl(url)})
  111. self.addVideo(params)
  112. if nextPage:
  113. params = dict(cItem)
  114. params.update({'title':_('Next page'), 'page':cItem.get('page', 1)+1})
  115. self.addDir(params)
  116. def listSearchResult(self, cItem, searchPattern, searchType):
  117. searchPattern = urllib.quote_plus(searchPattern)
  118. cItem = dict(cItem)
  119. cItem['url'] = self.SRCH_URL + searchPattern
  120. self.listItems(cItem)
  121. def getLinksForVideo(self, cItem):
  122. printDBG("StreamComplet.getLinksForVideo [%s]" % cItem)
  123. urlTab = []
  124. params = dict(self.defaultParams)
  125. header = dict(self.HEADER)
  126. header['Referer'] = cItem['url']
  127. params['header'] = header
  128. sts, data = self.cm.getPage(cItem['url'], params)
  129. if not sts: return []
  130. if 0:
  131. adminData = self.cm.ph.getDataBeetwenMarkers(data, 'jQuery.ajax({', '});', False)[1]
  132. adminUrl = self.cm.ph.getSearchGroups(adminData, "url:'([^']+?)'")[0]
  133. adminUrl += '?' + self.cm.ph.getSearchGroups(adminData, "data:'([^']+?)'")[0]
  134. header = dict(self.HEADER)
  135. header['X-Requested-With'] = 'XMLHttpRequest'
  136. header['Referer'] = cItem['url']
  137. paramsAdmin = dict(self.defaultParams)
  138. paramsAdmin['header'] = header
  139. sts, adminData = self.cm.getPage(adminUrl, paramsAdmin)
  140. printDBG('>>>>>>>>>>>>>> adminData[%s]' % adminData)
  141. projekktor_controlbar={"muted":false,"volume":0.5};
  142. mainPlayerUrl = self.cm.ph.getSearchGroups(data, 'src="(http[^"]+?player[^"]+?)"')[0]
  143. #printDBG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> playerUrl[%s]" % playerUrl)
  144. movieId = self.cm.ph.getSearchGroups(mainPlayerUrl+'/', 'f=([0-9]+?)/')[0]
  145. if movieId != '':
  146. playerUrl = 'http://ok.ru/video/' + movieId
  147. tmpParams = copy.deepcopy(params)
  148. tmpParams['header']['User-Agent'] = self.USER_AGENT2
  149. sts, data = self.cm.getPage(playerUrl, tmpParams)
  150. if not sts: return []
  151. try:
  152. tmp = clean_html(re.search(r'data-options=(?P<quote>["\'])(?P<player>{.+?%s.+?})(?P=quote)' % movieId, data).group('player'))
  153. tmp = byteify( json.loads( tmp ) )
  154. tmp = byteify( json.loads( tmp['flashvars']['metadata'] ) )
  155. for item in tmp['videos']:
  156. videoUrl = self.up.decorateUrl(item['url'], {'User-Agent':self.USER_AGENT2})
  157. urlTab.append({'name':item['name'], 'url':videoUrl, 'need_resolve':0})
  158. except:
  159. printExc()
  160. playerUrl = 'http://m.ok.ru/video/' + movieId
  161. tmpParams['header']['User-Agent'] = self.USER_AGENT
  162. sts, data = self.cm.getPage(playerUrl, tmpParams)
  163. if not sts: return []
  164. videoUrl = self.cm.ph.getSearchGroups(data, 'href="(http[^"]+?moviePlaybackRedirect[^"]+?)"')[0].replace('&amp;', '&')
  165. if videoUrl.startswith('http'):
  166. videoUrl = self.up.decorateUrl(videoUrl, {'User-Agent':self.USER_AGENT})
  167. urlTab.insert(0, {'name':'default', 'url':videoUrl, 'need_resolve':0})
  168. return urlTab
  169. playerUrl = mainPlayerUrl.replace('&#038;', '&')
  170. sts, data = self.cm.getPage(playerUrl, params)
  171. if not sts: return []
  172. printDBG(data)
  173. videoUrl = self.cm.ph.getSearchGroups(data, """src:[^'^"]+?['"]([^'^"]+?)['"]""")[0]
  174. if videoUrl != '' and videoUrl != 'vimplevideo.mp4':
  175. videoUrl = 'http://media.vimple.me/playeryw.swf/' + videoUrl
  176. videoUrl = self.up.decorateUrl(videoUrl, {'User-Agent':self.USER_AGENT})
  177. return [{'name':'vimeo.me', 'url':videoUrl, 'need_resolve':0}]
  178. newPlayerUrl = self.cm.ph.getSearchGroups(data, '''["'](http[^"^']+?embed_player.php[^"^']+?)["']''')[0]
  179. if 'http%3A%2F%2F' in newPlayerUrl:
  180. newPlayerUrl = urllib.unquote(newPlayerUrl)
  181. for item in [cItem['url'], playerUrl, newPlayerUrl]:
  182. url = self.up.decorateUrl(item, {'Referer':cItem['url']})
  183. tmp = self.up.getVideoLinkExt(url)
  184. for item in tmp:
  185. item['need_resolve'] = 0
  186. urlTab.append(item)
  187. return urlTab
  188. def getFavouriteData(self, cItem):
  189. return cItem['url']
  190. def getLinksForFavourite(self, fav_data):
  191. return self.getLinksForVideo({'url':fav_data})
  192. def handleService(self, index, refresh = 0, searchPattern = '', searchType = ''):
  193. printDBG('handleService start')
  194. CBaseHostClass.handleService(self, index, refresh, searchPattern, searchType)
  195. name = self.currItem.get("name", '')
  196. category = self.currItem.get("category", '')
  197. printDBG( "handleService: |||||||||||||||||||||||||||||||||||| name[%s], category[%s] " % (name, category) )
  198. self.currList = []
  199. #MAIN MENU
  200. if name == None:
  201. self.listsTab(self.MAIN_CAT_TAB, {'name':'category'})
  202. elif category == 'categories':
  203. self.listCategories(self.currItem, 'items')
  204. #ITEMS
  205. elif category == 'items':
  206. self.listItems(self.currItem)
  207. #SEARCH
  208. elif category in ["search", "search_next_page"]:
  209. cItem = dict(self.currItem)
  210. cItem.update({'search_item':False, 'name':'category'})
  211. self.listSearchResult(cItem, searchPattern, searchType)
  212. #HISTORIA SEARCH
  213. elif category == "search_history":
  214. self.listsHistory({'name':'history', 'category': 'search'}, 'desc', _("Type: "))
  215. else:
  216. printExc()
  217. CBaseHostClass.endHandleService(self, index, refresh)
  218. class IPTVHost(CHostBase):
  219. def __init__(self):
  220. CHostBase.__init__(self, StreamComplet(), True, [CDisplayListItem.TYPE_VIDEO, CDisplayListItem.TYPE_AUDIO])
  221. def getLogoPath(self):
  222. return RetHost(RetHost.OK, value = [GetLogoDir('streamcompletlogo.png')])
  223. def getLinksForVideo(self, Index = 0, selItem = None):
  224. retCode = RetHost.ERROR
  225. retlist = []
  226. if not self.isValidIndex(Index): return RetHost(retCode, value=retlist)
  227. urlList = self.host.getLinksForVideo(self.host.currList[Index])
  228. for item in urlList:
  229. retlist.append(CUrlItem(item["name"], item["url"], item['need_resolve']))
  230. return RetHost(RetHost.OK, value = retlist)
  231. # end getLinksForVideo
  232. def converItem(self, cItem):
  233. hostList = []
  234. searchTypesOptions = [] # ustawione alfabetycznie
  235. hostLinks = []
  236. type = CDisplayListItem.TYPE_UNKNOWN
  237. possibleTypesOfSearch = None
  238. if 'category' == cItem['type']:
  239. if cItem.get('search_item', False):
  240. type = CDisplayListItem.TYPE_SEARCH
  241. possibleTypesOfSearch = searchTypesOptions
  242. else:
  243. type = CDisplayListItem.TYPE_CATEGORY
  244. elif cItem['type'] == 'video':
  245. type = CDisplayListItem.TYPE_VIDEO
  246. elif 'more' == cItem['type']:
  247. type = CDisplayListItem.TYPE_MORE
  248. elif 'audio' == cItem['type']:
  249. type = CDisplayListItem.TYPE_AUDIO
  250. if type in [CDisplayListItem.TYPE_AUDIO, CDisplayListItem.TYPE_VIDEO]:
  251. url = cItem.get('url', '')
  252. if '' != url:
  253. hostLinks.append(CUrlItem("Link", url, 1))
  254. title = cItem.get('title', '')
  255. description = cItem.get('desc', '')
  256. icon = cItem.get('icon', '')
  257. return CDisplayListItem(name = title,
  258. description = description,
  259. type = type,
  260. urlItems = hostLinks,
  261. urlSeparateRequest = 1,
  262. iconimage = icon,
  263. possibleTypesOfSearch = possibleTypesOfSearch)
  264. # end converItem
  265. def getSearchItemInx(self):
  266. try:
  267. list = self.host.getCurrList()
  268. for i in range( len(list) ):
  269. if list[i]['category'] == 'search':
  270. return i
  271. except:
  272. printDBG('getSearchItemInx EXCEPTION')
  273. return -1
  274. def setSearchPattern(self):
  275. try:
  276. list = self.host.getCurrList()
  277. if 'history' == list[self.currIndex]['name']:
  278. pattern = list[self.currIndex]['title']
  279. search_type = list[self.currIndex]['search_type']
  280. self.host.history.addHistoryItem( pattern, search_type)
  281. self.searchPattern = pattern
  282. self.searchType = search_type
  283. except:
  284. printDBG('setSearchPattern EXCEPTION')
  285. self.searchPattern = ''
  286. self.searchType = ''
  287. return