annotate laterlinks3/laterlinks_flask_app.py @ 117:476cb019ad9f

add laterlinks3
author paulo
date Tue, 08 Sep 2020 23:52:57 -0700
parents
children 65db090a697e
rev   line source
paulo@117 1 import csv
paulo@117 2 import datetime
paulo@117 3 import os
paulo@117 4
paulo@117 5 import flask
paulo@117 6
paulo@117 7 from html3.html3 import HTML
paulo@117 8
paulo@117 9 app = flask.Flask(__name__)
paulo@117 10
paulo@117 11 PIN = os.environ.get('LLPIN')
paulo@117 12 STRTIME_FMT = "%Y-%m-%d %H:%M:%S"
paulo@117 13
paulo@117 14
paulo@117 15 class LLDialect(csv.Dialect):
paulo@117 16 delimiter = '\t'
paulo@117 17 quoting = csv.QUOTE_NONE
paulo@117 18 lineterminator = '\n'
paulo@117 19
paulo@117 20
paulo@117 21 LLDIALECT = LLDialect()
paulo@117 22 LLDB_FN = "lldb.tsv"
paulo@117 23 LLDB_UNREAD_FN = "lldb_unread.tsv"
paulo@117 24
paulo@117 25
paulo@117 26 class LLError(Exception):
paulo@117 27 pass
paulo@117 28
paulo@117 29 class PinFailError(LLError):
paulo@117 30 def __str__(self):
paulo@117 31 return "PIN FAIL!"
paulo@117 32
paulo@117 33 class PinSetupError(LLError):
paulo@117 34 def __str__(self):
paulo@117 35 return "PIN SETUP ERROR!"
paulo@117 36
paulo@117 37 class MissingFieldsError(LLError):
paulo@117 38 def __str__(self):
paulo@117 39 return "MISSING FIELD(s)!"
paulo@117 40
paulo@117 41
paulo@117 42 def lldb_unread_load():
paulo@117 43 return csv.reader(open(LLDB_UNREAD_FN), LLDIALECT)
paulo@117 44
paulo@117 45
paulo@117 46 def lldb_add(inp):
paulo@117 47 title = inp.get("title")
paulo@117 48 url = inp.get("url")
paulo@117 49 if not (title and url):
paulo@117 50 raise MissingFieldsError()
paulo@117 51
paulo@117 52 dt_str = datetime.datetime.now().strftime(STRTIME_FMT)
paulo@117 53 with open(LLDB_FN, 'a') as lldb_f:
paulo@117 54 csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str])
paulo@117 55 with open(LLDB_UNREAD_FN, 'a') as lldb_f:
paulo@117 56 csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str])
paulo@117 57
paulo@117 58
paulo@117 59 def lldb_unread_delete(inp):
paulo@117 60 delete = inp.getlist("delete")
paulo@117 61 if not delete:
paulo@117 62 raise MissingFieldsError()
paulo@117 63
paulo@117 64 lldb_unread = [i for i in lldb_unread_load()]
paulo@117 65 lldb_unread_f = open(LLDB_UNREAD_FN, 'w')
paulo@117 66
paulo@117 67 try:
paulo@117 68 for i in delete:
paulo@117 69 for j in lldb_unread:
paulo@117 70 dt_str = j[2]
paulo@117 71 if i == dt_str:
paulo@117 72 lldb_unread.remove(j)
paulo@117 73 finally:
paulo@117 74 csv.writer(lldb_unread_f, LLDIALECT).writerows(lldb_unread)
paulo@117 75 lldb_unread_f.close()
paulo@117 76
paulo@117 77
paulo@117 78
paulo@117 79 @app.route("/", methods=["GET", "POST"])
paulo@117 80 def index():
paulo@117 81 is_post = (flask.request.method == "POST")
paulo@117 82 inp = flask.request.form
paulo@117 83 cookies = flask.request.cookies
paulo@117 84
paulo@117 85 if is_post:
paulo@117 86 if not PIN:
paulo@117 87 raise PinSetupError
paulo@117 88 elif cookies.get("llpin") != PIN:
paulo@117 89 raise PinFailError
paulo@117 90
paulo@117 91 if inp["submit"] == "Add":
paulo@117 92 lldb_add(inp)
paulo@117 93 elif inp["submit"] == "Delete":
paulo@117 94 lldb_unread_delete(inp)
paulo@117 95
paulo@117 96 title = "later links..."
paulo@117 97 root = HTML("html")
paulo@117 98
paulo@117 99 header = root.head
paulo@117 100 header.link(rel="stylesheet", type="text/css", href=flask.url_for("static", filename="index.css"))
paulo@117 101 header.title(title)
paulo@117 102
paulo@117 103 body = root.body
paulo@117 104 body.h1(title)
paulo@117 105
paulo@117 106 form = body.form(action="/", method="post")
paulo@117 107
paulo@117 108 table = form.table
paulo@117 109 hrow = table.tr
paulo@117 110 hrow.th("Link")
paulo@117 111 hrow.th("Created")
paulo@117 112 hrow.th.input(type="submit", name="submit", value="Delete")
paulo@117 113
paulo@117 114 for (title, url, dt_str) in lldb_unread_load():
paulo@117 115 row = table.tr
paulo@117 116 row.td.a(title, href=url)
paulo@117 117 row.td(dt_str)
paulo@117 118 row.td.input(type="checkbox", name="delete", value=dt_str)
paulo@117 119
paulo@117 120 p1 = form.p
paulo@117 121 p1.label("Title").input(type="text", name="title", size="64")
paulo@117 122 p1.br
paulo@117 123 p1.label("URL").input(type="text", name="url", size="64")
paulo@117 124 p1.br
paulo@117 125 p1.input(type="submit", name="submit", value="Add")
paulo@117 126
paulo@117 127 return str(root).encode("utf-8")