PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/plugin.video.kino-live.org/default.py

http://seppius-xbmc-repo.googlecode.com/
Python | 405 lines | 381 code | 5 blank | 19 comment | 2 complexity | a764cfc009800dfbfb641142304886da MD5 | raw file
Possible License(s): GPL-3.0, AGPL-1.0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Writer (c) 23/06/2011, Khrysev D.A., E-mail: x86demon@gmail.com
  5. #
  6. # This Program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2, or (at your option)
  9. # any later version.
  10. #
  11. # This Program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; see the file COPYING. If not, write to
  18. # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19. # http://www.gnu.org/licenses/gpl.html
  20. import urllib
  21. import urllib2
  22. import re
  23. import sys
  24. import os
  25. import cookielib
  26. import xbmcplugin
  27. import xbmcgui
  28. import xbmcaddon
  29. import xbmc
  30. from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
  31. import socket
  32. socket.setdefaulttimeout(50)
  33. icon = xbmc.translatePath(os.path.join(os.getcwd().replace(';', ''), 'icon.png'))
  34. siteUrl = 'kino-live.org'
  35. httpSiteUrl = 'http://' + siteUrl
  36. __settings__ = xbmcaddon.Addon(id='plugin.video.kino-live.org')
  37. __addondir__ = xbmc.translatePath(__settings__.getAddonInfo('profile'))
  38. if os.path.exists(__addondir__) == False:
  39. os.mkdir(__addondir__)
  40. cookiepath = os.path.join(__addondir__, 'plugin.video.kino-live.org.lwp')
  41. h = int(sys.argv[1])
  42. def construct_request(params):
  43. return '%s?%s' % (sys.argv[0], urllib.urlencode(params))
  44. def htmlEntitiesDecode(string):
  45. return BeautifulStoneSoup(string, convertEntities=BeautifulStoneSoup.HTML_ENTITIES).contents[0]
  46. def showMessage(heading, message, times=3000):
  47. xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s, "%s")' % (heading, message, times, icon))
  48. headers = {
  49. 'User-Agent': 'Opera/9.80 (X11; Linux i686; U; ru) Presto/2.7.62 Version/11.00',
  50. 'Accept': ' text/html, application/xml, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*',
  51. 'Accept-Language': 'ru-RU,ru;q=0.9,en;q=0.8',
  52. 'Accept-Charset': 'utf-8, utf-16, *;q=0.1',
  53. 'Accept-Encoding': 'identity, *;q=0'
  54. }
  55. def GET(url, referer, post_params=None):
  56. headers['Referer'] = referer
  57. if post_params != None:
  58. post_params = urllib.urlencode(post_params)
  59. headers['Content-Type'] = 'application/x-www-form-urlencoded'
  60. elif headers.has_key('Content-Type'):
  61. del headers['Content-Type']
  62. jar = cookielib.LWPCookieJar(cookiepath)
  63. if os.path.isfile(cookiepath):
  64. jar.load()
  65. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar))
  66. urllib2.install_opener(opener)
  67. req = urllib2.Request(url, post_params, headers)
  68. response = opener.open(req)
  69. the_page = response.read()
  70. response.close()
  71. jar.save()
  72. return the_page
  73. def logout(params):
  74. GET(httpSiteUrl + '/index.php?action=logout', httpSiteUrl)
  75. __settings__.setSetting("Login", "");
  76. __settings__.setSetting("Password", "")
  77. def check_login():
  78. login = __settings__.getSetting("Login")
  79. password = __settings__.getSetting("Password")
  80. if len(login) > 0:
  81. http = GET(httpSiteUrl, httpSiteUrl)
  82. if http == None: return None
  83. beautifulSoup = BeautifulSoup(http)
  84. userPanel = beautifulSoup.find('a', {"id": "loginlink"})
  85. if userPanel == None:
  86. os.remove(cookiepath)
  87. loginResponse = GET(httpSiteUrl, httpSiteUrl, {
  88. 'login': 'submit',
  89. 'login_name': login,
  90. 'login_password': password,
  91. 'submit': '????'
  92. })
  93. loginSoup = BeautifulSoup(loginResponse)
  94. userPanel = loginSoup.find('a', {"id": "loginlink"})
  95. if userPanel == None:
  96. showMessage('Login', 'Check login and password', 3000)
  97. else:
  98. return userPanel.text.encode('utf-8', 'cp1251')
  99. else:
  100. return userPanel.text.encode('utf-8', 'cp1251')
  101. return None
  102. def mainScreen(params):
  103. login = check_login()
  104. if login != None:
  105. li = xbmcgui.ListItem('[???????? %s]' % login.replace('??????, ', ''))
  106. uri = construct_request({
  107. 'href': httpSiteUrl + '/favorites/',
  108. 'mode': 'readCategory'
  109. })
  110. xbmcplugin.addDirectoryItem(h, uri, li, True)
  111. li = xbmcgui.ListItem('[?????????]')
  112. uri = construct_request({
  113. 'href': httpSiteUrl,
  114. 'mode': 'getCategories'
  115. })
  116. xbmcplugin.addDirectoryItem(h, uri, li, True)
  117. li = xbmcgui.ListItem('[?? ?????]')
  118. uri = construct_request({
  119. 'mode': 'getTags'
  120. })
  121. xbmcplugin.addDirectoryItem(h, uri, li, True)
  122. li = xbmcgui.ListItem('[?????]')
  123. uri = construct_request({
  124. 'mode': 'runSearch'
  125. })
  126. xbmcplugin.addDirectoryItem(h, uri, li, True)
  127. readCategory({
  128. 'href': httpSiteUrl + '/lastnews/'
  129. });
  130. def readCategory(params, postParams=None):
  131. categoryUrl = urllib.unquote_plus(params['href'])
  132. http = GET(categoryUrl, httpSiteUrl, postParams)
  133. if http == None: return False
  134. beautifulSoup = BeautifulSoup(http)
  135. content = beautifulSoup.find('div', attrs={'id': 'dle-content'})
  136. dataRows = content.findAll('div', 'tezt')
  137. if len(dataRows) == 0:
  138. showMessage('??????', '???????? ????????', 3000)
  139. return False
  140. else:
  141. for data in dataRows:
  142. img = data.find('img')
  143. cover = None
  144. if img != None:
  145. cover = img['src']
  146. if cover.find("://") < 0:
  147. cover = httpSiteUrl + cover
  148. titleContainer = data.findPrevious('div', 'ah1')
  149. if titleContainer == None:
  150. titleContainer = data.findPrevious('h1')
  151. href = titleContainer.find('a')
  152. if href is None:
  153. titleText = titleContainer.text
  154. href = data.findNextSibling('div', 'more').find('a')
  155. else:
  156. titleText = href.text
  157. titleText = titleText.encode('utf-8', 'cp1251')
  158. link = data.findNextSibling('div', 'more').find('a')
  159. href = link['href']
  160. plotEl = data.find('div', id=re.compile('news-id-\d+'))
  161. itemInfo = []
  162. for plotItemRow in plotEl.contents:
  163. try:
  164. itemInfo.append(plotItemRow.encode('utf-8', 'cp1251'))
  165. except:
  166. pass
  167. plot = "\n".join(itemInfo[2:])
  168. li = xbmcgui.ListItem(titleText, iconImage=cover, thumbnailImage=cover)
  169. li.setProperty('IsPlayable', 'false')
  170. li.setInfo(type='video', infoLabels={'title': titleText, 'plot': plot})
  171. uri = construct_request({
  172. 'mode': 'getFiles',
  173. 'cover': cover,
  174. 'title': titleText,
  175. 'href': href
  176. })
  177. xbmcplugin.addDirectoryItem(h, uri, li, True)
  178. #TODO: Find a way to use pager in search results
  179. if postParams == None:
  180. try:
  181. pager = content.find('div', 'pages')
  182. pages = pager.findAll('a')
  183. nextPageLink = pages[len(pages) - 1]
  184. if nextPageLink != None:
  185. li = xbmcgui.ListItem('[NEXT PAGE >]')
  186. li.setProperty('IsPlayable', 'false')
  187. uri = construct_request({
  188. 'href': nextPageLink['href'],
  189. 'mode': 'readCategory'
  190. })
  191. xbmcplugin.addDirectoryItem(h, uri, li, True)
  192. except:
  193. pass
  194. xbmcplugin.endOfDirectory(h)
  195. def getCategories(params):
  196. categoryUrl = urllib.unquote_plus(params['href'])
  197. http = GET(categoryUrl, httpSiteUrl)
  198. if http == None: return False
  199. beautifulSoup = BeautifulSoup(http)
  200. categoryContainer = beautifulSoup.find('ul', 'cats')
  201. categories = categoryContainer.findAll('a')
  202. if len(categories) == 0:
  203. showMessage('??????', '???????? ????????', 3000)
  204. return False
  205. else:
  206. for link in categories:
  207. if link != None:
  208. title = link.string
  209. if title == None:
  210. title = link.find("h2").string
  211. href = link['href']
  212. if href.find("://") < 0:
  213. href = httpSiteUrl + href
  214. li = xbmcgui.ListItem('[%s]' % title)
  215. li.setProperty('IsPlayable', 'false')
  216. uri = construct_request({
  217. 'href': href,
  218. 'mode': 'readCategory'
  219. })
  220. xbmcplugin.addDirectoryItem(h, uri, li, True)
  221. xbmcplugin.endOfDirectory(h)
  222. def getTags(params):
  223. http = GET(httpSiteUrl + '/tags/', httpSiteUrl)
  224. if http == None: return False
  225. beautifulSoup = BeautifulSoup(http)
  226. tagsContainer = beautifulSoup.find('td', 'news')
  227. tags = tagsContainer.findAll('a')
  228. if len(tags) == 0:
  229. showMessage('??????', '???????? ????????', 3000)
  230. return False
  231. else:
  232. tags.reverse()
  233. for link in tags:
  234. if link != None:
  235. title = link.string
  236. href = link['href']
  237. if href.find("://") < 0:
  238. href = httpSiteUrl + href
  239. li = xbmcgui.ListItem('[%s]' % title)
  240. li.setProperty('IsPlayable', 'false')
  241. uri = construct_request({
  242. 'href': href,
  243. 'mode': 'readCategory'
  244. })
  245. xbmcplugin.addDirectoryItem(h, uri, li, True)
  246. xbmcplugin.endOfDirectory(h)
  247. def getFiles(params):
  248. folderUrl = urllib.unquote_plus(params['href'])
  249. cover = urllib.unquote_plus(params['cover'])
  250. itemName = urllib.unquote_plus(params['title'])
  251. http = GET(folderUrl, httpSiteUrl)
  252. if http == None: return False
  253. playListRegexp = re.compile('pl=([^"]+)', re.IGNORECASE + re.DOTALL + re.MULTILINE)
  254. playlist = playListRegexp.findall(http)
  255. if len(playlist) > 0:
  256. commentRegexp = re.compile('"comment":"\s*([^"]+)', re.IGNORECASE + re.DOTALL + re.MULTILINE)
  257. fileRegexp = re.compile('"file":"\s*([^"]+)', re.IGNORECASE + re.DOTALL + re.MULTILINE)
  258. playlistJson = GET(playlist[0], folderUrl)
  259. comments = commentRegexp.findall(playlistJson)
  260. files = fileRegexp.findall(playlistJson)
  261. i = 0
  262. for comment in comments:
  263. li = xbmcgui.ListItem(comment, iconImage=cover, thumbnailImage=cover)
  264. li.setProperty('IsPlayable', 'true')
  265. li.setInfo(type='video', infoLabels={'title': itemName + ' - ' + comment})
  266. uri = construct_request({
  267. 'mode': 'play',
  268. 'file': files[i],
  269. 'referer': folderUrl
  270. })
  271. xbmcplugin.addDirectoryItem(h, uri, li)
  272. i = i + 1
  273. xbmcplugin.endOfDirectory(h)
  274. else:
  275. fileRegexp = re.compile('file=([^"]+)', re.IGNORECASE + re.DOTALL + re.MULTILINE)
  276. files = fileRegexp.findall(http)
  277. li = xbmcgui.ListItem(itemName, iconImage=cover, thumbnailImage=cover)
  278. li.setProperty('IsPlayable', 'true')
  279. li.setInfo(type='video', infoLabels={'title': itemName})
  280. xbmc.Player().play(getFile(files[0]), li)
  281. def runSearch(params):
  282. skbd = xbmc.Keyboard()
  283. skbd.setHeading('??? ?????')
  284. skbd.doModal()
  285. if skbd.isConfirmed():
  286. SearchStr = skbd.getText()
  287. params = {
  288. 'href': httpSiteUrl
  289. }
  290. postParams = {
  291. 'do': 'search',
  292. 'subaction': 'search',
  293. 'story': SearchStr.decode('utf-8').encode('cp1251')
  294. }
  295. return readCategory(params, postParams)
  296. def play(params):
  297. referer = urllib.unquote_plus(params['referer'])
  298. file = urllib.unquote_plus(params['file'])
  299. headers['Referer'] = referer
  300. i = xbmcgui.ListItem(path=getFile(file))
  301. xbmcplugin.setResolvedUrl(h, True, i)
  302. def getFile(files):
  303. files = files.split(' or ')
  304. file = files[0]
  305. if len(files) == 2:
  306. fileTest = urllib.urlopen(files[1])
  307. fileUrl = fileTest.geturl()
  308. if fileUrl:
  309. file = fileUrl
  310. return file
  311. def get_params(paramstring):
  312. param = []
  313. if len(paramstring) >= 2:
  314. params = paramstring
  315. cleanedparams = params.replace('?', '')
  316. if (params[len(params) - 1] == '/'):
  317. params = params[0:len(params) - 2]
  318. pairsofparams = cleanedparams.split('&')
  319. param = {}
  320. for i in range(len(pairsofparams)):
  321. splitparams = {}
  322. splitparams = pairsofparams[i].split('=')
  323. if (len(splitparams)) == 2:
  324. param[splitparams[0]] = splitparams[1]
  325. return param
  326. params = get_params(sys.argv[2])
  327. mode = None
  328. func = None
  329. try:
  330. mode = urllib.unquote_plus(params['mode'])
  331. except:
  332. mainScreen(params)
  333. if (mode != None):
  334. try:
  335. func = globals()[mode]
  336. except:
  337. pass
  338. if func: func(params)