"Initial commit"
This commit is contained in:
commit
33131ed07b
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*un~
|
||||
*.swp
|
||||
*.pyc
|
||||
config.tetalab.py
|
||||
|
2
config.local.py
Normal file
2
config.local.py
Normal file
@ -0,0 +1,2 @@
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||
SQLALCHEMY_DATABASE_URI = "postgresql://tetalab_user:tetalab@localhost/tetalab_stock"
|
3
ref.tetalab.org.wsgi
Normal file
3
ref.tetalab.org.wsgi
Normal file
@ -0,0 +1,3 @@
|
||||
import sys
|
||||
sys.path.insert(0, '/var/www/stock.tetalab.org')
|
||||
from stock_tetalab import app as application
|
BIN
static/images/404.jpg
Normal file
BIN
static/images/404.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
static/images/logo_tetalab.png
Normal file
BIN
static/images/logo_tetalab.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
static/images/working.jpg
Normal file
BIN
static/images/working.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
BIN
static/images/working.xcf
Normal file
BIN
static/images/working.xcf
Normal file
Binary file not shown.
0
static/scripts/tetalab.js
Normal file
0
static/scripts/tetalab.js
Normal file
224
static/style/style.css
Normal file
224
static/style/style.css
Normal file
@ -0,0 +1,224 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
background-color: #2B2B2B;
|
||||
}
|
||||
|
||||
div.main_wrapper {
|
||||
width: 1280px;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.center {
|
||||
width: auto;
|
||||
background-color: #E5E5E5;
|
||||
height: auto;
|
||||
border-style: solid;
|
||||
border-color: #AAAAAA;
|
||||
border-width: 1px 0 1px 0;
|
||||
}
|
||||
|
||||
div.banner {
|
||||
background: url(../images/logo_tetalab.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 10px -2px;
|
||||
background-color: #FF5D00;
|
||||
color: #FFFFFF;
|
||||
font-size: 24px;
|
||||
padding: 10px;
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
height: 40px;
|
||||
text-shadow: 0 0 1px #000000;
|
||||
}
|
||||
|
||||
div.top_menu {
|
||||
background-color: #BBBBBB;
|
||||
height: 30px;
|
||||
text-align: right;
|
||||
line-height: 30px;
|
||||
border-style: solid;
|
||||
border-color: #888888;
|
||||
border-width: 1px 0 0 0;
|
||||
}
|
||||
|
||||
span.top_menu_item {
|
||||
margin: 5px 2px 0 0;
|
||||
font-size: 12px;
|
||||
background-color: #F0ECE0;
|
||||
padding: 1px 5px 1px 5px;
|
||||
border-radius: 4px;
|
||||
border-style: solid;
|
||||
border-color: #888888;
|
||||
border-width: 1px;
|
||||
font-weight: bold;
|
||||
color: #FF5D00;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
span.top_menu_item_selected {
|
||||
margin: 5px 2px 0 0;
|
||||
font-size: 12px;
|
||||
background-color: #FF5D00;
|
||||
padding: 1px 5px 1px 5px;
|
||||
border-radius: 4px;
|
||||
border-style: solid;
|
||||
border-color: #888888;
|
||||
border-width: 1px;
|
||||
font-weight: bold;
|
||||
color: #F0ECE0;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
span.top_menu_item:hover, span.top_menu_item_selected:hover {
|
||||
background-color: #FFB387;
|
||||
color: #555555;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.content_wrapper {
|
||||
height: 497px;
|
||||
width: 1280px;
|
||||
}
|
||||
|
||||
div.left_menu {
|
||||
background-color: #E5E5E5;
|
||||
border-style: solid;
|
||||
border-color: #AAAAAA;
|
||||
border-width: 1px 1px 1px 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
width: 249px;
|
||||
height: 495px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
div.left_menu_item, div.left_menu_item_selected {
|
||||
background-color: #E5E5E5;
|
||||
width: 229px;
|
||||
height: 40px;
|
||||
overflow-y: hidden;
|
||||
border-style: solid;
|
||||
border-color: #AAAAAA;
|
||||
border-width: 0 0 1px 0;
|
||||
padding: 10px;
|
||||
line-height: 50px;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
div.left_menu_item:hover, div.left_menu_item_selected:hover {
|
||||
background-color: #FFB387;
|
||||
color: #555555;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.left_menu_item_selected {
|
||||
color: #F0ECE0;
|
||||
background-color: #FF5D00;
|
||||
|
||||
}
|
||||
|
||||
|
||||
div.content {
|
||||
position: absolute;
|
||||
top: 102px;
|
||||
left: 260px;
|
||||
width: 1010px;
|
||||
height: 475px;
|
||||
background-color: #E5E5E5;
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
border-style: solid;
|
||||
border-color: #AAAAAA;
|
||||
border-width: 1px 0 1px 0;
|
||||
color: #555555;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
div.git_desc, pre {
|
||||
border-style: solid;
|
||||
border-color: #FF5D00;
|
||||
border-width: 1px;
|
||||
background-color: #FFFFFF;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.git_desc {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
div.error {
|
||||
background: url(../images/404.jpg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-color: #000000;
|
||||
height: 476px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
font-size: 70px;
|
||||
font-weight: bold;
|
||||
color: #FF5D00;
|
||||
}
|
||||
|
||||
div.wip {
|
||||
background: url(../images/working.jpg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-color: #000000;
|
||||
height: 476px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
font-size: 70px;
|
||||
font-weight: bold;
|
||||
color: #FF5D00;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
background-color: #FF5D00;
|
||||
font-size: 10px;
|
||||
color: #2B2B2B;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/* ***********************************
|
||||
* Classes génériques
|
||||
*********************************** */
|
||||
|
||||
h3, h4 {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #FF5D00;
|
||||
text-decoration: none;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: #FFB387;
|
||||
}
|
||||
|
||||
span.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #FFB387;
|
||||
}
|
||||
|
||||
th, td {
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
tr:nth-child(even){background-color: #f2f2f2}
|
43
stock.sql
Normal file
43
stock.sql
Normal file
@ -0,0 +1,43 @@
|
||||
CREATE TABLE Stock_users (
|
||||
id serial primary key,
|
||||
mail text not NULL,
|
||||
password text not NULL,
|
||||
name text not NULL
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE Stock_kits (
|
||||
id serial primary key,
|
||||
name text not NULL,
|
||||
description text not NULL
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE Stock_providers (
|
||||
id serial primary key,
|
||||
address text not NULL,
|
||||
mail text not NULL,
|
||||
url text not NULL,
|
||||
comment text not NULL
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE Stock_componants (
|
||||
id serial primary key,
|
||||
name text not NULL,
|
||||
description text not NULL,
|
||||
last_price NUMERIC not NULL,
|
||||
mean_price NUMERIC not NULL,
|
||||
quantity NUMERIC not NULL,
|
||||
min_quantity NUMERIC not NULL,
|
||||
place text not NULL,
|
||||
provider_id integer REFERENCES Stock_providers(id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE Stock_kit_compositions (
|
||||
id serial primary key,
|
||||
kit_id integer REFERENCES Stock_kits(id),
|
||||
componant_id integer REFERENCES Stock_componants(id),
|
||||
quantity integer not NULL
|
||||
);
|
164
stock_tetalab.py
Executable file
164
stock_tetalab.py
Executable file
@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8
|
||||
|
||||
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_pyfile('config.py')
|
||||
app.secret_key = app.config.get('446307a5f61c2bb810436b2ee0f903f2')
|
||||
app.debug = True
|
||||
app.static_url_path='/static'
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
class Stock_users(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
mail = db.Column(db.Text, nullable=False)
|
||||
password = db.Column(db.Text, nullable=False)
|
||||
name = db.Column(db.Text, nullable=False)
|
||||
|
||||
class Stock_componants(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.Text, nullable=False)
|
||||
description = db.Column(db.Text, nullable=False)
|
||||
last_price = db.Column(db.Float)
|
||||
mean_price = db.Column(db.Float)
|
||||
quantity = db.Column(db.Integer)
|
||||
min_quantity = db.Column(db.Integer)
|
||||
place = db.Column(db.Text, nullable=False)
|
||||
provider_id = db.Column(db.Integer, nullable=False)
|
||||
|
||||
class Stock_providers(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.Text, nullable=False)
|
||||
postal_address = db.Column(db.Text)
|
||||
url = db.Column(db.Text)
|
||||
comment = db.Column(db.Text)
|
||||
|
||||
class Stock_kits(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.Text, nullable=False)
|
||||
description = db.Column(db.Text, nullable=False)
|
||||
|
||||
class Stock_kit_compositions(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
kit_id = db.Column(db.Integer, db.ForeignKey('Stock_kits.id'), nullable=False)
|
||||
component_id = db.Column(db.Integer, db.ForeignKey('Stock_componants.id'), nullable=False)
|
||||
component_quantity = db.Column(db.Integer, nullable=False)
|
||||
|
||||
@app.errorhandler(404)
|
||||
def page_not_found(e):
|
||||
return render_template('error.html'), 404
|
||||
|
||||
@app.route("/")
|
||||
def authenticate():
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
########################################################################
|
||||
# Componants
|
||||
########################################################################
|
||||
@app.route('/componants')
|
||||
def get_componants():
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/componants/<componant_id>')
|
||||
def get_componant(componant_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/componants/add/<componant_id>')
|
||||
def add_componant(componant_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/componants/edit/<componant_id>')
|
||||
def edit_componant(componant_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/componants/delete/<componant_id>')
|
||||
def delete_componant(componant_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
########################################################################
|
||||
# Kits
|
||||
########################################################################
|
||||
@app.route('/kits')
|
||||
def get_kits():
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/kits/<kit_id>')
|
||||
def get_kit(kit_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/kits/add/<kit_id>')
|
||||
def add_kit(kit_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/kits/edit/<kit_id>')
|
||||
def edit_kit(kit_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/kits/delete/<kit_id>')
|
||||
def delete_kit(kit_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
########################################################################
|
||||
# Providers
|
||||
########################################################################
|
||||
@app.route('/providers')
|
||||
def get_providers():
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/providers/<provider_id>')
|
||||
def get_provider(provider_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/providers/add/<provider_id>')
|
||||
def add_provider(provider_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/providers/edit/<provider_id>')
|
||||
def edit_provider(provider_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/providers/delete/<provider_id>')
|
||||
def delete_provider(provider_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
########################################################################
|
||||
# Users
|
||||
########################################################################
|
||||
@app.route('/users')
|
||||
def get_users():
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/users/<user_id>')
|
||||
def get_user(user_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/users/add/<user_id>')
|
||||
def add_user(user_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/users/edit/<user_id>')
|
||||
def edit_user(user_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
@app.route('/users/delete/<user_id>')
|
||||
def delete_user(user_id):
|
||||
return render_template('wip.html')
|
||||
|
||||
|
||||
##############################################
|
||||
|
||||
def get_distinct(query):
|
||||
results = []
|
||||
for result in query:
|
||||
result = result[0]
|
||||
if result not in results:
|
||||
results.append(result)
|
||||
return results
|
||||
|
||||
# Main #######################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
30
templates/error.html
Normal file
30
templates/error.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
|
||||
<head>
|
||||
<title>Référentiel Infrastructure Tetalab - {% block title %}How The Fuck{% 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/style/style.css" />
|
||||
<script type="text/javascript" src="/static/scripts/tetalab.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class='main_wrapper'>
|
||||
<div class='center'>
|
||||
<div class='banner' title='Référentiel infrastrusture Tetalab'>
|
||||
Référentiel Infrastructure Tetalab
|
||||
</div>
|
||||
<div class='top_menu'>
|
||||
<span class='top_menu_item' onclick='javascript:document.location="/";'>Retour</span>
|
||||
</div>
|
||||
<div class='content_wrapper'>
|
||||
<div class='error'>
|
||||
404
|
||||
</div>
|
||||
</div>
|
||||
<div class='footer'>
|
||||
Tetalab - Le Hacker Space Toulousain Putaing' Cong' -
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
56
templates/index.html
Normal file
56
templates/index.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy for HTML5 for Linux version 5.5.21" />
|
||||
<title>Stock Tetalab - {% 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/style/style.css" />
|
||||
<script type="text/javascript" src="/static/scripts/tetalab.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class='main_wrapper'>
|
||||
<div class='center'>
|
||||
<div class='banner' title='Stock Tetalab'>
|
||||
Stock Tetalab
|
||||
</div>
|
||||
<div class='top_menu'>
|
||||
{% block top_menu %} <span class='top_menu_item_selected' onclick='javascript:document.location="./";'>Accueil</span> {% endblock %}
|
||||
</div>
|
||||
<div class='content_wrapper'>
|
||||
<div class='left_menu'>
|
||||
{% block left_menu %}
|
||||
<div class='left_menu_item_selected' onclick='javascript:document.location="/";'>
|
||||
Accueil
|
||||
</div>
|
||||
<div class='left_menu_item' onclick='javascript:document.location="/componants";'>
|
||||
Composants
|
||||
</div>
|
||||
<div class='left_menu_item' onclick='javascript:document.location="/kits";'>
|
||||
Kits
|
||||
</div>
|
||||
<div class='left_menu_item' onclick='javascript:document.location="/providers";'>
|
||||
Fournisseurs
|
||||
</div>{% endblock %}
|
||||
</div>
|
||||
<div class='content'>
|
||||
{% block content %}
|
||||
<h1>Gestion du stock</h1>
|
||||
<p>Ceci est l'outil de gestion de stock du <a href='https://www.tetalab.org'>Tetalab</a>.</p>
|
||||
<p>Cet outil vous permet:
|
||||
<ul>
|
||||
<li>De gérer la liste des composants électroniques en possession du Tetalab</li>
|
||||
<li>De gérer la liste des fournisseurs de composants</li>
|
||||
<li>De gérer la liste des kits de montage</li>
|
||||
</ul>
|
||||
</p>
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
<div class='footer'>
|
||||
Tetalab - Le Hacker Space Toulousaing' Putaing' Cong' -
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
30
templates/wip.html
Normal file
30
templates/wip.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
|
||||
<head>
|
||||
<title>Référentiel Infrastructure Tetalab - {% block title %}How The Fuck{% 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/style/style.css" />
|
||||
<script type="text/javascript" src="/static/scripts/tetalab.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class='main_wrapper'>
|
||||
<div class='center'>
|
||||
<div class='banner' title='Référentiel infrastrusture Tetalab'>
|
||||
Référentiel Infrastructure Tetalab
|
||||
</div>
|
||||
<div class='top_menu'>
|
||||
<span class='top_menu_item' onclick='javascript:document.location="/";'>Retour</span>
|
||||
</div>
|
||||
<div class='content_wrapper'>
|
||||
<div class='wip'>
|
||||
Work In Progress
|
||||
</div>
|
||||
</div>
|
||||
<div class='footer'>
|
||||
Tetalab - Le Hacker Space Toulousain Putaing' Cong' -
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user