annotate laterlinks2/laterlinks_app.py @ 60:9d3a95d80def

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