def launch_game(game_id): core = RequiredFeature('core').request() game_controller = RequiredFeature('game-controller').request() core.logger.info('Launching game %s' % game_id) game_controller.launch_game(game_id) del core del game_controller
def __init__(self): self.core = RequiredFeature('core').request() self.plugin = RequiredFeature('plugin').request() self.base_path = '/usr/share/kodi/addons/skin.osmc/16x9/' self.shortcut_path = '/usr/share/kodi/addons/skin.osmc/shortcuts/' self.widget = 'Includes_Widgets.xml' self.var = 'Variables.xml' self.home = 'Home.xml' self.override = 'overrides.xml' self.widget_backup = 'Includes_Widgets.backup' self.var_backup = 'Variables.backup' self.home_backup = 'Home.backup' self.override_backup = 'overrides.backup' self.id = None self.supported = self.core.get_active_skin() == 'skin.osmc' \ and os.path.isfile(os.path.join(self.base_path, self.widget)) \ and os.path.isfile(os.path.join(self.base_path, self.var)) \ and os.path.isfile(os.path.join(self.base_path, self.home)) \ and os.path.isfile(os.path.join(self.shortcut_path, self.override)) self.rollback_supported = os.path.isfile(os.path.join(self.base_path, self.widget_backup)) \ and os.path.isfile(os.path.join(self.base_path, self.var_backup)) \ and os.path.isfile(os.path.join(self.base_path, self.home_backup)) \ and os.path.isfile(os.path.join(self.shortcut_path, self.override_backup))
def __init__(self, title=''): print 'Init Called' super(SelectInput, self).__init__(title) self.plugin = RequiredFeature('plugin').request() self.core = RequiredFeature('core').request() self.device_wrapper = RequiredFeature('device-wrapper').request() self.available_devices = self.device_wrapper.devices self.md5 = hashlib.md5() self.input_storage = self.plugin.get_storage('input_storage') for key, device in self.input_storage.iteritems(): print 'Devices during INIT: %s' % device.name background = None if self.core.get_active_skin() == 'skin.osmc': media_path = '/usr/share/kodi/addons/skin.osmc/media' if os.path.exists(media_path): background = os.path.join(media_path, 'dialogs/DialogBackground_old.png') if background is not None: self.background.setImage(background) self.removeControl(self.title_background) self.removeControl(self.window_close_button) self.removeControl(self.title_bar) self.controls = {} self.add_ctrl_btn = None self.setGeometry(1280, 720, 12, 6, padding=60) self.place_add_ctrl_btn() self.setFocus(self.add_ctrl_btn) self.connect(pyxbmct.ACTION_NAV_BACK, self.close_and_save) self.init_existing_controls( ) # initalise controls / mappings read from .storage
def start_running_game(): if plugin.get_setting('last_run', str): lastrun = plugin.get_setting('last_run', str) core = RequiredFeature('core').request() game_controller = RequiredFeature('game-controller').request() core.logger.info('Resuming game %s' % lastrun) game_controller.launch_game(lastrun) del core del game_controller
class ConfigController(Component): plugin = RequiredFeature('plugin') core = RequiredFeature('core') moonlight_helper = RequiredFeature('moonlight-helper') logger = RequiredFeature('logger') def __init__(self): pass def create_controller_mapping(self): self.logger.info('Starting mapping') controllers = ['XBOX', 'PS3', 'Wii'] ctrl_type = xbmcgui.Dialog().select( self.core.string('choose_ctrl_type'), controllers) map_name = xbmcgui.Dialog().input(self.core.string('enter_filename')) progress_dialog = xbmcgui.DialogProgress() progress_dialog.create(self.core.string('name'), self.core.string('starting_mapping')) self.core.logger.info('Trying to call subprocess') map_file = '%s/%s-%s.map' % (os.path.expanduser('~'), controllers[ctrl_type], map_name) success = self.moonlight_helper.create_ctrl_map( progress_dialog, map_file) if success: confirmed = xbmcgui.Dialog().yesno( self.core.string('name'), self.core.string('mapping_success'), self.core.string('set_mapping_active')) self.core.logger.info('Dialog Yes No Value: %s' % confirmed) if confirmed: self.plugin.set_setting('input_map', map_file) else: xbmcgui.Dialog().ok(self.core.string('name'), self.core.string('mapping_failure')) def pair_host(self): pair_dialog = xbmcgui.DialogProgress() pair_dialog.create(self.core.string('name'), 'Starting Pairing') success = self.moonlight_helper.pair_host(pair_dialog) if success: xbmcgui.Dialog().ok(self.core.string('name'), 'Successfully paired') else: confirmed = xbmcgui.Dialog().yesno( self.core.string('name'), 'Pairing failed - do you want to try again?') if confirmed: self.pair_host()
class CoreMonitor(Component): logger = RequiredFeature('logger') config_helper = RequiredFeature('config-helper') def __init__(self): pass def onSettingsChanged(self): self.logger.info('Settings change called') self.config_helper.configure()
def reset_cache(): core = RequiredFeature('core').request() confirmed = xbmcgui.Dialog().yesno(core.string('name'), core.string('reset_cache_warning')) if confirmed: scraper_chain = RequiredFeature('scraper-chain').request() scraper_chain.reset_cache() del scraper_chain del core
def launch_game_from_widget(xml_id): core = RequiredFeature('core').request() game_id = int(xml_id) internal_game_id = plugin.get_storage('sorted_game_storage').get(game_id) game_controller = RequiredFeature('game-controller').request() core.logger.info('Launching game %s' % internal_game_id) game_controller.launch_game(internal_game_id) del core del game_controller
def reset_cache(): import xbmcgui if plugin.get_setting('last_run', str): plugin.set_setting('last_run', '') core = RequiredFeature('core').request() confirmed = xbmcgui.Dialog().yesno(core.string('name'), core.string('reset_cache_warning')) if confirmed: scraper_chain = RequiredFeature('scraper-chain').request() scraper_chain.reset_cache() del scraper_chain del core
def show_games(): import xbmcgui if os.path.isfile( "/storage/.kodi/userdata/addon_data/script.luna/.storage/luna.conf" ): os.remove( "/storage/.kodi/userdata/addon_data/script.luna/.storage/luna.conf" ) if (check_host(plugin.get_setting('host', str)) == True): if os.path.isfile("/storage/.cache/moonlight/client.p12"): game_controller = RequiredFeature('game-controller').request() #plugin.set_content('movies') return plugin.finish(game_controller.get_games_as_list(), sort_methods=['label']) else: xbmcgui.Dialog().ok( 'Pair key not found!', 'Please pair with the host before proceeding...') open_settings() else: xbmcgui.Dialog().ok( 'Communication Error', 'The host is either not powered on or is asleep on the job. \nOtherwise, please troubleshoot a network issue.' )
def create_mapping(self, control): print 'Starting mapping' map_name = xbmcgui.Dialog().input(self.core.string('enter_filename')) progress_dialog = xbmcgui.DialogProgress() progress_dialog.create(self.core.string('name'), self.core.string('starting_mapping')) map_file = '%s/%s.map' % (os.path.expanduser('~'), map_name) moonlight_helper = RequiredFeature('moonlight-helper').request() success = moonlight_helper.create_ctrl_map_new(progress_dialog, map_file, control.device) if success: confirmed = xbmcgui.Dialog().yesno( self.core.string('name'), self.core.string('mapping_success'), self.core.string('set_mapping_active')) self.core.logger.info('Dialog Yes No Value: %s' % confirmed) if confirmed: control.set_mapping_file(map_file) for key, device in self.input_storage.iteritems(): print 'Iterating devices, current IS device: %s' % device.name if device.name == control.device.name: device.mapping = map_file print 'Found device and saved mapping' break else: xbmcgui.Dialog().ok(self.core.string('name'), self.core.string('mapping_failure'))
def testGetWrapperFeature(self): pairing_manager = RequiredFeature('pairing-manager').request() self.assertIsInstance(pairing_manager, PairingManagerWrapper) self.assertEqual(hasattr(pairing_manager, '_pairing_manager'), True) self.assertIsNone(pairing_manager._pairing_manager) crypto_provider = RequiredFeature('crypto-provider').request() self.assertIsInstance(crypto_provider, CryptoProviderWrapper) self.assertEqual(hasattr(crypto_provider, '_crypto_provider'), True) self.assertIsNone(crypto_provider._crypto_provider) asserted_path = os.path.join(os.path.expanduser('~'), '.cache/moonlight/') self.assertEqual(asserted_path, crypto_provider.get_key_dir()) self.assertIsNotNone(crypto_provider._crypto_provider) self.assertIsInstance(crypto_provider._crypto_provider, SimpleCryptoProvider) self.assertRaises(NotImplementedError, crypto_provider.get_client_private_key)
def __init__(self): AbstractScraper.__init__(self) self.plugin = RequiredFeature('plugin').request() self.api_url = 'http://www.omdbapi.com/?t=%s&plot=short&r=json&type=game' self.cover_cache = self._set_up_path( os.path.join(self.base_path, 'art/poster/')) self.api_cache = self._set_up_path( os.path.join(self.base_path, 'api_cache/'))
def __init__(self): AbstractScraper.__init__(self) self.plugin = RequiredFeature('plugin').request() self.api_url = 'https://www.igdb.com/api/v1/games/%s' self.api_img_url = 'https://res.cloudinary.com/igdb/image/upload/t_%s/%s.jpg' self.cover_cache = self._set_up_path( os.path.join(self.base_path, 'art/poster/')) self.api_cache = self._set_up_path( os.path.join(self.base_path, 'api_cache/'))
def build_etree(self, xml_string): try: etree = ET.fromstring(self.re_encode_string(xml_string)) except ET.ParseError as e: logger = RequiredFeature('logger').request() logger.error( "Building ETree from XML failed: %s. Offending string follows ..." % e.message) logger.error(xml_string) raise ValueError("Building ETree Failed") return etree
def show_game_info(game_id): core = RequiredFeature('core').request() game = core.get_storage().get(game_id) cache_fanart = game.get_selected_fanart() cache_poster = game.get_selected_poster() window = GameInfo(game, game.name) window.doModal() del window if cache_fanart != game.get_selected_fanart( ) or cache_poster != game.get_selected_poster(): xbmc.executebuiltin('Container.Refresh') del core del game
class Logger(Component): plugin = RequiredFeature('plugin') def __init__(self): pass def info(self, text): self.plugin.log.info(text) def debug(self, text): self.plugin.log.debug(text) def error(self, text): self.plugin.log.error(text)
def launch_game(game_id): import xbmcgui import time if (check_host(plugin.get_setting('host', str)) == True): if plugin.get_setting('last_run', str): lastrun = plugin.get_setting('last_run', str) if (lastrun != game_id): result = quit_game('Switch') if result == 'True': core = RequiredFeature('core').request() game_controller = RequiredFeature( 'game-controller').request() core.logger.info('Launching game %s' % game_id) game_controller.launch_game(game_id) del core del game_controller else: core = RequiredFeature('core').request() game_controller = RequiredFeature('game-controller').request() core.logger.info('Launching game %s' % game_id) game_controller.launch_game(game_id) del core del game_controller else: core = RequiredFeature('core').request() game_controller = RequiredFeature('game-controller').request() core.logger.info('Launching game %s' % game_id) game_controller.launch_game(game_id) del core del game_controller else: if plugin.get_setting('last_run', str): cleanup = xbmcgui.Dialog().yesno( 'Communication Error', 'The host is either not powered on or is asleep on the job. \nOtherwise, please troubleshoot a network issue. \nIf you have restarted the host since your last session, you will need to remove residual data. \n\nWould you like to remove residual data now?', nolabel='No', yeslabel='Yes') if cleanup: plugin.set_setting('last_run', '') else: xbmcgui.Dialog().ok( 'Communication Error', 'The host is either not powered on or is asleep on the job. \nOtherwise, please troubleshoot a network issue.' )
class PairingManagerWrapper(AbstractPairingManager): def __init__(self): # implementation will be lazy loaded when needed self._pairing_manager = None def pair(self, nvhttp, server_info, pin): if self._pairing_manager is None: self._load_pairing_manager() return self._pairing_manager.pair(nvhttp, server_info, pin) def _load_pairing_manager(self): try: module = importlib.import_module( 'resources.lib.nvhttp.pairingmanager.advancedpairingmanager') class_name = 'AdvancedPairingManager' except ImportError, e: print 'Could not load advanced pairing manager. Reason: %r' % e module = importlib.import_module( 'resources.lib.nvhttp.pairingmanager.simplepairingmanager') class_name = 'SimplePairingManager' class_ = getattr(module, class_name) self._pairing_manager = class_( RequiredFeature('crypto-provider').request())
def testConfigurationCorrectness(self): config = RequiredFeature('config-helper').request() config._configure(**self.fake_settings) config._dump_conf() self.assertEqual(self.bin_path, config.get_section_setting('General', 'binpath')) self.assertEqual('192.168.1.1', config.get_section_setting('General', 'address')) self.assertEqual('60', config.get_section_setting('General', 'fps')) self.assertEqual('-1', config.get_section_setting('General', 'bitrate')) self.assertEqual('1024', config.get_section_setting('General', 'packetsize')) self.assertEqual(os.path.join(self.addon_path, 'input.map'), config.get_section_setting('General', 'mapping')) self.assertEqual(os.path.join(self.addon_path, 'input.device'), config.get_section_setting('General', 'input')) self.assertEqual('False', config.get_section_setting('General', 'sops')) self.assertEqual('False', config.get_section_setting('General', 'localaudio')) self.assertEqual('False', config.get_section_setting('General', 'remote'))
def pair_host(self, dialog): return RequiredFeature('connection-manager').request().pair(dialog)
import xbmcaddon __addon__ = xbmcaddon.Addon() if __name__ == '__main__': if __addon__.getSetting("luna_widget_enable") == 'true': import resources.lib.config.bootstrap as bootstrapper from xbmcswift2 import xbmcgui from resources.lib.di.requiredfeature import RequiredFeature plugin = bootstrapper.bootstrap() WINDOW = xbmcgui.Window(10000) core = RequiredFeature('core').request() storage = core.get_storage() sorted_list = sorted(storage.raw_dict().keys()) sorted_storage = plugin.get_storage('sorted_game_storage') sorted_storage.clear() for i, game_name in enumerate(sorted_list): game = storage.get(game_name) WINDOW.setProperty('Luna.%s.name' % i, game.name) WINDOW.setProperty('Luna.%s.icon' % i, game.get_selected_poster()) WINDOW.setProperty('Luna.%s.thumb' % i, game.get_selected_poster()) WINDOW.setProperty('Luna.%s.fanart' % i, game.get_selected_fanart().get_original()) sorted_storage[i] = game_name sorted_storage.sync()
def setUp(self): self.chain = RequiredFeature('scraper-chain').request()
class GameInfo(pyxbmct.AddonDialogWindow): plugin = RequiredFeature('plugin') core = RequiredFeature('core') def __init__(self, game, title=''): super(GameInfo, self).__init__(title) self.game = game background = None if self.core.get_active_skin() == 'skin.osmc': media_path = '/usr/share/kodi/addons/skin.osmc/media' if os.path.exists(media_path): background = os.path.join(media_path, 'dialogs/DialogBackground_old.png') if background is not None: self.background.setImage(background) self.removeControl(self.title_background) self.removeControl(self.window_close_button) self.removeControl(self.title_bar) # init controls self.image = None self.genre = None self.year = None self.plot = None self.button_play = None self.button_cover_art = None self.button_fanart = None self.setGeometry(1280, 720, 12, 6, padding=60) self.set_info_controls(game) self.set_active_controls(game) self.set_navigation() self.connect(pyxbmct.ACTION_NAV_BACK, self.close) def set_info_controls(self, game): title_label = pyxbmct.Label(game.name, alignment=pyxbmct.ALIGN_LEFT, font='XLarge', textColor=COLOR_HEADING) self.placeControl(title_label, 0, 0, 2, 3) image_path = game.get_selected_poster() if image_path is None: image_path = '' self.image = pyxbmct.Image(image_path) self.placeControl(self.image, 2, 0, 6, 1) genre_label = pyxbmct.Label('Genre', alignment=pyxbmct.ALIGN_LEFT, font='Med', textColor=COLOR_DETAILS) self.placeControl(genre_label, 2, 2) self.genre = pyxbmct.FadeLabel(_alignment=pyxbmct.ALIGN_LEFT, font='Med') self.placeControl(self.genre, 2, 3, columnspan=3) self.genre.addLabel(game.get_genre_as_string()) year_label = pyxbmct.Label('Year', alignment=pyxbmct.ALIGN_LEFT, font='Med', textColor=COLOR_DETAILS) self.placeControl(year_label, 3, 2) self.year = pyxbmct.Label(game.year, alignment=pyxbmct.ALIGN_LEFT, font='Med') self.placeControl(self.year, 3, 3) self.plot = pyxbmct.TextBox() self.placeControl(self.plot, 4, 2, 6, 3) self.plot.setText(game.plot) self.plot.autoScroll(delay=5000, time=2000, repeat=10000) def set_active_controls(self, game): self.button_play = pyxbmct.Button('Play', focusTexture='', noFocusTexture='', focusedColor=COLOR_FO, textColor=COLOR_NF, font='Med', alignment=pyxbmct.ALIGN_LEFT) self.placeControl(self.button_play, 11, 0) self.connect(self.button_play, self.launch_game) self.button_cover_art = pyxbmct.Button('Choose Cover Art', focusTexture='', noFocusTexture='', focusedColor=COLOR_FO, textColor=COLOR_NF, font='Med', alignment=pyxbmct.ALIGN_LEFT) self.placeControl(self.button_cover_art, 11, 1, columnspan=2) self.connect(self.button_cover_art, self.select_cover_art) self.button_fanart = pyxbmct.Button('Choose Fanart', focusTexture='', noFocusTexture='', focusedColor=COLOR_FO, textColor=COLOR_NF, font='Med', alignment=pyxbmct.ALIGN_LEFT) self.placeControl(self.button_fanart, 11, 3, columnspan=2) self.connect(self.button_fanart, self.select_fanart) def set_navigation(self): self.button_play.controlRight(self.button_cover_art) self.button_play.controlLeft(self.button_fanart) self.button_cover_art.controlRight(self.button_fanart) self.button_cover_art.controlLeft(self.button_play) self.button_fanart.controlRight(self.button_play) self.button_fanart.controlLeft(self.button_cover_art) self.setFocus(self.button_play) def launch_game(self): xbmc.executebuiltin('XBMC.RunPlugin(%s)' % self.plugin.url_for( endpoint='launch_game', game_id=self.game.name)) def select_fanart(self): browser = xbmcgui.Dialog().browse( 2, 'Select Fanart', 'files', '.jpg|.png', False, False, self.game.get_selected_fanart().get_thumb()) if browser: self.game.set_selected_fanart(browser) self.core.get_storage().sync() def select_cover_art(self): browser = xbmcgui.Dialog().browse(2, 'Select Cover Art', 'files', '.jpg|.png', False, False, self.game.get_poster(0, '')) if browser: self.game.selected_poster = browser self.core.get_storage().sync() self.image = pyxbmct.Image(browser) self.placeControl(self.image, 2, 0, 6, 1) def setAnimation(self, control): control.setAnimations([( 'WindowOpen', 'effect=fade start=0 end=100 time=500', ), ( 'WindowClose', 'effect=fade start=100 end=0 time=500', )])
def re_encode_string(self, xml_string): logger = RequiredFeature('logger').request() regex = re.compile('UTF-\d{1,2}') specified_encoding = regex.search(xml_string) logger.info("Trying to decode as: %s" % 'ASCII') try: xml_string = xml_string.decode(encoding='ascii') except UnicodeDecodeError as e: logger.info("Decoding as %s failed, trying as %s" % ('ASCII', 'UTF-8')) try: xml_string = xml_string.decode(encoding='UTF-8') except UnicodeDecodeError as e: logger.info("Decoding as %s failed, trying as %s" % ('UTF-8', 'UTF-16')) try: xml_string = xml_string.decode(encoding='UTF-16') except UnicodeDecodeError as e: logger.error( "Decoding as UTF-16 failed, this was the last attempt. Offending string follows ..." ) logger.error(xml_string) raise ValueError("String Decode Failed") if specified_encoding is not None: try: logger.info("Trying to encode as specified in XML: %s" % specified_encoding.group(0)) xml_string = xml_string.encode( encoding=specified_encoding.group(0)) except UnicodeEncodeError as e: new_encode_setting = 'UTF-16' if specified_encoding.group( 0) == 'UTF-8' else 'UTF-8' logger.info("Encoding as %s failed, trying as %s" % (specified_encoding.group(0), new_encode_setting)) try: xml_string = xml_string.encode(encoding=new_encode_setting) except UnicodeEncodeError as e: logger.error( "Encoding as %s failed, this was the last attempt. Offending string follows ..." % new_encode_setting) logger.error(xml_string) raise ValueError("String Encode Failed") return xml_string else: logger.info("RegExp couldn't find a match in the XML string ...") try: logger.info("Trying to encode as: UTF-8") xml_string = xml_string.encode(encoding='UTF-8') except UnicodeEncodeError as e: logger.info("Encoding as UTF-8 failed, trying as UTF-16") try: xml_string = xml_string.encode(encoding='UTF-16') except UnicodeEncodeError as e: logger.error( "Encoding as UTF-16 failed, this was the last attempt. Offending string follows ..." ) logger.error(xml_string) raise ValueError("String Encode Failed") return xml_string
def __init__(self, crypto_provider): self.crypto_provider = crypto_provider self.config_helper = RequiredFeature('config-helper').request() self.logger = RequiredFeature('logger').request()
def list_games(self): return RequiredFeature('nvhttp').request().get_app_list()
def launch_game(self, game_id): import time import xbmcgui player = xbmc.Player() if player.isPlayingVideo(): player.stop() if self.plugin.get_setting('last_run', str): xbmc.audioSuspend() xbmc.executebuiltin("Dialog.Close(busydialog)") xbmc.executebuiltin("Dialog.Close(notification)") if os.path.isfile("/storage/moonlight/aml_decoder.stats"): os.remove("/storage/moonlight/aml_decoder.stats") self.config_helper.configure() if self.plugin.get_setting('last_run', str): sp = subprocess.Popen( ["moonlight", "stream", "-app", game_id, "-logging"], cwd="/storage/moonlight", env={'LD_LIBRARY_PATH': '/storage/moonlight'}, shell=False, preexec_fn=os.setsid) else: sp = subprocess.Popen( [ "moonlight", "stream", "-app", game_id, "-logging", "-delay", "10" ], cwd="/storage/moonlight", env={'LD_LIBRARY_PATH': '/storage/moonlight'}, shell=False, preexec_fn=os.setsid) subprocess.Popen([ '/storage/.kodi/addons/script.luna/resources/lib/launchscripts/osmc/moonlight-heartbeat.sh' ], shell=False) if not self.plugin.get_setting('last_run', str): xbmc.Player().play( '/storage/.kodi/addons/script.luna/resources/statics/loading.mp4' ) time.sleep(8) xbmc.audioSuspend() time.sleep(2.5) xbmc.Player().stop() self.plugin.set_setting('last_run', game_id) subprocess.Popen(['killall', '-STOP', 'kodi.bin'], shell=False) sp.wait() main = "pkill -x moonlight" heartbeat = "pkill -x moonlight-heart" print(os.system(main)) print(os.system(heartbeat)) xbmc.audioResume() if os.path.isfile("/storage/moonlight/aml_decoder.stats"): with open("/storage/moonlight/aml_decoder.stats") as stat_file: statistics = stat_file.read() if "StreamStatus = -1" in statistics: confirmed = xbmcgui.Dialog().yesno( 'Stream initialisation failed...', 'Try running ' + game_id + ' again?', nolabel='No', yeslabel='Yes') if confirmed: self.launch_game(game_id) else: xbmcgui.Dialog().ok('Stream statistics', statistics) game_controller = RequiredFeature('game-controller').request() game_controller.refresh_games() del game_controller xbmc.executebuiltin('Container.Refresh') xbmcgui.Dialog().notification( 'Information', game_id + ' is still running on host. Resume via Luna, ensuring to quit before the host is restarted!', xbmcgui.NOTIFICATION_INFO, False)
def rollback_osmc_skin(): skinpatcher = RequiredFeature('skin-patcher').request() skinpatcher.rollback() del skinpatcher xbmc.executebuiltin('ReloadSkin')
def pair_host(): config_controller = RequiredFeature('config-controller').request() config_controller.pair_host() del config_controller