diff --git a/pyweek.py b/pyweek.py index 1f1b8a2..ef57af1 100644 --- a/pyweek.py +++ b/pyweek.py @@ -2,6 +2,7 @@ Download and verify entries for a given challenge: """ +import subprocess import sys import os import re @@ -9,10 +10,13 @@ import time from packaging import version import zipfile +import tempfile import requests import click import progressbar +from rich.console import Console +from rich.markdown import Markdown __version__ = '0.5.3' PYWEEK_URL = 'https://pyweek.org' @@ -135,6 +139,9 @@ def download(challenge, directory): def verify(file: Path): """Determines if a given zip file is in the proper format.""" + in_correct_format(file) + +def in_correct_format(file: Path): errors = 0 def error(msg, critical=False): @@ -207,8 +214,64 @@ def error(msg, critical=False): if errors: error(f"{errors} error{"s" if errors > 1 else ""} occurred while verifying file {file}.") + return False + else: + click.echo(click.style(f"File {file} is in a valid format.", fg='green')) + return True + +@cli.command() +@click.argument( + 'file', + type=Path, +) +def run(file: Path): + """Extract and run the specified game from the zip file.""" + + if not in_correct_format(file): + click.echo("\nImproperly formatted file. Attempting to run anyway...\n") + else: + click.echo("\nSetting up venv...\n") + + # Extract the zip file to a temporary directory + temp_dir = Path(tempfile.mkdtemp()) + with zipfile.ZipFile(file, 'r') as zipped_file: + zipped_file.extractall(temp_dir) + top_level_dir = next(temp_dir.iterdir()) + + # No pint in trying if there is no run_game.py + run_game = temp_dir / top_level_dir / 'run_game.py' + if not run_game.exists(): + click.echo("No run_game.py file found. Exiting...") + sys.exit(1) + + # Set up the venv + venv_dir = temp_dir / 'venv' + subprocess.run([sys.executable, '-m', 'venv', venv_dir]) + python = venv_dir / 'bin' / 'python' + pip = venv_dir / 'bin' / 'pip' + + # Check if the requirements.txt file exists + requirements = temp_dir / top_level_dir / 'requirements.txt' + if not requirements.exists(): + click.echo("No requirements.txt file found. Attempting to run anyway...\n") + else: + click.echo("Installing requirements...\n") + subprocess.run([pip, 'install', '-r', requirements]) + + # Show the README rendered in the terminal + readme = temp_dir / top_level_dir / 'README.md' + if not readme.exists(): + click.echo("No README.md file found. Attempting to run anyway...\n") + input("\nPress Enter to play...") else: - click.echo(click.style(f"File {file} is valid.", fg='green')) + contents = readme.read_text() + console = Console() + click.echo("\nREADME.md") + console.print(Markdown(contents)) + input("\nPress Enter after reading to play...") + + # Run the game + subprocess.run([python, run_game]) CHUNK_SIZE = 10240 diff --git a/requirements.txt b/requirements.txt index 7204e2b..c324193 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ requests progressbar2 packaging colorama +rich