Skip to content

Commit

Permalink
simple download game
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleGoogle committed Jul 18, 2019
1 parent ce39536 commit 65c9fa5
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 12 deletions.
32 changes: 32 additions & 0 deletions src/consts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import enum
import sys


class PlatformNotSupported(Exception):
pass


class HP(enum.Enum):
"""HumbleBundle platform code name shown in subproducts>download section"""
WINDOWS = 'windows'
MAC = 'mac'
LINUX = 'linux'
ANDROID = 'android'
AUDIO = 'audio'
EBOOK = 'ebook'

def __eq__(self, other):
if type(other) == str:
return self.value == other
return super().__eq__(other)


GAME_PLATFORMS = [HP.WINDOWS, HP.MAC, HP.LINUX]
DLC_PLATFORMS = [HP.AUDIO, HP.EBOOK] # TODO push those with base game

if sys.platform == 'win32':
CURRENT_SYSTEM = HP.WINDOWS
elif sys.platform == 'darwin':
CURRENT_SYSTEM = HP.MAC
else:
raise PlatformNotSupported('GOG Galaxy 2.0 supports only Windows and macos for now')
28 changes: 28 additions & 0 deletions src/humblegame.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from typing import Dict

from galaxy.api.types import Game, LicenseType, LicenseInfo

from consts import CURRENT_SYSTEM, PlatformNotSupported


class HumbleGame:
def __init__(self, data):
Expand All @@ -17,3 +21,27 @@ def __repr__(self):
def __str__(self):
return f"HumbleGame({self.human_name}, {self.downloads})"


class HumbleDownloader:
"""Prepares downloads for specific conditionals"""
def __init__(self, target_platrofm=CURRENT_SYSTEM, target_bitness=None, use_torrent=False):
self.platform = target_platrofm
self.bitness = target_bitness

def find_best_url(self, downloads: dict) -> Dict[str, str]:
system_downloads = list(filter(lambda x: x['platform'] == self.platform, downloads))

if len(system_downloads) == 1:
download_struct = system_downloads[0]['download_struct']
elif len(system_downloads) == 0:
platforms = [dw.platform for dw in downloads]
raise PlatformNotSupported(f'{self.human_name} has only downloads for {platforms}')
elif len(system_downloads) > 1:
raise NotImplementedError('More system level conditionals required')

download_items = list(filter(lambda x: x['name'] == 'Download', download_struct))

if len(download_items) == 1:
return download_items[0]['url']
else:
raise NotImplementedError(f'Found downloads: {len(download_items)}. All: {downloads}')
39 changes: 27 additions & 12 deletions src/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import logging
import re
import webbrowser

from galaxy.api.plugin import Plugin, create_and_run_plugin
from galaxy.api.consts import Platform
Expand All @@ -11,7 +12,8 @@

from version import __version__
from webservice import AuthorizedHumbleAPI
from humblegame import HumbleGame
from humblegame import HumbleGame, HumbleDownloader
from consts import PlatformNotSupported, GAME_PLATFORMS


AUTH_PARAMS = {
Expand All @@ -25,13 +27,12 @@


class HumbleBundlePlugin(Plugin):
GAME_PLATFORMS = ['windows', 'mac', 'linux'] # TODO think about 'android'
DLC_PLATFORMS = ['ebook', 'audio'] # TODO push those with base game

def __init__(self, reader, writer, token):
super().__init__(Platform.HumbleBundle, __version__, reader, writer, token)
self._api = AuthorizedHumbleAPI()
self._games = []
self._downloader = HumbleDownloader()

async def authenticate(self, stored_credentials=None):
if not stored_credentials:
Expand All @@ -49,23 +50,37 @@ async def pass_login_credentials(self, step, credentials, cookies):
user_id, user_name = await self._api.authenticate(auth_cookie)
return Authentication(user_id, user_name)

def _is_game(self, sub):
whitelist = self.GAME_PLATFORMS
default = False
return next(filter(lambda x: x['platform'] in whitelist, sub['downloads']), default)

async def get_owned_games(self):
games = []

def is_game(sub):
default = False
return next(filter(lambda x: x['platform'] in GAME_PLATFORMS, sub['downloads']), default)

games = {}
gamekeys = await self._api.get_gamekeys()
for gamekey in gamekeys:
details = await self._api.get_order_details(gamekey)
logging.info(f'Parsing details of order {gamekey}:\n{json.dumps(details, indent=4)}')
for sub in details['subproducts']:
if self._is_game(sub):
games.append(HumbleGame(sub))
if is_game(sub):
games[sub['machine_name']] = HumbleGame(sub)

self.games = games
return [g.in_galaxy_format() for g in games]
return [g.in_galaxy_format() for g in games.values()]

async def install_game(self, game_id):
game = self.games.get(game_id)
if game is None:
logging.error(f'Install game: game {game_id} not found')
return

try:
url = self._downloader.find_best_url(game.downloads)
except Exception as e:
logging.exception(e)
else:
webbrowser.open(url['web'])


def shutdown(self):
self._api._session.close()
Expand Down
9 changes: 9 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ async def run_server_connection(reader, writer):
# ret = await reader.readline()
# print("ret", ret)

print("install_game")
writer.write(b'{"jsonrpc": "2.0", "method": "install_game", "params":{"game_id": "samorost2"}}\n')

# print("launch_game")
# writer.write(b'{"jsonrpc": "2.0", "method": "launch_game", "params":{"game_id": "samorost2"}}\n')

# print("uninstall_game")
# writer.write(b'{"jsonrpc": "2.0", "method": "uninstall_game", "params":{"game_id": "samorost2"}}\n')

async def wakeup():
while True:
await asyncio.sleep(1)
Expand Down

0 comments on commit 65c9fa5

Please sign in to comment.