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

minor additions to allow for better intergration #58

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
47 changes: 26 additions & 21 deletions nile/api/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import uuid
import json

from nile.utils import weblogin


class AuthenticationManager:
def __init__(self, session, config_manager, library_manager):
Expand Down Expand Up @@ -187,34 +189,37 @@ def handle_login(self, code, client_id, code_verifier, serial):
serial)
self.library_manager.sync()

def login(self, non_interactive=False):
def login(self, non_interactive=False, gui=False):
code_verifier = self.generate_code_verifier()
challenge = self.generate_challange(code_verifier)

serial = self.generate_device_serial()
client_id = self.generate_client_id(serial)

url = self.get_auth_url(client_id, challenge)
if non_interactive:
data = {
'client_id': client_id,
'code_verifier': code_verifier.decode("utf-8"),
'serial': serial,
'url': url
}
print(json.dumps(data))
return

print("Login URL: ", url)
print(
"The login URL will be opened in your browser, after you login paste the amazon.com url you were redirected to here")
input("Press ENTER to proceed")
try:
webbrowser.open(url)
except:
pass
redirect = input("Paste amazon.com url you got redirected to: ")
self.handle_redirect(redirect)
if gui:
weblogin.web_login(url, self.handle_redirect)
else:
if non_interactive:
data = {
'client_id': client_id,
'code_verifier': code_verifier.decode("utf-8"),
'serial': serial,
'url': url
}
print(json.dumps(data))
return

print("Login URL: ", url)
print(
"The login URL will be opened in your browser, after you login paste the amazon.com url you were redirected to here")
input("Press ENTER to proceed")
try:
webbrowser.open(url)
except:
pass
redirect = input("Paste amazon.com url you got redirected to: ")
self.handle_redirect(redirect)

def logout(self):
if not self.is_logged_in():
Expand Down
19 changes: 17 additions & 2 deletions nile/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def get_arguments():

auth_parser = sub_parsers.add_parser("auth", help="Authorization related things")
auth_parser.add_argument("--login", "-l", action="store_true", help="Login action")
auth_parser.add_argument("--status", "-s", action="store_true", help="Login action")
auth_parser.add_argument("--gui", "-g", action="store_true", help="Use GUI for login")
auth_parser.add_argument("--non-interactive", action="store_true", help="Display login data as JSON. Use `nile register` to finish login")
auth_parser.add_argument(
"--logout", action="store_true", help="Logout from the accout and deregister"
Expand All @@ -26,15 +28,21 @@ def get_arguments():
register_parser.add_argument("--serial", help="The device serial to register")

library_parser = sub_parsers.add_parser(
"library", help="Your games library is in this place"
"library", help="Your games library is in this place..."
)
library_parser.add_argument("sub_command", choices=["list", "sync"])
library_parser.add_argument(
"--json", "-j", action="store_true", help="Print info in JSON format"
)
library_parser.add_argument("--force", "-f", action="store_true", help="Force the action")
library_parser.add_argument(
"--installed", "-i", action="store_true", help="List only installed games"
"--installed", "-i", action="store_true", help="List only installed games... "

)

install_parser = sub_parsers.add_parser(
"install", aliases=["update", "verify"], help="Install a game"

)
install_parser.add_argument("id", help="Specify a ID of the game to be installed")
install_parser.add_argument("--max-workers", help="Specify max threads to be used")
Expand Down Expand Up @@ -67,6 +75,13 @@ def get_arguments():
"--wine-prefix", dest="wine_prefix", help="Specify wineprefix to be used"
)
launch_parser.add_argument("--wine", help="Specify wine binary")
launch_parser.add_argument(
"--json",
"-j",

action="store_true",
help="Output data in json format",
)
launch_parser.add_argument(
"--no-wine",
dest="dont_use_wine",
Expand Down
44 changes: 27 additions & 17 deletions nile/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def __migrate_old_ids(self):
def handle_auth(self):
if self.arguments.login:
if not self.auth_manager.is_logged_in():
self.auth_manager.login(self.arguments.non_interactive)
self.auth_manager.login(self.arguments.non_interactive, self.arguments.gui)
return True
else:
self.logger.error("You are already logged in")
Expand All @@ -66,6 +66,13 @@ def handle_auth(self):
self.auth_manager.refresh_token()
self.auth_manager.logout()
return False
elif self.arguments.status:
account = '<not logged in>'
if self.auth_manager.is_logged_in():
account = self.auth_manager.config.get("user").get("extensions").get("customer_info").get("name")
logged_in = account != '<not logged in>'
print(json.dumps({'Username': account, 'LoggedIn': logged_in}))
return False
self.logger.error("Specify auth action, use --help")

def handle_register(self):
Expand Down Expand Up @@ -114,22 +121,25 @@ def handle_library(self):
installed_dict[game["id"]] = game
games.sort(key=self.sort_by_title)
displayed_count = 0
for game in games:
if self.arguments.installed and not installed_dict.get(game["product"]["id"]):
continue
genres = (
(f'GENRES: {game["product"]["productDetail"]["details"]["genres"]}')
if game["product"]["productDetail"]["details"].get("genres")
else ""
)
if not constants.SUPPORTS_COLORS:
games_list += f'{"(INSTALLED) " if installed_dict.get(game["product"]["id"]) and not self.arguments.installed else ""}{game["product"].get("title")} ID: {game["product"]["id"]} {genres}\n'
else:
games_list += f'{constants.SHCOLORS["green"]}{"(INSTALLED) " if installed_dict.get(game["product"]["id"]) and not self.arguments.installed else ""}{constants.SHCOLORS["clear"]}{game["product"].get("title")} {constants.SHCOLORS["red"]}ID: {game["product"]["id"]}{constants.SHCOLORS["clear"]} {genres}\n'

displayed_count += 1
games_list += f"\n*** TOTAL {displayed_count} ***\n"
print(games_list)
if self.arguments.json:
print(json.dumps(games))
else:
for game in games:
if self.arguments.installed and not installed_dict.get(game["product"]["id"]):
continue
genres = (
(f'GENRES: {game["product"]["productDetail"]["details"]["genres"]}')
if game["product"]["productDetail"]["details"].get("genres")
else ""
)
if not constants.SUPPORTS_COLORS:
games_list += f'{"(INSTALLED) " if installed_dict.get(game["product"]["id"]) and not self.arguments.installed else ""}{game["product"].get("title")} ID: {game["product"]["id"]} {genres}\n'
else:
games_list += f'{constants.SHCOLORS["green"]}{"(INSTALLED) " if installed_dict.get(game["product"]["id"]) and not self.arguments.installed else ""}{constants.SHCOLORS["clear"]}{game["product"].get("title")} {constants.SHCOLORS["red"]}ID: {game["product"]["id"]}{constants.SHCOLORS["clear"]} {genres}\n'

displayed_count += 1
games_list += f"\n*** TOTAL {displayed_count} ***\n"
print(games_list)

elif cmd == "sync":
if not self.auth_manager.is_logged_in():
Expand Down
15 changes: 15 additions & 0 deletions nile/utils/launch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import sys
import os
import shutil
Expand All @@ -21,6 +22,7 @@ def __init__(self):
self.command = str()
self.arguments = list()
self.cwd = str()
self.dryrun = False

@classmethod
def parse(cls, game_path, path, unknown_arguments):
Expand All @@ -46,6 +48,7 @@ def __init__(self, config_manager, arguments, unknown_arguments, game):
self.game = game
self.bottle = arguments.bottle
self.wrapper = arguments.wrapper
self.dryrun = arguments.json
self.wine_prefix = arguments.wine_prefix
self.wine_bin = arguments.wine
if not self.wine_bin:
Expand Down Expand Up @@ -182,6 +185,18 @@ def start(self, game_path):
command.append(instruction.command)
command.extend(instruction.arguments)

if self.dryrun:
print(json.dumps({"command": {"instruction":instruction.command, "arguments": instruction.arguments},
"game_directory": game_path,
"env": {
'FUEL_DIR': fuel_dir,
'AMAZON_GAMES_SDK_PATH': amazon_sdk,
'AMAZON_GAMES_FUEL_ENTITLEMENT_ID': self.game['id'],
'AMAZON_GAMES_FUEL_PRODUCT_SKU': self.game['product']['sku'],
'AMAZON_GAMES_FUEL_DISPLAY_NAME': display_name
}}))
return

self.logger.info("Launching")

status = 0
Expand Down
23 changes: 23 additions & 0 deletions nile/utils/weblogin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import datetime
import json
import ssl
from urllib import error, request
from urllib.parse import urlparse, parse_qs

import webview
import os



def web_login(url, callback):
window = webview.create_window('Amazon Login', url)
def on_loaded():
url = window.get_current_url()
print(F"url: {window.get_current_url()}")
#print(window.)
print('Page is loaded')
if url.startswith("https://www.amazon.com/?openid.assoc_handle=amzn_sonic_games_launcher"):
callback(url)
window.destroy()
window.events.loaded += on_loaded
webview.start()