Skip to main content

get something working

ID
6240da0
date
2022-05-04 21:34:04+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
7829916
message
get something working
changed files
8 files, 228 additions, 161 deletions

Changed files

webapp/requirements.in (0) → webapp/requirements.in (26)

diff --git a/webapp/requirements.in b/webapp/requirements.in
new file mode 100644
index 0000000..b028da6
--- /dev/null
+++ b/webapp/requirements.in
@@ -0,0 +1,2 @@
+flask
+wcag_contrast_ratio

webapp/requirements.txt (0) → webapp/requirements.txt (443)

diff --git a/webapp/requirements.txt b/webapp/requirements.txt
new file mode 100644
index 0000000..ef4ceb1
--- /dev/null
+++ b/webapp/requirements.txt
@@ -0,0 +1,24 @@
+#
+# This file is autogenerated by pip-compile with python 3.9
+# To update, run:
+#
+#    pip-compile
+#
+click==8.1.3
+    # via flask
+flask==2.1.2
+    # via -r requirements.in
+importlib-metadata==4.11.3
+    # via flask
+itsdangerous==2.1.2
+    # via flask
+jinja2==3.1.2
+    # via flask
+markupsafe==2.1.1
+    # via jinja2
+wcag-contrast-ratio==0.9
+    # via -r requirements.in
+werkzeug==2.1.2
+    # via flask
+zipp==3.8.0
+    # via importlib-metadata

webapp/server.py (1963) → webapp/server.py (2403)

diff --git a/webapp/server.py b/webapp/server.py
index 2fba28c..98fda22 100755
--- a/webapp/server.py
+++ b/webapp/server.py
@@ -13,9 +13,12 @@ import wcag_contrast_ratio as contrast
 app = Flask(__name__)
 
 
+VERSION = subprocess.check_output(["dominant_colours", "--version"]).decode("utf8")
+
+
 @app.route("/")
 def index():
-    return render_template("index.html")
+    return render_template("index.html", version=VERSION)
 
 
 @app.template_filter("foreground_colour")
@@ -27,9 +30,9 @@ def foreground_colour(hex_string):
     ratio = contrast.rgb((red / 255, green / 255, blue / 255), (0, 0, 0))
 
     if contrast.passes_AA(ratio):
-        return '#000000'
+        return "#000000"
     else:
-        return '#FFFFFF'
+        return "#FFFFFF"
 
 
 @app.route("/palette", methods=["POST"])
@@ -49,18 +52,35 @@ def get_palette():
             # when running dominant_colours.
             tmp_file.flush()
 
-            result = subprocess.check_output(['dominant_colours', tmp_file.name, '--no-palette', '--max-colours=5'])
-            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])
+            result = subprocess.check_output(
+                ["dominant_colours", tmp_file.name, "--no-palette", "--max-colours=5"]
+            )
+            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')
+            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)
+            return render_template(
+                "palette.html",
+                colours=colours,
+                thumbnail_data_uri=thumbnail_data_uri,
+                version=VERSION,
+            )
 
 
 if __name__ == "__main__":
-    app.run(debug=True, host='0.0.0.0')
+    app.run(debug=True, host="0.0.0.0")

webapp/static/45degreee_fabric.png (0) → webapp/static/45degreee_fabric.png (153950)

diff --git a/webapp/static/45degreee_fabric.png b/webapp/static/45degreee_fabric.png
new file mode 100644
index 0000000..3c7fa3f
Binary files /dev/null and b/webapp/static/45degreee_fabric.png differ

webapp/static/style.css (0) → webapp/static/style.css (2097)

diff --git a/webapp/static/style.css b/webapp/static/style.css
new file mode 100644
index 0000000..5c7b01a
--- /dev/null
+++ b/webapp/static/style.css
@@ -0,0 +1,132 @@
+body {
+  margin:  0;
+  padding: 0;
+
+  /* Pattern from https://www.toptal.com/designers/subtlepatterns/awesome-pattern/ */
+  background-image: url('/static/45degreee_fabric.png');
+}
+
+main, footer {
+  max-width: 500px;
+  margin-left:  auto;
+  margin-right: auto;
+  text-align: center;
+  padding: 5px;
+
+  font: 14pt Avenir, Arial, sans-serif;
+  color: #333;
+}
+
+footer {
+  font-size: 9pt;
+  color: #aaa;
+}
+
+a, a:visited {
+  color: #555;
+}
+
+footer a, footer a:visited {
+  color: #888;
+}
+
+a:hover {
+  background: #ccc;
+}
+
+#results {
+  display: grid;
+  grid-template-columns: 325px 70px auto;
+  grid-template-rows: repeat(5, 56px);
+  grid-gap: 5px;
+  height: 300px;
+
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.thumbnail {
+  grid-row: 1 / span 5;
+  grid-column: 1 / 3;
+  width:  300px;
+  height: 300px;
+}
+
+img {
+  width:  100%;
+  height: 100%;
+  object-fit: contain;
+}
+
+.sample {
+  grid-column: 1 / 2;
+}
+
+.label {
+  font-family: monospace;
+  height:      56px;
+  line-height: 56px;
+  text-align: left;
+}
+
+.sample {
+  width:  56px;
+  height: 56px;
+  grid-column: 2 / 3;
+}
+
+.label {
+  grid-column: 3 / 3;
+}
+
+#label_1, #sample_1 { grid-row: 1 / 5; }
+#label_2, #sample_2 { grid-row: 2 / 5; }
+#label_3, #sample_3 { grid-row: 3 / 5; }
+#label_4, #sample_4 { grid-row: 4 / 5; }
+#label_5, #sample_5 { grid-row: 5 / 5; }
+
+@media screen and (max-width: 600px) {
+  .thumbnail {
+    width:  300px;
+    height: 230px;
+    margin-left: auto;
+    margin-right: auto;
+  }
+
+  #results {
+    grid-template-columns: 42px auto;
+    width: 300px;
+    grid-template-rows: 240px repeat(5, 42px);
+    grid-row-gap: 10px;
+    height: auto;
+  }
+
+  .thumbnail {
+    grid-column: 1 / span 2;
+    grid-row:1 / 6;
+  }
+
+  .sample {
+    grid-column: 1 / 2;
+  }
+
+  .label {
+    grid-column: 2 / 2;
+  }
+
+  #label_1, #sample_1 { grid-row: 2 / 6; }
+  #label_2, #sample_2 { grid-row: 3 / 6; }
+  #label_3, #sample_3 { grid-row: 4 / 6; }
+  #label_4, #sample_4 { grid-row: 5 / 6; }
+  #label_5, #sample_5 { grid-row: 6 / 6; }
+
+  .label {
+    height:      42px;
+    line-height: 42px;
+  }
+
+  .sample {
+    width:  42px;
+    height: 42px;
+  }
+}

webapp/templates/base.html (0) → webapp/templates/base.html (734)

diff --git a/webapp/templates/base.html b/webapp/templates/base.html
new file mode 100644
index 0000000..9015714
--- /dev/null
+++ b/webapp/templates/base.html
@@ -0,0 +1,26 @@
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
+
+    <link rel="stylesheet" href="/static/style.css">
+
+    <title>dominant colours</title>
+  </head>
+  <body>
+    <main>
+      <h2>find the dominant colours in an image</h2>
+      {% block content %}
+      {% endblock %}
+    </main>
+    <footer>
+        made with <span class="heart">&#x2764;</span> by <a href="https://alexwlchan.net">alexwlchan</a>
+        ·
+        {{ version }}
+        ·
+        code on <a href="https://github.com/alexwlchan/dominant_colours/tree/main/webapp">github</a>
+      </div>
+    </footer>
+  </body>
+</html>
\ No newline at end of file

webapp/templates/index.html (408) → webapp/templates/index.html (282)

diff --git a/webapp/templates/index.html b/webapp/templates/index.html
index 8cff40c..82c6be1 100644
--- a/webapp/templates/index.html
+++ b/webapp/templates/index.html
@@ -1,15 +1,11 @@
-<html>
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
+{% extends "base.html" %}
 
-</head>
-   <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
+{% block content %}
+  <p>upload an image to analyse:</p>
+
+  <form action="/palette" method="POST"
+     enctype="multipart/form-data">
+     <input type="file" name="file" accept=".gif,.jpg,.jpeg,.png"/>
+     <input type="submit"/>
+  </form>
+{% endblock %}

webapp/templates/palette.html (3058) → webapp/templates/palette.html (416)

diff --git a/webapp/templates/palette.html b/webapp/templates/palette.html
index 057fbe2..85ec9dc 100644
--- a/webapp/templates/palette.html
+++ b/webapp/templates/palette.html
@@ -1,138 +1,6 @@
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
+{% extends "base.html" %}
 
-</head>
-
-<h1>dominant colours</h1>
-
-  <style>
-/*    .colour {
-      width: calc(250px - 1em - .5em);
-/*      text-align: center;*/
-      padding: 5px;
-
-/*      margin: .25em;*/
-/*      border-radius: 5px;*/
-
-
-/*      margin-left: auto;*/
-/*      margin-right: auto;*/
-    }*/
-
-    main {
-/*      max-width: 700px;*/
-/*      margin-left: auto;*/
-/*      margin-right: auto;*/
-/*      text-align: center;*/
-    }
-
-    #results {
-/*      margin-top: 1em;*/
-      display: grid;
-      grid-template-columns: 325px 48px auto;
-      grid-template-rows: repeat(5, 48px);
-      grid-gap: 15px;
-      height: 300px;
-      width: 600px;
-      margin-left: auto;
-      margin-right: auto;
-    }
-
-    .thumbnail {
-/*      border: 4px solid #999;*/
-      grid-row: 1 / span 5;
-      grid-column: 1 / 3;
-      width:  300px;
-      height: 300px;
-      background: #ddd;
-/*      margin: -4px;*/
-    }
-
-    img {
-      width:  100%;
-      height: 100%;
-      object-fit: contain;
-    }
-
-    .sample {
-      grid-column: 1 / 2;
-    }
-
-    .label {
-      font-family: monospace;
-      font-size: 170%;
-      height:      48px;
-      line-height: 48px;
-    }
-
-    .sample {
-      width:  48px;
-      height: 48px;
-      border: 2px solid black;
-/*      margin: -2px;*/
-      grid-column: 2 / 3;
-    }
-
-    .label {
-      grid-column: 3 / 3;
-    }
-
-    #label_1, #sample_1 { grid-row: 1 / 5; }
-    #label_2, #sample_2 { grid-row: 2 / 5; }
-    #label_3, #sample_3 { grid-row: 3 / 5; }
-    #label_4, #sample_4 { grid-row: 4 / 5; }
-    #label_5, #sample_5 { grid-row: 5 / 5; }
-
-    @media screen and (max-width: 600px) {
-      .thumbnail {
-        width:  300px;
-        height: 230px;
-        margin-left: auto;
-        margin-right: auto;
-      }
-
-      #results {
-        grid-template-columns: 42px auto;
-        width: 300px;
-        grid-template-rows: 240px repeat(5, 42px);
-        grid-row-gap: 10px;
-        height: auto;
-      }
-
-      .thumbnail {
-        grid-column: 1 / span 2;
-        grid-row:1 / 6;
-      }
-
-      .sample {
-        grid-column: 1 / 2;
-      }
-
-      .label {
-        grid-column: 2 / 2;
-      }
-
-      #label_1, #sample_1 { grid-row: 2 / 6; }
-      #label_2, #sample_2 { grid-row: 3 / 6; }
-      #label_3, #sample_3 { grid-row: 4 / 6; }
-      #label_4, #sample_4 { grid-row: 5 / 6; }
-      #label_5, #sample_5 { grid-row: 6 / 6; }
-
-      .label {
-        height:      42px;
-        line-height: 42px;
-      }
-
-      .sample {
-        width:  42px;
-        height: 42px;
-      }
-    }
-  </style>
-
-<main>
+{% block content %}
   <div id="results">
     <div class="thumbnail">
       <img src="{{ thumbnail_data_uri }}">
@@ -144,5 +12,4 @@
   </div>
 
   <p><a href="/">try another image</a></p>
-</main>
-
+{% endblock %}