#!/usr/bin/env python
# coding=utf8
#
# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
#
import sys, os, os.path, re, sys
import urllib,urllib2
from xml.sax.saxutils import unescape,escape
from urllib import quote, unquote
import datetime
import HTMLParser
import json
import ConfigParser
import datetime
API_URL = 'https://m.lattelecom.tv/'
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"
headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
h = HTMLParser.HTMLParser()
class Source(object):
def __init__(self):
self.name = "ltc"
self.mobtv_cache = ""
self.session_id = ""
cur_directory = os.path.dirname(os.path.abspath(__file__))
config_file = os.path.join(cur_directory,"ltc.cfg")
config = ConfigParser.ConfigParser()
if os.path.exists(config_file):
config.read(config_file)
self.user = config.get("ltc","user")
self.password = config.get("ltc","password")
else:
self.user = ""
self.password = ""
#self.login()
self.headers = headers2dict("""
Host: m.lattelecom.tv
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
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
""")
self.headers2 = headers2dict("""
Host: www.lattelecom.tv
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Referer: https://www.lattelecom.tv/videonoma/360tv
""")
def get_content(self, data):
print "[ltc] get_content:", data
if "::" in data:
data = data.split("::")[1]
path = data.split("?")[0]
clist = path.split("/")[0]
params = data[data.find("?"):] if "?" in data else ""
qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
#lang = qs["lang"] if "lang" in qs else self.country
content=[]
content.append(("..return", "back","","Return back"))
if clist=="home":
content.extend([
("Live streams", "ltc::tiesraide","","TV live streams"),
("Archive", "ltc::arhivs","","TV live archive"),
("Video", "ltc::videonoma","","Video on demand"),
])
return content
### Tiešraides kanānālu saraksts
elif data=="tiesraide":
if not self.check_logedin():
self.login() # citādi nerāda TV3, LNT, TV6
r= self.call(data)
for item in re.findall(r'(?i)/(tiesraide/[^"]*?)">
([^<]+)
([^<]+)', r):
ch = item[0]
title = item[1]
data2 = item[0]
img = "https://m.lattelecom.tv/"+item[2].replace("105x105","150x150")
desc = "%s\n%s"%(item[3],item[4])
content.append((title,self.name+"::"+data2,img,desc))
return content
### Kanāla tiesraide
elif clist == "tiesraide" and "/" in data:
ch = data.split("/")[1]
if not self.check_logedin():
if not self.login():
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 ")
return content
r = self.call("tiesraide")
m = re.search('/%s">
(.+?)
(.+?)'%data, r, re.IGNORECASE)
if m:
title = "%s - %s (%s)"%(m.group(1),m.group(2),m.group(3))
else:
title = ch.upper()
desc = title
data2 = self.get_tv_url(ch)
if not data2:
content=("No stream found for '%s'"%data,"","","No stream found")
return content
content = (title,data2,"",desc)
return content
### Arhīva kanānālu saraksts
elif data=="arhivs":
r= self.call(data)
for item in re.findall(r'(?i)/(arhivs/[^"]+)".+?
([^<]+)', r, re.IGNORECASE)
if m:
ch_name = m.group(1)
else:
ch_name = ""
today = datetime.date.today()
for i in range(7):
date = today-datetime.timedelta(i)
title = ch_name + " - " + date.strftime("%d.%m.%Y")
data2 = "%s/%s"%(data,date.strftime("%Y-%m-%d"))
img = ""
desc = title
content.append((title,self.name+"::"+data2,img,desc))
return content
### Arhīva dienas raidijumi
elif clist=="arhivs" and len(data.split("/"))==3:
ch = data.split("/")[1]
date = data.split("/")[2]
r= self.call(data)
m = re.search('class="spac no_select">([^<]+)', r, re.IGNORECASE)
if m:
ch_name = m.group(1)
else:
ch_name = ""
for item in re.findall('(?i)href="/([^"]+?)" id="" class="archive_programm_a">
([^<]+)
([^<]+)', r):
title = "%s - %s"%(item[1],item[2])
data2 = item[0]
img = ""
desc = "%s (%s)\n%s"%(ch_name,date,title)
content.append((title,self.name+"::"+data2,img,desc))
return content
### Arhīva video
elif clist=="arhivs" and len(data.split("/"))==4:
ch = data.split("/")[1]
video_id=data.split("/")[-1]
if not self.check_logedin():
if not self.login():
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 ")
return content
data2 = self.get_arhivs_url(video_id)
if not data2:
content=("No stream found for '%s'"%data,"","","No stream found")
return content
r = self.call(data)
m = re.search('([^<]+)
([^<]+)
([^<]+)([^<]+)([^<]+)<', r, re.IGNORECASE)
if m:
title = "%s (%s %s %s %s)"%(m.group(1),m.group(2),m.group(3),m.group(4),m.group(5))
else:
title = ""
desc = title
content = (title,data2,"",desc)
return content
### Videonoma galvenā
elif data=="videonoma":
content.extend([
("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"),
("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"),
("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ā"),
("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"),
("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"),
("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"),
("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"),
("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"),
("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"),
("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"),
("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"),
("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"),
("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"),
("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"),
])
return content
### Videonomas saraksti
elif path == "videonoma":
url = "https://www.lattelecom.tv/movies-snippet.json"+params
r = self._http_request(url,self.headers2)
if not r:
return content
js = json.loads(r,"utf8")
if not r:
return content
for item in js["movies"]:
title = item["title"].encode("utf8")
data2 = item["url"][1:].encode("utf8")
if data2[-1]=="/": data2=data2[:-1]
if "/raidijumi/" in data2:
data2 += "?series"
img = "https://www.lattelecom.tv"+item["image"].encode("utf8")
desc = "%s\n%s"%(title,item["genre"].encode("utf8"))
content.append((title,self.name+"::"+data2,img,desc))
m = re.search("page=(\d+)",data)
if m:
page = int(m.group(1))
data2 = re.sub("page=\d+","page=%s"%(page+1),data)
content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
return content
### Sērijas
elif clist=="videonoma" and params=="?series":
url = "https://www.lattelecom.tv/"+path
r = self._http_request(url,self.headers2)
if not r:
return content
m = re.search('([^<]+?)
', r, re.DOTALL | re.IGNORECASE)
if m:
raidijums = m.group(1) + " - "
else:
raidijums = ""
for item in re.findall('(?si)
.*?([^<]+)([^<]+)', r):
title = "%s%s (%s)"%(raidijums,item[2],item[3])
data2 = item[0][1:]
img = "https://www.lattelecom.tv"+item[1]
desc = title
content.append((title,self.name+"::"+data2,img,desc))
return content
### Videonomas video
elif clist=="videonoma" and len(data.split("/"))>1:
ch = data.split("/")[1]
video_id=data[data.find("/")+1:]
#video_id=data.split("/")[-1]
if not self.check_logedin():
if not self.login():
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 ")
return content
data2 = self.get_noma_url(video_id)
if not data2:
content=("No stream found for '%s'"%data,"","","No stream found")
return content
r = self.call(data)
m = re.search('([^<]+)<', r, re.IGNORECASE)
if m:
title = m.group(1)
else:
title = ""
desc = title
content = (title,data2,"",desc)
return content
else:
return content
def is_video(self,data):
if "::" in data:
data = data.split("::")[1]
cmd = data.split("/")
if cmd[0] in ("tiesraide") and "/" in data:
return True
elif cmd[0]=="arhivs" and len(cmd)==4:
return True
elif cmd[0]=="videonoma" and len(cmd)==3 and not "?" in data:
return True
else:
return False
def call(self, data,headers=None):
if not headers: headers = self.headers
#if not lang: lang = self.country
url = API_URL + data
content = self._http_request(url,headers)
return content
def _http_request(self, url,headers=None):
if not headers: headers = self.headers
try:
r = urllib2.Request(url, headers=headers)
u = urllib2.urlopen(r)
content = u.read()
u.close()
return content
except Exception as ex:
return None
def login(self,user="",password=""):
"""Login in to site, create session cookies"""
self.mobtv_cache = ""
if not user: user=self.user
if not password: password = self.password
url0 = "https://m.lattelecom.tv"
class NoRedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_302(self, req, fp, code, msg, headers):
infourl = urllib.addinfourl(fp, headers, req.get_full_url())
infourl.status = code
infourl.code = code
return infourl
http_error_300 = http_error_302
http_error_301 = http_error_302
http_error_303 = http_error_302
http_error_307 = http_error_302
# Dabūjam sesijas id un url_gif, kas redirektējas uz auth_url
headers = headers2dict("""
Host: m.lattelecom.tv
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
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
DNT: 1
Connection: keep-alive
""")
response = urllib2.urlopen(urllib2.Request(url0+"/authorization", headers=headers))
session_id = response.headers["set-cookie"].split(";")[0]
html = response.read()
url_gif = url0 + re.search('(/auth/\d+.gif)', html).group(1)
# Dabūtjam auth_url
headers = headers2dict("""
Host: m.lattelecom.tv
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
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: https://m.lattelecom.tv/authorization
Connection: keep-alive
""")
headers["Cookie"] = session_id
urllib2.install_opener(urllib2.build_opener(NoRedirectHandler()))
response = urllib2.urlopen(urllib2.Request(url_gif, headers=headers))
if response.code == 302:
url_auth = response.headers["location"]
else:
self.error = u"auth.gif nenostrādāja"
#raise u"auth.gif nenostrādāja"
return False
# Pierakstāmies iekš auth.lattelecom.lv
headers = headers2dict("""
Host: auth.lattelecom.lv
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
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://m.lattelecom.tv/authorization
Connection: keep-alive
""")
response = urllib2.urlopen(urllib2.Request(url_auth, headers=headers))
if not response.code == 302:
self.error = u"pierakstīšanās auth.lattelecom.lv nenostrādāja"
return False
#raise "pierakstīšanās auth.lattelecom.lv nenostrādāja"
# nolasām auth_gif
## headers = headers2dict("""
## Host: m.lattelecom.tv
## 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
## Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
## Accept-Language: en-US,en;q=0.5
## Accept-Encoding: gzip, deflate
## DNT: 1
## Referer: http://m.lattelecom.tv/authorization
## """)
## headers["Cookie"] = session_id
## response = urllib2.urlopen(urllib2.Request(url_gif, headers=headers))
## if not response.code == 200:
## raise u"kļūda lasot auth_gif"
# Mēģinam ielogoties
headers = headers2dict("""
Host: m.lattelecom.tv
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
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: deflate
DNT: 1
Referer: http://m.lattelecom.tv/authorization
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded""")
headers["Cookie"] = session_id
data = "login=yes&email=%s&passw=%s"%(user,password)
req = urllib2.Request(url0+"/authorization", data, headers)
response = urllib2.urlopen(req)
#with open("auth.htm","w") as f: f.write(response.read())
if not response.code == 302:
self.error = u"kļūda ielogojoties"
#raise u"kļūda ielogojoties"
return False
mobtv = response.headers["set-cookie"].split(";")[0]
if not mobtv.split("=")[0]=="mobtv_cache":
#raise "nav mobtv cookie!"
self.error = "nav mobtv cookie!"
return False
# atveram /account
## headers = headers2dict("""
## Host: m.lattelecom.tv
## 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
## Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
## Accept-Language: en-US,en;q=0.5
## Accept-Encoding: deflate
## DNT: 1
## Referer: http://m.lattelecom.tv/authorization
## Connection: keep-alive """)
## headers["Cookie"] = "%s; %s"%(session_id,mobtv)
## response = urllib2.urlopen(urllib2.Request(url0+"/account", headers=headers))
## if not response.code == 302:
## raise u"kļūda atverot /account"
# atveram /profils
## headers = headers2dict("""
## Host: m.lattelecom.tv
## 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
## Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
## Accept-Language: en-US,en;q=0.5
## Accept-Encoding: deflate
## DNT: 1
## Referer: http://m.lattelecom.tv/authorization
## Connection: keep-alive
## """)
## headers["Cookie"] = "%s; %s"%(session_id,mobtv)
## response = urllib2.urlopen(urllib2.Request(url0+"/profils", headers=headers))
## if not response.code == 200:
## raise u"kļūda atverot /profils"
## with open("profils.htm","w") as f: f.write(response.read())
self.mobtv_cache = mobtv
self.session_id = session_id
self.headers["Cookie"] = "%s; %s; MobBitr=1; "%(self.session_id,self.mobtv_cache)
self.error = ""
return True
def check_logedin(self):
if not self.mobtv_cache:
return False
else:
#return True
url = "https://m.lattelecom.tv/profils"
headers = self.headers
headers["Cookie"] = "%s; %s; MobBitr=1; "%(self.session_id,self.mobtv_cache)
response = urllib2.urlopen(urllib2.Request(url, headers=self.headers))
if response.code == 200:
return True
else:
self.mobtv_cache = ""
return False
def is_logedin(self):
if self.mobtv_cache:
return True
else:
return False
def get_tv_channels(self,):
"""Get tv channels list"""
url = "https://m.lattelecom.tv/tiesraide"
response = urllib2.urlopen(urllib2.Request(url, headers=self.headers))
html = response.read()
channels = re.findall(r'(?si)data-url="/tiesraide/(.*?)">([^<]+)", r)[1]
data["language"]=re.findall('(?s)
', r)
data["language"]="lv" if "lv" in data["language"] else "ru" if "ru" in data["language"] else "en"
data["qs"]=re.findall('(?s)([^<]+)', r)
data["qs"]=dict(data["qs"])
qs = data["qs"].keys()
data["quality"] = "hd" if "hd" in qs else "hq" if "hq" in qs else "mhq" if "mhq" in qs else "lq"
data["mp4"] = data["qs"][data["quality"]]
data["token"] = re.search("(?s)([^<]+)", r).group(1)
data["resource_id"]=re.search("(?s)([^<]+)", r).group(1)
data["hls]"] = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])
return data
if __name__ == "__main__":
c = Source()
c.login("ivars777","kaskade7")
data = c.get_video_data("hd/hd_anonymous")
#print data
print data["hls"]
if len(sys.argv)>1:
data= sys.argv[1]
else:
data = "home"
content = c.get_content(data)
for item in content:
print item
#cat = api.get_categories(country)
#chan = api.get_channels("lv")
#prog = api.get_programs(channel=6400)
#prog = api.get_programs(category=55)
#seas = api.get_seasons(program=6453)
#str = api.get_streams(660243)
#res = api.get_videos(802)
#formats = api.getAllFormats()
#det = api.detailed("1516")
#vid = api.getVideos("13170")
pass