view laterlinks2/laterlinks_app.py @ 78:f833a888c548

add cookie-based PIN system, and update laterlinks to use it
author paulo
date Thu, 02 Jun 2016 00:27:50 -0700
parents 49ca145627cb
children d7d67887102f
line source
1 import datetime
2 import cgi
3 import urlparse
4 import csv
5 import traceback
7 import html
9 import pinlib
12 DEBUG = True
13 STRTIME_FMT = "%Y-%m-%d %H:%M:%S"
16 class LLDialect(csv.Dialect):
17 delimiter = '\t'
18 quoting = csv.QUOTE_NONE
19 lineterminator = '\n'
22 LLDIALECT = LLDialect()
23 LLDB_FN = "lldb.tsv"
24 LLDB_UNREAD_FN = "lldb_unread.tsv"
27 class LLError(Exception):
28 pass
30 class PinFailError(LLError):
31 def __str__(self):
32 return "PIN FAIL!"
34 class MissingFieldsError(LLError):
35 def __str__(self):
36 return "MISSING FIELD(s)!"
39 def lldb_unread_load():
40 return csv.reader(open(LLDB_UNREAD_FN), LLDIALECT)
43 def lldb_add(inp):
44 try:
45 title = inp["title"][0]
46 url = inp["url"][0]
47 except (KeyError, IndexError):
48 raise MissingFieldsError()
50 dt_str = datetime.datetime.now().strftime(STRTIME_FMT)
51 with open(LLDB_FN, 'a') as lldb_f:
52 csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str])
53 with open(LLDB_UNREAD_FN, 'a') as lldb_f:
54 csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str])
57 def lldb_unread_delete(inp):
58 try:
59 delete = inp["delete"]
60 except KeyError:
61 raise MissingFieldsError()
63 lldb_unread = [i for i in lldb_unread_load()]
64 lldb_unread_f = open(LLDB_UNREAD_FN, 'w')
67 try:
68 for i in delete:
69 for j in lldb_unread:
70 dt_str = j[2]
71 if i == dt_str:
72 lldb_unread.remove(j)
73 finally:
74 csv.writer(lldb_unread_f, LLDIALECT).writerows(lldb_unread)
75 lldb_unread_f.close()
79 def parse_wsgi_input(environ):
80 return urlparse.parse_qs(environ["wsgi.input"].read())
84 def main(environ):
85 is_post = (environ["REQUEST_METHOD"] == "POST")
86 cookies = pinlib.parse_cookies(environ)
87 inp = parse_wsgi_input(environ)
89 if is_post:
90 try:
91 pinlib.check(cookies)
92 except pinlib.PinFailError:
93 raise PinFailError
94 if inp["submit"][0] == "Add":
95 lldb_add(inp)
96 elif inp["submit"][0] == "Delete":
97 lldb_unread_delete(inp)
99 title = "later links..."
100 root = html.HTML("html")
102 header = root.header
103 header.link(rel="stylesheet", type="text/css", href="index.css")
104 header.title(title)
106 body = root.body
107 body.h1(title)
110 if (DEBUG):
111 debug = body.pre
112 for i in environ.items():
113 debug += cgi.escape("%s = %s \n" % i)
115 debug += cgi.escape("wsgi.input.read = %s \n" % inp)
116 debug += cgi.escape("cookies = %s \n" % cookies)
118 form = body.form(action="index.fcgi", method="post")
120 table = form.table
121 hrow = table.tr
122 hrow.th("Link")
123 hrow.th("Created")
124 hrow.th.input(type="submit", name="submit", value="Delete")
126 for i in lldb_unread_load():
127 (title, url, dt_str) = (j.decode("utf-8") for j in i)
128 row = table.tr
129 row.td.a(title, href=url)
130 row.td(dt_str)
131 row.td.input(type="checkbox", name="delete", value=dt_str)
133 p1 = form.p
134 p1.label("Title").input(type="text", name="title", size="64")
135 p1.br
136 p1.label("URL").input(type="text", name="url", size="64")
137 p1.br
138 p1.input(type="submit", name="submit", value="Add")
140 return unicode(root).encode("utf-8")
143 def app(environ, start_response):
144 response_code = "500 Internal Server Error"
145 response_type = "text/plain; charset=UTF-8"
147 try:
148 response_body = main(environ)
149 response_code = "200 OK"
150 response_type = "text/html; charset=UTF-8"
151 except LLError as e:
152 response_body = str(e)
153 except:
154 response_body = traceback.format_exc()
156 response_headers = [
157 ("Content-Type", response_type),
158 ("Content-Length", str(len(response_body))),
159 ]
160 start_response(response_code, response_headers)
162 return [response_body]