lists: basic working app
This commit is contained in:
parent
3096c1435a
commit
f7e82f2b41
103
lists
Executable file
103
lists
Executable file
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Smol listing manager."""
|
||||
|
||||
import smolcgi as scgi
|
||||
|
||||
if not (user_hash := scgi.cert_hash):
|
||||
scgi.exit_with_header(60, "You need a certificate to use this app")
|
||||
|
||||
import string
|
||||
import subprocess
|
||||
from os import getenv
|
||||
from pathlib import Path
|
||||
|
||||
STORAGE_PATH = Path(getenv("GEMINI_LISTS_PATH", "/var/gemini/lists"))
|
||||
if not STORAGE_PATH.exists():
|
||||
STORAGE_PATH.mkdir(parents=True)
|
||||
|
||||
ALLOWED_LIST_NAME_CHARS = string.ascii_lowercase + string.digits + "_"
|
||||
|
||||
def get_user_dir():
|
||||
user_dir = STORAGE_PATH / user_hash[7:]
|
||||
if not user_dir.is_dir():
|
||||
user_dir.mkdir()
|
||||
return user_dir
|
||||
|
||||
def show_lists():
|
||||
user_dir = get_user_dir()
|
||||
scgi.header(20, "text/gemini")
|
||||
print("# Lists")
|
||||
for child in user_dir.iterdir():
|
||||
if child.is_file():
|
||||
print(f"=> ./{child.name} 📄 {child.name}")
|
||||
print("=> ./_/create ✨ Create a new list")
|
||||
|
||||
def show_list(list_name):
|
||||
list_file = get_user_dir() / list_name
|
||||
try:
|
||||
with open(list_file, "rt") as f:
|
||||
content = f.read()
|
||||
except FileNotFoundError:
|
||||
scgi.not_found()
|
||||
else:
|
||||
scgi.header(20, "text/gemini")
|
||||
print("# " + list_name)
|
||||
print(content)
|
||||
print(f"=> ./{list_name}/add Append item")
|
||||
print(f"=> ./{list_name}/pop Pop first item")
|
||||
|
||||
def process_action(list_name, action):
|
||||
if list_name == "_" and action == "create":
|
||||
process_creation()
|
||||
elif action == "add":
|
||||
process_add(list_name)
|
||||
elif action == "pop":
|
||||
process_pop(list_name)
|
||||
else:
|
||||
scgi.not_found()
|
||||
|
||||
def process_creation():
|
||||
if not (new_list_name := scgi.query):
|
||||
meta = "List name (allowed chars: lowercase, digits, underscore)"
|
||||
scgi.require_input(meta)
|
||||
else:
|
||||
for char in new_list_name:
|
||||
if char not in ALLOWED_LIST_NAME_CHARS:
|
||||
scgi.temp_error(f"Illegal character in list name: {char}")
|
||||
list_file = get_user_dir() / new_list_name
|
||||
list_file.touch(mode=0o660)
|
||||
redirect_to_list(new_list_name)
|
||||
|
||||
def process_add(list_name):
|
||||
if not (item := scgi.query):
|
||||
scgi.require_input("Enter your item")
|
||||
else:
|
||||
if "\n" in item:
|
||||
scgi.temp_error("No new line allowed in item.")
|
||||
line = f"* {item}\n"
|
||||
list_file = get_user_dir() / list_name
|
||||
try:
|
||||
with open(list_file, "at") as f:
|
||||
f.write(line)
|
||||
except FileNotFoundError:
|
||||
scgi.not_found()
|
||||
else:
|
||||
redirect_to_list(list_name)
|
||||
|
||||
def process_pop(list_name):
|
||||
list_file = get_user_dir() / list_name
|
||||
subprocess.run(["sed", "-i", "1d", str(list_file)])
|
||||
redirect_to_list(list_name)
|
||||
|
||||
def redirect_to_list(list_name):
|
||||
scgi.redirect_temp(scgi.script + "/" + list_name)
|
||||
|
||||
path_components = scgi.path.lstrip("/").split("/", maxsplit=1)
|
||||
list_name = path_components[0]
|
||||
action = path_components[1] if len(path_components) > 1 else ''
|
||||
if not list_name:
|
||||
show_lists()
|
||||
elif not action and list_name != "_":
|
||||
show_list(list_name)
|
||||
else:
|
||||
process_action(list_name, action)
|
Reference in a new issue