예제 #1
0
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
예제 #2
0
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,
        }))
예제 #3
0
def hello(req):
    if req.method == 'POST':
        return status(req, 400)
    return HTMLResponse(
        render_path("tmpl/hello.htmo", {
            "base": MOUNT_POINT,
            "title": "hey",
        }))
예제 #4
0
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')
예제 #5
0
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],
            }), )
예제 #6
0
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,
        }))
예제 #7
0
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)
예제 #8
0
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",
        }))
예제 #9
0
 def inner(req, username):
     return HTMLResponse(render_path(name, {
         "base": MOUNT_POINT,
     }))