Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V0.2.0 Alpha #8

Merged
merged 19 commits into from
Dec 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a9e3f1a
LUNA-1: Refactored game storage; added icons for settings and games s…
wackerl91 Dec 18, 2015
6241307
LUNA-1: experimental implementation of querying omdb for game info
wackerl91 Dec 18, 2015
bfecaa8
LUNA-1: added another API as fallback; caching images to disk
wackerl91 Dec 19, 2015
4c4a324
LUNA: Pairing hotfix
wackerl91 Dec 19, 2015
32bfc17
Merge branch 'develop' of https://github.com/wackerl91/luna into feat…
wackerl91 Dec 19, 2015
8b33494
LUNA-1: Moved API calls into own class; added complete TGDB parsing i…
wackerl91 Dec 19, 2015
2caf29f
LUNA: launch hotfix
wackerl91 Dec 19, 2015
2277fe4
Merge branch 'develop' of https://github.com/wackerl91/luna into feat…
wackerl91 Dec 19, 2015
ca39ca1
LUNA-1: Steam no longer produces a (pointless) API call; added a chec…
wackerl91 Dec 19, 2015
7e47788
LUNA-1: Fixed some scraper related issues; added some code to handle …
wackerl91 Dec 19, 2015
02ca386
LUNA-1: Added API information to description
wackerl91 Dec 19, 2015
3884560
LUNA-1: Changed icon color to white to circumvent transparency issues
wackerl91 Dec 19, 2015
6ba2f9b
Merge pull request #4 from wackerl91/feature/LUNA-1
wackerl91 Dec 19, 2015
43b2197
LUNA-1: Added cache control option to wipe cached game data
wackerl91 Dec 19, 2015
da7cc13
Merge pull request #6 from wackerl91/feature/LUNA-2
wackerl91 Dec 19, 2015
b1996ee
LUNA-3: Made resolution selection optional (responsible for a weird b…
wackerl91 Dec 19, 2015
0344eea
Merge pull request #7 from wackerl91/feature/LUNA-3
wackerl91 Dec 19, 2015
767e3f2
LUNA: Upped version to 0.2.0 alpha for next release
wackerl91 Dec 19, 2015
df332dc
Merge branch 'develop' of https://github.com/wackerl91/script.luna in…
wackerl91 Dec 19, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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