Mercurial > hg > index.fcgi > www > www-1
diff laterlinks3/laterlinks_flask_app.py @ 118:65db090a697e
laterlinks3: add GCS support
author | paulo |
---|---|
date | Fri, 18 Sep 2020 01:13:29 -0700 |
parents | 476cb019ad9f |
children | 26cc1a16e7a3 |
line diff
1.1 --- a/laterlinks3/laterlinks_flask_app.py Tue Sep 08 23:52:57 2020 -0700 1.2 +++ b/laterlinks3/laterlinks_flask_app.py Fri Sep 18 01:13:29 2020 -0700 1.3 @@ -1,14 +1,17 @@ 1.4 import csv 1.5 import datetime 1.6 +import io 1.7 import os 1.8 +import tempfile 1.9 1.10 import flask 1.11 - 1.12 +import google.cloud.storage 1.13 from html3.html3 import HTML 1.14 1.15 app = flask.Flask(__name__) 1.16 1.17 -PIN = os.environ.get('LLPIN') 1.18 +GCS_BUCKET = google.cloud.storage.Client().get_bucket(os.environ.get("GCS_BUCKET")) 1.19 +PIN = os.environ.get("LLPIN") 1.20 STRTIME_FMT = "%Y-%m-%d %H:%M:%S" 1.21 1.22 1.23 @@ -39,30 +42,47 @@ 1.24 return "MISSING FIELD(s)!" 1.25 1.26 1.27 -def lldb_unread_load(): 1.28 - return csv.reader(open(LLDB_UNREAD_FN), LLDIALECT) 1.29 +def gcs_download(fn): 1.30 + tmp_f = tempfile.TemporaryFile("w+") 1.31 + blob = GCS_BUCKET.get_blob(fn) 1.32 + if blob: 1.33 + tmp_f.write(str(blob.download_as_string(), encoding="utf-8")) 1.34 + return tmp_f 1.35 1.36 1.37 -def lldb_add(inp): 1.38 +def gcs_upload(fn, tmp_f): 1.39 + blob = GCS_BUCKET.blob(fn) 1.40 + blob.upload_from_file(tmp_f, rewind=True) 1.41 + 1.42 + 1.43 +def lldb_unread_load(lldb_unread_tmp_f): 1.44 + lldb_unread_tmp_f.seek(0) 1.45 + return csv.reader(lldb_unread_tmp_f, LLDIALECT) 1.46 + 1.47 + 1.48 +def lldb_add(inp, lldb_tmp_f, lldb_unread_tmp_f): 1.49 title = inp.get("title") 1.50 url = inp.get("url") 1.51 if not (title and url): 1.52 raise MissingFieldsError() 1.53 1.54 dt_str = datetime.datetime.now().strftime(STRTIME_FMT) 1.55 - with open(LLDB_FN, 'a') as lldb_f: 1.56 - csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) 1.57 - with open(LLDB_UNREAD_FN, 'a') as lldb_f: 1.58 - csv.writer(lldb_f, LLDIALECT).writerow([title, url, dt_str]) 1.59 1.60 + lldb_tmp_f.seek(0, io.SEEK_END) 1.61 + csv.writer(lldb_tmp_f, LLDIALECT).writerow([title, url, dt_str]) 1.62 + gcs_upload(LLDB_FN, lldb_tmp_f) 1.63 1.64 -def lldb_unread_delete(inp): 1.65 + lldb_unread_tmp_f.seek(0, io.SEEK_END) 1.66 + csv.writer(lldb_unread_tmp_f, LLDIALECT).writerow([title, url, dt_str]) 1.67 + gcs_upload(LLDB_UNREAD_FN, lldb_unread_tmp_f) 1.68 + 1.69 + 1.70 +def lldb_unread_delete(inp, lldb_unread_tmp_f): 1.71 delete = inp.getlist("delete") 1.72 if not delete: 1.73 raise MissingFieldsError() 1.74 1.75 - lldb_unread = [i for i in lldb_unread_load()] 1.76 - lldb_unread_f = open(LLDB_UNREAD_FN, 'w') 1.77 + lldb_unread = [i for i in lldb_unread_load(lldb_unread_tmp_f)] 1.78 1.79 try: 1.80 for i in delete: 1.81 @@ -71,9 +91,10 @@ 1.82 if i == dt_str: 1.83 lldb_unread.remove(j) 1.84 finally: 1.85 - csv.writer(lldb_unread_f, LLDIALECT).writerows(lldb_unread) 1.86 - lldb_unread_f.close() 1.87 - 1.88 + lldb_unread_tmp_f.truncate(0) 1.89 + lldb_unread_tmp_f.seek(0) 1.90 + csv.writer(lldb_unread_tmp_f, LLDIALECT).writerows(lldb_unread) 1.91 + gcs_upload(LLDB_UNREAD_FN, lldb_unread_tmp_f) 1.92 1.93 1.94 @app.route("/", methods=["GET", "POST"]) 1.95 @@ -82,46 +103,48 @@ 1.96 inp = flask.request.form 1.97 cookies = flask.request.cookies 1.98 1.99 - if is_post: 1.100 - if not PIN: 1.101 - raise PinSetupError 1.102 - elif cookies.get("llpin") != PIN: 1.103 - raise PinFailError 1.104 + with gcs_download(LLDB_UNREAD_FN) as lldb_unread_tmp_f: 1.105 + if is_post: 1.106 + if not PIN: 1.107 + raise PinSetupError 1.108 + elif cookies.get("llpin") != PIN: 1.109 + raise PinFailError 1.110 1.111 - if inp["submit"] == "Add": 1.112 - lldb_add(inp) 1.113 - elif inp["submit"] == "Delete": 1.114 - lldb_unread_delete(inp) 1.115 + if inp["submit"] == "Add": 1.116 + with gcs_download(LLDB_FN) as lldb_tmp_f: 1.117 + lldb_add(inp, lldb_tmp_f, lldb_unread_tmp_f) 1.118 + elif inp["submit"] == "Delete": 1.119 + lldb_unread_delete(inp, lldb_unread_tmp_f) 1.120 1.121 - title = "later links..." 1.122 - root = HTML("html") 1.123 + title = "later links..." 1.124 + root = HTML("html") 1.125 1.126 - header = root.head 1.127 - header.link(rel="stylesheet", type="text/css", href=flask.url_for("static", filename="index.css")) 1.128 - header.title(title) 1.129 - 1.130 - body = root.body 1.131 - body.h1(title) 1.132 + header = root.head 1.133 + header.link(rel="stylesheet", type="text/css", href=flask.url_for("static", filename="index.css")) 1.134 + header.title(title) 1.135 + 1.136 + body = root.body 1.137 + body.h1(title) 1.138 1.139 - form = body.form(action="/", method="post") 1.140 + form = body.form(action="/", method="post") 1.141 1.142 - table = form.table 1.143 - hrow = table.tr 1.144 - hrow.th("Link") 1.145 - hrow.th("Created") 1.146 - hrow.th.input(type="submit", name="submit", value="Delete") 1.147 + table = form.table 1.148 + hrow = table.tr 1.149 + hrow.th("Link") 1.150 + hrow.th("Created") 1.151 + hrow.th.input(type="submit", name="submit", value="Delete") 1.152 1.153 - for (title, url, dt_str) in lldb_unread_load(): 1.154 - row = table.tr 1.155 - row.td.a(title, href=url) 1.156 - row.td(dt_str) 1.157 - row.td.input(type="checkbox", name="delete", value=dt_str) 1.158 + for (title, url, dt_str) in lldb_unread_load(lldb_unread_tmp_f): 1.159 + row = table.tr 1.160 + row.td.a(title, href=url) 1.161 + row.td(dt_str) 1.162 + row.td.input(type="checkbox", name="delete", value=dt_str) 1.163 1.164 - p1 = form.p 1.165 - p1.label("Title").input(type="text", name="title", size="64") 1.166 - p1.br 1.167 - p1.label("URL").input(type="text", name="url", size="64") 1.168 - p1.br 1.169 - p1.input(type="submit", name="submit", value="Add") 1.170 + p1 = form.p 1.171 + p1.label("Title").input(type="text", name="title", size="64") 1.172 + p1.br 1.173 + p1.label("URL").input(type="text", name="url", size="64") 1.174 + p1.br 1.175 + p1.input(type="submit", name="submit", value="Add") 1.176 1.177 - return str(root).encode("utf-8") 1.178 + return str(root).encode("utf-8")