summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorromangraef <roman.graef@gmail.com>2018-05-31 08:24:02 +0200
committerromangraef <roman.graef@gmail.com>2018-05-31 08:24:02 +0200
commit4a11fe9780deb76004be0e229edf298ac7200f0f (patch)
tree59d5d558f86483b4c73964b4683118cae87228dc
downloadmy-website-4a11fe9780deb76004be0e229edf298ac7200f0f.tar.gz
my-website-4a11fe9780deb76004be0e229edf298ac7200f0f.tar.bz2
my-website-4a11fe9780deb76004be0e229edf298ac7200f0f.zip
initial commit
-rw-r--r--.gitignore3
-rw-r--r--app.py37
-rw-r--r--json_serializable.py72
-rw-r--r--static/.gallery.css.map7
-rw-r--r--static/.gallery.scss28
-rw-r--r--static/.reset.css.map7
-rw-r--r--static/.reset.scss49
-rw-r--r--static/.spoiler.css.map7
-rw-r--r--static/.spoiler.scss21
-rw-r--r--static/main.css.map7
-rw-r--r--static/main.scss29
-rw-r--r--templates/base.html19
-rw-r--r--templates/index.html27
-rw-r--r--templates/project.html6
14 files changed, 319 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b3231b1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+venv/
+*.css
+projects.json
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..c3bfe9f
--- /dev/null
+++ b/app.py
@@ -0,0 +1,37 @@
+import json
+from typing import List
+
+from flask import Flask, render_template, abort
+
+from json_serializable import JsonSerializable, from_json
+
+app = Flask(__name__)
+
+
+class Project(JsonSerializable):
+ name: str
+ description: str
+ link: str
+
+
+with open('projects.json') as handle:
+ project_data: List[Project] = from_json(json.load(handle), List[Project])
+
+
+@app.route('/projects/<project_name>')
+def projects(project_name):
+ matches = [project for project in project_data if project.name.lower() == project_name.lower()]
+ if len(matches) == 0:
+ abort(404)
+ if len(matches) > 1:
+ abort(500)
+ return render_template('project.html', project=matches[0])
+
+
+@app.route('/')
+def hello_world():
+ return render_template('index.html')
+
+
+if __name__ == '__main__':
+ app.run()
diff --git a/json_serializable.py b/json_serializable.py
new file mode 100644
index 0000000..87db9d1
--- /dev/null
+++ b/json_serializable.py
@@ -0,0 +1,72 @@
+import json
+from datetime import datetime
+from enum import Enum
+from typing import Dict, Type, List
+
+
+def from_json(data, cls: Type):
+ if issubclass(cls, List):
+ list_type: Type = cls.__args__[0] if hasattr(cls, '__args__') else type(data[0])
+ instance = list()
+ for value in data:
+ instance.append(from_json(value, list_type))
+ return instance
+ if issubclass(cls, Dict):
+ item = data.copy().popitem() if len(data) > 0 else None
+ key_type: Type = cls.__args__[0] if hasattr(cls, '__args__') else type(item[0])
+ value_type: Type = cls.__args__[1] if hasattr(cls, '__args__') else type(item[0])
+ instance = dict()
+ for key, value in data.items():
+ instance[from_json(key, key_type)] = from_json(value, value_type)
+ return instance
+ if issubclass(cls, Enum):
+ return getattr(cls, data)
+ if issubclass(cls, datetime):
+ return datetime.fromtimestamp(data)
+ if issubclass(cls, JsonSerializable):
+ instance = cls()
+ annotations: dict = cls.__annotations__ if hasattr(cls, '__annotations__') else {}
+ for key, value in data.items():
+ value_type = annotations[key] if key in annotations.keys() else type(value)
+ setattr(instance, key, from_json(value, value_type))
+ return instance
+ return data
+
+
+def prepare_json(obj):
+ if isinstance(obj, JsonSerializable):
+ return prepare_json(obj.__dict__)
+ if isinstance(obj, Enum):
+ return obj.name
+ if isinstance(obj, datetime):
+ return obj.timestamp()
+ if any(isinstance(obj, cls) for cls in [list, set, frozenset]):
+ return [prepare_json(data) for data in obj]
+ if isinstance(obj, dict):
+ return {key: prepare_json(value) for key, value in obj.items()}
+ return obj
+
+
+class JsonSerializable(object):
+ @classmethod
+ def load(cls, data):
+ if isinstance(data, str):
+ data = json.loads(data)
+ return from_json(data, cls)
+
+ @classmethod
+ def load_from_file(cls, filename):
+ filename = str(filename)
+ with open(filename) as handle:
+ return cls.load(handle.read())
+
+ def dump_to_file(self, filename):
+ filename = str(filename)
+ with open(filename, 'w') as handle:
+ handle.write(self.dump())
+
+ def dump(self):
+ return json.dumps(prepare_json(self))
+
+ def __repr__(self):
+ return self.dump()
diff --git a/static/.gallery.css.map b/static/.gallery.css.map
new file mode 100644
index 0000000..5c9be46
--- /dev/null
+++ b/static/.gallery.css.map
@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": "AAAA,QAAS;EACP,OAAO,EAAE,IAAI;;AAGf,gBAAiB;EACf,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,GAAG;EACX,MAAM,EAAE,cAAc",
+"sources": [".gallery.scss"],
+"names": [],
+"file": ".gallery.css"
+} \ No newline at end of file
diff --git a/static/.gallery.scss b/static/.gallery.scss
new file mode 100644
index 0000000..20391a3
--- /dev/null
+++ b/static/.gallery.scss
@@ -0,0 +1,28 @@
+.gallery {
+ display: flex;
+}
+
+.gallery-element {
+ background: #e6ebf6;
+ cursor: pointer;
+ display: block;
+ min-width: 200px;
+ padding: 10px;
+ width: 33%;
+ min-height: 200px;
+ margin: 5px;
+ border: gray 1px solid;
+}
+
+.gallery-element:hover {
+ -webkit-transform: scale(1.2);
+ -moz-transform: scale(1.2);
+ -ms-transform: scale(1.2);
+ -o-transform: scale(1.2);
+ transform: scale(1.2);
+ -webkit-transition: all 100ms;
+ -moz-transition: all 100ms;
+ -ms-transition: all 100ms;
+ -o-transition: all 100ms;
+ transition: all 100ms;
+}
diff --git a/static/.reset.css.map b/static/.reset.css.map
new file mode 100644
index 0000000..ae18cb8
--- /dev/null
+++ b/static/.reset.css.map
@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": "AAAA;;;;;;;;;;;;wBAYyB;EACvB,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;EACT,SAAS,EAAE,IAAI;EACf,IAAI,EAAE,OAAO;EACb,cAAc,EAAE,QAAQ;;AAG1B,iDAAiD;AACjD;0CAC2C;EACzC,OAAO,EAAE,KAAK;;AAGhB,IAAK;EACH,WAAW,EAAE,CAAC;;AAGhB,MAAO;EACL,UAAU,EAAE,IAAI;;AAGlB,aAAc;EACZ,MAAM,EAAE,IAAI;;AAGd;iBACkB;EAChB,OAAO,EAAE,EAAE;EACX,OAAO,EAAE,IAAI;;AAGf,KAAM;EACJ,eAAe,EAAE,QAAQ;EACzB,cAAc,EAAE,CAAC",
+"sources": [".reset.scss"],
+"names": [],
+"file": ".reset.css"
+} \ No newline at end of file
diff --git a/static/.reset.scss b/static/.reset.scss
new file mode 100644
index 0000000..2cd953d
--- /dev/null
+++ b/static/.reset.scss
@@ -0,0 +1,49 @@
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+
+body {
+ line-height: 1;
+}
+
+ol, ul {
+ list-style: none;
+}
+
+blockquote, q {
+ quotes: none;
+}
+
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/static/.spoiler.css.map b/static/.spoiler.css.map
new file mode 100644
index 0000000..10e1998
--- /dev/null
+++ b/static/.spoiler.css.map
@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": "AAEA,cAAe;EACb,OAAO,EAAE,aAAa;EACtB,kBAAkB,EAAE,WAAW;EAC/B,eAAe,EAAE,WAAW;EAC5B,cAAc,EAAE,WAAW;EAC3B,aAAa,EAAE,WAAW;EAC1B,UAAU,EAAE,WAAW;EACvB,KAAK,EATM,OAAO;;AAapB,oBAAqB;EACnB,KAAK,EAbM,KAAK;;AAgBlB,QAAS;EACP,UAAU,EAlBC,OAAO;EAmBlB,KAAK,EAlBM,KAAK",
+"sources": [".spoiler.scss"],
+"names": [],
+"file": ".spoiler.css"
+} \ No newline at end of file
diff --git a/static/.spoiler.scss b/static/.spoiler.scss
new file mode 100644
index 0000000..7cdf4c8
--- /dev/null
+++ b/static/.spoiler.scss
@@ -0,0 +1,21 @@
+$spoiler-bg: #aa1d68;
+$spoiler-fg: white;
+.spoiler:after {
+ content: attr(content);
+ -webkit-transition: color 500ms;
+ -moz-transition: color 500ms;
+ -ms-transition: color 500ms;
+ -o-transition: color 500ms;
+ transition: color 500ms;
+ color: $spoiler-bg;
+
+}
+
+.spoiler:hover:after {
+ color: $spoiler-fg;
+}
+
+.spoiler {
+ background: $spoiler-bg;
+ color: $spoiler-fg;
+}
diff --git a/static/main.css.map b/static/main.css.map
new file mode 100644
index 0000000..e30bd6e
--- /dev/null
+++ b/static/main.css.map
@@ -0,0 +1,7 @@
+{
+"version": 3,
+"mappings": "AAEA,cAAe;EACb,OAAO,EAAE,aAAa;EACtB,kBAAkB,EAAE,WAAW;EAC/B,eAAe,EAAE,WAAW;EAC5B,cAAc,EAAE,WAAW;EAC3B,aAAa,EAAE,WAAW;EAC1B,UAAU,EAAE,WAAW;EACvB,KAAK,EATM,OAAO;;AAapB,oBAAqB;EACnB,KAAK,EAbM,KAAK;;AAgBlB,QAAS;EACP,UAAU,EAlBC,OAAO;EAmBlB,KAAK,EAlBM,KAAK;;ACDlB;;;;;;;;;;;;wBAYyB;EACvB,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;EACT,SAAS,EAAE,IAAI;EACf,IAAI,EAAE,OAAO;EACb,cAAc,EAAE,QAAQ;;AAG1B,iDAAiD;AACjD;0CAC2C;EACzC,OAAO,EAAE,KAAK;;AAGhB,IAAK;EACH,WAAW,EAAE,CAAC;;AAGhB,MAAO;EACL,UAAU,EAAE,IAAI;;AAGlB,aAAc;EACZ,MAAM,EAAE,IAAI;;AAGd;iBACkB;EAChB,OAAO,EAAE,EAAE;EACX,OAAO,EAAE,IAAI;;AAGf,KAAM;EACJ,eAAe,EAAE,QAAQ;EACzB,cAAc,EAAE,CAAC;;AC/CnB,QAAS;EACP,OAAO,EAAE,IAAI;;AAGf,gBAAiB;EACf,UAAU,EAAE,OAAO;EACnB,MAAM,EAAE,OAAO;EACf,OAAO,EAAE,KAAK;EACd,SAAS,EAAE,KAAK;EAChB,OAAO,EAAE,IAAI;EACb,KAAK,EAAE,GAAG;EACV,UAAU,EAAE,KAAK;EACjB,MAAM,EAAE,GAAG;EACX,MAAM,EAAE,cAAc;;AAGxB,sBAAuB;EACrB,iBAAiB,EAAE,UAAU;EAC7B,cAAc,EAAE,UAAU;EAC1B,aAAa,EAAE,UAAU;EACzB,YAAY,EAAE,UAAU;EACxB,SAAS,EAAE,UAAU;EACrB,kBAAkB,EAAE,SAAS;EAC7B,eAAe,EAAE,SAAS;EAC1B,cAAc,EAAE,SAAS;EACzB,aAAa,EAAE,SAAS;EACxB,UAAU,EAAE,SAAS;;ACtBvB,CAAE;EACA,WAAW,EAAE,mCAAmC;;AAGlD,QAAS;EACP,OAAO,EAAE,IAAI;EACb,UAAU,EAAE,MAAM;EAClB,MAAM,EAAE,MAAM;EACd,KAAK,EAAE,GAAG;EACV,SAAS,EAAE,KAAK;;AAGlB,EAAG;EACD,SAAS,EAAE,GAAG;EACd,MAAM,EAAE,GAAG;;AAGb,OAAQ;EACN,MAAM,EAAE,IAAI;;AAGd,CAAE;EACA,KAAK,EAAE,OAAO;EACd,eAAe,EAAE,OAAO",
+"sources": [".spoiler.scss",".reset.scss",".gallery.scss","main.scss"],
+"names": [],
+"file": "main.css"
+} \ No newline at end of file
diff --git a/static/main.scss b/static/main.scss
new file mode 100644
index 0000000..93c71e3
--- /dev/null
+++ b/static/main.scss
@@ -0,0 +1,29 @@
+@import ".spoiler";
+@import ".reset";
+@import ".gallery";
+
+* {
+ font-family: 'Montserrat', sans-serif !important;
+}
+
+.content {
+ padding: 30px;
+ text-align: center;
+ margin: 0 auto;
+ width: 50%;
+ min-width: 600px;
+}
+
+h1 {
+ font-size: 2em;
+ margin: 5px;
+}
+
+.spacer {
+ height: 50px;
+}
+
+a {
+ color: inherit;
+ text-decoration: inherit;
+} \ No newline at end of file
diff --git a/templates/base.html b/templates/base.html
new file mode 100644
index 0000000..8d51f29
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport"
+ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <title>{% block title %}{{ title }}{% endblock %}</title>
+ <link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
+ <link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
+</head>
+<body>
+<div id="content" class="content">
+ {% block body %}
+ No content found. THIS IS AN ERROR
+ {% endblock %}
+</div>
+</body>
+</html> \ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..cefce37
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+{% block body %}
+ <h1>Hey, You!</h1>
+ <p>I am Roman Gr&auml;f</p>
+ <p>I am a programmer!</p>
+ <p>I do things for you!</p>
+ <p>As long as it is not webdesign, I will program nearly anything for you</p>
+ <div class="spacer"></div>
+ <h1>Projects</h1>
+ <div class="gallery">
+ <a href="{{ url_for("projects", project_name="website") }}">
+ <div class="gallery-element">
+ This website
+ </div>
+ </a>
+ <div class="gallery-element">
+ Discord Bots
+ </div>
+ <div class="gallery-element">
+ LOGL
+ </div>
+ </div>
+
+{% endblock %}
+{% block title %}
+ Roman Gr&auml;f
+{% endblock %} \ No newline at end of file
diff --git a/templates/project.html b/templates/project.html
new file mode 100644
index 0000000..076e0a2
--- /dev/null
+++ b/templates/project.html
@@ -0,0 +1,6 @@
+{% extends "base.html" %}
+{% block body %}
+ <h1>{{ project.name }}</h1>
+ <p>{{ project.description }}</p>
+ <p><a href="{{ project.link }}">Link</a></p>
+{% endblock %}