# -*- coding: utf-8 -*- # Copyright: (c) 2019, Dag Wieers (@dagwieers) # GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ''' This file implements the Kodi xbmc module, either using stubs or alternative functionality ''' # pylint: disable=invalid-name,no-self-use,unused-argument from __future__ import absolute_import, division, print_function, unicode_literals import json import os import time from xbmcextra import global_settings, import_language LOGDEBUG = 0 LOGERROR = 4 LOGFATAL = 6 LOGINFO = 1 LOGNONE = 7 LOGNOTICE = 2 LOGSEVERE = 5 LOGWARNING = 3 LOG_MAPPING = { LOGDEBUG: 'Debug', LOGERROR: 'Error', LOGFATAL: 'Fatal', LOGINFO: 'Info', LOGNONE: 'None', LOGNOTICE: 'Notice', LOGSEVERE: 'Severe', LOGWARNING: 'Warning', } INFO_LABELS = { 'System.BuildVersion': '18.2', } REGIONS = { 'datelong': '%A, %e %B %Y', 'dateshort': '%Y-%m-%d', } GLOBAL_SETTINGS = global_settings() PO = import_language(language=GLOBAL_SETTINGS.get('locale.language')) def to_unicode(text, encoding='utf-8'): """ Force text to unicode """ return text.decode(encoding) if isinstance(text, bytes) else text def from_unicode(text, encoding='utf-8'): """ Force unicode to text """ import sys if sys.version_info.major == 2 and isinstance(text, unicode): # noqa: F821; pylint: disable=undefined-variable return text.encode(encoding) return text class Keyboard: ''' A stub implementation of the xbmc Keyboard class ''' def __init__(self, line='', heading=''): ''' A stub constructor for the xbmc Keyboard class ''' def doModal(self, autoclose=0): ''' A stub implementation for the xbmc Keyboard class doModal() method ''' def isConfirmed(self): ''' A stub implementation for the xbmc Keyboard class isConfirmed() method ''' return True def getText(self): ''' A stub implementation for the xbmc Keyboard class getText() method ''' return 'test' class Monitor: ''' A stub implementation of the xbmc Monitor class ''' def __init__(self, line='', heading=''): ''' A stub constructor for the xbmc Monitor class ''' def abortRequested(self): ''' A stub implementation for the xbmc Keyboard class abortRequested() method ''' return False def waitForAbort(self, timeout=None): ''' A stub implementation for the xbmc Keyboard class waitForAbort() method ''' return False class Player: ''' A stub implementation of the xbmc Player class ''' def __init__(self): self._count = 0 def play(self, item='', listitem=None, windowed=False, startpos=-1): ''' A stub implementation for the xbmc Player class play() method ''' return def isPlaying(self): ''' A stub implementation for the xbmc Player class isPlaying() method ''' # Return True four times out of five self._count += 1 return bool(self._count % 5 != 0) def setSubtitles(self, subtitleFile): ''' A stub implementation for the xbmc Player class setSubtitles() method ''' return def showSubtitles(self, visible): ''' A stub implementation for the xbmc Player class showSubtitles() method ''' return def getTotalTime(self): ''' A stub implementation for the xbmc Player class getTotalTime() method ''' return 0 def getTime(self): ''' A stub implementation for the xbmc Player class getTime() method ''' return 0 def getVideoInfoTag(self): ''' A stub implementation for the xbmc Player class getVideoInfoTag() method ''' return VideoInfoTag() def getPlayingFile(self): ''' A stub implementation for the xbmc Player class getPlayingFile() method ''' return '' class VideoInfoTag: ''' A stub implementation of the xbmc VideoInfoTag class ''' def __init__(self): ''' A stub constructor for the xbmc VideoInfoTag class ''' def getSeason(self): ''' A stub implementation for the xbmc VideoInfoTag class getSeason() method ''' return 0 def getEpisode(self): ''' A stub implementation for the xbmc VideoInfoTag class getEpisode() method ''' return 0 def getTVShowTitle(self): ''' A stub implementation for the xbmc VideoInfoTag class getTVShowTitle() method ''' return '' def getPlayCount(self): ''' A stub implementation for the xbmc VideoInfoTag class getPlayCount() method ''' return 0 def getRating(self): ''' A stub implementation for the xbmc VideoInfoTag class getRating() method ''' return 0 def executebuiltin(string, wait=False): # pylint: disable=unused-argument ''' A stub implementation of the xbmc executebuiltin() function ''' return def executeJSONRPC(jsonrpccommand): ''' A reimplementation of the xbmc executeJSONRPC() function ''' command = json.loads(jsonrpccommand) if command.get('method') == 'Settings.GetSettingValue': key = command.get('params').get('setting') return json.dumps(dict(id=1, jsonrpc='2.0', result=dict(value=GLOBAL_SETTINGS.get(key)))) if command.get('method') == 'Addons.GetAddonDetails': if command.get('params', {}).get('addonid') == 'script.module.inputstreamhelper': return json.dumps(dict(id=1, jsonrpc='2.0', result=dict(addon=dict(enabled='true', version='0.3.5')))) return json.dumps(dict(id=1, jsonrpc='2.0', result=dict(addon=dict(enabled='true', version='1.2.3')))) if command.get('method') == 'Textures.GetTextures': return json.dumps(dict(id=1, jsonrpc='2.0', result=dict(textures=[dict(cachedurl="", imagehash="", lasthashcheck="", textureid=4837, url="")]))) if command.get('method') == 'Textures.RemoveTexture': return json.dumps(dict(id=1, jsonrpc='2.0', result="OK")) log("executeJSONRPC does not implement method '{method}'".format(**command), 'Error') return json.dumps(dict(error=dict(code=-1, message='Not implemented'), id=1, jsonrpc='2.0')) def getCondVisibility(string): ''' A reimplementation of the xbmc getCondVisibility() function ''' if string == 'system.platform.android': return False return True def getInfoLabel(key): ''' A reimplementation of the xbmc getInfoLabel() function ''' return INFO_LABELS.get(key) def getLocalizedString(msgctxt): ''' A reimplementation of the xbmc getLocalizedString() function ''' for entry in PO: if entry.msgctxt == '#%s' % msgctxt: return entry.msgstr or entry.msgid if int(msgctxt) >= 30000: log('Unable to translate #{msgctxt}'.format(msgctxt=msgctxt), LOGERROR) return '' def getRegion(key): ''' A reimplementation of the xbmc getRegion() function ''' return REGIONS.get(key) def log(msg, level=LOGINFO): ''' A reimplementation of the xbmc log() function ''' if level in (LOGERROR, LOGFATAL): print('\033[31;1m%s: \033[32;0m%s\033[0;39m' % (LOG_MAPPING.get(level), to_unicode(msg))) if level == LOGFATAL: raise Exception(msg) elif level in (LOGWARNING, LOGNOTICE): print('\033[33;1m%s: \033[32;0m%s\033[0;39m' % (LOG_MAPPING.get(level), to_unicode(msg))) else: print('\033[32;1m%s: \033[32;0m%s\033[0;39m' % (LOG_MAPPING.get(level), to_unicode(msg))) def setContent(self, content): ''' A stub implementation of the xbmc setContent() function ''' return def sleep(seconds): ''' A reimplementation of the xbmc sleep() function ''' time.sleep(seconds) def translatePath(path): ''' A stub implementation of the xbmc translatePath() function ''' if path.startswith('special://home'): return path.replace('special://home', os.path.join(os.getcwd(), 'test/')) if path.startswith('special://masterprofile'): return path.replace('special://masterprofile', os.path.join(os.getcwd(), 'test/userdata/')) if path.startswith('special://profile'): return path.replace('special://profile', os.path.join(os.getcwd(), 'test/userdata/')) if path.startswith('special://userdata'): return path.replace('special://userdata', os.path.join(os.getcwd(), 'test/userdata/')) return path