You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
2.7 KiB
105 lines
2.7 KiB
#!/usr/bin/env python3 |
|
import requests |
|
import subprocess |
|
import sys |
|
import os |
|
import argparse |
|
import shlex |
|
|
|
|
|
def launch(command, data): |
|
if isinstance(command, str): |
|
command = [command] |
|
elif isinstance(command, tuple): |
|
command = list(command) |
|
elif not isinstance(command, list): |
|
raise ValueError("`command` must be `list`, `tuple`, or `str`") |
|
|
|
return subprocess.run(command, input=data) |
|
|
|
|
|
def yn(question, options="yn"): |
|
options = options.lower() |
|
|
|
options_display = f"[{'/'.join(options)}]" |
|
full_question = f"{question} {options_display} " |
|
|
|
response = "WILL NEVER OCCUR IN OPTIONS" |
|
while not response in options: |
|
response = input(full_question).lower().strip()[0] |
|
|
|
return response |
|
|
|
|
|
parser = argparse.ArgumentParser( |
|
description="Securely run a script from the Internet" |
|
) |
|
parser.add_argument("url", help="URL of the script") |
|
parser.add_argument( |
|
"-i", |
|
"--interpreter", |
|
help="Choose interpreter to use (default: `bash`)", |
|
default="bash", |
|
) |
|
group = parser.add_mutually_exclusive_group() |
|
group.add_argument( |
|
"-p", |
|
"--pager", |
|
help="Choose pager to use (default: `less`)", |
|
default="less", |
|
) |
|
group.add_argument( |
|
"-s", |
|
"--skip-pager", |
|
action="store_true", |
|
help="Skip pager and confirmation; run script immediately", |
|
) |
|
group.add_argument( |
|
"-q", |
|
"--quiet", |
|
action="store_true", |
|
help="Skip pager and confirmation; run script immediately; do not print anything", |
|
) |
|
args = parser.parse_args() |
|
url = args.url |
|
pager = shlex.split(args.pager) |
|
interpreter = shlex.split(args.interpreter) |
|
|
|
while True: |
|
if not args.quiet: |
|
print(f"Downloading `{url}`...") |
|
|
|
response = requests.get(url, allow_redirects=False) |
|
|
|
if response.status_code == 200: |
|
content = response.content |
|
break |
|
|
|
else: |
|
try: |
|
print(f"{response.status_code} {response.reason} (redirect to `{response.headers['location']}`)") |
|
if yn("Do you want to follow this redirect?") == 'y': |
|
url = response.headers['location'] |
|
else: |
|
print("Not redirecting.") |
|
sys.exit(0) |
|
except KeyError: |
|
print(f"Download failed: {response.status_code} {response.reason}") |
|
sys.exit(0) |
|
|
|
if not args.quiet: |
|
print("Download successful.") |
|
print("=" * os.get_terminal_size().columns) |
|
|
|
if args.skip_pager or args.quiet: |
|
launch(interpreter, content) |
|
else: |
|
launch(pager, content) |
|
|
|
response = yn("Do you want to run this script?") |
|
if response == "y": |
|
print("=" * os.get_terminal_size().columns) |
|
launch(interpreter, content) |
|
else: |
|
print("=" * os.get_terminal_size().columns) |
|
print("Script not run.")
|
|
|