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>
+