Skip to main content

get a very basic web app working

ID
7f6f056
date
2022-05-03 21:48:09+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
977c9a8
message
get a very basic web app working
changed files
3 files, 161 additions

Changed files

webapp/server.py (0) → webapp/server.py (1928)

diff --git a/webapp/server.py b/webapp/server.py
new file mode 100755
index 0000000..55b3c84
--- /dev/null
+++ b/webapp/server.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+
+import base64
+import colorsys
+import os
+import subprocess
+import tempfile
+
+from flask import Flask, render_template, request
+import wcag_contrast_ratio as contrast
+
+
+app = Flask(__name__)
+
+
+@app.route("/")
+def index():
+    return render_template("index.html")
+
+
+@app.template_filter("foreground_colour")
+def foreground_colour(hex_string):
+    red = int(hex_string[1:3], 16)
+    green = int(hex_string[3:5], 16)
+    blue = int(hex_string[5:7], 16)
+
+    ratio = contrast.rgb((red / 255, green / 255, blue / 255), (0, 0, 0))
+
+    if contrast.passes_AA(ratio):
+        return '#000000'
+    else:
+        return '#FFFFFF'
+
+
+@app.route("/palette", methods=["POST"])
+def get_palette():
+    if request.method == "POST":
+        uploaded_file = request.files["file"]
+        _, extension = os.path.splitext(uploaded_file.filename)
+
+        with tempfile.NamedTemporaryFile(suffix=extension) as tmp_file:
+            uploaded_file.save(tmp_file)
+
+            # If we don't flush here, the file may be incomplete.  This can
+            # lead to errors like:
+            #
+            #     failed to fill whole buffer
+            #
+            # when running dominant_colours.
+            tmp_file.flush()
+
+            result = subprocess.check_output(['dominant_colours', tmp_file.name, '--no-palette'])
+            colours = result.decode('utf8').strip().split('\n')
+
+            with tempfile.NamedTemporaryFile(suffix='jpg') as thumbnail_file:
+                subprocess.check_call(['convert', tmp_file.name, '-resize', '600x600', thumbnail_file.name])
+                thumbnail_file.seek(0)
+                thumbnail = thumbnail_file.read()
+
+            thumbnail_data_uri = (b'data:image/jpg;base64,' + base64.b64encode(thumbnail)).decode('ascii')
+
+            return render_template('palette.html', colours=colours, thumbnail_data_uri=thumbnail_data_uri)
+
+
+if __name__ == "__main__":
+    app.run(debug=True)

webapp/templates/index.html (0) → webapp/templates/index.html (220)

diff --git a/webapp/templates/index.html b/webapp/templates/index.html
new file mode 100644
index 0000000..05091c5
--- /dev/null
+++ b/webapp/templates/index.html
@@ -0,0 +1,9 @@
+<html>
+   <body>
+      <form action = "/palette" method = "POST"
+         enctype = "multipart/form-data">
+         <input type = "file" name = "file" />
+         <input type = "submit"/>
+      </form>
+   </body>
+</html>
\ No newline at end of file

webapp/templates/palette.html (0) → webapp/templates/palette.html (1605)

diff --git a/webapp/templates/palette.html b/webapp/templates/palette.html
new file mode 100644
index 0000000..2d3d0a7
--- /dev/null
+++ b/webapp/templates/palette.html
@@ -0,0 +1,86 @@
+  <style>
+    .colour {
+      width: calc(250px - 1em - .5em);
+/*      text-align: center;*/
+      padding: 5px;
+      font-family: monospace;
+/*      margin: .25em;*/
+      border-radius: 5px;
+      font-size: 150%;
+
+      margin-left: auto;
+      margin-right: auto;
+    }
+
+    #results {
+      margin-top: 1em;
+    }
+
+    main {
+      max-width: 700px;
+      margin-left: auto;
+      margin-right: auto;
+/*      text-align: center;*/
+    }
+
+    .thumbnail {
+      border: 1px solid #999;
+      width:  300px;
+      height: 300px;
+      padding: 10px;
+    }
+
+    img {
+      width:  300px;
+      height: 300px;
+      object-fit: contain;
+    }
+
+    .colour {
+      display: grid;
+/*      background: yellow;*/
+      grid-template-columns: 30px auto;
+      grid-gap: 12px;
+    }
+
+    .sample {
+      grid-column: 1 / 2;
+/*      background: green;*/
+    }
+
+    .label {
+      grid-column: 2 / 2;
+      height: 30px;
+/*      background: blue;*/
+    }
+
+    .sample {
+      width:  30px;
+      height: 30px;
+      border: 1px solid black;
+    }
+  </style>
+
+<main>
+  <div id="results">
+    <div class="thumbnail">
+      <img src="{{ thumbnail_data_uri }}">
+    </div>
+    <div class="palette">
+      {% for c in colours %}
+      <div class="colour">
+        <div class="sample" style="background: {{ c }}"></div>
+        <div class="label">{{ c }}</div>
+      </div>
+      {% endfor %}
+    </div>
+  </div>
+
+  <p>Try another image:</p>
+  <form action = "/palette" method = "POST"
+     enctype = "multipart/form-data">
+     <input type = "file" name = "file" />
+     <input type = "submit"/>
+  </form>
+</main>
+