Initial commit
4
tetawebapp/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*un~
|
||||||
|
*.swp
|
||||||
|
*.pyc
|
||||||
|
*.wsgi
|
2
tetawebapp/config.local.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||||
|
SQLALCHEMY_DATABASE_URI = "postgresql://tetawebapp:tetawebapp@localhost/tetawebapp"
|
1
tetawebapp/config.py
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
config.local.py
|
BIN
tetawebapp/static/fonts/RobotoCondensed-Bold.ttf
Normal file
BIN
tetawebapp/static/fonts/RobotoCondensed-Regular.ttf
Normal file
BIN
tetawebapp/static/images/404.png
Normal file
After Width: | Height: | Size: 254 KiB |
BIN
tetawebapp/static/images/add.png
Normal file
After Width: | Height: | Size: 386 B |
BIN
tetawebapp/static/images/dummy_pic.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
tetawebapp/static/images/edit.png
Normal file
After Width: | Height: | Size: 938 B |
BIN
tetawebapp/static/images/login.png
Normal file
After Width: | Height: | Size: 321 B |
BIN
tetawebapp/static/images/logo.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
tetawebapp/static/images/logout.png
Normal file
After Width: | Height: | Size: 327 B |
BIN
tetawebapp/static/images/refresh.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
tetawebapp/static/images/save.png
Normal file
After Width: | Height: | Size: 357 B |
BIN
tetawebapp/static/images/search.png
Normal file
After Width: | Height: | Size: 371 B |
BIN
tetawebapp/static/images/trash.png
Normal file
After Width: | Height: | Size: 878 B |
22
tetawebapp/static/styles/colors.css
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
:root {
|
||||||
|
--coloured-bg: #FF5D00;
|
||||||
|
--light-coloured-bg: #FFB387;
|
||||||
|
--clear-bg: #E5E5E5;
|
||||||
|
--mid-bg: #BBBBBB;
|
||||||
|
--dark-bg: #2B2B2B;
|
||||||
|
--dark-border: #888888;
|
||||||
|
--text-color: #555555;
|
||||||
|
--white: #FFFFFF;
|
||||||
|
--black: #000000;
|
||||||
|
--font-normal: url("/static/fonts/RobotoCondensed-Regular.ttf") format("truetype");
|
||||||
|
--font-bold: url("/static/fonts/RobotoCondensed-Bold.ttf") format("truetype");
|
||||||
|
--banner-logo: url(/static/images/logo.png);
|
||||||
|
--add_icon: url(/static/images/add.png);
|
||||||
|
--edit_icon: url(/static/images/edit.png);
|
||||||
|
--login_icon: url(/static/images/login.png);
|
||||||
|
--logout_icon: url(/static/images/logout.png);
|
||||||
|
--refresh_icon: url(/static/images/refresh.png);
|
||||||
|
--save_icon: url(/static/images/save.png);
|
||||||
|
--search_icon: url(/static/images/search.png);
|
||||||
|
--trash_icon: url(/static/images/trash.png);
|
||||||
|
}
|
13
tetawebapp/static/styles/fonts.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "Roboto Condensed";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: var(--font-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Roboto Condensed";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: var(--font-bold);
|
||||||
|
}
|
184
tetawebapp/static/styles/tetawebapp.css
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 10px;
|
||||||
|
font-family: "Roboto Condensed";
|
||||||
|
background-color: var(--dark-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content {
|
||||||
|
display: flex;
|
||||||
|
min-height: calc(100vh - 110px);
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article {
|
||||||
|
flex: 1;
|
||||||
|
background-color: var(--clear-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav {
|
||||||
|
flex: 0 0 200px;
|
||||||
|
background-color: var(--clear-bg);
|
||||||
|
border-right-color: var(--mid-bg);
|
||||||
|
border-right-style: solid;
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav {
|
||||||
|
order: -1;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav > a {
|
||||||
|
display: block;
|
||||||
|
background-color: var(--clear-bg);
|
||||||
|
font-size: 20px;
|
||||||
|
color: var(--text-color);
|
||||||
|
padding: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.content > nav > a:hover {
|
||||||
|
background-color: var(--light-coloured-bg);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
color: var(--text-color);
|
||||||
|
background-color: var(--clear-bg);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article {
|
||||||
|
padding: 10px;
|
||||||
|
color: var(--text-color);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article.error, main > article.error > p {
|
||||||
|
padding: 10px;
|
||||||
|
color: var(--text-color);
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > h3 {
|
||||||
|
font-size: 30px;
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > p,
|
||||||
|
main > article > ul,
|
||||||
|
main > article > ol {
|
||||||
|
color: var(--text-color);
|
||||||
|
text-align: justify;
|
||||||
|
text-justify: distribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > img {
|
||||||
|
display:inline-block;
|
||||||
|
border-color: var(--mid-bg);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > p > a {
|
||||||
|
color: var(--coloured-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article > p > a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article.right > img {
|
||||||
|
float: right;
|
||||||
|
margin: 0 0 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > article.left > img {
|
||||||
|
float: left;
|
||||||
|
margin: 0 10px 0px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
height: 65px;
|
||||||
|
font-size: 34px;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: right;
|
||||||
|
color: var(--white);
|
||||||
|
background: var(--banner-logo);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 10px;
|
||||||
|
text-shadow: 0 0 1px var(--black);
|
||||||
|
border-bottom-color: var(--dark-border);
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-top-color: var(--white);
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
height: 35px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1em;
|
||||||
|
border-bottom-color: var(--white);
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-top-color: var(--dark-border);
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header, footer,
|
||||||
|
div.content > nav > a.selected {
|
||||||
|
background-color: var(--coloured-bg);
|
||||||
|
color: var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"], textarea, select, pre {
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
background-color: var(--white);
|
||||||
|
color: var(--text-color);
|
||||||
|
padding: 5px;
|
||||||
|
font-family: "Roboto Condensed";
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
border-color: var(--coloured-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input[type="button"], input[type="submit"] {
|
||||||
|
border-color: var(--dark-border);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
background-color: var(--coloured-bg);
|
||||||
|
color: var(--white);
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 5px;
|
||||||
|
font-family: "Roboto Condensed";
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover, input[type="button"]:hover, input[type="submit"]:hover {
|
||||||
|
background-color: var(--light-coloured-bg);
|
||||||
|
color: var(--text-color);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
input[type="image"] {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="image"]:hover {
|
||||||
|
background-color: var(--coloured-bg);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
12
tetawebapp/templates/error.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% extends "index.html" %}
|
||||||
|
{% block title %}Erreur{% endblock %}
|
||||||
|
{% block nav %}{% endblock %}
|
||||||
|
{% block main %}
|
||||||
|
<article class='error'>
|
||||||
|
<h3>404 - Not found</h3>
|
||||||
|
<img src='/static/images/404.png' alt='404 - Not found' title='404 - Not found'/>
|
||||||
|
<p>The page you asked for was not found on this server.<br/>
|
||||||
|
It may has been lost, it may has never existed.<br/>
|
||||||
|
May be we don't care at all...</p>
|
||||||
|
</article>
|
||||||
|
{% endblock %}
|
135
tetawebapp/templates/index.html
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang='zxx'>
|
||||||
|
<head>
|
||||||
|
<title>{% block title %}Accueil{% endblock %}</title>
|
||||||
|
<meta name="viewport" content="initial-scale=1.0" />
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/styles/colors.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/styles/fonts.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/styles/tetawebapp.css" />
|
||||||
|
<script type="text/javascript" src="/static/scripts/tetawebapp.js"></script>
|
||||||
|
</head>
|
||||||
|
{% block bodyheader %}
|
||||||
|
<body>
|
||||||
|
{% endblock %}
|
||||||
|
<header>{% block banner %}TetaWebApp{% endblock %}</header>
|
||||||
|
<div class='content'>
|
||||||
|
{% block nav %}
|
||||||
|
<nav>
|
||||||
|
{% block menu %}
|
||||||
|
{% for item in menu %}
|
||||||
|
{% if item[2] == 1 %}
|
||||||
|
<a class='selected' href='{{ item[1] }}'>{{ item[0] }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href='{{ item[1] }}'>{{ item[0] }}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
</nav>
|
||||||
|
{% endblock%}
|
||||||
|
<main>
|
||||||
|
{% block main %}
|
||||||
|
<article class='right'>
|
||||||
|
<h3>Le putain de titre</h3>
|
||||||
|
<img src='/static/images/dummy_pic.png' alt='dummy pic' title='dummy pic'/>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
|
||||||
|
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||||
|
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
|
||||||
|
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
|
||||||
|
officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||||
|
sed do eiusmod tempor incididunt ut labore
|
||||||
|
</p>
|
||||||
|
<p>This <a href='/plop.html'>link</a> may lead to an error page</p>
|
||||||
|
<p>
|
||||||
|
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||||
|
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
|
||||||
|
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
|
||||||
|
officia deserunt mollit anim id est laborum.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
|
||||||
|
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||||
|
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
|
||||||
|
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
|
||||||
|
officia deserunt mollit anim id est laborum.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
<article class='left'>
|
||||||
|
<h3>Le putain de titre 2</h3>
|
||||||
|
<img src='/static/images/dummy_pic.png' alt='dummy pic' title='dummy pic'/>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
|
||||||
|
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||||
|
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
|
||||||
|
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
|
||||||
|
officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||||
|
sed do eiusmod tempor incididunt ut labore
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||||
|
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
|
||||||
|
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
|
||||||
|
officia deserunt mollit anim id est laborum.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
|
||||||
|
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
||||||
|
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
|
||||||
|
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
|
||||||
|
officia deserunt mollit anim id est laborum.
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
<article>
|
||||||
|
<h3>Inputs demo</h3>
|
||||||
|
<ul>
|
||||||
|
<li>plop</li>
|
||||||
|
<li>plap</li>
|
||||||
|
<li>plip</li>
|
||||||
|
</ul>
|
||||||
|
<ol>
|
||||||
|
<li>plop</li>
|
||||||
|
<li>plap</li>
|
||||||
|
<li>plip</li>
|
||||||
|
</ol>
|
||||||
|
<input type='text'/>
|
||||||
|
<button>Click me</button>
|
||||||
|
<br/>
|
||||||
|
<textarea cols='25'></textarea>
|
||||||
|
<br/>
|
||||||
|
<select>
|
||||||
|
{% for item in menu %}
|
||||||
|
<option>{{ item[0] }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<input type='submit' value='Click me too'/>
|
||||||
|
<br/>
|
||||||
|
<input type='button' value='And me !' />
|
||||||
|
<br/>
|
||||||
|
<input type='image' value='' src='/static/images/add.png' title='add' alt='add'/>
|
||||||
|
<input type='image' value='' src='/static/images/edit.png' title='edit' alt='edit'/>
|
||||||
|
<input type='image' value='' src='/static/images/login.png' title='login' alt='login'/>
|
||||||
|
<input type='image' value='' src='/static/images/logout.png' title='logout' alt='logout'/>
|
||||||
|
<input type='image' value='' src='/static/images/refresh.png' title='refresh' alt='refresh'/>
|
||||||
|
<input type='image' value='' src='/static/images/save.png' title='save' alt='save'/>
|
||||||
|
<input type='image' value='' src='/static/images/search.png' title='search' alt='search'/>
|
||||||
|
<input type='image' value='' src='/static/images/trash.png' title='trash' alt='trash'/>
|
||||||
|
<br/>
|
||||||
|
<pre>
|
||||||
|
#!/bin/sh
|
||||||
|
# This is code sample
|
||||||
|
while [ 1 ]
|
||||||
|
do
|
||||||
|
echo "Tits or GTFO !"
|
||||||
|
sleep .1
|
||||||
|
done
|
||||||
|
</pre>
|
||||||
|
</article>
|
||||||
|
{% endblock %}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
{% block footer %}
|
||||||
|
<footer>© - Tetalab - Le hacker space Toulousaing' putaing' cong' -</footer>
|
||||||
|
{% endblock%}
|
||||||
|
</body>
|
||||||
|
</html>
|
56
tetawebapp/tetawebapp.py
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8
|
||||||
|
|
||||||
|
# Required modules
|
||||||
|
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
# Optionnal modules
|
||||||
|
import psycopg2
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# App settings
|
||||||
|
########################################################################
|
||||||
|
app = Flask(__name__)
|
||||||
|
# Path to static files
|
||||||
|
app.static_url_path='/static'
|
||||||
|
# Set debug mode to False for production
|
||||||
|
app.debug = True
|
||||||
|
# Various configuration settings belong here (optionnal)
|
||||||
|
app.config.from_pyfile('config.local.py')
|
||||||
|
# Generate a new key: head -n 40 /dev/urandom | md5sum | cut -d' ' -f1
|
||||||
|
app.secret_key = 'ce1d1c9ff0ff388a838b3a1e3207dd27'
|
||||||
|
# Feel free to use SQLAlchemy (or not)
|
||||||
|
db = SQLAlchemy(app)
|
||||||
|
|
||||||
|
app.menu = [('accueil', '/plap.html', 0),
|
||||||
|
('Motherfuckisme', '/plap.html', 1 ),
|
||||||
|
('We make porn', '/plap.html', 0 ),
|
||||||
|
('mes couilles sur la comode3', '/plap.html', 0 ),
|
||||||
|
('mes couilles sur la comode4', '/plap.html', 0 ),
|
||||||
|
('mes couilles sur la comode5', '/plap.html', 0 ),
|
||||||
|
('mes couilles sur la comode6', '/plap.html', 0 ),
|
||||||
|
('mes couilles sur la comode7', '/plap.html', 0 )
|
||||||
|
]
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Routes
|
||||||
|
########################################################################
|
||||||
|
@app.errorhandler(404)
|
||||||
|
def page_not_found(e):
|
||||||
|
""" 404 not found """
|
||||||
|
return render_template('error.html', menu=app.menu), 404
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/", methods=['GET', 'POST'])
|
||||||
|
def index():
|
||||||
|
return render_template('index.html', menu=app.menu)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Main
|
||||||
|
########################################################################
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0')
|