169 lines
No EOL
6.2 KiB
Python
Executable file
169 lines
No EOL
6.2 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
import os
|
|
import subprocess
|
|
import argparse
|
|
from shutil import unpack_archive
|
|
import yaml
|
|
import mergedeep
|
|
from lib import handlers
|
|
from appdirs import user_data_dir, user_config_dir
|
|
|
|
config = {
|
|
'global': {
|
|
'game_dir': os.path.join(user_data_dir(), 'minitch'),
|
|
'os': 'linux'
|
|
},
|
|
'games': {}
|
|
}
|
|
|
|
def read_config():
|
|
global config
|
|
path = os.path.join(user_config_dir(), 'minitchrc')
|
|
try:
|
|
with open(path, 'r') as f:
|
|
c = {**config, **yaml.safe_load(f)}
|
|
mergedeep.merge(config, c)
|
|
|
|
except FileNotFoundError:
|
|
pass
|
|
except yaml.YAMLError:
|
|
raise SystemExit('Invalid config')
|
|
|
|
def write_config():
|
|
global config
|
|
path = os.path.join(user_config_dir(), 'minitchrc')
|
|
with open(path, 'w') as f:
|
|
yaml.dump(config, f, default_flow_style=False)
|
|
|
|
def parse_config(args):
|
|
if args.api_key:
|
|
config['global']['api_key'] = args.api_key
|
|
|
|
def parse_search(args):
|
|
global config
|
|
if not 'api_key' in config['global']:
|
|
raise SystemExit('You have to set your api key first.')
|
|
game_handler = handlers.GameHandler(config['global']['api_key'], output_format=args.output)
|
|
game_handler.find(args.query)
|
|
|
|
def parse_uploads(args):
|
|
global config
|
|
if not 'api_key' in config['global']:
|
|
raise SystemExit('You have to set your api key first.')
|
|
game_handler = handlers.GameHandler(config['global']['api_key'], output_format=args.output)
|
|
game_handler.uploads(args.game_id)
|
|
|
|
def install_game(game_id, dst_path, output_format):
|
|
global config
|
|
|
|
# Download game
|
|
game_handler = handlers.GameHandler(config['global']['api_key'], output_format=output_format)
|
|
dst, upload, meta = game_handler.download(game_id, dst_path, os_type=config['global']['os'])
|
|
|
|
# Unpack game
|
|
print('Extracting...')
|
|
unpack_archive(dst, dst_path)
|
|
|
|
return dst, upload, meta
|
|
|
|
def parse_install(args):
|
|
global config
|
|
|
|
# Create target directory
|
|
game_path = os.path.join(config['global']['game_dir'], args.game_id)
|
|
os.makedirs(game_path, exist_ok=True)
|
|
|
|
try:
|
|
dst, upload, meta = install_game(args.game_id, game_path, args.output)
|
|
|
|
# Write game to config
|
|
config['games'][args.game_id] = {
|
|
'path': game_path,
|
|
'last_update': upload['updated_at'],
|
|
'url': meta['url'],
|
|
'title': meta['title'],
|
|
'description': meta['short_text']
|
|
}
|
|
|
|
print('FYI: As itch.io does not have any information on how to execute the game, you have to set the executable manually on first run with the --executable option')
|
|
except handlers.HandlerException as err:
|
|
raise SystemExit(str(err))
|
|
|
|
def parser_run(args):
|
|
global config
|
|
if not args.game_id in config['games']:
|
|
raise SystemExit('Game is not installed.')
|
|
if args.executable:
|
|
config['games'][args.game_id]['executable'] = args.executable
|
|
if not 'executable' in config['games'][args.game_id]:
|
|
raise SystemExit('You have to define the executable before you can run the game.')
|
|
|
|
if args.update:
|
|
game_handler = handlers.GameHandler(config['global']['api_key'], output_format=args.output)
|
|
print('Checking for updates...')
|
|
if game_handler.check_update(args.game_id, config['games'][args.game_id]['last_update'], config['global']['os']):
|
|
dst, upload, meta = install_game(args.game_id, config['games'][args.game_id]['path'], args.output)
|
|
config['games'][args.game_id]['last_update'] = upload['updated_at']
|
|
|
|
|
|
# Run executable
|
|
os.chdir(config['games'][args.game_id]['path'])
|
|
os.chmod(config['games'][args.game_id]['executable'], 755)
|
|
game_args = config['games'][args.game_id]['args'] if 'args' in config['games'][args.game_id] else []
|
|
subprocess.run([config['games'][args.game_id]['executable'], *game_args])
|
|
|
|
def parser_list(args):
|
|
global config
|
|
game_handler = handlers.GameHandler(config['global']['api_key'], output_format=args.output)
|
|
game_handler.list_local(config['games'])
|
|
|
|
def main():
|
|
read_config()
|
|
|
|
parser = argparse.ArgumentParser(description='Tiny little itch.io client')
|
|
subparsers = parser.add_subparsers(title='subcommands', description='valid subcommands', help='additional help')
|
|
|
|
# Global arguments
|
|
parser.add_argument('--output', '-o', choices=('table', 'json'), default='table', help='set the output format')
|
|
|
|
# Parser for "config" command
|
|
parser_config = subparsers.add_parser('config', aliases=['c'], help='config help')
|
|
parser_config.add_argument('--api_key', type=str, help='set api key')
|
|
parser_config.set_defaults(func=parse_config)
|
|
|
|
# Parser for "search" command
|
|
parser_search = subparsers.add_parser('search', aliases=['s'], help='search help')
|
|
parser_search.add_argument('query', type=str, help='the search query')
|
|
parser_search.set_defaults(func=parse_search)
|
|
|
|
# Parser for "uploads" command
|
|
parser_search = subparsers.add_parser('uploads', help='uploads help')
|
|
parser_search.add_argument('game_id', type=str, help='game_id to query')
|
|
parser_search.set_defaults(func=parse_uploads)
|
|
|
|
# Parser for "install" command
|
|
parser_search = subparsers.add_parser('install', aliases=['i'], help='install help')
|
|
parser_search.add_argument('game_id', type=str, help='game_id to query')
|
|
parser_search.set_defaults(func=parse_install)
|
|
|
|
# Parser for "run" command
|
|
parser_search = subparsers.add_parser('run', aliases=['r'], help='run help')
|
|
parser_search.add_argument('game_id', type=str, help='game_id to run')
|
|
parser_search.add_argument('--executable', '-e', type=str, help='set executable relative to game path (e.g. -e "chess_2_linux_v2/chess 2.x86_64")')
|
|
parser_search.add_argument('--update', '-u', help='check for update before running', action='store_true')
|
|
parser_search.set_defaults(func=parser_run)
|
|
|
|
# Parser for "list" command
|
|
parser_search = subparsers.add_parser('list', aliases=['l'], help='list help')
|
|
parser_search.set_defaults(func=parser_list)
|
|
|
|
args = parser.parse_args()
|
|
try:
|
|
args.func(args)
|
|
except AttributeError:
|
|
parser.error('too few arguments')
|
|
|
|
write_config()
|
|
|
|
if __name__ == "__main__":
|
|
main() |