AV-98/src/av98/main.py
Solderpunk 0268cd426b Further splitting up and renaming of files.
Now that everything lives in src/av98/ as per the latest Python
fashion, it's a problem to have a file named av98.py.  So split
it out into main.py (which just implements the argument parsing)
and client.py.  The old clientcerts.py has become certmanager.py
so that tab completion for client.py is quick and easy.
2023-11-25 16:12:46 +01:00

131 lines
4.5 KiB
Python
Executable File

#!/usr/bin/env python3
# AV-98 Gemini client
# Dervied from VF-1 (https://github.com/solderpunk/VF-1),
# (C) 2019, 2020, 2023 Solderpunk <solderpunk@posteo.net>
# With contributions from:
# - danceka <hannu.hartikainen@gmail.com>
# - <jprjr@tilde.club>
# - <vee@vnsf.xyz>
# - Klaus Alexander Seistrup <klaus@seistrup.dk>
# - govynnus <govynnus@sdf.org>
# - Nik <nic@tilde.team>
# - <sario528@ctrl-c.club>
# - rmgr
# - Aleksey Ryndin
import argparse
import os.path
import shutil
import sys
from av98 import __version__
from av98.client import GeminiClient
def main():
# Parse args
parser = argparse.ArgumentParser(description='A command line gemini client.')
parser.add_argument('--bookmarks', action='store_true',
help='start with your list of bookmarks')
parser.add_argument('--dl', '--download', action='store_true',
help='download a single URL and quit')
parser.add_argument('-o', '--output', metavar='FILE',
help='filename to save --dl URL to')
parser.add_argument('--tls-cert', metavar='FILE', help='TLS client certificate file')
parser.add_argument('--tls-key', metavar='FILE', help='TLS client certificate private key file')
parser.add_argument('--restricted', action="store_true", help='Disallow shell, add, and save commands')
parser.add_argument('--version', action='store_true',
help='display version information and quit')
parser.add_argument('url', metavar='URL', nargs='*',
help='start with this URL')
args = parser.parse_args()
# Handle --version
if args.version:
print("AV-98 " + __version__)
sys.exit()
# Instantiate client
gc = GeminiClient(args.restricted)
# Activate client certs now in case they are needed for --download below
if args.tls_cert and args.tls_key:
gc.client_cert_manager._activate_client_cert(args.tls_cert, args.tls_key)
for url in args.url:
gi = GeminiItem(url)
gc.client_cert_manager.active_cert_domains.append(gi.host)
# Handle --download
if args.dl:
gc.onecmd("set debug True")
# Download
gi = GeminiItem(args.url[0])
gi, mime = gc._fetch_over_network(gi)
# Decide on a filename
if args.output:
filename = args.output
else:
if mime == "text/gemini":
# Parse gemtext in the hopes of getting a gi.name for the filename
gc.active_raw_file = gc.raw_file_buffer
gc._handle_gemtext(gi)
filename = gi.derive_filename(mime)
# Copy from temp file to pwd with a nice name
shutil.copyfile(gc.raw_file_buffer, filename)
size = os.path.getsize(filename)
# Notify user where the file ended up
print("Wrote %d byte %s response to %s." % (size, mime, filename))
gc.do_quit()
sys.exit()
# Process config file
rcfile = os.path.join(gc.config_dir, "av98rc")
if os.path.exists(rcfile):
print("Using config %s" % rcfile)
with open(rcfile, "r") as fp:
for line in fp:
line = line.strip()
if ((args.bookmarks or args.url) and
any((line.startswith(x) for x in ("go", "g", "tour", "t")))
):
if args.bookmarks:
print("Skipping rc command \"%s\" due to --bookmarks option." % line)
else:
print("Skipping rc command \"%s\" due to provided URLs." % line)
continue
gc.cmdqueue.append(line)
# Say hi
print("Welcome to AV-98!")
if args.restricted:
print("Restricted mode engaged!")
print("Enjoy your patrol through Geminispace...")
# Add commands to the queue based on command line arguments
if args.bookmarks:
gc.cmdqueue.append("bookmarks")
elif args.url:
if len(args.url) == 1:
gc.cmdqueue.append("go %s" % args.url[0])
else:
for url in args.url:
if not url.startswith("gemini://"):
url = "gemini://" + url
gc.cmdqueue.append("tour %s" % url)
gc.cmdqueue.append("tour")
# Endless interpret loop until user quits
while True:
try:
gc.cmdloop()
break
except KeyboardInterrupt:
print("")
# Say goodbye
print()
print("Thank you for patrolling with AV-98!")
sys.exit()
if __name__ == '__main__':
main()