From a9e3f1a20a56bed070f4df8b2a2a00180ef99b0e Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Fri, 18 Dec 2015 21:27:02 +0100 Subject: [PATCH 01/13] LUNA-1: Refactored game storage; added icons for settings and games subviews --- addon.py | 30 +++++++++++++++++++----------- addon.xml | 2 +- resources/icons/cog.png | Bin 0 -> 23701 bytes resources/icons/controller.png | Bin 0 -> 26784 bytes 4 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 resources/icons/cog.png create mode 100644 resources/icons/controller.png diff --git a/addon.py b/addon.py index 19de610..351110f 100755 --- a/addon.py +++ b/addon.py @@ -32,11 +32,13 @@ def index(): items = [{ 'label': 'Games', + 'thumbnail': addon_internal_path+'/resources/icons/cog.png', 'path': plugin.url_for( endpoint='show_games' ) }, { 'label': 'Settings', + 'thumbnail': addon_internal_path+'/resources/icons/controller.png', 'path': plugin.url_for( endpoint='open_settings' ) @@ -151,29 +153,29 @@ def context_menu(): ) ] - Config.dump_conf() - game_storage = plugin.get_storage('game_storage') - game_storage.clear() - games = get_games() + games = plugin.get_storage('game_storage') + + if len(games) == 0: + get_games() + items = [] - for i, game in enumerate(games): - label = game + for game in games: items.append({ - 'label': label, + 'label': game.name, + 'thumbnail': '', 'replace_context_menu': True, 'context_menu': context_menu(), 'path': plugin.url_for( endpoint='launch_game', - game_id=game + game_id=game.name ) }) - game_storage.sync() return plugin.finish(items) @plugin.route('/games/all/refresh') def do_full_refresh(): - return get_games() + get_games() @plugin.route('/games/launch/') @@ -189,6 +191,7 @@ def launch_game(game_id): def launch_moonlight_pair(): + configure_helper(Config, Config.get_binary()) code = [] process = subprocess.Popen([Config.get_binary(), 'pair', Config.get_host()], stdout=subprocess.PIPE) while True: @@ -206,6 +209,7 @@ def loop_lines(dialog, iterator): def get_games(): + configure_helper(Config, Config.get_binary()) game_list = [] list_proc = subprocess.Popen([Config.get_binary(), 'list', Config.get_host()], stdout=subprocess.PIPE) while True: @@ -214,7 +218,11 @@ def get_games(): game_list.append(line[3:].strip()) if not line: break - return game_list + game_storage = plugin.get_storage('game_storage') + game_storage.clear() + for game in game_list: + game_storage['game'] = {'name': game} + game_storage.sync() def get_binary(): diff --git a/addon.xml b/addon.xml index 516035f..93b1a5d 100644 --- a/addon.xml +++ b/addon.xml @@ -11,6 +11,6 @@ all Moonlight Launcher for Kodi - Moonlight Launcher for Kodi + Moonlight Launcher for Kodi. [CR]Icons made by Freepik from www.flaticon.com diff --git a/resources/icons/cog.png b/resources/icons/cog.png new file mode 100644 index 0000000000000000000000000000000000000000..e4e9d9637b20b7f33584fb5ed7b7bc0e47009ce2 GIT binary patch literal 23701 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%0DkTaeP0=Mgh1n}YlZJyitWPBjD0%QQ=bflkHt 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 literal 0 HcmV?d00001 From 62413074a1daa8674ff431eefa27fa6a42fc7c23 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Fri, 18 Dec 2015 22:08:54 +0100 Subject: [PATCH 02/13] LUNA-1: experimental implementation of querying omdb for game info --- addon.py | 29 +++++++++++++++++++++-------- resources/lib/game.py | 7 +++++++ 2 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 resources/lib/game.py diff --git a/addon.py b/addon.py index 351110f..fb217f5 100755 --- a/addon.py +++ b/addon.py @@ -2,10 +2,13 @@ import subprocess import threading import stat +import json +import urllib2 from xbmcswift2 import Plugin, xbmcgui, xbmc, xbmcaddon from resources.lib.confighelper import ConfigHelper +from resources.lib.game import Game STRINGS = { 'name': 30000, @@ -161,13 +164,19 @@ def context_menu(): items = [] for game in games: items.append({ - 'label': game.name, - 'thumbnail': '', + 'label': game.get('name'), + 'thumbnail': game.get('thumb', ''), + 'info': { + 'originaltitle': game.get('name'), + 'year': game.get('year'), + 'plot': game.get('plot'), + 'genre': game.get('genre'), + }, 'replace_context_menu': True, 'context_menu': context_menu(), 'path': plugin.url_for( endpoint='launch_game', - game_id=game.name + game_id=game.get('name') ) }) return plugin.finish(items) @@ -209,19 +218,23 @@ def loop_lines(dialog, iterator): def get_games(): + api_url = 'http://www.omdbapi.com/?t=%s&plot=short&r=json&type=game' configure_helper(Config, Config.get_binary()) game_list = [] list_proc = subprocess.Popen([Config.get_binary(), 'list', Config.get_host()], stdout=subprocess.PIPE) while True: line = list_proc.stdout.readline() log(line[3:]) - game_list.append(line[3:].strip()) - if not line: - break + if line[3:] != '': + game_list.append(line[3:].strip()) + if not line: + break game_storage = plugin.get_storage('game_storage') game_storage.clear() - for game in game_list: - game_storage['game'] = {'name': game} + for game_name in game_list: + response = json.load(urllib2.urlopen(api_url % game_name)) + game = Game(game_name, response) + game_storage[game_name] = game game_storage.sync() diff --git a/resources/lib/game.py b/resources/lib/game.py new file mode 100644 index 0000000..89da944 --- /dev/null +++ b/resources/lib/game.py @@ -0,0 +1,7 @@ +class Game: + def __init__(self, name, json): + self.name = name + self.year = json['Year'] + self.genre = json['Genre'] + self.plot = json['Plot'] + self.thumb = json['Poster'] From bfecaa810f03a7e71fa6a7a1858e62279d5bfd88 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 02:02:25 +0100 Subject: [PATCH 03/13] LUNA-1: added another API as fallback; caching images to disk --- addon.py | 177 ++++++++++++++++++++++++++++-------------- resources/lib/game.py | 17 +++- 2 files changed, 132 insertions(+), 62 deletions(-) diff --git a/addon.py b/addon.py index fb217f5..847f6c8 100755 --- a/addon.py +++ b/addon.py @@ -4,6 +4,7 @@ import stat import json import urllib2 +import xml.etree.ElementTree as ET from xbmcswift2 import Plugin, xbmcgui, xbmc, xbmcaddon @@ -35,15 +36,15 @@ def index(): items = [{ 'label': 'Games', - 'thumbnail': addon_internal_path+'/resources/icons/cog.png', + 'thumbnail': addon_internal_path + '/resources/icons/cog.png', 'path': plugin.url_for( - endpoint='show_games' + endpoint='show_games' ) }, { 'label': 'Settings', - 'thumbnail': addon_internal_path+'/resources/icons/controller.png', + 'thumbnail': addon_internal_path + '/resources/icons/controller.png', 'path': plugin.url_for( - endpoint='open_settings' + endpoint='open_settings' ) }] return plugin.finish(items) @@ -67,8 +68,8 @@ def create_mapping(): progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( - _('name'), - _('starting_mapping') + _('name'), + _('starting_mapping') ) log('Trying to call subprocess') @@ -100,9 +101,9 @@ def create_mapping(): if os.path.isfile(map_file) and success == 'true': confirmed = xbmcgui.Dialog().yesno( - _('name'), - _('mapping_success'), - _('set_mapping_active') + _('name'), + _('mapping_success'), + _('set_mapping_active') ) log('Dialog Yes No Value: %s' % confirmed) if confirmed: @@ -114,8 +115,8 @@ def create_mapping(): else: if success == 'false': xbmcgui.Dialog().ok( - _('name'), - _('mapping_failure') + _('name'), + _('mapping_failure') ) else: return @@ -133,8 +134,8 @@ def pair_host(): line = code[0] xbmcgui.Dialog().ok( - _('name'), - line + _('name'), + line ) @@ -145,38 +146,41 @@ def context_menu(): ( _('addon_settings'), 'XBMC.RunPlugin(%s)' % plugin.url_for( - endpoint='open_settings' + endpoint='open_settings' ) ), ( _('full_refresh'), 'XBMC.RunPlugin(%s)' % plugin.url_for( - endpoint='do_full_refresh' + endpoint='do_full_refresh' ) ) ] games = plugin.get_storage('game_storage') - if len(games) == 0: + if len(games.raw_dict()) == 0: get_games() items = [] - for game in games: + for i, game_name in enumerate(games): + game = games.get(game_name) + print game.thumb items.append({ - 'label': game.get('name'), - 'thumbnail': game.get('thumb', ''), + 'label': game.name, + 'icon': game.thumb, + 'thumbnail': game.thumb, 'info': { - 'originaltitle': game.get('name'), - 'year': game.get('year'), - 'plot': game.get('plot'), - 'genre': game.get('genre'), + 'originaltitle': game.name, + 'year': game.year, + 'plot': game.plot, + 'genre': game.genre, }, 'replace_context_menu': True, 'context_menu': context_menu(), 'path': plugin.url_for( - endpoint='launch_game', - game_id=game.get('name') + endpoint='launch_game', + game_id=game.name ) }) return plugin.finish(items) @@ -192,9 +196,9 @@ def launch_game(game_id): log('Launching game %s' % game_id) configure_helper(Config, Config.get_binary()) log('Reconfigured helper and dumped conf to disk.') - subprocess.call([addon_internal_path+'/resources/lib/launch-helper-osmc.sh', - addon_internal_path+'/resources/lib/launch.sh', - addon_internal_path+'/resources/lib/moonlight-heartbeat.sh', + subprocess.call([addon_internal_path + '/resources/lib/launch-helper-osmc.sh', + addon_internal_path + '/resources/lib/launch.sh', + addon_internal_path + '/resources/lib/moonlight-heartbeat.sh', game_id, Config.get_config_path()]) @@ -219,21 +223,78 @@ def loop_lines(dialog, iterator): def get_games(): api_url = 'http://www.omdbapi.com/?t=%s&plot=short&r=json&type=game' + fallback_url = 'http://thegamesdb.net/api/GetGame.php?name=%s' + + def find_image(e): + for i in e.findall('Game'): + if i.find('Platform').text == 'PC': + for boxart in i.find('Images'): + if boxart.get('side') == 'front': + return boxart.text + return None + + if not os.path.exists(addon_path + '/boxarts'): + os.makedirs(addon_path + '/boxarts') + configure_helper(Config, Config.get_binary()) game_list = [] list_proc = subprocess.Popen([Config.get_binary(), 'list', Config.get_host()], stdout=subprocess.PIPE) while True: line = list_proc.stdout.readline() - log(line[3:]) if line[3:] != '': + log(line[3:]) game_list.append(line[3:].strip()) - if not line: - break + if not line: + break + log('Done getting games from moonlight') game_storage = plugin.get_storage('game_storage') game_storage.clear() for game_name in game_list: - response = json.load(urllib2.urlopen(api_url % game_name)) - game = Game(game_name, response) + # TODO: this should be a little scraper inside lib + request_name = game_name.replace(" ", "+") + request_name = request_name.replace(":", "") + log('Trying to query API %s' % api_url % request_name) + response = json.load(urllib2.urlopen(api_url % request_name)) + print response + + if response['Response'] == 'False': + game = Game(game_name, None) + + else: + if response['Poster'] == 'N/A': + img_base_url = None + log('Trying to query fallback API %s' % fallback_url % request_name) + # TODO: properly cache game information and load from disk before querying this API + # TODO 2: build an option to clear the cached information + curl = subprocess.Popen(['curl', '-XGET', fallback_url % request_name], stdout=subprocess.PIPE) + with open(addon_path + request_name + '.xml', 'w') as last_request: + last_request.write(curl.stdout.read()) + + root = ET.ElementTree(file=addon_path + request_name + '.xml').getroot() + + for item in root: + if item.tag == 'baseImgUrl': + img_base_url = item.text + + image_url = find_image(root) + + if img_base_url is not None and image_url is not None: + if not os.path.isfile(addon_path + '/boxarts/' + os.path.basename(image_url)): + with open(addon_path + '/boxarts/' + os.path.basename(image_url), 'wb') as img: + img_curl = subprocess.Popen(['curl', '-XGET', img_base_url+image_url], stdout=subprocess.PIPE) + img.write(img_curl.stdout.read()) + img.close() + response['Poster'] = addon_path + '/boxarts/' + os.path.basename(image_url) + else: + if not os.path.isfile(addon_path + '/boxarts/' + os.path.basename(response['Poster'])): + with open(addon_path + '/boxarts/' + os.path.basename(response['Poster']), 'wb') as img: + img_curl = subprocess.Popen(['curl', '-XGET', response['Poster']], stdout=subprocess.PIPE) + img.write(img_curl.stdout.read()) + img.close() + response['Poster'] = addon_path + '/boxarts/' + os.path.basename(response['Poster']) + + game = Game(game_name, response) + game_storage[game_name] = game game_storage.sync() @@ -258,23 +319,23 @@ def configure_helper(config, binary_path): :param binary_path: string """ config.configure( - addon_path, - binary_path, - plugin.get_setting('host', unicode), - plugin.get_setting('enable_custom_resolution', bool), - plugin.get_setting('resolution_width', str), - plugin.get_setting('resolution_height', str), - plugin.get_setting('resolution', str), - plugin.get_setting('framerate', str), - plugin.get_setting('graphic_optimizations', bool), - plugin.get_setting('remote_optimizations', bool), - plugin.get_setting('local_audio', bool), - plugin.get_setting('enable_custom_bitrate', bool), - plugin.get_setting('bitrate', int), - plugin.get_setting('packetsize', int), - plugin.get_setting('enable_custom_input', bool), - plugin.get_setting('input_map', str), - plugin.get_setting('input_device', str) + addon_path, + binary_path, + plugin.get_setting('host', unicode), + plugin.get_setting('enable_custom_resolution', bool), + plugin.get_setting('resolution_width', str), + plugin.get_setting('resolution_height', str), + plugin.get_setting('resolution', str), + plugin.get_setting('framerate', str), + plugin.get_setting('graphic_optimizations', bool), + plugin.get_setting('remote_optimizations', bool), + plugin.get_setting('local_audio', bool), + plugin.get_setting('enable_custom_bitrate', bool), + plugin.get_setting('bitrate', int), + plugin.get_setting('packetsize', int), + plugin.get_setting('enable_custom_input', bool), + plugin.get_setting('input_map', str), + plugin.get_setting('input_device', str) ) config.dump_conf() @@ -283,19 +344,19 @@ def configure_helper(config, binary_path): def check_script_permissions(): - st = os.stat(addon_internal_path+'/resources/lib/launch.sh') + st = os.stat(addon_internal_path + '/resources/lib/launch.sh') if not bool(st.st_mode & stat.S_IXUSR): - os.chmod(addon_internal_path+'/resources/lib/launch.sh', st.st_mode | 0111) + os.chmod(addon_internal_path + '/resources/lib/launch.sh', st.st_mode | 0111) log('Changed file permissions for launch') - st = os.stat(addon_internal_path+'/resources/lib/launch-helper-osmc.sh') + st = os.stat(addon_internal_path + '/resources/lib/launch-helper-osmc.sh') if not bool(st.st_mode & stat.S_IXUSR): - os.chmod(addon_internal_path+'/resources/lib/launch-helper-osmc.sh', st.st_mode | 0111) + os.chmod(addon_internal_path + '/resources/lib/launch-helper-osmc.sh', st.st_mode | 0111) log('Changed file permissions for launch-helper-osmc') - st = os.stat(addon_internal_path+'/resources/lib/moonlight-heartbeat.sh') + st = os.stat(addon_internal_path + '/resources/lib/moonlight-heartbeat.sh') if not bool(st.st_mode & stat.S_IXUSR): - os.chmod(addon_internal_path+'/resources/lib/moonlight-heartbeat.sh', st.st_mode | 0111) + os.chmod(addon_internal_path + '/resources/lib/moonlight-heartbeat.sh', st.st_mode | 0111) log('Changed file permissions for moonlight-heartbeat') @@ -319,6 +380,6 @@ def _(string_id): plugin.run() else: xbmcgui.Dialog().ok( - _('name'), - _('configure_first') + _('name'), + _('configure_first') ) diff --git a/resources/lib/game.py b/resources/lib/game.py index 89da944..9b6bf41 100644 --- a/resources/lib/game.py +++ b/resources/lib/game.py @@ -1,7 +1,16 @@ class Game: def __init__(self, name, json): self.name = name - self.year = json['Year'] - self.genre = json['Genre'] - self.plot = json['Plot'] - self.thumb = json['Poster'] + if json is not None: + self.year = json['Year'] + self.genre = json['Genre'] + self.plot = json['Plot'] + if json['Poster'] != 'N/A': + self.thumb = json['Poster'] + else: + self.thumb = '' + else: + self.year = '' + self.genre = '' + self.plot = '' + self.thumb = '' From 4c4a324a4df101bb336093d7fb1ed18fe0a842f2 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 13:05:01 +0100 Subject: [PATCH 04/13] LUNA: Pairing hotfix --- addon.py | 114 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/addon.py b/addon.py index 19de610..4e84866 100755 --- a/addon.py +++ b/addon.py @@ -33,12 +33,12 @@ def index(): items = [{ 'label': 'Games', 'path': plugin.url_for( - endpoint='show_games' + endpoint='show_games' ) }, { 'label': 'Settings', 'path': plugin.url_for( - endpoint='open_settings' + endpoint='open_settings' ) }] return plugin.finish(items) @@ -62,8 +62,8 @@ def create_mapping(): progress_dialog = xbmcgui.DialogProgress() progress_dialog.create( - _('name'), - _('starting_mapping') + _('name'), + _('starting_mapping') ) log('Trying to call subprocess') @@ -95,9 +95,9 @@ def create_mapping(): if os.path.isfile(map_file) and success == 'true': confirmed = xbmcgui.Dialog().yesno( - _('name'), - _('mapping_success'), - _('set_mapping_active') + _('name'), + _('mapping_success'), + _('set_mapping_active') ) log('Dialog Yes No Value: %s' % confirmed) if confirmed: @@ -109,8 +109,8 @@ def create_mapping(): else: if success == 'false': xbmcgui.Dialog().ok( - _('name'), - _('mapping_failure') + _('name'), + _('mapping_failure') ) else: return @@ -118,19 +118,29 @@ def create_mapping(): @plugin.route('/actions/pair-host') def pair_host(): - code = launch_moonlight_pair() + pair_dialog = xbmcgui.DialogProgress() + pair_dialog.create( + _('name'), + 'Starting Pairing' + ) - if len(code) > 1: - line = code[1] - if line == '': - line = _('pair_failure_paired') - else: - line = code[0] + mapping = subprocess.Popen(['stdbuf', '-oL', Config.get_binary(), 'pair', Config.get_host()], + stdout=subprocess.PIPE) - xbmcgui.Dialog().ok( - _('name'), - line - ) + lines_iterator = iter(mapping.stdout.readline, b"") + + thread = threading.Thread(target=loop_lines, args=(pair_dialog, lines_iterator)) + thread.start() + + while True: + xbmc.sleep(1000) + if not thread.isAlive(): + pair_dialog.close() + xbmcgui.Dialog().ok( + _('name'), + 'Successfully paired' + ) + break @plugin.route('/games') @@ -140,13 +150,13 @@ def context_menu(): ( _('addon_settings'), 'XBMC.RunPlugin(%s)' % plugin.url_for( - endpoint='open_settings' + endpoint='open_settings' ) ), ( _('full_refresh'), 'XBMC.RunPlugin(%s)' % plugin.url_for( - endpoint='do_full_refresh' + endpoint='do_full_refresh' ) ) ] @@ -163,8 +173,8 @@ def context_menu(): 'replace_context_menu': True, 'context_menu': context_menu(), 'path': plugin.url_for( - endpoint='launch_game', - game_id=game + endpoint='launch_game', + game_id=game ) }) game_storage.sync() @@ -181,9 +191,9 @@ def launch_game(game_id): log('Launching game %s' % game_id) configure_helper(Config, Config.get_binary()) log('Reconfigured helper and dumped conf to disk.') - subprocess.call([addon_internal_path+'/resources/lib/launch-helper-osmc.sh', - addon_internal_path+'/resources/lib/launch.sh', - addon_internal_path+'/resources/lib/moonlight-heartbeat.sh', + subprocess.call([addon_internal_path + '/resources/lib/launch-helper-osmc.sh', + addon_internal_path + '/resources/lib/launch.sh', + addon_internal_path + '/resources/lib/moonlight-heartbeat.sh', game_id, Config.get_config_path()]) @@ -237,23 +247,23 @@ def configure_helper(config, binary_path): :param binary_path: string """ config.configure( - addon_path, - binary_path, - plugin.get_setting('host', unicode), - plugin.get_setting('enable_custom_resolution', bool), - plugin.get_setting('resolution_width', str), - plugin.get_setting('resolution_height', str), - plugin.get_setting('resolution', str), - plugin.get_setting('framerate', str), - plugin.get_setting('graphic_optimizations', bool), - plugin.get_setting('remote_optimizations', bool), - plugin.get_setting('local_audio', bool), - plugin.get_setting('enable_custom_bitrate', bool), - plugin.get_setting('bitrate', int), - plugin.get_setting('packetsize', int), - plugin.get_setting('enable_custom_input', bool), - plugin.get_setting('input_map', str), - plugin.get_setting('input_device', str) + addon_path, + binary_path, + plugin.get_setting('host', unicode), + plugin.get_setting('enable_custom_resolution', bool), + plugin.get_setting('resolution_width', str), + plugin.get_setting('resolution_height', str), + plugin.get_setting('resolution', str), + plugin.get_setting('framerate', str), + plugin.get_setting('graphic_optimizations', bool), + plugin.get_setting('remote_optimizations', bool), + plugin.get_setting('local_audio', bool), + plugin.get_setting('enable_custom_bitrate', bool), + plugin.get_setting('bitrate', int), + plugin.get_setting('packetsize', int), + plugin.get_setting('enable_custom_input', bool), + plugin.get_setting('input_map', str), + plugin.get_setting('input_device', str) ) config.dump_conf() @@ -262,19 +272,19 @@ def configure_helper(config, binary_path): def check_script_permissions(): - st = os.stat(addon_internal_path+'/resources/lib/launch.sh') + st = os.stat(addon_internal_path + '/resources/lib/launch.sh') if not bool(st.st_mode & stat.S_IXUSR): - os.chmod(addon_internal_path+'/resources/lib/launch.sh', st.st_mode | 0111) + os.chmod(addon_internal_path + '/resources/lib/launch.sh', st.st_mode | 0111) log('Changed file permissions for launch') - st = os.stat(addon_internal_path+'/resources/lib/launch-helper-osmc.sh') + st = os.stat(addon_internal_path + '/resources/lib/launch-helper-osmc.sh') if not bool(st.st_mode & stat.S_IXUSR): - os.chmod(addon_internal_path+'/resources/lib/launch-helper-osmc.sh', st.st_mode | 0111) + os.chmod(addon_internal_path + '/resources/lib/launch-helper-osmc.sh', st.st_mode | 0111) log('Changed file permissions for launch-helper-osmc') - st = os.stat(addon_internal_path+'/resources/lib/moonlight-heartbeat.sh') + st = os.stat(addon_internal_path + '/resources/lib/moonlight-heartbeat.sh') if not bool(st.st_mode & stat.S_IXUSR): - os.chmod(addon_internal_path+'/resources/lib/moonlight-heartbeat.sh', st.st_mode | 0111) + os.chmod(addon_internal_path + '/resources/lib/moonlight-heartbeat.sh', st.st_mode | 0111) log('Changed file permissions for moonlight-heartbeat') @@ -298,6 +308,6 @@ def _(string_id): plugin.run() else: xbmcgui.Dialog().ok( - _('name'), - _('configure_first') + _('name'), + _('configure_first') ) From 8b33494c8978fb676ca5e518456ec238be472365 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 15:07:53 +0100 Subject: [PATCH 05/13] LUNA-1: Moved API calls into own class; added complete TGDB parsing if there's no OMDB data available --- addon.py | 74 +++----------------- resources/lib/scraper.py | 141 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 65 deletions(-) create mode 100644 resources/lib/scraper.py diff --git a/addon.py b/addon.py index fc3d8cc..da8ef4b 100755 --- a/addon.py +++ b/addon.py @@ -2,14 +2,10 @@ import subprocess import threading import stat -import json -import urllib2 -import xml.etree.ElementTree as ET - from xbmcswift2 import Plugin, xbmcgui, xbmc, xbmcaddon from resources.lib.confighelper import ConfigHelper -from resources.lib.game import Game +from resources.lib.scraper import ScraperCollection STRINGS = { 'name': 30000, @@ -232,23 +228,10 @@ def loop_lines(dialog, iterator): def get_games(): - api_url = 'http://www.omdbapi.com/?t=%s&plot=short&r=json&type=game' - fallback_url = 'http://thegamesdb.net/api/GetGame.php?name=%s' - - def find_image(e): - for i in e.findall('Game'): - if i.find('Platform').text == 'PC': - for boxart in i.find('Images'): - if boxart.get('side') == 'front': - return boxart.text - return None - - if not os.path.exists(addon_path + '/boxarts'): - os.makedirs(addon_path + '/boxarts') - - configure_helper(Config, Config.get_binary()) game_list = [] + configure_helper(Config, Config.get_binary()) list_proc = subprocess.Popen([Config.get_binary(), 'list', Config.get_host()], stdout=subprocess.PIPE) + while True: line = list_proc.stdout.readline() if line[3:] != '': @@ -256,56 +239,17 @@ def find_image(e): game_list.append(line[3:].strip()) if not line: break + log('Done getting games from moonlight') + game_storage = plugin.get_storage('game_storage') game_storage.clear() - for game_name in game_list: - # TODO: this should be a little scraper inside lib - request_name = game_name.replace(" ", "+") - request_name = request_name.replace(":", "") - log('Trying to query API %s' % api_url % request_name) - response = json.load(urllib2.urlopen(api_url % request_name)) - print response - if response['Response'] == 'False': - game = Game(game_name, None) + scraper = ScraperCollection(addon_path) + + for game_name in game_list: + game_storage[game_name] = scraper.query_game_information(game_name) - else: - if response['Poster'] == 'N/A': - img_base_url = None - log('Trying to query fallback API %s' % fallback_url % request_name) - # TODO: properly cache game information and load from disk before querying this API - # TODO 2: build an option to clear the cached information - curl = subprocess.Popen(['curl', '-XGET', fallback_url % request_name], stdout=subprocess.PIPE) - with open(addon_path + request_name + '.xml', 'w') as last_request: - last_request.write(curl.stdout.read()) - - root = ET.ElementTree(file=addon_path + request_name + '.xml').getroot() - - for item in root: - if item.tag == 'baseImgUrl': - img_base_url = item.text - - image_url = find_image(root) - - if img_base_url is not None and image_url is not None: - if not os.path.isfile(addon_path + '/boxarts/' + os.path.basename(image_url)): - with open(addon_path + '/boxarts/' + os.path.basename(image_url), 'wb') as img: - img_curl = subprocess.Popen(['curl', '-XGET', img_base_url+image_url], stdout=subprocess.PIPE) - img.write(img_curl.stdout.read()) - img.close() - response['Poster'] = addon_path + '/boxarts/' + os.path.basename(image_url) - else: - if not os.path.isfile(addon_path + '/boxarts/' + os.path.basename(response['Poster'])): - with open(addon_path + '/boxarts/' + os.path.basename(response['Poster']), 'wb') as img: - img_curl = subprocess.Popen(['curl', '-XGET', response['Poster']], stdout=subprocess.PIPE) - img.write(img_curl.stdout.read()) - img.close() - response['Poster'] = addon_path + '/boxarts/' + os.path.basename(response['Poster']) - - game = Game(game_name, response) - - game_storage[game_name] = game game_storage.sync() diff --git a/resources/lib/scraper.py b/resources/lib/scraper.py new file mode 100644 index 0000000..2d8faf1 --- /dev/null +++ b/resources/lib/scraper.py @@ -0,0 +1,141 @@ +import json +import os +import subprocess +import urllib2 +from xml.etree.ElementTree import ElementTree + +from game import Game + + +class ScraperCollection: + def __init__(self, addon_path): + _configure(addon_path) + self.omdb = OmdbScraper() + self.tgdb = TgdbScraper(addon_path) + self.img_path = addon_path + '/boxarts/' + + def query_game_information(self, game_name): + game_name = game_name.replace(" ", "+").replace(":", "") + return _get_information(self, game_name) + + +class OmdbScraper: + def __init__(self): + self.api_url = 'http://www.omdbapi.com/?t=%s&plot=short&r=json&type=game' + + +class TgdbScraper: + def __init__(self, addon_path): + self.api_url = 'http://thegamesdb.net/api/GetGame.php?name=%s' + self.api_cache = addon_path + '/api_cache/' + + +def _configure(addon_path): + if not os.path.exists(addon_path + '/boxarts'): + os.makedirs(addon_path + '/boxarts') + if not os.path.exists(addon_path + '/api_cache'): + os.makedirs(addon_path + '/api_cache') + + +def _get_information(self, game_name): + """ + + :type self: ScraperCollection + """ + omdb_response = json.load(urllib2.urlopen(self.omdb.api_url % game_name)) + + full_img_url = '' + full_img_path = '' + + if omdb_response['Response'] == 'False': + file_path = self.tgdb.api_cache + game_name + '.xml' + _cache_tgdb_response_data(self, file_path, game_name) + + root = ElementTree(file=file_path) + + omdb_response = _parse_xml(root) + full_img_url = omdb_response['Poster'] + full_img_path = self.img_path + os.path.basename(full_img_url) + + if omdb_response['Response'] == 'True': + if omdb_response['Poster'] == 'N/A': + file_path = self.tgdb.api_cache + game_name + '.xml' + _cache_tgdb_response_data(self, file_path, game_name) + + root = ElementTree(file=file_path) + + full_img_url = _build_image_path(_get_img_base_url(root), _get_image(root)) + full_img_path = self.img_path + os.path.basename(full_img_url) + else: + full_img_url = omdb_response['Poser'] + full_img_path = self.img_path + os.path.basename(full_img_url) + + _dump_image(full_img_path, full_img_url) + omdb_response['Poster'] = full_img_path + + return Game(game_name, omdb_response) + + +def _cache_tgdb_response_data(self, file_path, name): + """ + + :type self: ScraperCollection + """ + if not os.path.isfile(file_path): + curl = subprocess.Popen(['curl', '-XGET', self.tgdb.api_url % name], stdout=subprocess.PIPE) + with open(file_path, 'w') as response_file: + response_file.write(curl.stdout.read()) + + +def _get_img_base_url(r): + return r.find('baseImgUrl').text + + +def _get_image(r): + for i in r.findall('Game'): + if i.find('Platform') == 'PC': + for b in i.find('Images'): + if b.get('side') == 'front': + return b.text + return None + + +def _parse_xml(r): + data = {} + img_base_url = _get_img_base_url(r) + for i in r.findall('Game'): + if i.find('Platform') == 'PC': + if i.find('ReleaseDate'): + data['Year'] = os.path.basename(i.find('ReleaseDate').text) + else: + data['Year'] = 'N/A' + if i.find('Overview'): + data['Plot'] = i.find('Overview').text + else: + data['Plot'] = 'N/A' + data['Poster'] = 'N/A' + for b in i.find('Images'): + if b.get('side') == 'front': + data['Poster'] = img_base_url + b.text + if not i.find('Genres'): + data['Genre'] = 'N/A' + for g in i.find('Genres'): + data['Genre'] = ', '.join([data['Genre'], g.text]) + return data + + +def _build_image_path(base_url, img_url=None): + if base_url is not None and img_url is not None: + return base_url + img_url + if base_url is not None: + return base_url + else: + return None + + +def _dump_image(path, url): + if not os.path.exists(path): + with open(path, 'wb') as img: + img_curl = subprocess.Popen(['curl', '-XGET', url], stdout=subprocess.PIPE) + img.write(img_curl.stdout.read()) + img.close() From 2caf29f4fe24cd6e29983eba0769f7be787dd942 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 15:38:33 +0100 Subject: [PATCH 06/13] LUNA: launch hotfix --- resources/lib/launch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/launch.sh b/resources/lib/launch.sh index a35bcfb..9cabbdd 100644 --- a/resources/lib/launch.sh +++ b/resources/lib/launch.sh @@ -3,4 +3,4 @@ GAME=$1 CONF_PATH=$2 -sudo moonlight stream -app "${GAME}" -config ${CONF_PATH} +moonlight stream -app "${GAME}" -config "${CONF_PATH}" From ca39ca1840fc33220aafb2c4a4a7afd865f2bceb Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 19:01:59 +0100 Subject: [PATCH 07/13] LUNA-1: Steam no longer produces a (pointless) API call; added a check to determine pairing state (WIP) --- addon.py | 59 +++++++++++++++++++++++++++++----------- resources/lib/scraper.py | 4 +++ 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/addon.py b/addon.py index da8ef4b..fb8bb0d 100755 --- a/addon.py +++ b/addon.py @@ -126,23 +126,58 @@ def pair_host(): 'Starting Pairing' ) - mapping = subprocess.Popen(['stdbuf', '-oL', Config.get_binary(), 'pair', Config.get_host()], + pairing = subprocess.Popen(['stdbuf', '-oL', Config.get_binary(), 'pair', Config.get_host()], stdout=subprocess.PIPE) - lines_iterator = iter(mapping.stdout.readline, b"") + lines_iterator = iter(pairing.stdout.readline, b"") thread = threading.Thread(target=loop_lines, args=(pair_dialog, lines_iterator)) thread.start() + success = '' + while True: xbmc.sleep(1000) if not thread.isAlive(): pair_dialog.close() + success = 'try' + break + if pair_dialog.iscanceled(): + pairing.kill() + pair_dialog.close() + success = 'canceled' + log('Pairing canceled') + break + + if success == 'try': + pairing = subprocess.Popen(['stdbuf', '-oL', Config.get_binary(), 'pair', Config.get_host()], + stdout=subprocess.PIPE) + + lines_iterator = iter(pairing.stdout.readline, b"") + + last_line = '' + for line in lines_iterator: + log('Output while checking for pairing state: ' + line) + last_line = line + if not line: + pairing.kill() + break + if last_line == 'Failed to pair to server: Already paired': xbmcgui.Dialog().ok( _('name'), 'Successfully paired' ) - break + else: + confirmed = xbmcgui.Dialog().yesno( + _('name'), + 'Pairing failed - do you want to try again?' + ) + if confirmed: + pair_host() + else: + return + else: + return @plugin.route('/games') @@ -209,18 +244,6 @@ def launch_game(game_id): Config.get_config_path()]) -def launch_moonlight_pair(): - configure_helper(Config, Config.get_binary()) - code = [] - process = subprocess.Popen([Config.get_binary(), 'pair', Config.get_host()], stdout=subprocess.PIPE) - while True: - line = process.stdout.readline() - code.append(line) - if not line: - break - return code - - def loop_lines(dialog, iterator): for line in iterator: log(line) @@ -243,12 +266,16 @@ def get_games(): log('Done getting games from moonlight') game_storage = plugin.get_storage('game_storage') + cache = game_storage.raw_dict() game_storage.clear() scraper = ScraperCollection(addon_path) for game_name in game_list: - game_storage[game_name] = scraper.query_game_information(game_name) + if cache.has_key(game_name): + game_storage[game_name] = cache.get(game_name) + else: + game_storage[game_name] = scraper.query_game_information(game_name) game_storage.sync() diff --git a/resources/lib/scraper.py b/resources/lib/scraper.py index 2d8faf1..bfab576 100644 --- a/resources/lib/scraper.py +++ b/resources/lib/scraper.py @@ -41,7 +41,11 @@ def _get_information(self, game_name): """ :type self: ScraperCollection + :rtype Game """ + if game_name == 'Steam': + return Game(game_name, None) + omdb_response = json.load(urllib2.urlopen(self.omdb.api_url % game_name)) full_img_url = '' From 7e477880271c3746b58e717c83d7eaaa66f0d650 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 21:48:55 +0100 Subject: [PATCH 08/13] LUNA-1: Fixed some scraper related issues; added some code to handle canceled pairing --- addon.py | 45 ++++++++++++++++++++++------------------ resources/lib/game.py | 7 ++----- resources/lib/scraper.py | 32 ++++++++++++++-------------- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/addon.py b/addon.py index fb8bb0d..1ad0ea6 100755 --- a/addon.py +++ b/addon.py @@ -1,7 +1,8 @@ import os +import stat import subprocess import threading -import stat + from xbmcswift2 import Plugin, xbmcgui, xbmc, xbmcaddon from resources.lib.confighelper import ConfigHelper @@ -134,43 +135,47 @@ def pair_host(): thread = threading.Thread(target=loop_lines, args=(pair_dialog, lines_iterator)) thread.start() - success = '' + success = False while True: xbmc.sleep(1000) if not thread.isAlive(): - pair_dialog.close() - success = 'try' + success = True break if pair_dialog.iscanceled(): pairing.kill() pair_dialog.close() - success = 'canceled' + success = False log('Pairing canceled') break - if success == 'try': - pairing = subprocess.Popen(['stdbuf', '-oL', Config.get_binary(), 'pair', Config.get_host()], - stdout=subprocess.PIPE) - - lines_iterator = iter(pairing.stdout.readline, b"") + if success: + pair_dialog.update(0, 'Checking if pairing has been successful.') + xbmc.sleep(1000) + pairing_check = subprocess.Popen([Config.get_binary(), 'list', Config.get_host()], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) last_line = '' - for line in lines_iterator: - log('Output while checking for pairing state: ' + line) - last_line = line - if not line: - pairing.kill() + while True: + line = pairing_check.stdout.readline() + err = pairing_check.stderr.readline() + if line != '': + last_line = line + if err != '': + last_line = err + if not line and not err: break - if last_line == 'Failed to pair to server: Already paired': + + pair_dialog.close() + if last_line.lower().strip() != 'You must pair with the PC first'.lower().strip(): xbmcgui.Dialog().ok( _('name'), 'Successfully paired' ) else: confirmed = xbmcgui.Dialog().yesno( - _('name'), - 'Pairing failed - do you want to try again?' + _('name'), + 'Pairing failed - do you want to try again?' ) if confirmed: pair_host() @@ -206,7 +211,6 @@ def context_menu(): items = [] for i, game_name in enumerate(games): game = games.get(game_name) - print game.thumb items.append({ 'label': game.name, 'icon': game.thumb, @@ -273,7 +277,8 @@ def get_games(): for game_name in game_list: if cache.has_key(game_name): - game_storage[game_name] = cache.get(game_name) + if not game_storage.get(game_name): + game_storage[game_name] = cache.get(game_name) else: game_storage[game_name] = scraper.query_game_information(game_name) diff --git a/resources/lib/game.py b/resources/lib/game.py index 9b6bf41..e5ca4fe 100644 --- a/resources/lib/game.py +++ b/resources/lib/game.py @@ -5,12 +5,9 @@ def __init__(self, name, json): self.year = json['Year'] self.genre = json['Genre'] self.plot = json['Plot'] - if json['Poster'] != 'N/A': - self.thumb = json['Poster'] - else: - self.thumb = '' + self.thumb = json['Poster'] else: self.year = '' self.genre = '' self.plot = '' - self.thumb = '' + self.thumb = 'N/A' diff --git a/resources/lib/scraper.py b/resources/lib/scraper.py index bfab576..fafe061 100644 --- a/resources/lib/scraper.py +++ b/resources/lib/scraper.py @@ -2,7 +2,7 @@ import os import subprocess import urllib2 -from xml.etree.ElementTree import ElementTree +import xml.etree.ElementTree as ET from game import Game @@ -15,8 +15,10 @@ def __init__(self, addon_path): self.img_path = addon_path + '/boxarts/' def query_game_information(self, game_name): - game_name = game_name.replace(" ", "+").replace(":", "") - return _get_information(self, game_name) + request_name = game_name.replace(" ", "+").replace(":", "") + game = _get_information(self, request_name) + game.name = game_name + return game class OmdbScraper: @@ -48,30 +50,28 @@ def _get_information(self, game_name): omdb_response = json.load(urllib2.urlopen(self.omdb.api_url % game_name)) - full_img_url = '' - full_img_path = '' - if omdb_response['Response'] == 'False': file_path = self.tgdb.api_cache + game_name + '.xml' _cache_tgdb_response_data(self, file_path, game_name) - root = ElementTree(file=file_path) + root = ET.ElementTree(file=file_path).getroot() omdb_response = _parse_xml(root) + full_img_url = omdb_response['Poster'] full_img_path = self.img_path + os.path.basename(full_img_url) - if omdb_response['Response'] == 'True': + else: if omdb_response['Poster'] == 'N/A': file_path = self.tgdb.api_cache + game_name + '.xml' _cache_tgdb_response_data(self, file_path, game_name) - root = ElementTree(file=file_path) + root = ET.ElementTree(file=file_path).getroot() full_img_url = _build_image_path(_get_img_base_url(root), _get_image(root)) full_img_path = self.img_path + os.path.basename(full_img_url) else: - full_img_url = omdb_response['Poser'] + full_img_url = omdb_response['Poster'] full_img_path = self.img_path + os.path.basename(full_img_url) _dump_image(full_img_path, full_img_url) @@ -97,7 +97,7 @@ def _get_img_base_url(r): def _get_image(r): for i in r.findall('Game'): - if i.find('Platform') == 'PC': + if i.find('Platform').text == 'PC': for b in i.find('Images'): if b.get('side') == 'front': return b.text @@ -108,7 +108,7 @@ def _parse_xml(r): data = {} img_base_url = _get_img_base_url(r) for i in r.findall('Game'): - if i.find('Platform') == 'PC': + if i.find('Platform').text == 'PC': if i.find('ReleaseDate'): data['Year'] = os.path.basename(i.find('ReleaseDate').text) else: @@ -123,9 +123,11 @@ def _parse_xml(r): data['Poster'] = img_base_url + b.text if not i.find('Genres'): data['Genre'] = 'N/A' - for g in i.find('Genres'): - data['Genre'] = ', '.join([data['Genre'], g.text]) - return data + else: + for g in i.find('Genres'): + data['Genre'] = ', '.join([data['Genre'], g.text]) + break + return data def _build_image_path(base_url, img_url=None): From 02ca38692bb3b781c3a7e3463ba883263e06b088 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 21:55:13 +0100 Subject: [PATCH 09/13] LUNA-1: Added API information to description --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 93b1a5d..c088418 100644 --- a/addon.xml +++ b/addon.xml @@ -11,6 +11,6 @@ all Moonlight Launcher for Kodi - Moonlight Launcher for Kodi. [CR]Icons made by Freepik from www.flaticon.com + Moonlight Launcher for Kodi. [CR]Icons made by Freepik from www.flaticon.com [CR]Game information and posters are provided by OMDB (http://www.omdbapi.com) under CC-BY4.0 [CR]Additional game information and posters provided by TheGamesDB (http://thegamesdb.net) From 388456085f5a860afffa847536137efe2d304882 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 22:09:15 +0100 Subject: [PATCH 10/13] LUNA-1: Changed icon color to white to circumvent transparency issues --- addon.py | 4 ++-- addon.xml | 2 +- resources/icons/cog.png | Bin 23701 -> 25620 bytes resources/icons/controller.png | Bin 26784 -> 29750 bytes 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addon.py b/addon.py index 1ad0ea6..f9096b6 100755 --- a/addon.py +++ b/addon.py @@ -33,13 +33,13 @@ def index(): items = [{ 'label': 'Games', - 'thumbnail': addon_internal_path + '/resources/icons/cog.png', + 'thumbnail': addon_internal_path + '/resources/icons/controller.png', 'path': plugin.url_for( endpoint='show_games' ) }, { 'label': 'Settings', - 'thumbnail': addon_internal_path + '/resources/icons/controller.png', + 'thumbnail': addon_internal_path + '/resources/icons/cog.png', 'path': plugin.url_for( endpoint='open_settings' ) diff --git a/addon.xml b/addon.xml index c088418..01df65f 100644 --- a/addon.xml +++ b/addon.xml @@ -11,6 +11,6 @@ all Moonlight Launcher for Kodi - Moonlight Launcher for Kodi. [CR]Icons made by Freepik from www.flaticon.com [CR]Game information and posters are provided by OMDB (http://www.omdbapi.com) under CC-BY4.0 [CR]Additional game information and posters provided by TheGamesDB (http://thegamesdb.net) + Moonlight Launcher for Kodi. [CR]Icons made by Freepik (www.flaticon.com/authors/freepik) from www.flaticon.com [CR]Game information and posters are provided by OMDB (http://www.omdbapi.com) under CC-BY4.0 [CR]Additional game information and posters provided by TheGamesDB (http://thegamesdb.net) diff --git a/resources/icons/cog.png b/resources/icons/cog.png index e4e9d9637b20b7f33584fb5ed7b7bc0e47009ce2..4354129b4922c2fb88ae80edf59a149f38a17064 100644 GIT binary patch literal 25620 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 G`hNfmKsU(% literal 23701 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%0DkTaeP0=Mgh1n}YlZJyitWPBjD0%QQ=bflkHt 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 literal 26784 zcmeEu=T}qT^EE`IsYowU1*8{2M0!zrmENRisM4hOCMpOLdJ`!^LYL5y7Er`MK#)*F zM{4LjkdWlz^Zh5DH@{c+zPM|jS?8SDGqY#b{rKES`wsOzY7!EXJGwd=rX(bQ>sJ5? zCHeK^G;{)c{U8l6)qYA+H^PA?AyFgI)lfGNCEY8enCG|1ZX1->85vGXuPn`Ddv3$9 zT_MC<@~N&a)+U6GFR^3$v;9M8Nh0d8=ntmn>S-mV&dwkBP1O9)aYT3aR*-O*YHQ-XlFI$CQZP{$oRtDFu_N6~IwY=|%*u7P2h%xTx+ zp#@ECDbh!5!Ced2<6F5mq(||Q;;*W{WZ~FiNX(*;CeL4)xW`#58;?3{mMU%#dD^wv zp&1VMyZx`fU#i}tBzrB`OQp7#SRozXV!rL|7FaM`(Kda*VrZ)ZteUatpiMsWuJ?9a z_UR=DdIyqPfXczHlCvo}hA)0Pheap?uF0dsf-G{9Ac-{AkxUOy3g8G&I99gA2BI@e z$pFHX-^JSv+r8UUQp&s)jWOaFDNM`DM=rDP|Kps>)L4pQdE_&Qpzc9Nc}PULEXFABkBH6c_=B#c+!eup|M<|QJtqmu=ni?E=CG; z_iS|YL>n(HCFA|&R{!P+Z@1?KuUBO;gT?v_+6z_-Zgl@~TsCE>-?%#RK-V|D)$gz9 z>Ug|JpB1D)hmP_#?{e#k?7vpia_^QSYm5zM;Ra-X=z1-ZxUXcE6Gh5kZN2VBSW3Jt zb@7$l3I!xu=2l!R)pzmlhTpxx?m+M66_q{Mp2|K9biIz5ky9&zXp8nk>T+F?-x-*$ z9LDLUqXm{_ms=lJrWkC?VuCPX7(D8FgJ|>U0g6>$4zi0x3nxhH4BCyD6TU$P0_olq z7K@3GTMC?6r{3gZP?F`LjqN3)JM82t62j-5`lG=#uhRW5*ToL9B*ZlZ3SxI=g7y?r zoAY%Iccgv--@|XGa$ej2R~?X=KDs|(r7IXzuV-Jk^l|ds)LEM9yN^A*YVHqs_GISB zqzX=dZHT)(sVZ!(s!Jb|sUS3IFR{cOm6=t;t)55gXWwB|;a#YYfc=x|2i{5@rv?Dx zT4}8vL06qwq6N)@%BoD`kLOGWFHG`dcm4+DOS2kvil;v23Q#(~He0Qa%<_3OPR}?^ zg{SbGw5skHr)|q6uGyj68?>oVTN7o_X`iah6|ck`X7KcS$L~=o8MUfPoPJbiHX9MgnLk*5+)}*M>l%)Fstv#idxyh2*Fue|M+`^rREp^;$ zbP#e9%&upZ4zgPmq%gYI#<1p?*z2Q!5XHmAX_6dtLYe|O(d5W=NT$SQRjgwg7hksr z^48q?u^-^?;%r3i3q_rd+`#tp4x8Dgi0q%^jVI(=k=~sSvyxm&Az#L{ha-I;qmb*1 z`rB|hTK-Mk>D?%WN^$5npltd`(d8+o$fx#TNJmh!YwOq!X{cWg`V#H|7)ObLT7O+d2pUzEnT19i@%?w0W-q1y!d- zT%G!}{k{IhS1N|sX!JOENFV-yOURMu?9($An|}egoxQf#b_A(Hza(59?lbNSt_bJE zG6#YyrABexprbTkB9+`wwA_wJu;1y5$rvq83+H*EJ1cwiu@`2_Mcj6nd+q7?-Cz&> z-rIBQ5uvu$7^8{N#r$cN=Ge%EtEIjlukW?#*C@~Ll@+;q0=cV~5R};J-D3iawpXy~ zC~6jMe9M7PYp$`<@%E$`-%72RyPGR3H3{{~7{E44TWzcCz~-{UPx7`J#(?~QxR1OK z?I1_5zDjg8!#T%p1uGq1<}W?~+vjkuUF9R|Zoj)gfjSf{yf;?teJ+j{qNbx}qEJyC zw^+Ei_2`;P0tMHb8z;Hu$9sb49{6f}F|6BKO=DwcgRV~YIe^gA*F?>TET9V>Yh zP^d(*JK`_o2_Ee%dnyO81F2r1y4_qM{CO%QGxTZstNWQ+y`u+hL5NG5%X9H6tDz7y ztbE>3U}y+Q)R|LQUYQQv-e`KwFeKpVvLLt_QcBEd z^>*p0Kt>ClAugC81FDo=Pr1E|$-P(Alsr_z5JZ>2r1xY>TA{Uvd1I}1u3UD?zm0bK zlaoNr>AhuZ6PL)=+aL#>lNi&UT4(x2-tt!yys4R!J7DjsCs*#R5_KjE2QT!8KHo0m zQY2VxH~a$X+09nKZByH?9mHta@VNJ&&G*^nVL&g1{*yG`eoC*>K8c*xuY|*|?cv{b zf>i9182Og3xkcY@@$s_MG*I$7z|kI>quL;=T+MiuV?M|{H^aN6#vG)*C})U$M$Dt2 z<&NM&zDdf^+M~SH2Df?dDPTSP6&WCf?hsWUGw=E(g_w(oQ5DAYk=>6A6wjAu3dANQN0Lfx8*u>g#gYVJ1XKNR{vA zecH@ZNBR(ESb_a5B>Z5r7OS7rz4q4Y55J1cERWRH&b&QfMgTdO7Su$4^ zRf+d>9L<%uulZjh68JtAE|zM~)%Tg>k+N1qtrkz(r{2cKHFRJ3y<;kbXRh-ikn%cb z>%E{16+6kBnz%qW%mQTrar|T|4@3=R975<-3;v5ow0SZBuDQ<&bccBRt~1vC297v2VL(7oAmVpu z&n~BcyM!KJzX&96hXp zBeH-8FHp~Tp6A6Alg_4X}ae8&pgXg zkJiOWQ_+-U{#2nRNshw#oFp~T#QfbEEcIGo*1cWK-$+;}HBF^dqr5?M)qHoZ14J zQck!*N~>q;9@px1a>M_ovQ>*ce>^6#BuMrt4<{)_jN``&cPJhEyq%#{h4nq7Uf^qR z;W?5^LFv}H!K1iI^9#nBay)L;)9{fF!al!&3gR|9AWq@>)XrvX zAt|oop`S3;scOsj$p~gd7k0hL0|);1Y9&Sh$IPSZy(Um#+Yq;dkA+(baE?r=wcNdj zYln_fj6ZFA_ZZsvefw!mWSm+!fMU=&N&R8Voh6X9aFkyIW!yC%wT6F6X|;FtVBuX) zri!$_=WT98v}C_NT!y%BE*J@qq*mL66v+v5pW&w^+Py%pq}ClN?zrAp4hBI9GP9MT zBU!)A1>^c%t|rL#WM)TBkg6?4lru%)fao06{s>#8jfh?C@-J%DlMrZuKZvo%0TAG# zB6-pJl6dntbE&hkP28X}D78g+wgVpRoJ3Vy(YW*=MYdejxlhtro##0PY1=nZ$XM{K zIX0%|20-@y!)LwtA3&dG<%r#o+iK-my@D3|?tK1OD??$`q=nmYH?jl?IIy%CAN3Sgdi&^HDSWw$$num>kYEJFF z^cU`T%56D{^$K4n{CPYRtkT76HtE-?E5L~4cudfQXK zsICC}C)SGR_Wp}-?(4~!5m_&?@td7_#umRjnfn^BqgG9!S=MjC+uqEn-CXfa(N>rH*2{UZ22^q87{WsP?*~5hDxPO$FJaP9fRKEtGPU}Tc)*=>~i?`KXFE)gGOW`ki8?66+9V8CI+sT?Ash|O{3a-HB-Txr`a^hXKu+LviCOnR zoEdJk3_LEGuIDS3^!d&Y3&A97z_by{BHxS+EPe8Z_}$tJ-(t`4e?%IS=ok1oEtbM? zpl=yc9#6>@S!4|(J?Klb z!85MShMr6)!TTn^(Q=hEU6uYQS1sL})kG(P%1h19e9P~@1dZG#Se!rcsFQmiaBRIR zC6BcFGS%=y3XuOCP{nNCT}i64Bb-_W7T)jIQq)47s!%xz@GR;Si88pL+)|0p{=V;i zdx@K(Mc$6Plbv!Su$8cL5nX<4-I33mjpzsZCmkzj@i6H0T0JE&Rl4&X<+~PQI=ZcQ z43TyW7x%PxFCBBAS%!Lixes5~k1QL6zMTW$Y4mYjvO2)F=-!TVG zR*q*CFWT)|J_(O=mPy~Aq*AiGK4`z7vsxCgl29Je3r^GmTl@?B-(84cjv9 zFt2k~dx#QB2E+tn8+b<>T7gLawp_i0sf$ZspS??eY1Q%~2-5kT++p1Ln2Kt)9|-6* zqTC>6sx9)1YdIO!gR0N*irK#G@nHB?wF{y=U|3BcHg-uXxJ<^b-2&#w!(Ig?xDC1{ zJ(?0(_u&1*B*JZ4*h{W=?_0%z#qgpa&DhP#;<~&igGme*pJ-BA)2q>rmh*ppgHBoZ z8aiI*hodFw(AE5gT1<&_aEs{P+f@qjdy_Z)^2f|)|ci7%^UHG^Y8ez?OOJIF_VsKXEC<^JYps9-g(!_%4*6-*HtUHYX zJJhqa6dDrgP|vm>)aMVo;4(Et=kgohfW1=>L29ftX~xC#e?|{#q&k%C{~pg z1@r76qAEEbXs=}+%DntPT%Bg8H{kT(XJl6|@Z69wM31ekmSKL5`Z0oxu$H|^zJBze z>PA#d+H|?zzei|$Fn895)LAc)TsR}AcSJhZ3gbOXjBoCT&(Z>RK<)O!?EkFnWFvOZ zS-JMuxiB1NX&~A+B%drh#&Om1@0Coos$b}`h{qqGxcKb(-Z#n1I()@Dd-tgNo&TpFMjVj!T;=YhB$Ts>)^>+Etz58#+S%v&xyI)+UhiH zfF2HD!Pd{ao1wQc)?9mnAYmN}N+lZ=EzvpjQhH^r_JiY!9s@VT{wl*|V!jV;Xz~26 zFNHUj7=GF2`sBIMr(9o7V8IN8k5M_NVoT6?TPLhy_79^OB!=Nf!h@0vqBEan-_Y!L zd)cVsh4Gkc)#cD@=m3H`|66__nOC>%uIce4jRlkP)$m2NQm4P;Jg^;p>h9?0rEY8B zqF<)fvn|!U$1i>CMP)fE4HS7+S291UxRA(KT#hL7?X%AVCVvrqk z>Pd5D7KmKll(}m7g%BV79$1sCYk;pmY7EGbW3D-<1?x{1y$8>px;9I_Pt(GZqcya`! z<I={_B^I&SnE1gNO(c>`chTXk;ql^Y3cbUZb9iFVfpPDsyDzU>- zv6ddwH{y~WrvI~hZKZ#*-LOkAa~VI7L3f0HlC(QlhbwOIi1RG>YsaM1RD-4GqCc02 z;rI{xR8)Bul;c#rWmeSJ^gQxA(44q-S?07!1!A(>X=(oG&>8BTszi^m5j6jD zLL1mv;g2n{jx>mVU4`Q-cycR8Bqjf{_yH88V0kDkdcc&!iTnJ6G3hJOGDwVTB zU-kZior1oC?!TkSTNaMO_|j7)kJc*;n%D%^*1=?AH6T6>#$33Fpyy}fs{+#G07aqE z>g*iDO(Qm@xq;c*W4tWNT5(&)F`RA|j1h|wjE4-_I zy?*l0hJz`^mHJ-jge-=kSSHZ^{5ff~B&WrcIxhOFOe(bfQ24huZr}QyjKQ+|`jg6) zEYya_$UtBqbU@X3c?cK&n?4Gr7F?Qo;}ZN!RVnM(VY$f#YQT9%;hYhr#`D(|0Q;wG zs8ES#Uf8Hv8`Z-n?bZ#t`p;OwHHQ>-ze5opmVBQlgkIM!tT`cLd)kvL9I^=vhuKvX zf08W!*00iV7HO_1*KFxHO5GhQ8wg%vacp`6D!co_wo_G7Ji~Vk82L8yxV86Eov7rp z)o(~iHmkGDpL0u?ZU*Rg1mMV+0NShSOh2SKo#YMJLUX?hJyg*isRqzDpEYTybgzlow!`**fi( zh$W=wN%ltOnq#1Bp!ub52Hp@-)!*P`4%0lB7m$~||Cr%W56R0Uz0F$u)hByk)R6*z zq&LBM9LdIJv0;v*(O;?c(r6F67E7+x^BHT!3`;m(kQS{d5vX?F+ zKB{(?;ArC{U>xwNY_Z4^XF=L$s!)**y>;jDtB2{S4(mJb{cYx4dSc|_B=;kQT{V*~ zqI-_@q?j&Sd7e1l;h}ZE700lqlTOI|$0|AOT@d+<1|nof#~x(RrYOKT7%?FQGSo>S zD-xJ16Diq(*)v>jH4#d~XcYGy=`W7+$)azc`2G!s`hXCt&Q582(sNU(3hLpM{5_DTx30}wc z@q~-$mw}IQVyMIF3!&UbH2!BvV(7gC9}iSy6MXceoSN-5_Ogvy&y2vFM8QSTtBr^1 zM=W`Xiz78Zcl4{ijL!IZRsPeLO#w2R-iZ6-@~9tBkSlQN?TA8HMxzdL1rFDrsdFQ+ z^NNJ;WH4>T`62p?SSm^l%H6tO-6~^i71QkC&;(uZuF=k1oMBF9ZmuNPRQ(OA{)Vq^ zJ=+z)30JD9>Pd5Umdx9thn_8b+t6Y`{6_t45id+PCJ}5+@;&5NoSN+t=woniGT>5C zxQ*m3i7uDG!#cvIwtq3*xr&d|i*-lKx`>qkJwLBEpAr*+6Fa=*pAFdWR2p7xdmQHq z4(yIMuE5Prbpx@BHLiS(@985rf6Dzzy|K?cd~xiA-J-I77?JVJsa7?2C-cy6NG?jJ zuniaw)G+6$u}r$>!5d{|L~_pZ$>Ob=lFKQoB!#dx1~>6RKe0Y0a_VsvV-MX4(RbW5 zO1*hAo_O4^ucrO9LpFa}hL^OB2XW77rH~<~O`_qH@TA1h7yiSqy8~Cqocv5qPh-qM z*>UV;T3Dp&3?>E@(;X_wyQ4)fsKfq;I8}1DE0m8iZS6iF`s<{e%lsvd+3A#5=qD6( ztf(btsnIVr)KD{te9sWOp!rwwbs|ErjGP>tS|lu?-0PZeICgrixdnR35VxqFC$-Vj zh_KA@Jb%|~s!3CQ#Ci;+@JX_6XnCO@mCPIF(fJ0D_HUcWpN<3ihaXM<({iJIEo53I zP_`r0MN4_z=HN-ohy}g}YMI;iu-5Mhk~CS|7zIteMOMg_v9DQc261%9dJv?wda}HrL|Evd*Cpkzdpghjmu6Wo-#U#1b5Tu|ELz zK4_nnO#|mhJw2-T5?q?1Fm#Z&GDF7%uituaG?DNXJr@Z$d=<85QBHTnh$3p-UIU-8 zz0r^b@mtRJ=#5g&R(_s$BUD%zDrNeVIbnr}PUrjyy{}Z+_~QLG7DUhGqAC@A;h-&V zX81$6G?+hbX*<+$LF@G7!HHPJMUgtObo9sEk`+Z%B?2=(q9gg30Vrk-p z;>4YMt&-D&Up&~mX#!_}IBEy)vpu^cmMRs5QvZ|!>*1ZpKke`u)`ggHiMKUftDewR zO*)%WMZv>I;Y?j!k>6$GxLsIrf^o`+n*F2mIfHFP>*6aOTGl6V2ZM2hRvQda*eA98 z-+8}O7IE2pWOK&vwysI8;`&gmbu#xqjH4~%lA7&MMVDXSlxO!sOU_^xr{raQ%x!l3XA&3kli+*Hl~!oxrx>$ z19L1G`Lz8a@-%%yPveE$-JyeO)+ z?6&>qUwp@DtH*TbN%WuW79c?0ny3`LgCA}o9@HO;>R)94r1DbZp^I~I-fTmf;060t zirt${BI*1~Wi;8eQ5Uhf7Dc;qFM6Rt7ri{(eVmEj@gC^?F;A-x+nAwr*QzUwwS163tKAWZC1ycVE;X zDEYbpRL4Ea`B=*WwYl8pPx0LA0XMYn>s9p9)6?$zbdexokhsORM1iZ(uaCOMxE8Y5 zp1Fto#pxAWhp7fzm`5%<(j zy_U(X3M&-Oqqr`SvfPo>OFOp~|_MMoJbLock{fS#hV{9#bwU z8ee^-wD$NA5-T@sn-yEdN++>)Ov{=A5n@ zZ-^d=5%!qwe-xddKlEaLp?1|#kaHRz?V|jg!;S-(G__j4%CTd6f0Z()k2*R%SOY4H zcSpfLxIAAC4l!TC*ed2FSkYmo7|9I9GvvlFQfm`4Br3CAD5kF6GJ>9hUi4#p_s7z*2{NajgFW)xXZe&w(atQhNuxv zw>*4z(NPN54W5YNm?>Fb-?A$g8ZpN2y!4bQJ9EUi}jqjL6M_z0q@9JT)e8e=# z8Qy&It3@}|VB2?`PR85MJgH*29=Qe<2oV`cN6glme!s|>KuHS5v*^?W=XiB&LV{@` zX!D!^qt8(z>8`lv=?ALMKko_V>4V)tk2P6A3L7(tH!`!P+{{r;V?vgb8Bld5h+q{z%pA0vxvm8=u^C^Hz7NjXK!O)br^)jM1duJ>!pU7K+Z)>Kuo1SwmO#K|WSmz#=GqY_r&;;QOhK4>x z{1-G9*45HsS=+3V4_}1LzxUB4fYeRu0_;q4v=%O00B?wkmGE`xldK?w$D1dOoe?-rCe)kdEc!V2v{oZm;5 zGiQiZb)DxDY!rqow$1}wBEtS_+kO&wQxvR?vzt71FD7ZB0@t~lp<>#R)m(jH z7>(0c6~)IlfBdoW9zk)PryWyy)jq@GVls)2g$Ms8I9Bo)T@GeuDrLGq&x>|Ivn5!> z)|vGV)TST%y*b&76=+|oxKip44AX+Vyj)oH_j)Ey5C+z=lbRV~Xqpf3Lb@ z2e$=9m3H3rFy?asU@onV6ZpQfgZD4&Gykj|%E8q~68()4WGIs{e9L1o zTS&0@d+7O3K`Hh>?&mn{?9|e^?}ThIt4-9;Ec}-WV${E+!1&m?NGPG{Y!L_hdM-I` zm1TDt(>fC2-8&a~ylYGb=%bXot_YRGW=L^mTVFJ6(u-cJUiA}-tS@(}r#XVzFJSIy4G8~p#RDT|m`@N@?{7V(G_y*+IXfqIQ! zTq?&&*uST1P2k6fz3#mr)Ms+Y&6<>>YOTyiHvpFgO)sZN>?b!L|FXgx4{Xg)u zVM3(vO7|#^^XHihL|;Fqmqjwvu5J5ep*mDbP8ZpqO(g6Mh-TSysoKohHVTI)NQH8Y z*^#0p;c@qyMxmZM?#*5zDcT!pewIBuGI;!Lm+D)_yES{g!VV72J!SE=OJ{-LPa+84 z8Nb}Y55SFI19c*U^*@;xR2*dmsFM)mnYn0vPKqx6I33$g^I^J0M(Stq&V1^bJZ#vjXBf3uj&ecAhD&Zz&p$ zHg`yzS-Xu=THj;{bbd$*uij!^XM=wHUijS?!0NCiZTOFT4W3_`Qh5iBCs$W3wbGbE zsxM`={y1P%*|h}!&7j<(-Fs38umAWBt<9fTN5d_OvpMwr=6 zAvoB=v@>)I_{(DCjH+nqy2>5pxhzQ3eIXB{{d6~%WDI2?qImVla@R5ZN5ab>DU(5pHS z)smCVo*G??aPc3DSXNQLc&?4G%vm`TVaYIFZczXa3hy?avC6}?yrGeLm)c(7XLZ?H zSDe}B<|qe&r8^*6Qn(nr&P3_tTs~OgL$GDnbAD)A7_Mg;g{%mQw8=lQaj`Qd^GWwD z`tZWg*1YQ{&JEcm`*#u_!hBN-0>4~4KVf)5^l3AcAP;;Lo^>kVv8@tN=T#@HnZ)pB zH)*PmJ=tv<#y6@*;xu~BZKEuE>}dqOOKxJ9Nu&r5T4aelAdrW z8x(eWw3l)5?wkVIG1K;=Zi#v`^GkWZXW~`HH}l&tKD!!O`$VdN(FRdl3NAiHVY|T{ z_mwDtoj3rSfm5q&k9v59On42%z`n5TiY9ws=o>HWxcGG0x5)LKm|kyN6iiZle4`_D zw;`FiyFt9DT2&*wpjkw5RCfP?W;NZLT|FuGCYP37c)_+Z0`|IZ2XYbtOMgWc`2m)2 zT4qYI#ns1H9Fx;Ms_V#WZ+wq#)aeV4;fhs(_rjp(9^j@^ZOvF$eRv zbi%jeN{F2Y=*vZXkf|hBBMo*RX!>!9Vp%iAJFQ^-og3eFUisP60Zhx+H1U%a)wR)> zmR}V;gLhR&9pGZCQjNIAoUC!53&2ZJ^c33}F+^W-cU<4Kb>{{ZeP|aFm)@Hwm(x*~ zp>HopqBuCd)t#*G!WRxm=U^p&Mz&ZoQA}wglzU;xsbajHOYNeHU)cWPOI5}4`Z`J! zIKv|BvO_v!jL{DKQEEw7nXzt_kxNU%1!U^)PPN1~#mnB)C%jxg#guT(=CwIbki{)z=`QRrDlKyho}I4uL4WuF8v~gi#stfS?8gXM`5ttQ5%_^HM{fd{!9q0;~;z0H3~yj zdSdK{y#Hu`jP8xtPD^%mF{rB0-45pK*pk*A*ppv^C_XO@?ZAM^yi2ELv8u}A=bxn1 z&MgQaWD2BkD-Y;2F?5`aMLPOc5io#BJlJr-aw~iA(p&UwVn3rhCGx2gB`Lhwy#N#b zb}IScNbA;h7|x}qNTv^sczgb^QrTX-Q!<-AGI{D(C@A7R&1=(0TI1u)$kgXFq6e=qN|o1+ZtPR;S$sveJ3A?r4J>x8Jc z=V{)?(*uj+$=v8+ob!$G$E<9T@L3XGRVPaE zM-w$%2b1d~rWGqo)C$)xgSp;0T5WqTLW@ZxGem;*PH}y0biXhn5al`%awL1mv=$%@D9^guRgBe zEBVG2Qvg41;J5hAD{M2!kHqt7q-I2Zpf#!+AMR08fnRg%xp?Plo{!i)i5m6$l6RI{ z1tLb7p4g#&)fMbJUU;emJln z=@HL{6do>zQv5CY!&}VF?ZkH`5U_23w0XJ4!m(F08~1rvz7p~o-)`S3aJE3*WYHRi z?CQWokD7OzCIuG9N@^rcTwWI#u?=lDLGoFD>x%yhnHKTFFPI1T5wAri`jNc1!{HY# zNR@QW4#Qrlk%l@esD%orr`?0O!2*$+gXKqM$~tXS;81Gtv;d94yMKL+<4rajC#DcP zk@UMZkD@&c7Ml+qs-}+Id%c3Wz6Hw2mxNr@;xDn`@3hg~ynH=-^k@}Qc!zY<%fAhv z_HXGSgPH0^IjG;KF`m^;jeM$le`)4jVRoqa1c6h4sH1$YM*<31jC&rSO9)UL-7wkc zbkm%@%8F&N$`Kx|2ae_xx_~o<6sw;1A?%%T;6?iUUmaYQeUG8Yrre!{wLJ6%xX%cxY!5y^{|SO6t2*AB67B*znV8kjk0z){ZfrZYdfX+FkIx# zLv4wuz=#LGmLmrK*VGXGDyeLiOA&>Q8ht*ba+flv#_Gv|SN)4Tm4 zvLO&6HmZYfilp%KES|NNDNp_`jo+~gw*lbLf-qM;2k-_uu zWA4scznTLnw5C`MK!r>`yi5r98;`j&$2PMcKCg#;g^tmS5jpE*zRHS&{vz-zTVlCQ zRlOT>nk7C?^{})|wX3z%`2#Uu$xMHBZ7NT!g%T9iQI^W_ejPY)G#fS29uP5bro;Yb zmI6E{sI^S0`foaf9tR9qx{X~s?wb2x%WsFsrQCFwC0aepFA^zmvp5_z+jE%6vt1O8 z?>@G~U%h@^Q9mt53Ri-|s=a&B91(Dl8X-&sB>m|{^)=KV}OeSBRTOemCH58Nnf z46y?ghr1jP>Rv?Gc%Ab17f2V+Jo@eCMkRNCHfud;3}0^0O%m<71K&_)tKd0gWviME zjX;C+R|ZJfy_HE16=}j@f&9{u(jS=3AZ9hnC1L5AV4Yz3%pp3*pz>^@82> z%@Td}Pv<0YF>^jQAj{I;vK%uxkm5z%3+mMj;Cvf1%c>Em4aPeqB+xO(vk8H5X(F~d) z>E$IOD*Dv~6|(JZEYK+(%N0C)rgv~|t}7yF?xUzbU7NL|%79-kcD$T20i@o-?zzFE zpuwMiVcr;1Gha0PIIYUi-dVaaH%%|s1oOJM6A`q?zGQi>THI?j`aDw79sbC-%GK~~ zU7C^_&%GPdri-BdY<_>h;jW&%ip-HU#A zft2DlF4ws^ypE;C$D&iOich)KpTm9zj$tw3iK6ruCpS@v4rz>jeZGEkH3M<-aE+Z9 z3)GT~;N9T1;@(vH?|Hn;xxuSm5LQ`n6X%E|Bga_}dj1FXUA3AAZTpTt`6#Yp(xY{@ ztD3gDH+lDD4p`e(%fL9@C?;F;$jA9^ioV3YWLL{ozg&u;BLW%h^5}<>r7*_v+m+>Q z>|X0G!&0K7FpCj+^0Q+S($xFu!OPb3m9;hVr8kHb>}Pqy+dTCtpS14Pjr%zKZHNl| zQZZ6?Ihns0^^dZO0;6CQAAtF7-ofvf8Banyj7<={}>&e7Xg zJh!IwO5PO18?jm>d4z}3eytfKOW#}1|r7d!oa@=2t~Vy`P(dPpub7e?egQFZLpb^22>m&>SgfZL7s z>Cit8m$zF(oWFJYikSDObbb6VteN1OJLySoD*^Lc`j;S}j1=tYBohzrCdBs(Ufw2! zKZXBFG*23|Fe3Tlib<@{+W{Kh_MvWXgNLZK+vsKkIv{ET`l@k%Bm zuld{k<%nLoc6q@D7B-m3W?t+5q6TO$eRV!a9(NK9{T!n92e(s4RKiS8k?yQ>ny(VH z$-G1UXJ^<4H5mZ~frG3Dt1ZuLhS)6|C@0S5{(+o3k}8zxR4A-AxK3s}Hs|03k2X1O zGf}*?dqQQJ`v6KfLCEgse|0B}I}pRp6b*4^zciqKL?5imk$%_V8WCN8K+%@1b}Bn! zDu0t5qrA_7@ekR&{(b3ndiA3Hi2-LQ3AqX^%HAG_+jhKZbU{1OW+1p+nn zmOe{H0G4YS;F?P2v#arF-9;{dL)1Mw=sWHQcR{nLxTr9K_6;=|5>2`(d!h+(wg|R! zwiFDrKasr0&J6|RewGrC06f%YTNC#}#7DnaB;7r@9p@5Xgk?K6p||IMj0k4H9bb)# z#uTNR5W>z+&b6<*h^h)V(yd_snNzl&dORx1jVpLSo000pes zVvX|`q3VA93nSf8B!N8uhsrhn4nU?`O3e5nv( zC38?W9V5X*BV@>PkB_qqe=F`ic$li!r;&B9cI+pU2qVQ~t>q6+Ms`9`4(z8xuv_fT=3X*#$EP0afumtfZgBuBoAwi?afx_<{;s6=>7d( z;kTLHSjZ;JfJk6s1$ape4}EK?*Ymw>)F&&ZxE)D!C}SLZ@0BW2xbuwRN{eV)kdyjg z;Gylg-*gOsEN_eN4Tum@`)R<8_hSO2TSqaH$|TvaRR=~B3*N+OM>3Qb@h>Fs$!|7bB;pn18a0|YQ<*BKX7j56^d&5k`52HWX1GK9^YL_ zq@kA++&bwI!Y8S-+ZzzxmW(^FuVg~~^qUFFWeoPWUXuH!jhy6uUe9bSekGPX)sxKT z;`m5p*or@`G>Rz+Wmrh^LX>u};(^G|2R62VF&tEMfK&3gK;X!jLsigvxhZS0P3X7y z7`BZlY51ISDZ}sinRju=TCQ~D8^CH2Vd;tcW;mor%sqZ>kAK-3oyV3A79{D^P%@d# z{LiT!0K(hnvFFTC=1~WM8kebCx385(b#{3Dp3FL%GF{kvFO7q$&MgOiEU(8YQ)la> z9H)UnzISx zDs|)!y!=c4MCKwPjPLAA!X(eVeY@WR9~Cj#<&%9(qR~eOl)&V5&Uqo)v-AcHj7x^K2mA z&f`jwnpIZ6jNRH_Oad ze!k?PihJO^PVF%!E43>p>DBbj9NEf1LXrK_MY0M1v5MqD^JGnc{Y?B(lPjh5#U2b!ajcRMX)y>8`40zieDv%l(r9G#qfqC*mT^24EHdt=ju zmcd2uQs`&Y+7|@HXCK5{#eBv7@3c#4jI|E0h~Mh!an#%KELOELq&eJ%kNYgC zNwvTfwS~bQk`X36UInqG(pYy($8;NMvp09cj+4H;I}g1$VZVblwA|xaX8r7a<9ZfM z)%25lpEoX+>E*N8A7rp^fBs*4XZ{a$_db56DU@uLM21Yr62=zUQkFr;KH0m6A{5!f zpzctZu`emaSjLi_?9(mAE<^S$LNj({24nfYru+W<3*VpKzj-{I>vhh#&ULPH&ULQy z9A`dK_CiR_uaeLAlO`J8p^p-M?m^mW_bfY*`iru=j!a*Aux;C7RfpW;_dPrnODD+f zKF-|=?|?YFyDXaaFBmQ7|PgR3QH0AsW>RryN8H%Ql12mV?l>&Wfg_UDhKh z*Q-M(3>G^-1CN5O{t?xKdK7AuI$(d5T|c>){;D$iEUjns_?W+vRHI~Dm*dw8)B#KS z6HrFsE)H_0r?w)ibG_rb=E@EzGskeJ(4qESi^ZVxeeHe+slF7kcIs^R68bvh!ntWH zy+d@wdFP&qU2}u(D82>ZImBC!i-3d6xyw0~UF<|OSdc@XKZEPu?X3WOzXZj;5xz$n zXJDE+PhBfcn7qTHrkzn~t7b#!`S{Xc)YqTaVSuM$*S&N4+`|``P$>+l9F6iH{N| zWZMP>Eh~97@i2u+oo>|eD)VIY>P?BXbSq6L$4^d#g@aUlibu6GI!l_?Xt0u`;5-$* z-Mwo;K{#C3DDA%;^SO3oJWJ?$PfqXFjqal(h19<2Ep+?{EI0o8O0k<1(^8}Ef8W-q za)}QS_BEENs@IlV_ylYvU+R;!J)HTTq%Ww+92=2!5e|aBcytugfvCak72mm5JL`@t zaYBn-;N6@6orTA)7et(iwuP!qyPggt9b(k(7iUpYMxI7oesHxfA{}k1&J5mX>HQY* zz$3rYZ$SLItijEnklc%B0ytu$m}nY0tZ{xqEUS5@AywZKrn3*045YL6dQsH16Rj>t zN=!eQ_PcvM4{P|kAi1xT|2bDXwO8%j+_~cXAKcFJp*pn5uww_4iDK$_`o_%Ct9-+K zaFFNdFsAGxa{FmRwzq+c4?-K6FN^pW)t2fR zEl)m?s4gygy!B9k9O_7GHMJcnex;-%8Xksx>~kd>8T2t&UsvmtwMNd%TaM=$XLVz% zEA$LjBnDl14`#IwHL!=X;*d-QZ9$ngVMsTpRd4r!WCwB-Tm%`a8Zs%o$)Sy69<0&DQ$r}OIqix@W7k8o)ot))8z?dpNrR`CHpjERqijLF9Yw)M zdU$G0(_bnROATp9s>wl#p*d+2Pf_F#AD2m!Q&Pd()HGbF?`iv2Kx?ZF2O!B?-Y+kG zf|kjPpP*n zip7z1>hnQ9(-^!YKPAM~hAcB5ISUDl8a8ebxyVv_}zJ?%sh`i~8+1 zw*(a!31cp_%RB|SkGQGb72%J#aV(Bc#aRNrH3?jDTX`LJ;<$oXng@Rl%KQ*q~K~~@GF>+FaZzpFLBTc-r<7nPisq7GJg_z&rq{u^#D^iO>?{ zp%B;Mhj8lkzv9nwxS;Wp&I(p!+6L|-+l)wtMj}KqB*sTij3@v`Xd&5F0bx+d^j z=r~AoS&Z0*^~Ux9=`u0Vz}K*9DkIWy?LiK|Nx0t5H;bv_hgNcw-P7S-TnLNwG7YWK zjPVw<`k{e)X!@X=>}=5F0ZDf+_|?*$zaR1^>_9E@yyPPaKzSE zy)%1y%5mYJaW-`sa<5~t`>X%BXW3b|h#ZE4uX21f{d%4pAr;8`2!FMad2j_R;G}eR)h706WH)uOe~*D8~Ym9 z8rcOo3U3SY290jB;NMz2>&I@fI}37LyW{wXf0guA0M2sY-08J?mD6+5U%=DBGwYV% zJs_w=p=%`fF8Ty|M>_8c$Fe8uJsgA%$Dik*m-U>DQcqAj`RUp`Yq-m* zU7H-k8PtVqVZS48Stl4Vg*#jH))^c^xoPm`-Sa@E5#V4${t0Od`4Z9|a*FQZ2ge#4 zj2Uvw%0u}Vuh8-{@n%|cwj^4f#9g(s47VKR8L6Dq3)D+getL$E7ILF47*tM{SvgrZ zYrCn$mLUaFuTa(B4<%kNDE^tm4SE1tms?j^zcUzJT`tGtB1~_SC#YP%+@%gYlo-6t zy!t`tz4UvPK&#-h{g%;TJ4Q1`I;4 z+WE^y!*PONl^ChQRGc(?n!v#fm<;9PDiCg)9C?x}B`63|fe)m#oaP0f8rQ-0V#Vvo zbvI^kPKCd47K7HshkFXCoj&K%is!SgOh0ab-FwbFY=jT#4e@xgrW~(1$pZB3v^pa~ z9nq~qKULd-j$k+_*1oXX);~IYnd9eqMydi;nW{$Bbh=3|ysgd{#Wv+{C`!Xg@9+wF z=KNMLGX^nm@USz|3sJS5_UYPs1{7=YoX;dJsP72R7=inf)^F}yWnc*3;u^CUZ z!siJ-qnASdRu74{sB_O@MM0;n_S+id+E8xvN?(j^q_P~SWe;lqUHaiQv>rT@54{`* zUCVQ^)|lVsBs%~3^c=w54n)5waVY*QruHjqgEWXO5{)(-^LqGR#Zt|%pXMTuy1nRfA4E|?Q~ zCZE%tIUNpiD>g3x_S;yO2@UZq<#T%Rw>9SkJSIJwTtcHRFRM4QeHDF6uQFCLAZ8Pt z&1u9SQWxt{mea>xixE0I?6K)6hLL9h$qs_2I;KZ*7oNnU6dd+Gu|pH}1iM&n`J58m z=lSkrX-GBLaldfoc~D`epl{Q5`gDkG5(6lYxp!pn2~B$+{)315fa>hD&8$Sxndo?N zDeR|U>--O|_xoJU_TY7P#g9!9q?6aY0U`>3P_n(C-oT+!R#q?FXber%##h`ZTi0E4 zC_g1Qu?tbWf487P-k|8WE|~9I;i=KdWr?h_`ETW4MdCGBK1s{N_~rnh8Jd3mJ2R7J zz3BbfjNt}2HXxpd7y?2?>=h8j&*EHoTkFZb)4JL$g7?laQqNN3a}IIcUh50%D{v}s zF=Xj_qFEk&7;VQd|Bv@X{+P$sg(!#GAvYf1;7n=Sq(9%enLF8jpmpfFgzxXqnTAx~ zhjWk1x+mm3SJ%F|0>PG}_N9}t?#@v7BbL=`17!)8uD7&@g0(4u56mBBFr#nW#RF46 z-{rXI**jVjO&z#_LpNKHTT+)~FCMgl81qNry6T@`!b`JCGZt9+l zyz*5F1h@lV>)d@DfdO+8P6Y-6T{PJg0(A25rpu3U#TPzr@ZYx;%e=HGL6)vVMx3AT zGgkw=AXA@w#WIbcySEzt41~Szn*XZ9>fhP%A?{!jI6Uviq6yI?R;Xb^YuuscoV+I& zX!^>W`eMt4wX9sCfG`aLjeEl3xyo;m6-YBe+&-0~QQ95E&@hNN_|>eD(qB3_J(NqZV>Z}zZ{H|FRAL@PF3#^ix;Sa9SCk)jYKfzp_ z)*PQFjOya~_smK83eH}otNrn)RuNhnupk4;;#uCa-U20eR38ScZt}dSP6WK-%+GUS zD=(aFq|-8g>~I9U?ah>oRZMs=^S*!|lborr%1{g7iE6k!0YM)JK-BM@;y)C)Qbe4j&mz5S+dkZ0yuv8%rj^RSby z7wKluEQL5%>+!X7T7M%QjO7O(P|BIG@ewfbwZY2fYWm7EaR(o=?LsPS;TvCuy{dbD z`nJIr*l5KK(*pG28OUA~kJm)3JM$%#aQ~i{E_P`B(6KRts1pFI=^7}~b-7Ue^7Jz7 z)Fll@!jy}hRPfZVh-}z8XKbCO5`r$xlR;a_i?kktWTaj|C>_MfxX=pBSMr88L`UM3$neCShU~xdL zzO($_>Yy~$r2ycW@f|$uhG{5z@64i0NHh;^>b60!YXZKqdo_p%pN`cJignj0>H@`I z1Pmc2jP{YXS*Q*fU#=h^If$x2d*Rdk?|t`5HIa{;Vz-((K@#Gr=knrpWW?9BE1UJ8 z!dK1#`#4~hw5|8#?mq`wEQryDSAj2kLwA725V>Z3(= zH=h`C4(e+-6CMIcbAr};)`xQUg8^wFj2>JLeA$iP8|q7!H!Zp5R1|Qf-@5ga9L@h7 zG+9G@4dWd2%Gw~z3lMb$tq-kF=I)~a(W@9k04i|V4eGmC9j#jLkNo=6jVw(aUM~O0 zd?1D}&gJblsqDMkKYT-u;qEm?st0w;1bGV(6v3Flo9Ti(KM<`^m&>km=FTF%2=SS6 zjos^zO3@*^m`||h`*7O;W8=p1sSLw=Mu?`W6IgPa44p&p;h=m2Kx>7lf{N_#vDf~?2NAE;;R@Dfbl8hSrge=E7 zgv;w$ZLh?R^kx4>-S0%1FzK-aP_TqB8p=+Zbvtdb;*6dF9_IHIVgGQl>QsI8TSc7# z=2@jqnMv_;W2RzdDJi(A9KwuPqdMshfK?<3&(Yy>gI>A4UXVuBh$|%E;FN-Ud4%L& z;9p_tuAi95%I-ZDWv%Y+5C;e6Uwlu#Wa(emNl7eH(&hy+-{%3$*k+oHdsCD*#O=q(UxS$%}sjNugMe*MtDxDC`y{i~z=*ZR?2b z^usvED60{_Y4F?dBcZ z03!wP3}%LSAUTy3#ykV~omy4)=XyRF3Y@#b!oyyi`?QBb9D1E>3TW#!OMv87nyh=%>nBu1 z6e|$QVn*z z4xYP|Do5zlr@TGda1KShhzTXibu9nY6Q%in$R#V~u>CtL{d}kcf*@5#v|bX+e?y>Z zmO{rs^!sLv#o$_`ML5afnfTk!g$sT~344F%-Pc>hxha&6hd%o!z~nL@3P918VtA=g zno*JmCVfZ>{hkxuT%BQYa&HC9cG*GU7mHq9ez(^{U<1*;dVH|?w`UFy(78J1fK`$J z#`JIlHiTT3k48R9S}qe}aEQka#CU7Y(d>>MUPY z&ZKnG+Wl!=a~v3*Zh|t};IY4dFf%uqXQC?=AL}d;G}!m|WY1c0o{3)@u{AdXvB?Xt z`eZ^ayA{l{6)M!}z3oL?Tv@7)m!Wa z$N4F#0#y1O7n*~)js;wpUauHNlB+vu7GJN)75D>}Kj_N1f6{4AkCw}CtliiQt`A6+ zKUsz1LwS$1)(9{{fWxa99FI&S6drj=v>(&ikwy(lIyWuz9hb)5YZ)aapJ%fZQu!|S z`l@gdp)*|8#)`=^cdP(XS8*B`7(o_Bj0p~e2<_b(Bg6bm+kw02%GN21BaJJUx%!&GbwdlUL%%19YXtzR7dY(OU73URAgzuAQpm@-&XdRuEWBIcJo;N#yR>k? zy|+1_jnwxAqSW%hmzkA%TO~^}`9Sy;`Bs`+nSMrRKDT-3j(O15QTNji)12sOFkbN$ z2J3Dk(J!Cf;&Yu9UM1FU-5{|MKXyNVcHmDmSKVK;6`q{*xxj{^vk*BLF%KX;`-D34 z;~-WFV#>mc)kpGf`@+wgnkCSMx~o2v$K!9Wuf27bh?GvvFRDhVTP^@(pIw|d8^MPr10kNExTDdCPm5KC*%G%Up zo1Q-4I7M7a54*GI(0zKPZpU|g`H{>?I&D@YC5)hi@jYB{=ssrmfTux0Gp7r`C$98;gH{&pa0yF}{#rl}JbO2Bb>OuTJms zF^s8L*QT^5ZRTdhRTLRG!d${SEJ7+xSm@M-xck$(X z9AUk-Nx~7iH$SG>InY^~>*VcT+4St_rMzjFrfXSppE6S7n})2toq(tw(_ZRd8KYdQ zG)&3v89)J!KxmJ(#M>^J;E7pWNK)>ef?e01>YVUg^<{+=yBAFzi}&43nQwH6*<>VD z67v`1yEkQB-#lZj{2rue?9p)V2NPY50H2Wi`Q6L%mic2#6;sIPL-RXq$6|&%30ab7 z2)2Y7%g!g;IUlQ(j5AboKby7~1%BIuxV4_o?UBCqxLmyRG%(Y-K#+4Q!4KjHKA1Jb zuAyWTezPNW7S9sjUXSFa+cQoB_e?`I>?r~k$k#WLJeK1pHcFbkooDv|rZTX+09$Pc zpPJ4?LhtY_Ch_nl!I5z7PZ>4Bgk|@GZSfTs@`k<4_8rm!7WYNMls#cY`J^+OC_qL2 zv#JWpq=gaSm}DGMcO;YW9J2?ZnY~6PAQO@1ieq7p^vlrs0(%B<%Z zNVgSdmcW1#dEf7mH!9?Yh z61S4b`3r=%ZCJFL*t`}e9~y@)eIExLll-yTr&Gv0R@ja28&H0V%a@`FDvHEUG~Z*Z z@~+z+vv~v93gEdFK#)6XDQtX?%sl+>dIC@eo~!hy%4nFcgAygRt6~^dV^&$+ zn`zy0F(l^qxGC+s|Gieb=ZV$+ci(4?N@R)t>u@-tI5!bwSWQ2y@zEq^RM}GLp^~3c zgi?x9{%^GF_7H3sdudYrdhlcvnTG~yB?w>_=8Ve#L46p2Xe-EXbJI6Hu%elfr)Qc4uf5xBp z%x@_()c!()Ai*f0ogcUDd*pt-OlTZf?{7KAfK@x5m-L%COI^qn5VWP?7Ta zb+dGPfVq|R$6)TMgpZ0x(()3y4}e!zF+ zcxZR#9GykW09q5;yji~hyV;I#C^$>F3FN}6J4N7)_78B?Mw^_IEzT9wF=fI34l<27 zKz!Pa9ADAW59FPreLFcom~Rvjlm*U3cvd2mE!k*CzAvufFFCsRtOZ6fByAY!Kj_s0 zAj{e}(w4>|&R;E$MbmP8-kIHOwLF^S{+-(P=T`u-)xfHLL9AtRpD>kc0O?@~5n+C{ zJcY;)MEv+qsw}pwB#qj-cF#tqDATvN3}D`?bFhO&Qw&KA`Q@6;ujEu@3i4t?RG0&L z^DfRRXhfmL8{-~|Xegqe0D#tX0TkJ3WFukMgs~L%AbL(2J5X_PdQ4NbC z$p5RyL}2gRObEstq8XhRB9O7j{ zT=Y6|>rdw$_n9Tjgf_1Et_J+>Esz#ZO`?1mqOt93B%o}_JhGg!uA&U%`dcAsJ9$-k zbpZE&|A_tHN;!CR9Ph7<-QJfW1(O`Gs3i73z5O$=e~gPB=cmt4x(@#L=l}HZKO^}6 hH5u|V@W)JS++V)^e9|un{NxaWp0<(J$J>rC{vWp9d@cY0 From 43b21975f8f727eb7a748c7ad78e393d41f6e499 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 22:31:03 +0100 Subject: [PATCH 11/13] LUNA-1: Added cache control option to wipe cached game data --- addon.py | 25 +++++++++++++++++++++++++ resources/language/English/strings.xml | 2 ++ resources/settings.xml | 3 +++ 3 files changed, 30 insertions(+) diff --git a/addon.py b/addon.py index f9096b6..27fc398 100755 --- a/addon.py +++ b/addon.py @@ -1,4 +1,5 @@ import os +import shutil import stat import subprocess import threading @@ -185,6 +186,30 @@ def pair_host(): return +@plugin.route('/actions/reset-cache') +def reset_cache(): + confirmed = xbmcgui.Dialog().yesno( + _('name'), + 'This will remove all cached game information and clear the game storage. Next time you\'re going to ' + + 'visit the game view it will take some time until all information is available again. ' + + 'Are you sure you want to do this?' + ) + if confirmed: + plugin.get_storage('game_storage').clear() + if os.path.exists(addon_path + '/boxarts'): + shutil.rmtree(addon_path + '/boxarts', ignore_errors=True) + log('Deleted boxarts folder on user request') + if os.path.exists(addon_path + '/api_cache'): + shutil.rmtree(addon_path + '/api_cache', ignore_errors=True) + log('Deleted api cache on user request') + xbmcgui.Dialog().ok( + _('name'), + 'Deleted cache.' + ) + else: + return + + @plugin.route('/games') def show_games(): def context_menu(): diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index c02fc26..46e9c74 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -23,6 +23,8 @@ Input Map Input Device Create Map for Above Device + Cache Control + Remove Game Cache Addon Settings Full Refresh diff --git a/resources/settings.xml b/resources/settings.xml index 480f986..abe5f02 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -23,4 +23,7 @@ + + + From b1996eef836d371ed30ab8cd912946f8e984880d Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 22:43:51 +0100 Subject: [PATCH 12/13] LUNA-3: Made resolution selection optional (responsible for a weird bug in a number of cases) --- addon.py | 3 +- resources/language/English/strings.xml | 1 + resources/lib/confighelper.py | 78 +++++++++++++++----------- resources/settings.xml | 5 +- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/addon.py b/addon.py index 27fc398..2472519 100755 --- a/addon.py +++ b/addon.py @@ -346,7 +346,8 @@ def configure_helper(config, binary_path): plugin.get_setting('packetsize', int), plugin.get_setting('enable_custom_input', bool), plugin.get_setting('input_map', str), - plugin.get_setting('input_device', str) + plugin.get_setting('input_device', str), + plugin.get_setting('override_default_resolution', bool) ) config.dump_conf() diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index 46e9c74..9549fbe 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -25,6 +25,7 @@ Create Map for Above Device Cache Control Remove Game Cache + Override Default Resolution Addon Settings Full Refresh diff --git a/resources/lib/confighelper.py b/resources/lib/confighelper.py index b9cf4b7..38d33d6 100644 --- a/resources/lib/confighelper.py +++ b/resources/lib/confighelper.py @@ -46,9 +46,11 @@ def _reset(self): self.input_device = None self.full_path = None - def _configure(self, addon_path, binary_path=None, host_ip=None, enable_custom_res=False, resolution_width=None, resolution_height=None, resolution=None, - framerate=None, graphics_optimizations=False, remote_optimizations=False, local_audio=False, enable_custom_bitrate=False, bitrate=None, packetsize=None, - enable_custom_input=False, input_map=None, input_device=None): + def _configure(self, addon_path, binary_path=None, host_ip=None, enable_custom_res=False, resolution_width=None, + resolution_height=None, resolution=None, + framerate=None, graphics_optimizations=False, remote_optimizations=False, local_audio=False, + enable_custom_bitrate=False, bitrate=None, packetsize=None, + enable_custom_input=False, input_map=None, input_device=None, override_default_resolution=False): self.addon_path = addon_path self.binary_path = binary_path @@ -67,31 +69,35 @@ def _configure(self, addon_path, binary_path=None, host_ip=None, enable_custom_r self.enable_custom_input = enable_custom_input self.input_map = input_map self.input_device = input_device + self.override_default_resolution = override_default_resolution self.full_path = ''.join([self.addon_path, conf]) - def configure(self, addon_path, binary_path=None, host_ip=None, enable_custom_res=False, resolution_width=None, resolution_height=None, resolution=None, - framerate=None, graphics_optimizations=False, remote_optimizations=False, local_audio=False, enable_custom_bitrate=False, bitrate=None, packetsize=None, - enable_custom_input=False, input_map=None, input_device=None): + def configure(self, addon_path, binary_path=None, host_ip=None, enable_custom_res=False, resolution_width=None, + resolution_height=None, resolution=None, + framerate=None, graphics_optimizations=False, remote_optimizations=False, local_audio=False, + enable_custom_bitrate=False, bitrate=None, packetsize=None, + enable_custom_input=False, input_map=None, input_device=None, override_default_resolution=False): self._configure( - addon_path, - binary_path, - host_ip, - enable_custom_res, - resolution_width, - resolution_height, - resolution, - framerate, - graphics_optimizations, - remote_optimizations, - local_audio, - enable_custom_bitrate, - bitrate, - packetsize, - enable_custom_input, - input_map, - input_device + addon_path, + binary_path, + host_ip, + enable_custom_res, + resolution_width, + resolution_height, + resolution, + framerate, + graphics_optimizations, + remote_optimizations, + local_audio, + enable_custom_bitrate, + bitrate, + packetsize, + enable_custom_input, + input_map, + input_device, + override_default_resolution ) def dump_conf(self): @@ -107,17 +113,23 @@ def dump_conf(self): config.set('General', 'binpath', self.binary_path) config.set('General', 'address', self.host_ip) - if self.enable_custom_res: - config.set('General', 'width', int(self.resolution_width[0])) - config.set('General', 'height', int(self.resolution_height[0])) - + if not self.override_default_resolution: + if config.has_option('General', 'height'): + config.remove_option('General', 'height') + if config.has_option('General', 'width'): + config.remove_option('General', 'width') else: - if self.resolution == '1920x1080': - config.set('General', 'width', 1920) - config.set('General', 'height', 1080) - if self.resolution == '1280x720': - config.set('General', 'width', 1280) - config.set('General', 'height', 720) + if self.enable_custom_res: + config.set('General', 'width', int(self.resolution_width[0])) + config.set('General', 'height', int(self.resolution_height[0])) + + else: + if self.resolution == '1920x1080': + config.set('General', 'width', 1920) + config.set('General', 'height', 1080) + if self.resolution == '1280x720': + config.set('General', 'width', 1280) + config.set('General', 'height', 720) config.set('General', 'fps', self.framerate) if self.enable_custom_bitrate: diff --git a/resources/settings.xml b/resources/settings.xml index abe5f02..be51ca5 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -4,8 +4,9 @@ - - + + + From 767e3f26995434488e501bff0585f0902bfd3dc9 Mon Sep 17 00:00:00 2001 From: Ludwig Wacker Date: Sat, 19 Dec 2015 22:46:31 +0100 Subject: [PATCH 13/13] LUNA: Upped version to 0.2.0 alpha for next release --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 01df65f..0b380a3 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - +