paulo@117: import csv paulo@117: import datetime paulo@117: import os paulo@117: paulo@117: import flask paulo@117: paulo@117: from html3.html3 import HTML paulo@117: paulo@117: app = flask.Flask(__name__) paulo@117: paulo@117: PIN = os.environ.get('LLPIN') paulo@117: STRTIME_FMT = "%Y-%m-%d %H:%M:%S" paulo@117: paulo@117: paulo@117: class LLDialect(csv.Dialect): paulo@117: delimiter = '\t' paulo@117: quoting = csv.QUOTE_NONE paulo@117: lineterminator = '\n' paulo@117: paulo@117: paulo@117: LLDIALECT = LLDialect() paulo@117: LLDB_FN = "lldb.tsv" paulo@117: LLDB_UNREAD_FN = "lldb_unread.tsv" paulo@117: paulo@117: paulo@117: class LLError(Exception): paulo@117: pass paulo@117: paulo@117: class PinFailError(LLError): paulo@117: def __str__(self): paulo@117: return "PIN FAIL!" paulo@117: paulo@117: class PinSetupError(LLError): paulo@117: def __str__(self): paulo@117: return "PIN SETUP ERROR!" paulo@117: paulo@117: class MissingFieldsError(LLError): paulo@117: def __str__(self): paulo@117: return "MISSING FIELD(s)!" paulo@117: paulo@117: paulo@117: def lldb_unread_load(): paulo@117: return csv.reader(open(LLDB_UNREAD_FN), LLDIALECT) paulo@117: paulo@117: paulo@117: def lldb_add(inp): paulo@117: title = inp.get("title") paulo@117: url = inp.get("url") paulo@117: if not (title and url): paulo@117: raise MissingFieldsError() paulo@117: paulo@117: dt_str = datetime.datetime.now().strftime(STRTIME_FMT) paulo@117: with open(LLDB_FN, 'a') as lldb_f: paulo@117: csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) paulo@117: with open(LLDB_UNREAD_FN, 'a') as lldb_f: paulo@117: csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) paulo@117: paulo@117: paulo@117: def lldb_unread_delete(inp): paulo@117: delete = inp.getlist("delete") paulo@117: if not delete: paulo@117: raise MissingFieldsError() paulo@117: paulo@117: lldb_unread = [i for i in lldb_unread_load()] paulo@117: lldb_unread_f = open(LLDB_UNREAD_FN, 'w') paulo@117: paulo@117: try: paulo@117: for i in delete: paulo@117: for j in lldb_unread: paulo@117: dt_str = j[2] paulo@117: if i == dt_str: paulo@117: lldb_unread.remove(j) paulo@117: finally: paulo@117: csv.writer(lldb_unread_f, LLDIALECT).writerows(lldb_unread) paulo@117: lldb_unread_f.close() paulo@117: paulo@117: paulo@117: paulo@117: @app.route("/", methods=["GET", "POST"]) paulo@117: def index(): paulo@117: is_post = (flask.request.method == "POST") paulo@117: inp = flask.request.form paulo@117: cookies = flask.request.cookies paulo@117: paulo@117: if is_post: paulo@117: if not PIN: paulo@117: raise PinSetupError paulo@117: elif cookies.get("llpin") != PIN: paulo@117: raise PinFailError paulo@117: paulo@117: if inp["submit"] == "Add": paulo@117: lldb_add(inp) paulo@117: elif inp["submit"] == "Delete": paulo@117: lldb_unread_delete(inp) paulo@117: paulo@117: title = "later links..." paulo@117: root = HTML("html") paulo@117: paulo@117: header = root.head paulo@117: header.link(rel="stylesheet", type="text/css", href=flask.url_for("static", filename="index.css")) paulo@117: header.title(title) paulo@117: paulo@117: body = root.body paulo@117: body.h1(title) paulo@117: paulo@117: form = body.form(action="/", method="post") paulo@117: paulo@117: table = form.table paulo@117: hrow = table.tr paulo@117: hrow.th("Link") paulo@117: hrow.th("Created") paulo@117: hrow.th.input(type="submit", name="submit", value="Delete") paulo@117: paulo@117: for (title, url, dt_str) in lldb_unread_load(): paulo@117: row = table.tr paulo@117: row.td.a(title, href=url) paulo@117: row.td(dt_str) paulo@117: row.td.input(type="checkbox", name="delete", value=dt_str) paulo@117: paulo@117: p1 = form.p paulo@117: p1.label("Title").input(type="text", name="title", size="64") paulo@117: p1.br paulo@117: p1.label("URL").input(type="text", name="url", size="64") paulo@117: p1.br paulo@117: p1.input(type="submit", name="submit", value="Add") paulo@117: paulo@117: return str(root).encode("utf-8")