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")