def login(req): if req.method == 'POST': if "username" not in req.form or "password" not in req.form: return status(req, 400) username = req.form["username"] password = req.form["password"] auth_result = auth_mgr.try_log_in(username, password) if auth_result == AuthManager.USER_NOT_FOUND: return HTMLResponse( render_path( "tmpl/login.htmo", { "base": MOUNT_POINT, "bad_username": True, "bad_password": False, }), status=403, # This one is iffy. ) elif auth_result == AuthManager.PW_WRONG: return HTMLResponse( render_path( "tmpl/login.htmo", { "base": MOUNT_POINT, "bad_username": False, "bad_password": True, }), status=403, # This one is iffy. ) else: id_, expiration = auth_result from_ = url_unquote(req.args.get("from", "")) resp = redirect(MOUNT_POINT + from_, code=303) resp.set_cookie(COOKIE_NAME, id_, expires=expiration, secure=True) return resp if auth_mgr.cookie_to_username(req.cookies.get(COOKIE_NAME)): # Already logged in. return redirect(MOUNT_POINT, code=303) else: resp = HTMLResponse( render_path( "tmpl/login.htmo", { "base": MOUNT_POINT, "bad_username": False, "bad_password": False, }), ) resp.delete_cookie(COOKIE_NAME) return resp
def page_list(req, username): ls = Popen(( 'git', '--git-dir=repo/.git/', '--work-tree=repo/', 'ls-files', '-z', ), stdin=DEVNULL, stdout=PIPE, universal_newlines=True) out = ls.stdout.read(500) ls.terminate() try: ls.wait(0.1) except Popen.TimeoutExpired: ls.kill() ls.wait(0.1) i = out.rfind('\0') if i == -1: # not found i = 0 out = out[:i] names = map( lambda name: {'name': escape(name)}, sorted(out.split('\0')), ) return HTMLResponse( render_path('tmpl/page_list.htmo', { 'base': MOUNT_POINT, 'names': names, }))
def hello(req): if req.method == 'POST': return status(req, 400) return HTMLResponse( render_path("tmpl/hello.htmo", { "base": MOUNT_POINT, "title": "hey", }))
def page(req, username, name): assert not (name.startswith("./") or name.startswith("../")) if name.startswith(".") or name.endswith("/"): return status(req, 400) if req.method == 'POST': if 'stamp' not in req.form or 'text' not in req.form: return status(req, 400) global prev_stamp try: prev_stamp = int(req.form['stamp']) except ValueError: return status(req, 400) filename = "repo/" + name makedirs(path.dirname(filename), exist_ok=True) with open(filename, "w") as f: f.write(req.form['text'].rstrip() + "\n") if not commit_file(name): return status(req, 500) return redirect(req.full_path, code=303) if 'edit' in req.args: filename = "repo/" + name try: with open(filename, "r") as f: content = f.read().rstrip() except (FileNotFoundError, NotADirectoryError, IsADirectoryError): return status(req, 404) global stamp resp = HTMLResponse( render_path( 'tmpl/page.htmo', { 'base': MOUNT_POINT, 'content': content, 'name': name, 'stamp': str(stamp), 'prevstamp': str(prev_stamp), 'title': "Edit \"{}\"".format(name), })) stamp = (stamp + 1) & stamp_mask return resp else: return redirect(req.path + '?edit')
def note(req, username): if not "day" in req.args: return redirect( (MOUNT_POINT + "note?day=" + datetime.datetime.now( datetime.timezone( datetime.timedelta(hours=-8))).date().isoformat()), code=307, # like 302 but with more explicit semantics ) day_str = req.args["day"] day_match = re.match("^([0-9]{4})-([0-9]{2})-([0-9]{2})$", day_str) if not day_match: raise status(req, 400) try: day = datetime.date(*map(int, day_match.groups())) except ValueError: raise status(req, 400) name = "notes/" + username + "/" + day_str one_day = datetime.timedelta(days=1) if req.method == 'POST': if not "content" in req.form: raise status(req, 400) with open(name, "w") as f: f.write(req.form["content"] + "\n") return redirect(req.full_path, code=303) try: with open(name, "r") as f: content = f.read() except FileNotFoundError: content = "" return HTMLResponse( render_path( "tmpl/note.htmo", { "base": MOUNT_POINT, "title": day_str, "day": day_str, "yesterday": (day - one_day).isoformat(), "tomorrow": (day + one_day).isoformat(), "content": html.escape(content)[:-1], }), )
def create(req, username): if req.method == 'POST': if 'name' not in req.form: return status(req, 400) name = path.relpath(req.form['name'].lstrip("/")) if name.startswith(".") or name.endswith("/"): return status(req, 400) filename = "repo/" + name makedirs(path.dirname(filename), exist_ok=True) try: with open(filename, "x") as f: pass if not commit_file(name): return status(req, 500) except FileExistsError: pass return redirect(MOUNT_POINT + "page/" + name + "?edit") return HTMLResponse( render_path("tmpl/create.htmo", { 'base': MOUNT_POINT, }))
def regen(tmpl_path): html_path = tmpl_path[:tmpl_path.rfind(".")] + ".html" print("Regenerating " + html_path) s = render_path(tmpl_path) with open(html_path, "w") as f: f.write(s)
def home(req, username): if req.method == 'POST': if "url" not in req.form: return status(req, 400) try: p = sub.run( ( "youtube-dl", "-x", "--audio-format", "mp3", "--get-filename", req.form["url"], ), universal_newlines=True, stdout=sub.PIPE, timeout=10, ) except sub.TimeoutExpired: return HTMLResponse( render_path( "tmpl/error.htmo", { "base": MOUNT_POINT, "text": escape("Getting name took too long"), })) if p.returncode != 0: return HTMLResponse( render_path( "tmpl/error.htmo", { "base": MOUNT_POINT, "text": escape("Can't get name (site might not be supported)"), })) vid_name = p.stdout.strip() sub.run(("rm", "-rf", "dl/")) os.mkdir("dl") try: p = sub.run( ( "youtube-dl", "-x", "--audio-format", "mp3", "-o", "dl/" + vid_name, req.form["url"], ), stdout=sub.DEVNULL, timeout=60, ) except sub.TimeoutExpired: return HTMLResponse( render_path( "tmpl/error.htmo", { "base": MOUNT_POINT, "text": escape("Downloading took too long"), })) if p.returncode != 0: return HTMLResponse( render_path( "tmpl/error.htmo", { "base": MOUNT_POINT, "text": escape("Can't download (don't know why)"), })) mp3_name = vid_name[:vid_name.rfind('.')] + '.mp3' with open("dl/" + mp3_name, "rb") as f: return Response( f.read(), # TODO headers=[('Content-Disposition', 'attachment; filename="{}"'.format(escape(mp3_name))) ], content_type="audio/mpeg", ) return HTMLResponse( render_path("tmpl/home.htmo", { "base": MOUNT_POINT, "title": "Audio downloader", }))
def inner(req, username): return HTMLResponse(render_path(name, { "base": MOUNT_POINT, }))