Enigma2 plugin to to play various online streams (mostly Latvian).

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. #!/usr/bin/env python
  2. # coding=utf8
  3. #
  4. # This file is part of PlayStream - enigma2 plugin to play video streams from various sources
  5. # Copyright (c) 2016 ivars777 (ivars777@gmail.com)
  6. # Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
  7. #
  8. import sys, os, os.path, re, sys
  9. import urllib,urllib2
  10. from xml.sax.saxutils import unescape,escape
  11. from urllib import quote, unquote
  12. import datetime
  13. import HTMLParser
  14. import json
  15. import ConfigParser
  16. import datetime
  17. API_URL = 'https://m.lattelecom.tv/'
  18. user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
  19. headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
  20. h = HTMLParser.HTMLParser()
  21. class Source(object):
  22. def __init__(self):
  23. self.name = "ltc"
  24. self.mobtv_cache = ""
  25. self.session_id = ""
  26. cur_directory = os.path.dirname(os.path.abspath(__file__))
  27. config_file = os.path.join(cur_directory,"ltc.cfg")
  28. config = ConfigParser.ConfigParser()
  29. if os.path.exists(config_file):
  30. config.read(config_file)
  31. self.user = config.get("ltc","user")
  32. self.password = config.get("ltc","password")
  33. else:
  34. self.user = ""
  35. self.password = ""
  36. #self.login()
  37. self.headers = headers2dict("""
  38. Host: m.lattelecom.tv
  39. User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile Safari/600.1.4
  40. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  41. Accept-Language: en-US,en;q=0.5
  42. Connection: keep-alive
  43. """)
  44. self.headers2 = headers2dict("""
  45. Host: www.lattelecom.tv
  46. Accept: application/json, text/javascript, */*; q=0.01
  47. X-Requested-With: XMLHttpRequest
  48. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
  49. Referer: https://www.lattelecom.tv/videonoma/360tv
  50. """)
  51. def get_content(self, data):
  52. print "[ltc] get_content:", data
  53. if "::" in data:
  54. data = data.split("::")[1]
  55. path = data.split("?")[0]
  56. clist = path.split("/")[0]
  57. params = data[data.find("?"):] if "?" in data else ""
  58. qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
  59. #lang = qs["lang"] if "lang" in qs else self.country
  60. content=[]
  61. content.append(("..return", "back","","Return back"))
  62. if clist=="home":
  63. content.extend([
  64. ("Live streams", "ltc::tiesraide","","TV live streams"),
  65. ("Archive", "ltc::arhivs","","TV live archive"),
  66. ("Video", "ltc::videonoma","","Video on demand"),
  67. ])
  68. return content
  69. ### Tiešraides kanānālu saraksts
  70. elif data=="tiesraide":
  71. if not self.check_logedin():
  72. self.login() # citādi nerāda TV3, LNT, TV6
  73. r= self.call(data)
  74. for item in re.findall(r'(?i)/(tiesraide/[^"]*?)"><div title="([^"]*?)" class="channel-placeholder" style="width: 131px; height: 131px; background-image:url\(/(.+?\.png)\).+?rinfo">([^<]+)</span><span class="info_time">([^<]+)</span>', r):
  75. ch = item[0]
  76. title = item[1]
  77. data2 = item[0]
  78. img = "https://m.lattelecom.tv/"+item[2].replace("105x105","150x150")
  79. desc = "%s\n%s"%(item[3],item[4])
  80. content.append((title,self.name+"::"+data2,img,desc))
  81. return content
  82. ### Kanāla tiesraide
  83. elif clist == "tiesraide" and "/" in data:
  84. ch = data.split("/")[1]
  85. if not self.check_logedin():
  86. if not self.login():
  87. content=("Can not login\nPlease check lattelecom.tv username/password in\n/usr/lib/enigma2/python/Plugins/Extensions/sources/ltc.cfg file","","","No stream found. Please check lattelecom.tv username/password in sources/ltc.cfg file ")
  88. return content
  89. r = self.call("tiesraide")
  90. m = re.search('/%s"><div title="([^"]*?)".+?rinfo">(.+?)</span><span class="info_time">(.+?)</span>'%data, r, re.IGNORECASE)
  91. if m:
  92. title = "%s - %s (%s)"%(m.group(1),m.group(2),m.group(3))
  93. else:
  94. title = ch.upper()
  95. desc = title
  96. data2 = self.get_tv_url(ch)
  97. if not data2:
  98. content=("No stream found for '%s'"%data,"","","No stream found")
  99. return content
  100. content = (title,data2,"",desc)
  101. return content
  102. ### Arhīva kanānālu saraksts
  103. elif data=="arhivs":
  104. r= self.call(data)
  105. for item in re.findall(r'(?i)/(arhivs/[^"]+)".+?<div title="([^"]*?)".+?background-image:url\(/(.+?\.png)\)', r):
  106. ch = item[0]
  107. title = item[1]
  108. data2 = item[0]
  109. img = "https://m.lattelecom.tv/"+item[2].replace("105x105","150x150")
  110. desc = "%s 7 dienu arhīvs"%title
  111. content.append((title,self.name+"::"+data2,img,desc))
  112. return content
  113. ### Arhīva datumi
  114. elif clist=="arhivs" and len(data.split("/"))==2:
  115. ch = data.split("/")[1]
  116. r= self.call(data)
  117. m = re.search('class="spac no_select">([^<]+)</span>', r, re.IGNORECASE)
  118. if m:
  119. ch_name = m.group(1)
  120. else:
  121. ch_name = ""
  122. today = datetime.date.today()
  123. for i in range(7):
  124. date = today-datetime.timedelta(i)
  125. title = ch_name + " - " + date.strftime("%d.%m.%Y")
  126. data2 = "%s/%s"%(data,date.strftime("%Y-%m-%d"))
  127. img = ""
  128. desc = title
  129. content.append((title,self.name+"::"+data2,img,desc))
  130. return content
  131. ### Arhīva dienas raidijumi
  132. elif clist=="arhivs" and len(data.split("/"))==3:
  133. ch = data.split("/")[1]
  134. date = data.split("/")[2]
  135. r= self.call(data)
  136. m = re.search('class="spac no_select">([^<]+)</span>', r, re.IGNORECASE)
  137. if m:
  138. ch_name = m.group(1)
  139. else:
  140. ch_name = ""
  141. for item in re.findall('(?i)href="/([^"]+?)" id="" class="archive_programm_a"><div class="archive_programm "><div class="chanel_time"><span>([^<]+)</span></div><div class="archive_programm_one"><span>([^<]+)', r):
  142. title = "%s - %s"%(item[1],item[2])
  143. data2 = item[0]
  144. img = ""
  145. desc = "%s (%s)\n%s"%(ch_name,date,title)
  146. content.append((title,self.name+"::"+data2,img,desc))
  147. return content
  148. ### Arhīva video
  149. elif clist=="arhivs" and len(data.split("/"))==4:
  150. ch = data.split("/")[1]
  151. video_id=data.split("/")[-1]
  152. if not self.check_logedin():
  153. if not self.login():
  154. content=("Can not login\nPlease check lattelecom.tv username/password in\n/usr/lib/enigma2/python/Plugins/Extensions/sources/ltc.cfg file","","","No stream found. Please check lattelecom.tv username/password in sources/ltc.cfg file ")
  155. return content
  156. data2 = self.get_arhivs_url(video_id)
  157. if not data2:
  158. content=("No stream found for '%s'"%data,"","","No stream found")
  159. return content
  160. r = self.call(data)
  161. m = re.search('<div class="name">([^<]+)</div><div class="channell">([^<]+)</div><div class="bcastinfo"><span>([^<]+)</span><span>([^<]+)</span><span>([^<]+)<', r, re.IGNORECASE)
  162. if m:
  163. title = "%s (%s %s %s %s)"%(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5))
  164. else:
  165. title = ""
  166. desc = title
  167. content = (title,data2,"",desc)
  168. return content
  169. ### Videonoma galvenā
  170. elif data=="videonoma":
  171. content.extend([
  172. ("Filmas - jaunākās", "ltc::videonoma?page=0&genre=all_movies&sorts=laiks&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/media/features/2013-12-17/aa3b_videonoma_dropdown_filmas.png","Jaunākās filmas"),
  173. ("Filmas - pēc nosaukuma", "ltc::videonoma?page=0&genre=all_movies&sorts=title&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/media/features/2013-12-17/aa3b_videonoma_dropdown_filmas.png","Filmas pēc nosaukuma"),
  174. ("Filmas - latviski", 'ltc::videonoma?page=0&genre=all_movies&sorts=title&cnt=40&clear=true&filter={"valoda":["lv"]}',"https://www.lattelecom.tv/media/features/2013-12-17/aa3b_videonoma_dropdown_filmas.png","Filmas latviešu valodā"),
  175. ("Filmas - pēc reitinga", "ltc::videonoma?page=0&genre=all_movies&sorts=imbd&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/media/features/2013-12-17/aa3b_videonoma_dropdown_filmas.png","Filmas pēc IMBD reitinga"),
  176. ("Bērniem - jaunākās", "ltc::videonoma?page=0&genre=3&sorts=laiks&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_berniem.png","Jaunākie bernu video"),
  177. ("Bērniem - pēc nosaukuma", "ltc::videonoma?page=0&genre=3&sorts=title&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_berniem.png","Bērnu video pēc nosaukuma"),
  178. ("Bērniem - latviski", 'ltc::videonoma?page=0&genre=3&sorts=title&cnt=40&clear=true&filter={"valoda":[\"lv\"]}',"https://www.lattelecom.tv/images/redesign/videonoma_dropdown_berniem.png","Bērnu video latviski"),
  179. ("Bērniem - pēc reitinga", "ltc::videonoma?page=0&genre=3&sorts=imbd&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_berniem.png","Bērnu video pēc IMBD reitinga"),
  180. ("Sērijas - jaunākās", "ltc::videonoma?page=0&genre=27&sorts=laiks&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_raidijumi.png","Jaunākās sērijas"),
  181. ("Sērijas - animācijas", "ltc::videonoma?page=0&genre=27&sorts=title&cnt=40&clear=true&filter={\"zanrs\":[\"201\"]}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_raidijumi.png","Animācijas serijas"),
  182. ("Sērijas - pēc nosaukuma", "ltc::videonoma?page=0&genre=27&sorts=title&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_raidijumi.png","Sērijas pēc pēc nosaukuma"),
  183. ("Sērijas - latviski", 'ltc::videonoma?page=0&genre=27&sorts=title&cnt=40&clear=true&filter={"valoda":["lv"]}',"https://www.lattelecom.tv/images/redesign/videonoma_dropdown_raidijumi.png","Sērijas latviski"),
  184. ("Koncerti - jaunākie", "ltc::videonoma?page=0&genre=19&sorts=laiks&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_koncerti.png","Jaunākie koncerti"),
  185. ("Koncerti - pēc nosaukuma", "ltc::videonoma?page=0&genre=19&sorts=title&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_koncerti.png","Koncerti pēc pēc nosaukuma"),
  186. ])
  187. return content
  188. ### Videonomas saraksti
  189. elif path == "videonoma":
  190. url = "https://www.lattelecom.tv/movies-snippet.json"+params
  191. r = self._http_request(url,self.headers2)
  192. if not r:
  193. return content
  194. js = json.loads(r,"utf8")
  195. if not r:
  196. return content
  197. for item in js["movies"]:
  198. title = item["title"].encode("utf8")
  199. data2 = item["url"][1:].encode("utf8")
  200. if data2[-1]=="/": data2=data2[:-1]
  201. if "/raidijumi/" in data2:
  202. data2 += "?series"
  203. img = "https://www.lattelecom.tv"+item["image"].encode("utf8")
  204. desc = "%s\n%s"%(title,item["genre"].encode("utf8"))
  205. content.append((title,self.name+"::"+data2,img,desc))
  206. m = re.search("page=(\d+)",data)
  207. if m:
  208. page = int(m.group(1))
  209. data2 = re.sub("page=\d+","page=%s"%(page+1),data)
  210. content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
  211. return content
  212. ### Sērijas
  213. elif clist=="videonoma" and params=="?series":
  214. url = "https://www.lattelecom.tv/"+path
  215. r = self._http_request(url,self.headers2)
  216. if not r:
  217. return content
  218. m = re.search('<div class="movie_details"><div class="movie_titles"><div class="en">([^<]+?)</div>', r, re.DOTALL | re.IGNORECASE)
  219. if m:
  220. raidijums = m.group(1) + " - "
  221. else:
  222. raidijums = ""
  223. for item in re.findall('(?si)<a class="elementxxx forward-link[^"]*" href="([^"]+)">.*?<img src="([^"]+)" class="img"><span class="titlez">([^<]+)</span><span class="epizode_number">([^<]+)</span>', r):
  224. title = "%s%s (%s)"%(raidijums,item[2],item[3])
  225. data2 = item[0][1:]
  226. img = "https://www.lattelecom.tv"+item[1]
  227. desc = title
  228. content.append((title,self.name+"::"+data2,img,desc))
  229. return content
  230. ### Videonomas video
  231. elif clist=="videonoma" and len(data.split("/"))>1:
  232. ch = data.split("/")[1]
  233. video_id=data[data.find("/")+1:]
  234. #video_id=data.split("/")[-1]
  235. if not self.check_logedin():
  236. if not self.login():
  237. content=("Can not login\nPlease check lattelecom.tv username/password in\n/usr/lib/enigma2/python/Plugins/Extensions/sources/ltc.cfg file","","","No stream found. Please check lattelecom.tv username/password in sources/ltc.cfg file ")
  238. return content
  239. data2 = self.get_noma_url(video_id)
  240. if not data2:
  241. content=("No stream found for '%s'"%data,"","","No stream found")
  242. return content
  243. r = self.call(data)
  244. m = re.search('<span class="movie">([^<]+)<', r, re.IGNORECASE)
  245. if m:
  246. title = m.group(1)
  247. else:
  248. title = ""
  249. desc = title
  250. content = (title,data2,"",desc)
  251. return content
  252. else:
  253. return content
  254. def is_video(self,data):
  255. if "::" in data:
  256. data = data.split("::")[1]
  257. cmd = data.split("/")
  258. if cmd[0] in ("tiesraide") and "/" in data:
  259. return True
  260. elif cmd[0]=="arhivs" and len(cmd)==4:
  261. return True
  262. elif cmd[0]=="videonoma" and len(cmd)==3 and not "?" in data:
  263. return True
  264. else:
  265. return False
  266. def call(self, data,headers=None):
  267. if not headers: headers = self.headers
  268. #if not lang: lang = self.country
  269. url = API_URL + data
  270. content = self._http_request(url,headers)
  271. return content
  272. def _http_request(self, url,headers=None):
  273. if not headers: headers = self.headers
  274. try:
  275. r = urllib2.Request(url, headers=headers)
  276. u = urllib2.urlopen(r)
  277. content = u.read()
  278. u.close()
  279. return content
  280. except Exception as ex:
  281. return None
  282. def login(self,user="",password=""):
  283. """Login in to site, create session cookies"""
  284. self.mobtv_cache = ""
  285. if not user: user=self.user
  286. if not password: password = self.password
  287. url0 = "https://m.lattelecom.tv"
  288. class NoRedirectHandler(urllib2.HTTPRedirectHandler):
  289. def http_error_302(self, req, fp, code, msg, headers):
  290. infourl = urllib.addinfourl(fp, headers, req.get_full_url())
  291. infourl.status = code
  292. infourl.code = code
  293. return infourl
  294. http_error_300 = http_error_302
  295. http_error_301 = http_error_302
  296. http_error_303 = http_error_302
  297. http_error_307 = http_error_302
  298. # Dabūjam sesijas id un url_gif, kas redirektējas uz auth_url
  299. headers = headers2dict("""
  300. Host: m.lattelecom.tv
  301. User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile Safari/600.1.4
  302. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  303. Accept-Language: en-US,en;q=0.5
  304. DNT: 1
  305. Connection: keep-alive
  306. """)
  307. response = urllib2.urlopen(urllib2.Request(url0+"/authorization", headers=headers))
  308. session_id = response.headers["set-cookie"].split(";")[0]
  309. html = response.read()
  310. url_gif = url0 + re.search('(/auth/\d+.gif)', html).group(1)
  311. # Dabūtjam auth_url
  312. headers = headers2dict("""
  313. Host: m.lattelecom.tv
  314. User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile Safari/600.1.4
  315. Accept: image/png,image/*;q=0.8,*/*;q=0.5
  316. Accept-Language: en-US,en;q=0.5
  317. Accept-Encoding: gzip, deflate
  318. DNT: 1
  319. Referer: https://m.lattelecom.tv/authorization
  320. Connection: keep-alive
  321. """)
  322. headers["Cookie"] = session_id
  323. urllib2.install_opener(urllib2.build_opener(NoRedirectHandler()))
  324. response = urllib2.urlopen(urllib2.Request(url_gif, headers=headers))
  325. if response.code == 302:
  326. url_auth = response.headers["location"]
  327. else:
  328. self.error = u"auth.gif nenostrādāja"
  329. #raise u"auth.gif nenostrādāja"
  330. return False
  331. # Pierakstāmies iekš auth.lattelecom.lv
  332. headers = headers2dict("""
  333. Host: auth.lattelecom.lv
  334. User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
  335. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  336. Accept-Language: en-US,en;q=0.5
  337. Accept-Encoding: gzip, deflate
  338. DNT: 1
  339. Referer: http://m.lattelecom.tv/authorization
  340. Connection: keep-alive
  341. """)
  342. response = urllib2.urlopen(urllib2.Request(url_auth, headers=headers))
  343. if not response.code == 302:
  344. self.error = u"pierakstīšanās auth.lattelecom.lv nenostrādāja"
  345. return False
  346. #raise "pierakstīšanās auth.lattelecom.lv nenostrādāja"
  347. # nolasām auth_gif
  348. ## headers = headers2dict("""
  349. ## Host: m.lattelecom.tv
  350. ## User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
  351. ## Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  352. ## Accept-Language: en-US,en;q=0.5
  353. ## Accept-Encoding: gzip, deflate
  354. ## DNT: 1
  355. ## Referer: http://m.lattelecom.tv/authorization
  356. ## """)
  357. ## headers["Cookie"] = session_id
  358. ## response = urllib2.urlopen(urllib2.Request(url_gif, headers=headers))
  359. ## if not response.code == 200:
  360. ## raise u"kļūda lasot auth_gif"
  361. # Mēģinam ielogoties
  362. headers = headers2dict("""
  363. Host: m.lattelecom.tv
  364. User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
  365. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  366. Accept-Language: en-US,en;q=0.5
  367. Accept-Encoding: deflate
  368. DNT: 1
  369. Referer: http://m.lattelecom.tv/authorization
  370. Connection: keep-alive
  371. Content-Type: application/x-www-form-urlencoded""")
  372. headers["Cookie"] = session_id
  373. data = "login=yes&email=%s&passw=%s"%(user,password)
  374. req = urllib2.Request(url0+"/authorization", data, headers)
  375. response = urllib2.urlopen(req)
  376. #with open("auth.htm","w") as f: f.write(response.read())
  377. if not response.code == 302:
  378. self.error = u"kļūda ielogojoties"
  379. #raise u"kļūda ielogojoties"
  380. return False
  381. mobtv = response.headers["set-cookie"].split(";")[0]
  382. if not mobtv.split("=")[0]=="mobtv_cache":
  383. #raise "nav mobtv cookie!"
  384. self.error = "nav mobtv cookie!"
  385. return False
  386. # atveram /account
  387. ## headers = headers2dict("""
  388. ## Host: m.lattelecom.tv
  389. ## User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
  390. ## Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  391. ## Accept-Language: en-US,en;q=0.5
  392. ## Accept-Encoding: deflate
  393. ## DNT: 1
  394. ## Referer: http://m.lattelecom.tv/authorization
  395. ## Connection: keep-alive """)
  396. ## headers["Cookie"] = "%s; %s"%(session_id,mobtv)
  397. ## response = urllib2.urlopen(urllib2.Request(url0+"/account", headers=headers))
  398. ## if not response.code == 302:
  399. ## raise u"kļūda atverot /account"
  400. # atveram /profils
  401. ## headers = headers2dict("""
  402. ## Host: m.lattelecom.tv
  403. ## User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
  404. ## Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  405. ## Accept-Language: en-US,en;q=0.5
  406. ## Accept-Encoding: deflate
  407. ## DNT: 1
  408. ## Referer: http://m.lattelecom.tv/authorization
  409. ## Connection: keep-alive
  410. ## """)
  411. ## headers["Cookie"] = "%s; %s"%(session_id,mobtv)
  412. ## response = urllib2.urlopen(urllib2.Request(url0+"/profils", headers=headers))
  413. ## if not response.code == 200:
  414. ## raise u"kļūda atverot /profils"
  415. ## with open("profils.htm","w") as f: f.write(response.read())
  416. self.mobtv_cache = mobtv
  417. self.session_id = session_id
  418. self.headers["Cookie"] = "%s; %s; MobBitr=1; "%(self.session_id,self.mobtv_cache)
  419. self.error = ""
  420. return True
  421. def check_logedin(self):
  422. if not self.mobtv_cache:
  423. return False
  424. else:
  425. #return True
  426. url = "https://m.lattelecom.tv/profils"
  427. headers = self.headers
  428. headers["Cookie"] = "%s; %s; MobBitr=1; "%(self.session_id,self.mobtv_cache)
  429. response = urllib2.urlopen(urllib2.Request(url, headers=self.headers))
  430. if response.code == 200:
  431. return True
  432. else:
  433. self.mobtv_cache = ""
  434. return False
  435. def is_logedin(self):
  436. if self.mobtv_cache:
  437. return True
  438. else:
  439. return False
  440. def get_tv_channels(self,):
  441. """Get tv channels list"""
  442. url = "https://m.lattelecom.tv/tiesraide"
  443. response = urllib2.urlopen(urllib2.Request(url, headers=self.headers))
  444. html = response.read()
  445. channels = re.findall(r'(?si)data-url="/tiesraide/(.*?)"><div title="(.*?)" class="channel-placeholder" style="width: 131px; height: 131px; background-image:url\(/media/imse/105x105s/channels/(.*?)\)', html)
  446. for i in range(len(channels)):
  447. channels[i]=[channels[i][0],channels[i][1],"https://m.lattelecom.tv/media/imse/100x100s/channels/"+channels[i][2]]
  448. return channels
  449. #----------------------------------------------------------------------
  450. def get_tv_url(self,video_id):
  451. """Get m3u8 url for given live tv channel"""
  452. url = "https://m.lattelecom.tv/tiesraide/%s"%video_id
  453. data = self.get_video_data("tiesraide/%s"%video_id)
  454. headers = self.headers
  455. headers["Cookie"] = "%s; %s; _hjIncludedInSample=0; MobBitr=1; MobRentBitr=%s; MobRentLang=%s;"%(self.session_id,self.mobtv_cache,data["quality"],data["language"])
  456. response = urllib2.urlopen(urllib2.Request(url, headers=headers))
  457. html = response.read()
  458. m3u8 = re.search('x-mpegURL" src="(.*?)"', html).group(1) if "x-mpegURL" in html else ""
  459. return unescape(m3u8)
  460. #----------------------------------------------------------------------
  461. def get_noma_url(self,video_id,quality="hq",language="lv"):
  462. """Get m3u8 url for given rental video"""
  463. video_id1,video_id2=video_id.split("/")
  464. data = self.get_video_data(video_id)
  465. url = "https://m.lattelecom.tv/free_origin?show_origin=1&type=4&video_url=%s&bitrate=%s&lng=%s"%(video_id2,data["quality"],data["language"])
  466. headers = self.headers
  467. headers["Cookie"] = "%s; %s; MobRentBitr=%s; MobBitr=1; MobRentLang=%s"%(self.session_id,self.mobtv_cache,quality,language)
  468. response = urllib2.urlopen(urllib2.Request(url, headers=headers))
  469. m3u8 = response.read()
  470. return unescape(m3u8)
  471. #----------------------------------------------------------------------
  472. def get_arhivs_url(self,video_id):
  473. """Get m3u8 url for given archive video"""
  474. #data = self.get_video_data("arhivs/%s"%video_id)
  475. url = "https://m.lattelecom.tv/free_origin?show_origin=1&type=arhivs&event_id=%s&bitrate=mhq"%(video_id) #,data["quality"])
  476. headers = self.headers
  477. headers["Cookie"] = "%s; %s; MobBitr=1; "%(self.session_id,self.mobtv_cache)
  478. response = urllib2.urlopen(urllib2.Request(url, headers=headers))
  479. m3u8 = response.read()
  480. return unescape(m3u8)
  481. def get_video_data(self,video_id):
  482. url = "https://www.lattelecom.tv/xmls/%s.xml"%video_id
  483. headers = self.headers2
  484. headers["Cookie"] = self.session_id
  485. #headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"
  486. response = urllib2.urlopen(urllib2.Request(url, headers=headers))
  487. r = response.read()
  488. data = {}
  489. data["server"] = re.findall("(?s)<origin>([^<]+)</origin>", r)[1]
  490. data["language"]=re.findall('(?s)<language code="([^"]+)">', r)
  491. data["language"]="lv" if "lv" in data["language"] else "ru" if "ru" in data["language"] else "en"
  492. data["qs"]=re.findall('(?s)<stream quality="([^"]+)">([^<]+)</stream>', r)
  493. data["qs"]=dict(data["qs"])
  494. qs = data["qs"].keys()
  495. data["quality"] = "hd" if "hd" in qs else "hq" if "hq" in qs else "mhq" if "mhq" in qs else "lq"
  496. data["mp4"] = data["qs"][data["quality"]]
  497. data["token"] = re.search("(?s)<auth_token>([^<]+)</auth_token>", r).group(1)
  498. data["resource_id"]=re.search("(?s)<resource_id>([^<]+)</resource_id>", r).group(1)
  499. data["hls]"] = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])
  500. return data
  501. if __name__ == "__main__":
  502. c = Source()
  503. c.login("ivars777","kaskade7")
  504. data = c.get_video_data("hd/hd_anonymous")
  505. #print data
  506. print data["hls"]
  507. if len(sys.argv)>1:
  508. data= sys.argv[1]
  509. else:
  510. data = "home"
  511. content = c.get_content(data)
  512. for item in content:
  513. print item
  514. #cat = api.get_categories(country)
  515. #chan = api.get_channels("lv")
  516. #prog = api.get_programs(channel=6400)
  517. #prog = api.get_programs(category=55)
  518. #seas = api.get_seasons(program=6453)
  519. #str = api.get_streams(660243)
  520. #res = api.get_videos(802)
  521. #formats = api.getAllFormats()
  522. #det = api.detailed("1516")
  523. #vid = api.getVideos("13170")
  524. pass