class KodiHelper:
"""Consumes all the configuration data from Kodi as well as turns data into lists of folders and videos"""
- msl_service_server_url = 'http://localhost:%PORT%'
- """str: MSL service url"""
-
def __init__ (self, plugin_handle, base_url):
"""Fetches all needed info from Kodi & configures the baseline of the plugin
self.cookie_path = self.base_data_path + 'COOKIE'
self.data_path = self.base_data_path + 'DATA'
self.config_path = os.path.join(self.base_data_path, 'config')
+ self.msl_data_path = xbmc.translatePath('special://profile/addon_data/service.msl').decode('utf-8') + '/'
self.verb_log = self.addon.getSetting('logging') == 'true'
self.default_fanart = self.addon.getAddonInfo('fanart')
self.win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
return False
# inputstream addon properties
- msl_service_url = self.msl_service_server_url.replace('%PORT%', str(self.addon.getSetting('msl_service_port')))
+ msl_service_url = 'http://localhost:' + str(self.addon.getSetting('msl_service_port'))
play_item = xbmcgui.ListItem(path=msl_service_url + '/manifest?id=' + video_id)
play_item.setProperty(inputstream_addon + '.license_type', 'com.widevine.alpha')
play_item.setProperty(inputstream_addon + '.manifest_type', 'mpd')
# from Crypto.Hash import HMAC, SHA256
from Crypto.Util import Padding
import xml.etree.ElementTree as ET
-from common import log
-from common import ADDONUSERDATA
+from KodiHelper import KodiHelper
+
+plugin_handle = int(sys.argv[1])
+base_url = sys.argv[0]
+kodi_helper = KodiHelper(
+ plugin_handle=plugin_handle,
+ base_url=base_url
+)
pp = pprint.PrettyPrinter(indent=4)
self.email = email
self.password = password
try:
- os.mkdir(ADDONUSERDATA)
+ os.mkdir(kodi_helper.msl_data_path)
except OSError:
pass
self.__load_msl_data()
self.handshake_performed = True
elif self.file_exists('rsa_key.bin'):
- log('RSA Keys do already exist load old ones')
+ kodi_helper.log(msg='RSA Keys do already exist load old ones')
self.__load_rsa_keys()
self.__perform_key_handshake()
else:
- log('Create new RSA Keys')
+ kodi_helper.log(msg='Create new RSA Keys')
# Create new Key Pair and save
self.rsa_key = RSA.generate(2048)
self.__save_rsa_keys()
try:
resp.json()
- log('MANIFEST RESPONE JSON: '+resp.text)
+ kodi_helper.log(msg='MANIFEST RESPONE JSON: '+resp.text)
except ValueError:
# Maybe we have a CHUNKED response
resp = self.__parse_chunked_msl_response(resp.text)
try:
resp.json()
- log('LICENSE RESPONE JSON: '+resp.text)
+ kodi_helper.log(msg='LICENSE RESPONE JSON: '+resp.text)
except ValueError:
# Maybe we have a CHUNKED response
resp = self.__parse_chunked_msl_response(resp.text)
'headerdata': base64.standard_b64encode(header),
'signature': '',
}
- log('Key Handshake Request:')
- log(json.dumps(request))
+ kodi_helper.log(msg='Key Handshake Request:')
+ kodi_helper.log(msg=json.dumps(request))
resp = self.session.post(self.endpoints['manifest'], json.dumps(request, sort_keys=True))
if resp.status_code == 200:
resp = resp.json()
if 'errordata' in resp:
- log('Key Exchange failed')
- log(base64.standard_b64decode(resp['errordata']))
+ kodi_helper.log(msg='Key Exchange failed')
+ kodi_helper.log(msg=base64.standard_b64decode(resp['errordata']))
return False
self.__parse_crypto_keys(json.JSONDecoder().decode(base64.standard_b64decode(resp['headerdata'])))
else:
- log('Key Exchange failed')
- log(resp.text)
+ kodi_helper.log(msg='Key Exchange failed')
+ kodi_helper.log(msg=resp.text)
def __parse_crypto_keys(self, headerdata):
self.__set_master_token(headerdata['keyresponsedata']['mastertoken'])
self.rsa_key = RSA.importKey(loaded_key)
def __save_rsa_keys(self):
- log('Save RSA Keys')
+ kodi_helper.log(msg='Save RSA Keys')
# Get the DER Base64 of the keys
encrypted_key = self.rsa_key.exportKey()
self.save_file('rsa_key.bin', encrypted_key)
:param filename: The filename
:return: True if so
"""
- return os.path.isfile(ADDONUSERDATA + filename)
+ return os.path.isfile(kodi_helper.msl_data_path + filename)
@staticmethod
def save_file(filename, content):
:param filename: The filename
:param content: The content of the file
"""
- with open(ADDONUSERDATA + filename, 'w') as file_:
+ with open(kodi_helper.msl_data_path + filename, 'w') as file_:
file_.write(content)
file_.flush()
:param filename: The file to load
:return: The content of the file
"""
- with open(ADDONUSERDATA + filename) as file_:
+ with open(kodi_helper.msl_data_path + filename) as file_:
file_content = file_.read()
return file_content
from urlparse import urlparse, parse_qs
from MSL import MSL
-from common import ADDON
-email = ADDON.getSetting('email')
-password = ADDON.getSetting('password')
+from KodiHelper import KodiHelper
+
+plugin_handle = int(sys.argv[1])
+base_url = sys.argv[0]
+kodi_helper = KodiHelper(
+ plugin_handle=plugin_handle,
+ base_url=base_url
+)
+
+account = kodi_helper.addon.get_credentials()
+email = account['email']
+password = account['password']
msl = MSL(email, password)
class MSLHttpRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+++ /dev/null
-import os
-import xbmc
-import xbmcaddon
-import xbmcgui
-import xbmcvfs
-
-ADDON = xbmcaddon.Addon()
-ADDONVERSION = ADDON.getAddonInfo('version')
-ADDONNAME = ADDON.getAddonInfo('name')
-ADDONPATH = ADDON.getAddonInfo('path').decode('utf-8')
-ADDONPROFILE = xbmc.translatePath( ADDON.getAddonInfo('profile') ).decode('utf-8')
-ADDONUSERDATA = xbmc.translatePath("special://profile/addon_data/service.msl").decode('utf-8') + "/"
-ICON = ADDON.getAddonInfo('icon')
-
-def log(txt):
- if isinstance (txt,str):
- txt = txt.decode("utf-8")
- message = u'%s: %s' % ("service.msl", txt)
- xbmc.log(msg=message.encode("utf-8"), level=xbmc.LOGDEBUG)
import xbmc
import xbmcaddon
import socket
-from resources.lib.common import log
+from resources.lib.KodiHelper import KodiHelper
from resources.lib.MSLHttpRequestHandler import MSLHttpRequestHandler
def select_unused_port():
s.close()
return port
+plugin_handle = int(sys.argv[1])
+base_url = sys.argv[0]
addon = xbmcaddon.Addon()
+
+kodi_helper = KodiHelper(
+ plugin_handle=plugin_handle,
+ base_url=base_url
+)
+
PORT = select_unused_port()
addon.setSetting('msl_service_port', str(PORT))
-log("Picked Port: " + str(PORT))
+kodi_helper.log(msg='Picked Port: ' + str(PORT))
Handler = MSLHttpRequestHandler
SocketServer.TCPServer.allow_reuse_address = True
server = SocketServer.TCPServer(('127.0.0.1', PORT), Handler)
server.server_close()
server.socket.close()
server.shutdown()
- log("Stopped MSL Service")
+ kodi_helper.log(msg='Stopped MSL Service')