diff --git a/plugin.video.mytv_bg/addon.py b/plugin.video.mytv_bg/addon.py index 907b954cdf..7defb8cf86 100644 --- a/plugin.video.mytv_bg/addon.py +++ b/plugin.video.mytv_bg/addon.py @@ -1,11 +1,16 @@ #!/usr/bin/python # -*- coding: utf-8 -*- + + #imports -from xbmcswift import Plugin, xbmc, xbmcaddon, xbmcplugin, xbmcgui, clean_dict +import xbmcplugin +import xbmc +import xbmcaddon +import xbmcplugin +import routing from urllib2 import urlopen, HTTPError import urlparse -import xbmcgui from pyxbmct.addonwindow import * import sys import json @@ -15,66 +20,64 @@ import urllib2 import datetime import time +import re + +__addon__ = xbmcaddon.Addon() +__addon_name__ = __addon__.getAddonInfo('name') +__id__ = __addon__.getAddonInfo('id') +__lang__ = __addon__.getLocalizedString +__settings__ = xbmcaddon.Addon(id=__addon__.getAddonInfo('id')) +__version__ = __addon__.getAddonInfo('version') +__profile_path__ = xbmc.translatePath( __addon__.getAddonInfo('profile') ).decode("utf-8") +__token_filepath__ = __profile_path__ + '/token.txt' -__addon__ = xbmcaddon.Addon() -__addon_name__ = __addon__.getAddonInfo('name') -__id__ = __addon__.getAddonInfo('id') -__lang__ = __addon__.getLocalizedString -__version__ = __addon__.getAddonInfo('version') -__profile_path__ = xbmc.translatePath( __addon__.getAddonInfo('profile') ).decode("utf-8") -__token_filepath__ = __profile_path__ + '/token.txt' +router = routing.Plugin() # BEGIN # Plugin -class Plugin_mod(Plugin): - - def add_items(self, iterable, is_update=False, sort_method_ids=[]): - items = [] - urls = [] - for i, li_info in enumerate(iterable): - - items.append( - self._make_listitem(**li_info) - ) - - if self._mode in ['crawl', 'interactive']: - print '[%d] %s%s%s (%s)' % (i + 1, '', li_info.get('label'), - '', li_info.get('url')) - urls.append(li_info.get('url')) - - if self._mode is 'xbmc': - xbmcplugin.addDirectoryItems(self.handle, items, len(items)) - for id in sort_method_ids: - xbmcplugin.addSortMethod(self.handle, id) - xbmcplugin.endOfDirectory(self.handle, updateListing=is_update) - - return urls - - def _make_listitem(self, label, path='', **options): - - li = xbmcgui.ListItem(label, path=path) - cleaned_info = clean_dict(options.get('info')) - - li.setArt({ 'poster': options.get('thumb'), 'thumb': options.get('thumb')}) - li.setInfo('video', { - 'originaltitle': label, - 'title': label, - 'sorttitle': options.get('key') - }) - - return options['url'], li, options.get('is_folder', True) +class Plugin_mod(object): + + def add_items(self, iterable, is_update=False, sort_method_ids=[]): + items = [] + urls = [] + for i, li_info in enumerate(iterable): + + items.append( + self._make_listitem(**li_info) + ) + + xbmcplugin.addDirectoryItems(int(sys.argv[1]), items, len(items)) + for id in sort_method_ids: + xbmcplugin.addSortMethod(int(sys.argv[1]), id) + xbmcplugin.endOfDirectory(int(sys.argv[1]), updateListing=is_update) + + return urls + + def _make_listitem(self, label, path='', **options): + + li = xbmcgui.ListItem(label, path=path) + cleaned_info =options.get('info') + + li.setArt({ 'poster': options.get('thumb'), 'thumb': options.get('thumb')}) + li.setInfo('video', { + 'originaltitle': label, + 'title': label, + 'sorttitle': options.get('key') + }) + + return options['url'], li, options.get('is_folder', True) # END # Plugin # Plugin_mod -plugin = Plugin_mod(__addon_name__, __id__) +plugin = Plugin_mod() # BEGIN # -if plugin.get_setting('server_url'): - SITE_PATH = plugin.get_setting('server_url') +if __settings__.getSetting('server_url'): + SITE_PATH = __settings__.getSetting('server_url') else: - SITE_PATH = 'http://bgtime.tv/api/mobile_v4/' + SITE_PATH = 'http://bgtime.tv/api/mobile_v4/' # Onli load master menu @@ -84,32 +87,35 @@ def _make_listitem(self, label, path='', **options): # END # -@plugin.route('/') +@router.route('/') def main_menu(): + request = urllib2.Request(ONLI_MASTER_MENU, headers={"User-Agent" : xbmc.getUserAgent()+ " XBMC/Kodi MyTV Addon " + str(__version__)}) + response = urllib2.urlopen(request) - request = urllib2.Request(ONLI_MASTER_MENU, headers={"User-Agent" : "XBMC/Kodi MyTV Addon " + str(__version__)}) - response = urllib2.urlopen(request) - - dataNew = json.loads(response.read()) + dataNew = json.loads(response.read()) - menulist = dataNew['menu'] - items = [] + menulist = dataNew['menu'] + items = [] - for (key, val) in menulist.iteritems(): - label = val['title'].encode('utf-8') - items.append({ - 'label': label, - 'key': u"{0}".format(key), - 'url': plugin.url_for('tvList', url=val['key'], title=label), - 'thumb': "{0}".format(val["thumb"])}) + for (key, val) in menulist.iteritems(): + label = val['title'].encode('utf-8') - return plugin.add_items(items, False, [xbmcplugin.SORT_METHOD_VIDEO_SORT_TITLE, xbmcplugin.SORT_METHOD_VIDEO_TITLE]) + items.append({ + 'label': label, + 'key': u"{0}".format(key), + 'url': router.url_for(tvList, urllib.quote_plus(val['key'])+'?'+urllib.urlencode({'title' : label})), + 'thumb': "{0}".format(val["thumb"])}) + + return plugin.add_items(items, False, [xbmcplugin.SORT_METHOD_VIDEO_SORT_TITLE, xbmcplugin.SORT_METHOD_VIDEO_TITLE]) -@plugin.route('/tvlist/') +@router.route('/tvList/') def tvList(url): args = urlparse.parse_qs(sys.argv[2][1:], keep_blank_values=True, strict_parsing=False) + + url = url.replace(sys.argv[2][1:], '') title_tmp = args.get('title', None) + filters = False if title_tmp is None: title = '' @@ -128,13 +134,13 @@ def tvList(url): dialog = xbmcgui.Dialog() - if(not plugin.get_setting('username')) or (not plugin.get_setting('password')): + if(not __settings__.getSetting('username')) or (not __settings__.getSetting('password')): dialog.ok(__lang__(30003), __lang__(30005)) return signin = login( - plugin.get_setting('username'), - plugin.get_setting('password'), + __settings__.getSetting('username'), + __settings__.getSetting('password'), url ) @@ -149,12 +155,15 @@ def tvList(url): dialog.ok(__lang__(30003), signin.data['msg']) return else: + # xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xbmcgui.ListItem(label=title)) if 'quality_urls' in signin.data and len(signin.data['quality_urls']) > 1: for key,val in enumerate(signin.data['quality_urls']): items.append(val['title']) ret = dialog.select(__lang__(30006), items) + tvPlay(signin.data['quality_urls'][ret]['key'], title, show_title, getTrackingKey(signin.data['quality_urls'][ret])) return + tvPlay(signin.data['key'], title, show_title, getTrackingKey(signin.data)) return @@ -168,50 +177,90 @@ def tvList(url): for (key, val) in enumerate(menulist): if val['type'] == 'item': + url_parameters = { + 'tracking': getTrackingKey(val), + 'title' : '' + } + items.append({ 'label': u"{0}".format(val['title']), + 'label2': u"{0}".format(getTrackingKey(val)), 'key': u"{0}".format(key), - 'url': plugin.url_for('tvPlay', url=val['key'], tracking_key=getTrackingKey(val)), + 'url': router.url_for(tvPlayCaller, urllib.quote_plus(val['key'])+'?'+urllib.urlencode(url_parameters)), 'thumb': "{0}".format(val["thumb"])}) elif val['type'] == 'menu': label = val['title'].encode('utf-8') + + url_parameters = { + 'show_title': _show_title, + 'title' : label + } items.append({ 'label': label, 'key': u"{0}".format(key), - 'url': plugin.url_for('tvList', url=val['key'], title=label, show_title=_show_title), + 'url': router.url_for(tvList, urllib.quote_plus(val['key'])+'?'+urllib.urlencode(url_parameters)), 'thumb': "{0}".format(val["thumb"])}) return plugin.add_items(items, False, [xbmcplugin.SORT_METHOD_VIDEO_SORT_TITLE, xbmcplugin.SORT_METHOD_VIDEO_TITLE]) -def getTrackingKey(val): - if 'tracking_key' in val: - return val['tracking_key'] - return None -@plugin.route('/tvPlay/') + +@router.route('/tvPlayCaller/') +def tvPlayCaller(url): + args = urlparse.parse_qs(sys.argv[2][1:], keep_blank_values=True, strict_parsing=False) + tracking_key_tmp = args.get('show_title', None) + + if tracking_key_tmp is None: + tracking_key = '' + else: + tracking_key = tracking_key_tmp[0]; + + + url = url.replace(sys.argv[2][1:], '') + + title = '' + show_title = '' + + tvPlay(url, title, show_title, tracking_key) + + def tvPlay(url, title, show_title, tracking_key): player = Player() - if title: - li = xbmcgui.ListItem(label=show_title + ' ' + title) + + #if previous is running calling onPlayerStopped + if player.isPlaying(): + player.stop() + + li = xbmcgui.ListItem(label=show_title + ' ' + title) + has_inputstream = _has_inputstream() + + if has_inputstream: + li.setProperty('inputstreamaddon', 'inputstream.adaptive') + li.setProperty('inputstream.adaptive.manifest_type', 'hls') + player.play(url, li) - else: - player.play(url) + xbmc.sleep(500) + + # if video doesn't start because of inputstream_adaptive + if not player.isPlaying(): + new_li = xbmcgui.ListItem(label=show_title + ' ' + title) + player.play(url, new_li) + player.is_playing = True player.tracking_key = tracking_key now = datetime.datetime.today() str_time = int(time.mktime(now.timetuple())) counter = 0 - + xbmc.executebuiltin( "Dialog.Close(busydialog)" ) while(player.is_playing): - if player.isPlaying(): player.info = { - 'key' : tracking_key, + 'key' : tracking_key, 'stream_started': str_time, - 'current_time' : int(player.getTime()), + 'current_time' : int(player.getTime()), } if counter == 90 and tracking_key is not None: counter = 0 @@ -223,25 +272,64 @@ def tvPlay(url, title, show_title, tracking_key): return + +def getTrackingKey(val): + if 'tracking_key' in val: + return val['tracking_key'] + return None + +def _json_rpc_request(payload): + response = xbmc.executeJSONRPC(json.dumps(payload)) + + return json.loads(response) + +def _has_inputstream(): + """Checks if selected InputStream add-on is installed.""" + + payload = { + 'jsonrpc': '2.0', + 'id': 1, + 'method': 'Addons.GetAddonDetails', + 'params': { + 'addonid': 'inputstream.adaptive' + } + } + + data = _json_rpc_request(payload) + + if 'error' in data: + try: + xbmc.executebuiltin('InstallAddon(inputstream.adaptive)', True) + xbmc.executeJSONRPC('{"jsonrpc":"2.0","id":1,"method":"Addons.SetAddonEnabled","params":{"addonid":"inputstream.adaptive","enabled":true}}') + return xbmcaddon.Addon('inputstream.adaptive') + except: + xbmcgui.Dialog().ok('Missing inputstream.adaptive add-on', 'inputstream.adaptive add-on not found or not enabled.This add-on is required to view DRM protected content.') + return False + else: + return True + + + # START # class Player(xbmc.Player): - info = None - tracking_key = None - is_live = None - is_playing = False + info = None + tracking_key = None + is_live = None + is_playing = False def __init__(self): xbmc.Player.__init__(self) - def onPlayBackStarted(self): + def onPlayBackStarted(self): + if self.tracking_key is not None: now = datetime.datetime.today() str_time = int(time.mktime(now.timetuple())) self.info = { - 'key' : self.tracking_key, + 'key' : self.tracking_key, 'stream_started': str_time, - 'current_time' : int(self.getTime()), + 'current_time' : int(self.getTime()), } self.reportPlaybackProgress(self.info, 'start') @@ -252,7 +340,6 @@ def onPlayBackPaused(self): pass def onPlayBackStopped(self): - if self.info is not None: self.reportPlaybackProgress(self.info, 'stop') @@ -269,7 +356,7 @@ def getToken(self): if temp_token: arr = temp_token.partition(" ") token = arr[0] - if arr[2] and arr[2] != __addon__.getSetting('username'): + if arr[2] and arr[2] != __settings__.getSetting('username'): token = ''; temp_token = '' @@ -280,11 +367,11 @@ def reportPlaybackProgress(self, info, action): token = self.getToken() if info is None: return if self.tracking_key is not None: - data ={ 'token' : token, - 'key' : self.tracking_key, - 'stream_started' : str(int(info['stream_started'])), - 'current_time' : str(int(info['current_time'])), - 'action' : action, + data ={ 'token' : token, + 'key' : self.tracking_key, + 'stream_started' : str(int(info['stream_started'])), + 'current_time' : str(int(info['current_time'])), + 'action' : action, } send = urllib.urlencode(data) request = urllib2.Request(SITE_PATH +'tracking/report_playback', send, headers={"User-Agent" : xbmc.getUserAgent()+ " MyTV Addon " + str(__version__)}) @@ -316,7 +403,7 @@ def __init__(self, username, password, url, send = None): self.data=self.getLive() if send is not None: - self.data.update(send) + self.data.update(send) self.data=self.getData(SITE_PATH + url) def logIN(self): @@ -333,6 +420,7 @@ def getData(self, url): try: response = urllib2.urlopen(self.request) + except HTTPError, e: dialog = xbmcgui.Dialog() dialog.ok(__lang__(30003), e.code) @@ -393,7 +481,7 @@ def makeUserPass(self): def writeInFile(self): fopen = open(__token_filepath__, "w+") - fopen.write(self.token + " " + plugin.get_setting('username')) + fopen.write(self.token + " " + __settings__.getSetting('username')) fopen.close() def openReadFile(self): @@ -404,21 +492,26 @@ def openReadFile(self): if temp_token: arr = temp_token.partition(" ") self.token = arr[0] - if arr[2] and arr[2] != plugin.get_setting('username'): + if arr[2] and arr[2] != __settings__.getSetting('username'): self.token = ''; temp_token = '' else: self.writeInFile() - # END # LOGIN +def getInputstream(): + try: return xbmcaddon.Addon('inputstream.adaptive') + except: pass + return False + + # LOG Method def __log(text): - xbmc.log('%s addon: %s' % (__addon_name__, text)) - + xbmc.log('%s addon: %s' % (__addon_name__, text)) + if __name__ == '__main__': - plugin.run() + router.run(sys.argv) diff --git a/plugin.video.mytv_bg/addon.xml b/plugin.video.mytv_bg/addon.xml index a281fbf572..95dbf792c9 100644 --- a/plugin.video.mytv_bg/addon.xml +++ b/plugin.video.mytv_bg/addon.xml @@ -1,9 +1,9 @@ - + - +