summaryrefslogtreecommitdiff
path: root/plugin.video.plutotv/default.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugin.video.plutotv/default.py')
-rw-r--r--plugin.video.plutotv/default.py166
1 files changed, 104 insertions, 62 deletions
diff --git a/plugin.video.plutotv/default.py b/plugin.video.plutotv/default.py
index 045c36c..515dcde 100644
--- a/plugin.video.plutotv/default.py
+++ b/plugin.video.plutotv/default.py
@@ -17,11 +17,12 @@
# along with PlutoTV. If not, see <http://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
-import os, sys, time, datetime, net, requests, re, traceback
+import os, sys, time, datetime, net, re, traceback
import urllib, socket, json, urlresolver, collections
import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon
from simplecache import SimpleCache
+
# Plugin Info
ADDON_ID = 'plugin.video.plutotv'
REAL_SETTINGS = xbmcaddon.Addon(id=ADDON_ID)
@@ -31,17 +32,18 @@ ADDON_PATH = REAL_SETTINGS.getAddonInfo('path').decode('utf-8')
ADDON_VERSION = REAL_SETTINGS.getAddonInfo('version')
ICON = REAL_SETTINGS.getAddonInfo('icon')
FANART = REAL_SETTINGS.getAddonInfo('fanart')
-
+LANGUAGE = REAL_SETTINGS.getLocalizedString
## GLOBALS ##
TIMEOUT = 15
USER_EMAIL = REAL_SETTINGS.getSetting('User_Email')
PASSWORD = REAL_SETTINGS.getSetting('User_Password')
-FIT_REGION = REAL_SETTINGS.getSetting('Filter_Region') == 'true'
+USER_REGION = REAL_SETTINGS.getSetting("Select_Country")
+FIT_REGION = False if USER_REGION == 'US' else True
DEBUG = REAL_SETTINGS.getSetting('Enable_Debugging') == 'true'
-HIDE_PLUTO = REAL_SETTINGS.getSetting("Hide_Ads") == "true"
COOKIE_JAR = xbmc.translatePath(os.path.join(SETTINGS_LOC, "cookiejar.lwp"))
PTVL_RUN = xbmcgui.Window(10000).getProperty('PseudoTVRunning') == 'True'
+HIDE_PLUTO = PTVL_RUN
IGNORE_KEYS = ['pluto.tv','plutotv','pluto tv','promo']
YTURL = 'plugin://plugin.video.youtube/play/?video_id='
VMURL = 'plugin://plugin.video.vimeo/play/?video_id='
@@ -50,7 +52,6 @@ BASE_API = 'https://api.pluto.tv/v1'
BASE_LINEUP = 'https://api.pluto.tv/v1/channels.json'
BASE_GUIDE = 'https://api.pluto.tv/v1/timelines/%s.000Z/%s.000Z/matrix.json'
BASE_CLIPS = 'https://api.pluto.tv/v2/episodes/%s/clips.json'
-USER_REGION = 'US'
PLUTO_MENU = [("Channel Guide" , BASE_LINEUP, 0),
("Browse Channels", BASE_LINEUP, 1)]
@@ -74,6 +75,14 @@ def stringify(string):
string = string.encode('utf-8', 'ignore')
return string
+def inputDialog(heading=ADDON_NAME, default='', key=xbmcgui.INPUT_ALPHANUM, opt=0, close=0):
+ retval = xbmcgui.Dialog().input(heading, default, key, opt, close)
+ if len(retval) > 0:
+ return retval
+
+def yesnoDialog(str1, str2='', str3='', header=ADDON_NAME, yes='', no='', autoclose=0):
+ return xbmcgui.Dialog().yesno(header, str1, str2, str3, no, yes, autoclose)
+
def getParams():
param=[]
if len(sys.argv[2])>=2:
@@ -91,26 +100,30 @@ def getParams():
return param
socket.setdefaulttimeout(TIMEOUT)
-
class PlutoTV():
def __init__(self):
log('__init__')
self.net = net.Net()
self.cache = SimpleCache()
self.categoryMenu = self.getCategories()
-
+ self.mediaType = self.getMediaTypes()
+
def login(self):
log('login')
- header_dict = {}
- header_dict['Accept'] = 'application/json, text/javascript, */*; q=0.01'
- header_dict['Host'] = 'api.pluto.tv'
- header_dict['Connection'] = 'keep-alive'
- header_dict['Referer'] = 'http://pluto.tv/'
- header_dict['Origin'] = 'http://pluto.tv'
- header_dict['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.2; rv:24.0) Gecko/20100101 Firefox/24.0'
-
+ #ignore guest login
+ if USER_EMAIL == LANGUAGE(30009):
+ return
+
if len(USER_EMAIL) > 0:
+ header_dict = {}
+ header_dict['Accept'] = 'application/json, text/javascript, */*; q=0.01'
+ header_dict['Host'] = 'api.pluto.tv'
+ header_dict['Connection'] = 'keep-alive'
+ header_dict['Referer'] = 'http://pluto.tv/'
+ header_dict['Origin'] = 'http://pluto.tv'
+ header_dict['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.2; rv:24.0) Gecko/20100101 Firefox/24.0'
+
try:
#remove COOKIE_JAR Folder
xbmcvfs.rmdir(COOKIE_JAR)
@@ -128,17 +141,25 @@ class PlutoTV():
form_data = ({'optIn': 'true', 'password': PASSWORD,'synced': 'false', 'userIdentity': USER_EMAIL})
self.net.set_cookies(COOKIE_JAR)
try:
- loginlink = self.loadJson(self.net.http_POST(BASE_API + '/auth/local', form_data=form_data, headers=header_dict).content.encode("utf-8").rstrip())
+ loginlink = json.loads(self.net.http_POST(BASE_API + '/auth/local', form_data=form_data, headers=header_dict).content.encode("utf-8").rstrip())
if loginlink and loginlink['email'].lower() == USER_EMAIL.lower():
- xbmcgui.Dialog().notification(ADDON_NAME, 'Welcome Back %s' % loginlink['displayName'], ICON, 4000)
+ xbmcgui.Dialog().notification(ADDON_NAME, LANGUAGE(30006) + loginlink['displayName'], ICON, 4000)
self.net.save_cookies(COOKIE_JAR)
- return True
else:
- xbmcgui.Dialog().notification(ADDON_NAME, 'Invalid User Credentials', ICON, 4000)
+ xbmcgui.Dialog().notification(ADDON_NAME, LANGUAGE(30007), ICON, 4000)
except Exception,e:
log('login, Unable to create the storage directory ' + str(e), xbmc.LOGERROR)
-
-
+
+ else:
+ #firstrun wizard
+ if yesnoDialog(LANGUAGE(30008),no=LANGUAGE(30009), yes=LANGUAGE(30010)):
+ REAL_SETTINGS.setSetting('User_Email',inputDialog(LANGUAGE(30001)))
+ REAL_SETTINGS.setSetting('User_Password',inputDialog(LANGUAGE(30002)))
+ else:
+ REAL_SETTINGS.setSetting('User_Email',LANGUAGE(30009))
+ xbmc.executebuiltin('RunScript("' + ADDON_PATH + '/country.py' + '")')
+
+
def openURL(self, url):
log('openURL, url = ' + url)
try:
@@ -151,21 +172,20 @@ class PlutoTV():
header_dict['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.2; rv:24.0) Gecko/20100101 Firefox/24.0'
self.net.set_cookies(COOKIE_JAR)
trans_table = ''.join( [chr(i) for i in range(128)] + [' '] * 128 )
- cacheResponce = self.cache.get(ADDON_NAME + 'openURL, url = %s'%url)
- if not cacheResponce:
+ cacheResponse = self.cache.get(ADDON_NAME + '.openURL, url = %s'%url)
+ if not cacheResponse:
try:
req = self.net.http_GET(url, headers=header_dict).content.encode("utf-8", 'ignore')
except:
req = self.net.http_GET(url, headers=header_dict).content.translate(trans_table)
self.net.save_cookies(COOKIE_JAR)
- self.cache.set(ADDON_NAME + 'openURL, url = %s'%url, json.loads(stringify(req)), expiration=datetime.timedelta(hours=8))
- responce = self.cache.get(ADDON_NAME + 'openURL, url = %s'%url)
- if len(responce) > 0:
- return responce
+ self.cache.set(ADDON_NAME + '.openURL, url = %s'%url, json.loads(stringify(req)), expiration=datetime.timedelta(hours=1))
+ return self.cache.get(ADDON_NAME + '.openURL, url = %s'%url)
except Exception,e:
log('openURL, Unable to open url ' + str(e), xbmc.LOGERROR)
xbmcgui.Dialog().notification(ADDON_NAME, 'Unable to Connect, Check User Credentials', ICON, 4000)
-
+ return []
+
def mainMenu(self):
log('mainMenu')
@@ -178,8 +198,8 @@ class PlutoTV():
log('browseMenu')
for item in self.categoryMenu:
self.addDir(*item)
-
+
def getCategories(self):
log('getCategories')
collect= []
@@ -192,24 +212,42 @@ class PlutoTV():
lineup.append(("%s"%(key), BASE_LINEUP, 2))
lineup.insert(0,("Featured" , BASE_LINEUP, 2))
lineup.insert(2,("All Channels", BASE_LINEUP, 2))
- del collect[:]
- if len(lineup) > 0:
- return lineup
+ return lineup
+
+ def getMediaTypes(self):
+ mediaType = {}
+ for type in self.categoryMenu:
+ type = type[0]
+ if type == 'Movies':
+ mediaType[type] = 'movie'
+ elif type == 'TV':
+ mediaType[type] = 'episodes'
+ elif type == 'Music + Radio':
+ mediaType[type] = 'musicvideo'
+ else:
+ mediaType[type] = 'video'
+ return mediaType
+
def browse(self, chname, url):
log('browse, chname = ' + chname)
- data = (self.openURL(url))
+ geowarn = False
+ data = (self.openURL(url))
for channel in data:
- id = channel['_id']
- cat = channel['category']
- number = channel['number']
- region = channel['regionFilter']['exclude']
- name = channel['name']
- plot = channel['description']
- feat = (channel.get('featured','') or 0) == -1
-
- if FIT_REGION == True and USER_REGION in region:
+ id = channel['_id']
+ cat = channel['category']
+ number = channel['number']
+ region = channel['regionFilter']['include']
+ exclude = channel['regionFilter']['exclude']
+ name = channel['name']
+ plot = channel['description']
+ feat = (channel.get('featured','') or 0) == -1
+
+ if FIT_REGION == True and (USER_REGION in exclude or USER_REGION not in region):
+ if geowarn == False:
+ geowarn = True
+ xbmcgui.Dialog().notification(ADDON_NAME, LANGUAGE(30004), ICON, 4000)
continue
thumb = ICON
@@ -221,21 +259,21 @@ class PlutoTV():
logo = ICON
if 'logo' in channel:
logo = (channel['logo']['path'] or ICON)
-
+
if chname == "All Channels":
title = "%s - %s: %s" % (cat, number, name)
- infoLabels ={"label":title ,"title":title ,"plot":plot, "code":number, "genre":cat, "imdbnumber":id}
+ infoLabels ={"mediatype":self.mediaType[cat],"label":title ,"title":title ,"plot":plot, "code":number, "genre":cat, "imdbnumber":id}
infoArt ={"thumb":thumb,"poster":thumb,"fanart":land,"icon":logo,"logo":logo}
self.addDir(title, id, 8, infoLabels, infoArt)
elif chname == "Featured" and feat == True:
title = "%s - %s: %s" % (cat, number, name)
- infoLabels ={"label":title ,"title":title ,"plot":plot, "code":number, "genre":cat, "imdbnumber":id}
+ infoLabels ={"mediatype":self.mediaType[cat],"label":title ,"title":title ,"plot":plot, "code":number, "genre":cat, "imdbnumber":id}
infoArt ={"thumb":thumb,"poster":thumb,"fanart":land,"icon":logo,"logo":logo}
self.addDir(title, id, 8, infoLabels, infoArt)
elif chname.lower() == cat.lower():
title = "%s: %s" % (number, name)
- infoLabels ={"label":title ,"title":title ,"plot":plot, "code":number, "genre":cat, "imdbnumber":id}
+ infoLabels ={"mediatype":self.mediaType[cat],"label":title ,"title":title ,"plot":plot, "code":number, "genre":cat, "imdbnumber":id}
infoArt ={"thumb":thumb,"poster":thumb,"fanart":land,"icon":logo,"logo":logo}
self.addDir(title, id, 8, infoLabels, infoArt)
@@ -247,21 +285,26 @@ class PlutoTV():
def browseGuide(self, start=0, end=24):
log('browseGuide')
- start = 0 if start == BASE_LINEUP else int(start)
- data = (self.openURL(BASE_LINEUP))
- data = list(self.pagination(data, end))
- start = 0 if start >= len(data) else start
+ geowarn = False
+ start = 0 if start == BASE_LINEUP else int(start)
+ data = (self.openURL(BASE_LINEUP))
+ data = list(self.pagination(data, end))
+ start = 0 if start >= len(data) else start
for channel in data[start]:
chid = channel['_id']
chcat = channel['category']
chnum = channel['number']
- region = channel['regionFilter']['exclude']
+ region = channel['regionFilter']['include']
+ exclude = channel['regionFilter']['exclude']
chname = channel['name']
chplot = channel['description']
chthumb = (channel['thumbnail']['path'] or ICON)
feat = (channel.get('featured','') or 0) == -1
- if FIT_REGION == True and USER_REGION in region:
+ if FIT_REGION == True and (USER_REGION in exclude or USER_REGION not in region):
+ if geowarn == False:
+ geowarn = True
+ xbmcgui.Dialog().notification(ADDON_NAME, LANGUAGE(30004), ICON, 4000)
continue
t1 = datetime.datetime.now().strftime('%Y-%m-%dT%H:00:00')
@@ -275,9 +318,9 @@ class PlutoTV():
epdur = int(item['episode']['duration'] or '0') // 1000
live = item['episode']['liveBroadcast']
thumb = chthumb #(item['episode']['thumbnail']['path'] or chthumb) #site doesn't update missing episode thumbs
-
+
title = "%s: %s - %s" % (chnum, chname, epname)
- infoLabels ={"label":title ,"title":title ,"plot":epplot, "code":epid, "genre":epgenre, "imdbnumber":chid, "duration":epdur}
+ infoLabels ={"mediatype":self.mediaType[chcat],"label":title ,"title":title ,"plot":epplot, "code":epid, "genre":epgenre, "imdbnumber":chid, "duration":epdur}
infoArt ={"thumb":thumb,"poster":thumb,"fanart":FANART,"icon":ICON,"logo":ICON}
self.addLink(title, chid, 9, infoLabels, infoArt, end)
start += 1
@@ -286,7 +329,6 @@ class PlutoTV():
def resolveURL(self, provider, url):
log('resolveURL, provider = ' + provider)
- print url
if provider == 'jwplatform' or url[-4:] == 'm3u8':
return url
elif provider == 'youtube':
@@ -299,7 +341,7 @@ class PlutoTV():
return VMURL + url.split('/vimeo.com/')[1]
return urlresolver.resolve(url)
-
+
def playChannel(self, name, url):
log('playChannel')
if PTVL_RUN == True:
@@ -333,7 +375,7 @@ class PlutoTV():
continue
liz=xbmcgui.ListItem(name, path=url)
- infoList = {"label":name,"title":name,"duration":dur}
+ infoList = {"mediatype":"video","label":name,"title":name,"duration":dur}
infoArt = {"thumb":thumb,"poster":thumb,"icon":ICON,"fanart":FANART}
liz.setInfo(type="Video", infoLabels=infoList)
liz.setArt(infoArt)
@@ -346,7 +388,7 @@ class PlutoTV():
playlist.add(url, liz, idx)
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, liz)
-
+
def playContent(self, name, url):
log('playContent')
origurl = url
@@ -374,7 +416,7 @@ class PlutoTV():
continue
liz=xbmcgui.ListItem(name, path=url)
- infoList = {"label":name,"title":name,"duration":dur}
+ infoList = {"mediatype":"video","label":name,"title":name,"duration":dur}
infoArt = {"thumb":thumb,"poster":thumb,"icon":ICON,"fanart":FANART}
liz.setInfo(type="Video", infoLabels=infoList)
liz.setArt(infoArt)
@@ -386,7 +428,7 @@ class PlutoTV():
liz.setProperty('ResumeTime', str(vid_offset) )
self.addLink(name, url, 7, infoList, infoArt, len(data))
-
+
def playVideo(self, name, url, list=None):
log('playVideo')
if not list:
@@ -400,7 +442,7 @@ class PlutoTV():
liz=xbmcgui.ListItem(name)
liz.setProperty('IsPlayable', 'true')
if infoList == False:
- liz.setInfo( type="Video", infoLabels={"label":name,"title":name} )
+ liz.setInfo(type="Video", infoLabels={"mediatype":"video","label":name,"title":name})
else:
liz.setInfo(type="Video", infoLabels=infoList)
@@ -418,7 +460,7 @@ class PlutoTV():
liz=xbmcgui.ListItem(name)
liz.setProperty('IsPlayable', 'false')
if infoList == False:
- liz.setInfo(type="Video", infoLabels={"label":name,"title":name} )
+ liz.setInfo(type="Video", infoLabels={"mediatype":"video","label":name,"title":name} )
else:
liz.setInfo(type="Video", infoLabels=infoList)
if infoArt == False: