Mercurial > hg > index.fcgi > www > www-1
comparison laterlinks2/laterlinks_app.py @ 60:9d3a95d80def
add laterlinks2
author | paulo |
---|---|
date | Fri, 18 Jul 2014 00:47:15 -0700 |
parents | |
children | 49ca145627cb |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e812f0cee4ad |
---|---|
1 import datetime | |
2 import cgi | |
3 import urlparse | |
4 import csv | |
5 import traceback | |
6 | |
7 import html | |
8 | |
9 | |
10 DEBUG = True | |
11 STRTIME_FMT = "%Y-%m-%d %H:%M:%S" | |
12 MY_PIN = "qworpy" | |
13 | |
14 | |
15 class LLDialect(csv.Dialect): | |
16 delimiter = '\t' | |
17 quoting = csv.QUOTE_NONE | |
18 lineterminator = '\n' | |
19 | |
20 | |
21 LLDIALECT = LLDialect() | |
22 LLDB_FN = "lldb.tsv" | |
23 LLDB_UNREAD_FN = "lldb_unread.tsv" | |
24 | |
25 | |
26 class LLError(Exception): | |
27 pass | |
28 | |
29 class PinFailError(LLError): | |
30 def __str__(self): | |
31 return "PIN FAIL!" | |
32 | |
33 class MissingFieldsError(LLError): | |
34 def __str__(self): | |
35 return "MISSING FIELD(s)!" | |
36 | |
37 | |
38 def lldb_unread_load(): | |
39 return csv.reader(open(LLDB_UNREAD_FN), LLDIALECT) | |
40 | |
41 | |
42 def lldb_add(inp): | |
43 try: | |
44 title = inp["title"][0] | |
45 url = inp["url"][0] | |
46 except (KeyError, IndexError): | |
47 raise MissingFieldsError() | |
48 | |
49 dt_str = datetime.datetime.now().strftime(STRTIME_FMT) | |
50 with open(LLDB_FN, 'a') as lldb_f: | |
51 csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) | |
52 with open(LLDB_UNREAD_FN, 'a') as lldb_f: | |
53 csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) | |
54 | |
55 | |
56 def lldb_unread_delete(inp): | |
57 try: | |
58 delete = inp["delete"] | |
59 except KeyError: | |
60 raise MissingFieldsError() | |
61 | |
62 lldb_unread = [i for i in lldb_unread_load()] | |
63 lldb_unread_f = open(LLDB_UNREAD_FN, 'w') | |
64 | |
65 | |
66 try: | |
67 for i in delete: | |
68 for j in lldb_unread: | |
69 dt_str = j[2] | |
70 if i == dt_str: | |
71 lldb_unread.remove(j) | |
72 finally: | |
73 csv.writer(lldb_unread_f, LLDIALECT).writerows(lldb_unread) | |
74 lldb_unread_f.close() | |
75 | |
76 | |
77 | |
78 def parse_wsgi_input(environ): | |
79 return urlparse.parse_qs(environ["wsgi.input"].read()) | |
80 | |
81 | |
82 def get_pin(inp): | |
83 if "pin" not in inp: | |
84 raise PinFailError() | |
85 | |
86 pin = inp["pin"][0] | |
87 if pin != MY_PIN: | |
88 raise PinFailError() | |
89 | |
90 return pin | |
91 | |
92 | |
93 def main(environ): | |
94 pin = '' | |
95 is_post = (environ["REQUEST_METHOD"] == "POST") | |
96 inp = parse_wsgi_input(environ) | |
97 | |
98 if is_post: | |
99 pin = get_pin(inp) | |
100 if inp["submit"][0] == "Add": | |
101 lldb_add(inp) | |
102 elif inp["submit"][0] == "Delete": | |
103 lldb_unread_delete(inp) | |
104 | |
105 title = "later links..." | |
106 root = html.HTML("html") | |
107 | |
108 header = root.header | |
109 header.link(rel="stylesheet", type="text/css", href="index.css") | |
110 header.title(title) | |
111 | |
112 body = root.body | |
113 body.h1(title) | |
114 | |
115 | |
116 if (DEBUG): | |
117 debug = body.pre | |
118 for i in environ.items(): | |
119 debug += cgi.escape("%s = %s \n" % i) | |
120 | |
121 debug += cgi.escape("wsgi.input.read = %s" % inp) | |
122 | |
123 form = body.form(action="index.fcgi", method="post") | |
124 | |
125 table = form.table | |
126 hrow = table.tr | |
127 hrow.th("Link") | |
128 hrow.th("Created") | |
129 hrow.th.input(type="submit", name="submit", value="Delete") | |
130 | |
131 for i in lldb_unread_load(): | |
132 (title, url, dt_str) = (j.decode("utf-8") for j in i) | |
133 row = table.tr | |
134 row.td.a(title, href=url) | |
135 row.td(dt_str) | |
136 row.td.input(type="checkbox", name="delete", value=dt_str) | |
137 | |
138 p1 = form.p | |
139 p1.label("Title").input(type="text", name="title", size="64") | |
140 p1.br | |
141 p1.label("URL").input(type="text", name="url", size="64") | |
142 p1.br | |
143 p1.input(type="submit", name="submit", value="Add") | |
144 | |
145 p2 = form.p | |
146 p2.input(type="password", name="pin", value=pin) | |
147 | |
148 return unicode(root).encode("utf-8") | |
149 | |
150 | |
151 def app(environ, start_response): | |
152 response_code = "500 Internal Server Error" | |
153 response_type = "text/plain; charset=UTF-8" | |
154 | |
155 try: | |
156 response_body = main(environ) | |
157 response_type = "text/html; charset=UTF-8" | |
158 except LLError as e: | |
159 response_body = str(e) | |
160 except: | |
161 response_body = traceback.format_exc() | |
162 | |
163 response_headers = [ | |
164 ("Content-Type", response_type), | |
165 ("Content-Length", str(len(response_body))), | |
166 ] | |
167 start_response(response_code, response_headers) | |
168 | |
169 return [response_body] |