# -*- coding: utf-8 -*-
TITLE = "EtvNet3"
PREFIX = "/video/EtvNet3"
ICON_SEARCH = "icon-search.png"
ART = "art-default.jpg"
ICON = "icon-default.png"
API_URL = "http://etvnet.com/api/v2.0/"
BASE_URL = "http://etvnet.com/"
LOGGEDIN = False
sessionid = ""
SORT_VALUES = ["on_air","production_year","name","mark_total"]
DIR_VALUES = ["desc","asc"]
PERPAGE = "10"
TRANSLIT = False
USEDETAILS = False
import translit
###################################################################################################
def Start():
# Initialize the plug-in
Plugin.AddViewGroup("Details", viewMode="InfoList", mediaType="items")
Plugin.AddViewGroup("List", viewMode="List", mediaType="items")
# Setup the default attributes for the ObjectContainer
ObjectContainer.title1 = TITLE
ObjectContainer.view_group = "List"
ObjectContainer.art = R(ART)
# Setup the default attributes for the other objects
DirectoryObject.thumb = R(ICON)
DirectoryObject.art = R(ART)
VideoClipObject.thumb = R(ICON)
VideoClipObject.art = R(ART)
###################################################################################################
@handler("/video/etvnet3", TITLE)
def MainMenu():
LOGGEDIN = Login()
oc = ObjectContainer()
oc.add(DirectoryObject(
key = Callback(GetChannels),
title = TXT("Каналы")))
oc.add(PrefsObject(title = "Login Info", thumb=R(ICON)))
# Log("MyLog> url %s" % (url))
return oc
#####################################################################
def Thumb(url):
try:
data = HTTP.Request(url, cacheTime = CACHE_1MONTH).content
return DataObject(data, "image/jpeg")
except:
return Redirect(R(ICON))
####################################################################################################
def GetChannels():
oc = ObjectContainer()
url = API_URL + "channel_list.json"
obj = JSON.ObjectFromURL(url, encoding="utf-8")
sortby=""
sortdir=""
index = 0
sortby = SORT_VALUES[index]
sortdir = DIR_VALUES[index]
for item in obj:
slug=item["slug"]
link="channel/"+str(slug)+".json?"
title = TXT(item["name"])
oc.add(DirectoryObject(
key = Callback(GetCategories, link = link, page = 1, chslug = slug),
title = title))
return oc
####################################################################################################
def stub():
oc = ObjectContainer()
return oc
####################################################################################################
def GetCategories(link = "catalog.json?", page = 1, chslug=""):
Log(">>GetCategories called link:'%s' page:%d chslug:'%s'" % (link, page, chslug))
oc = ObjectContainer()
sortby = ""
sortdir = ""
index = 0
#index = SORT_NAMES.index(Prefs["sort"])
sortby = SORT_VALUES[index]
#index = DIR_NAMES.index(Prefs["direction"])
sortdir = DIR_VALUES[index]
thumb = ""
url = API_URL + link + "per_page=" + PERPAGE + "&sort=" + sortby + "&dir=" + sortdir
if (page > 0):
url = url + "&page="+str(page)
obj = JSON.ObjectFromURL(url)
st = JSON.StringFromObject(obj)
#title = title + " "+str(currpage)+"/"+str(totpages)
if (obj["header"].has_key("categories")):
Log("----> Categories count=\"%d\"" % len(obj["header"]["categories"]))
for item in obj["header"]["categories"]:
url = "catalog/" + str(item["slug"])+".json?"
if (chslug != ""):
url = "channel/"+chslug+"/"+str(item["slug"])+".json?"
count = item["count"]
title = TXT(item["name"]);
Log(">> Category=\"%s\"" % title)
oc.add(DirectoryObject(
key = Callback(GetCategories, link = url, page = 1, chslug = chslug),
title = title))
if (len(obj["header"]["categories"]) == 0 and obj.has_key("results")):
for item in obj["results"]:
id = item["id"]
try:
originally_available_at = Datetime.ParseDate(item["on_air"]).date()
except:
originally_available_at = None
if (item["class"] == "Container"):
rating_key = id
oc.add(TVShowObject(
key = Callback(GetEpisodes, id = id),
rating_key = id,
title = TXT(item["name"]),
rating = float(item["mark_total"]),
originally_available_at = originally_available_at,
episode_count = int(item["children_count"])))
else:
oc.add(GetEpisodeOrSeason(id = id));
if (obj["header"]["page_info"]["current"] != obj["header"]["page_info"]["total"]):
oc.add(DirectoryObject(
key = Callback(GetCategories, link = link, page = page + 1, chslug = chslug),
title = TXT(" >> Страница ") + str(page + 1),
thumb = R("next.png")))
return oc
####################################################################################################
def GetEpisodes(id, page = 1):
Log(">> GetEpisodes id:%s" % id)
sortby = SORT_VALUES[0]
sortdir = DIR_VALUES[0]
oc = ObjectContainer()
url = API_URL +"media/details/"+str(id) + ".json?" + "per_page=" + PERPAGE + "&sort=" + sortby + "&dir=" + sortdir
if (page > 1):
url = url + "&page=" + str(page)
objMedia = JSON.ObjectFromURL(url)
for item in objMedia["children"]:
eps = GetEpisodeOrSeason(id = item["id"])
if not eps == None:
oc.add(eps);
if (objMedia["media"]["children_page_info"]["current"] != objMedia["media"]["children_page_info"]["total"]):
oc.add(DirectoryObject(
key = Callback(GetEpisodes, id = id, page = page + 1),
title = objMedia["media"]["name"] + TXT(" -> Страница ") + str(page + 1),
thumb = R("next.png")))
return oc
####################################################################################################
def GetEpisodeOrSeason(id):
url = API_URL +"media/details/"+str(id) + ".json?"
Log(">> Making episode")
#eps = EpisodeObject(url = url, title = TXT(item["name"]))
#oc.add(eps)
try:
objMedia = JSON.ObjectFromURL(url)
except:
return None
try:
originally_available_at = Datetime.ParseDate(objMedia['media']["on_air"]).date()
except:
originally_available_at = None
bitrates = objMedia['media']['bitrates']
duration = objMedia['media']['duration']
eps = VideoClipObject(
title = TXT(objMedia['media']["name"]),
rating = float(objMedia['media']["mark_total"]),
key = id,
summary = TXT(objMedia['media']['description']),
thumb=objMedia['media']['screenshots_path']+'b01.jpg',
originally_available_at = originally_available_at,
rating_key = id
)
for item in bitrates:
eps.add(MediaObject(
bitrate = int(item),
protocol = Protocol.WebKit,
duration = duration,
video_resolution = item,
optimized_for_streaming = True,
parts = [PartObject(key = Callback(PlayMedia, id = id, bitrate = item) , duration = duration)],
))
return eps
####################################################################################################
def PlayMedia(id, bitrate):
url = API_URL +"media/watch/" + str(id) + "/" + str(bitrate) +".json?is_preview=0&other_server=0"
viewObj = JSON.ObjectFromURL(url)
if (viewObj.has_key('status') and viewObj['status']=='ok'):
vurl = WindowsMediaVideoURL(viewObj['url'])
Log(">> Playing Video:%s" % viewObj['url'])
return Redirect(vurl)
####################################################################################################
def TXT(text):
if text == None:
return None
if TRANSLIT:
return translit.translify(text)
return text.decode("utf-8")
####################################################################################################
def ValidatePrefs():
u = Prefs["username"]
p = Prefs["password"]
## do some checks and return a
## message container
if( u and p ):
LOGGEDIN = Login()
if LOGGEDIN == False:
return MessageContainer(
"Success",
"User and password provided ok"
)
else:
return MessageContainer(
"Error",
"You need to provide both a user and password"
)
####################################################################################################
def Login():
global LOGGEDIN, sessionid
if (LOGGEDIN):
return True
elif (not Prefs["username"] and not Prefs["password"]):
return False
else:
#initiate = HTTP.Request(BASE_URL+"/login/", encoding="iso-8859-1", cacheTime=1)
values = {
"username" : Prefs["username"],
"password" : Prefs["password"]
}
url = API_URL + "session.json"
try:
obj = JSON.ObjectFromURL(url, values=values, encoding="utf-8", cacheTime=1)
except:
obj=[]
Log("----> Someting Bad\"%s\"" % (values))
LOGGEDIN = False
return False
sessionid = obj["sessid"]
if (len(sessionid) > 0):
LOGGEDIN = True
Log(" --> Login successful! %s SSID=\"%s\"" % (LOGGEDIN, sessionid))
return True
else:
LOGGEDIN = False
Log(" --> Username/password incorrect!")
return False
####################################################################################################