Skip to content

Commit

Permalink
Merge pull request #8 from wackerl91/develop
Browse files Browse the repository at this point in the history
V0.2.0 Alpha
  • Loading branch information
wackerl91 committed Dec 19, 2015
2 parents 8c1b99d + df332dc commit a13b060
Show file tree
Hide file tree
Showing 10 changed files with 385 additions and 112 deletions.
242 changes: 168 additions & 74 deletions addon.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import os
import shutil
import stat
import subprocess
import threading
import stat

from xbmcswift2 import Plugin, xbmcgui, xbmc, xbmcaddon

from resources.lib.confighelper import ConfigHelper
from resources.lib.scraper import ScraperCollection

STRINGS = {
'name': 30000,
Expand All @@ -32,13 +34,15 @@
def index():
items = [{
'label': 'Games',
'thumbnail': addon_internal_path + '/resources/icons/controller.png',
'path': plugin.url_for(
endpoint='show_games'
endpoint='show_games'
)
}, {
'label': 'Settings',
'thumbnail': addon_internal_path + '/resources/icons/cog.png',
'path': plugin.url_for(
endpoint='open_settings'
endpoint='open_settings'
)
}]
return plugin.finish(items)
Expand All @@ -62,8 +66,8 @@ def create_mapping():

progress_dialog = xbmcgui.DialogProgress()
progress_dialog.create(
_('name'),
_('starting_mapping')
_('name'),
_('starting_mapping')
)

log('Trying to call subprocess')
Expand Down Expand Up @@ -95,9 +99,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:
Expand All @@ -109,28 +113,101 @@ def create_mapping():
else:
if success == 'false':
xbmcgui.Dialog().ok(
_('name'),
_('mapping_failure')
_('name'),
_('mapping_failure')
)
else:
return


@plugin.route('/actions/pair-host')
def pair_host():
code = launch_moonlight_pair()
pair_dialog = xbmcgui.DialogProgress()
pair_dialog.create(
_('name'),
'Starting Pairing'
)

pairing = subprocess.Popen(['stdbuf', '-oL', Config.get_binary(), 'pair', Config.get_host()],
stdout=subprocess.PIPE)

lines_iterator = iter(pairing.stdout.readline, b"")

thread = threading.Thread(target=loop_lines, args=(pair_dialog, lines_iterator))
thread.start()

success = False

while True:
xbmc.sleep(1000)
if not thread.isAlive():
success = True
break
if pair_dialog.iscanceled():
pairing.kill()
pair_dialog.close()
success = False
log('Pairing canceled')
break

if len(code) > 1:
line = code[1]
if line == '':
line = _('pair_failure_paired')
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 = ''
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

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?'
)
if confirmed:
pair_host()
else:
return
else:
line = code[0]
return

xbmcgui.Dialog().ok(
_('name'),
line

@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')
Expand All @@ -140,65 +217,62 @@ 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'
)
)
]

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.raw_dict()) == 0:
get_games()

items = []
for i, game in enumerate(games):
label = game
for i, game_name in enumerate(games):
game = games.get(game_name)
items.append({
'label': label,
'label': game.name,
'icon': game.thumb,
'thumbnail': game.thumb,
'info': {
'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
endpoint='launch_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/<game_id>')
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()])


def launch_moonlight_pair():
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)
Expand All @@ -207,14 +281,33 @@ def loop_lines(dialog, iterator):

def get_games():
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()
log(line[3:])
game_list.append(line[3:].strip())
if line[3:] != '':
log(line[3:])
game_list.append(line[3:].strip())
if not line:
break
return game_list

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:
if cache.has_key(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)

game_storage.sync()


def get_binary():
Expand All @@ -237,23 +330,24 @@ 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),
plugin.get_setting('override_default_resolution', bool)
)

config.dump_conf()
Expand All @@ -262,19 +356,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')


Expand All @@ -298,6 +392,6 @@ def _(string_id):
plugin.run()
else:
xbmcgui.Dialog().ok(
_('name'),
_('configure_first')
_('name'),
_('configure_first')
)
4 changes: 2 additions & 2 deletions addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.luna" name="Luna" version="0.1.1~alpha" provider-name="wackerl91">
<addon id="script.luna" name="Luna" version="0.2.0~alpha" provider-name="wackerl91">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
<import addon="script.module.xbmcswift2" version="2.4.0"/>
Expand All @@ -11,6 +11,6 @@
<platform>all</platform>
<language></language>
<summary>Moonlight Launcher for Kodi</summary>
<description>Moonlight Launcher for Kodi</description>
<description>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)</description>
</extension>
</addon>
Binary file added resources/icons/cog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/icons/controller.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions resources/language/English/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
<string id="30018">Input Map</string>
<string id="30019">Input Device</string>
<string id="30020">Create Map for Above Device</string>
<string id="30021">Cache Control</string>
<string id="30022">Remove Game Cache</string>
<string id="30023">Override Default Resolution</string>
<!-- Context Menu -->
<string id="30100">Addon Settings</string>
<string id="30101">Full Refresh</string>
Expand Down
Loading

0 comments on commit a13b060

Please sign in to comment.