Mercurial > hg > index.fcgi > www > www-1
changeset 60:9d3a95d80def
add laterlinks2
author | paulo |
---|---|
date | Fri, 18 Jul 2014 00:47:15 -0700 |
parents | 6edb5112c804 |
children | 16bcb4ae6985 |
files | laterlinks2/laterlinks_app.py laterlinks2/lldb.tsv laterlinks2/lldb_unread.tsv laterlinks2/test_server.py |
diffstat | 2 files changed, 207 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/laterlinks2/laterlinks_app.py Fri Jul 18 00:47:15 2014 -0700 1.3 @@ -0,0 +1,169 @@ 1.4 +import datetime 1.5 +import cgi 1.6 +import urlparse 1.7 +import csv 1.8 +import traceback 1.9 + 1.10 +import html 1.11 + 1.12 + 1.13 +DEBUG = True 1.14 +STRTIME_FMT = "%Y-%m-%d %H:%M:%S" 1.15 +MY_PIN = "qworpy" 1.16 + 1.17 + 1.18 +class LLDialect(csv.Dialect): 1.19 + delimiter = '\t' 1.20 + quoting = csv.QUOTE_NONE 1.21 + lineterminator = '\n' 1.22 + 1.23 + 1.24 +LLDIALECT = LLDialect() 1.25 +LLDB_FN = "lldb.tsv" 1.26 +LLDB_UNREAD_FN = "lldb_unread.tsv" 1.27 + 1.28 + 1.29 +class LLError(Exception): 1.30 + pass 1.31 + 1.32 +class PinFailError(LLError): 1.33 + def __str__(self): 1.34 + return "PIN FAIL!" 1.35 + 1.36 +class MissingFieldsError(LLError): 1.37 + def __str__(self): 1.38 + return "MISSING FIELD(s)!" 1.39 + 1.40 + 1.41 +def lldb_unread_load(): 1.42 + return csv.reader(open(LLDB_UNREAD_FN), LLDIALECT) 1.43 + 1.44 + 1.45 +def lldb_add(inp): 1.46 + try: 1.47 + title = inp["title"][0] 1.48 + url = inp["url"][0] 1.49 + except (KeyError, IndexError): 1.50 + raise MissingFieldsError() 1.51 + 1.52 + dt_str = datetime.datetime.now().strftime(STRTIME_FMT) 1.53 + with open(LLDB_FN, 'a') as lldb_f: 1.54 + csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) 1.55 + with open(LLDB_UNREAD_FN, 'a') as lldb_f: 1.56 + csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) 1.57 + 1.58 + 1.59 +def lldb_unread_delete(inp): 1.60 + try: 1.61 + delete = inp["delete"] 1.62 + except KeyError: 1.63 + raise MissingFieldsError() 1.64 + 1.65 + lldb_unread = [i for i in lldb_unread_load()] 1.66 + lldb_unread_f = open(LLDB_UNREAD_FN, 'w') 1.67 + 1.68 + 1.69 + try: 1.70 + for i in delete: 1.71 + for j in lldb_unread: 1.72 + dt_str = j[2] 1.73 + if i == dt_str: 1.74 + lldb_unread.remove(j) 1.75 + finally: 1.76 + csv.writer(lldb_unread_f, LLDIALECT).writerows(lldb_unread) 1.77 + lldb_unread_f.close() 1.78 + 1.79 + 1.80 + 1.81 +def parse_wsgi_input(environ): 1.82 + return urlparse.parse_qs(environ["wsgi.input"].read()) 1.83 + 1.84 + 1.85 +def get_pin(inp): 1.86 + if "pin" not in inp: 1.87 + raise PinFailError() 1.88 + 1.89 + pin = inp["pin"][0] 1.90 + if pin != MY_PIN: 1.91 + raise PinFailError() 1.92 + 1.93 + return pin 1.94 + 1.95 + 1.96 +def main(environ): 1.97 + pin = '' 1.98 + is_post = (environ["REQUEST_METHOD"] == "POST") 1.99 + inp = parse_wsgi_input(environ) 1.100 + 1.101 + if is_post: 1.102 + pin = get_pin(inp) 1.103 + if inp["submit"][0] == "Add": 1.104 + lldb_add(inp) 1.105 + elif inp["submit"][0] == "Delete": 1.106 + lldb_unread_delete(inp) 1.107 + 1.108 + title = "later links..." 1.109 + root = html.HTML("html") 1.110 + 1.111 + header = root.header 1.112 + header.link(rel="stylesheet", type="text/css", href="index.css") 1.113 + header.title(title) 1.114 + 1.115 + body = root.body 1.116 + body.h1(title) 1.117 + 1.118 + 1.119 + if (DEBUG): 1.120 + debug = body.pre 1.121 + for i in environ.items(): 1.122 + debug += cgi.escape("%s = %s \n" % i) 1.123 + 1.124 + debug += cgi.escape("wsgi.input.read = %s" % inp) 1.125 + 1.126 + form = body.form(action="index.fcgi", method="post") 1.127 + 1.128 + table = form.table 1.129 + hrow = table.tr 1.130 + hrow.th("Link") 1.131 + hrow.th("Created") 1.132 + hrow.th.input(type="submit", name="submit", value="Delete") 1.133 + 1.134 + for i in lldb_unread_load(): 1.135 + (title, url, dt_str) = (j.decode("utf-8") for j in i) 1.136 + row = table.tr 1.137 + row.td.a(title, href=url) 1.138 + row.td(dt_str) 1.139 + row.td.input(type="checkbox", name="delete", value=dt_str) 1.140 + 1.141 + p1 = form.p 1.142 + p1.label("Title").input(type="text", name="title", size="64") 1.143 + p1.br 1.144 + p1.label("URL").input(type="text", name="url", size="64") 1.145 + p1.br 1.146 + p1.input(type="submit", name="submit", value="Add") 1.147 + 1.148 + p2 = form.p 1.149 + p2.input(type="password", name="pin", value=pin) 1.150 + 1.151 + return unicode(root).encode("utf-8") 1.152 + 1.153 + 1.154 +def app(environ, start_response): 1.155 + response_code = "500 Internal Server Error" 1.156 + response_type = "text/plain; charset=UTF-8" 1.157 + 1.158 + try: 1.159 + response_body = main(environ) 1.160 + response_type = "text/html; charset=UTF-8" 1.161 + except LLError as e: 1.162 + response_body = str(e) 1.163 + except: 1.164 + response_body = traceback.format_exc() 1.165 + 1.166 + response_headers = [ 1.167 + ("Content-Type", response_type), 1.168 + ("Content-Length", str(len(response_body))), 1.169 + ] 1.170 + start_response(response_code, response_headers) 1.171 + 1.172 + return [response_body]
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/laterlinks2/test_server.py Fri Jul 18 00:47:15 2014 -0700 2.3 @@ -0,0 +1,38 @@ 2.4 +import os 2.5 +import sys 2.6 +import signal 2.7 + 2.8 +import cherrypy 2.9 +from cherrypy import wsgiserver 2.10 + 2.11 +import laterlinks_app 2.12 + 2.13 + 2.14 +def sighandler(signum, frame): 2.15 + sys.stderr.write("Caught signal: %s \n" % signum) 2.16 + server.stop() 2.17 + 2.18 + 2.19 +class FileServerRoot: 2.20 + def default(self, *args): 2.21 + if len(args) == 0: 2.22 + raise cherrypy.HTTPError(404) 2.23 + 2.24 + filepath = os.path.abspath(os.path.join(*args)) 2.25 + return cherrypy.lib.static.serve_file(filepath) 2.26 + 2.27 + default.exposed = True 2.28 + 2.29 + 2.30 +if __name__ == "__main__": 2.31 + fileServerApp = cherrypy.Application(FileServerRoot()) 2.32 + dispatcher = wsgiserver.WSGIPathInfoDispatcher({ 2.33 + "/index.fcgi": laterlinks_app.app, 2.34 + "": fileServerApp, 2.35 + }) 2.36 + server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 8000), dispatcher) 2.37 + 2.38 + signal.signal(signal.SIGINT, sighandler) 2.39 + signal.signal(signal.SIGTERM, sighandler) 2.40 + 2.41 + server.start()