Browse Source

"Initial commit"

Doug Le Tough 2 years ago
commit
33131ed07b

+ 5
- 0
.gitignore View File

@@ -0,0 +1,5 @@
1
+*un~
2
+*.swp
3
+*.pyc
4
+config.tetalab.py
5
+

+ 2
- 0
config.local.py View File

@@ -0,0 +1,2 @@
1
+SQLALCHEMY_TRACK_MODIFICATIONS = True
2
+SQLALCHEMY_DATABASE_URI = "postgresql://tetalab_user:tetalab@localhost/tetalab_stock"

+ 1
- 0
config.py View File

@@ -0,0 +1 @@
1
+config.local.py

+ 3
- 0
ref.tetalab.org.wsgi View File

@@ -0,0 +1,3 @@
1
+import sys
2
+sys.path.insert(0, '/var/www/stock.tetalab.org')
3
+from stock_tetalab import app as application

BIN
static/images/404.jpg View File


BIN
static/images/logo_tetalab.png View File


BIN
static/images/working.jpg View File


BIN
static/images/working.xcf View File


+ 0
- 0
static/scripts/tetalab.js View File


+ 224
- 0
static/style/style.css View File

@@ -0,0 +1,224 @@
1
+body {
2
+  font-family: sans-serif;
3
+  background-color: #2B2B2B;
4
+}
5
+
6
+div.main_wrapper {
7
+    width: 1280px;
8
+    height: auto;
9
+    margin: 0 auto;
10
+    padding: 10px;
11
+    position: relative;
12
+}
13
+
14
+div.center {
15
+  width: auto;
16
+  background-color: #E5E5E5;
17
+  height: auto;
18
+  border-style: solid;
19
+  border-color: #AAAAAA;
20
+  border-width: 1px 0 1px 0;
21
+}
22
+
23
+div.banner {
24
+  background: url(../images/logo_tetalab.png);
25
+  background-repeat: no-repeat;
26
+  background-position: 10px -2px;
27
+  background-color: #FF5D00;
28
+  color: #FFFFFF;
29
+  font-size: 24px;
30
+  padding: 10px;
31
+  text-align: right;
32
+  font-weight: bold;
33
+  height: 40px;
34
+  text-shadow: 0 0 1px #000000;
35
+}
36
+
37
+div.top_menu {
38
+  background-color: #BBBBBB;
39
+  height: 30px;
40
+  text-align: right;
41
+  line-height: 30px;
42
+  border-style: solid;
43
+  border-color: #888888;
44
+  border-width: 1px 0 0 0;
45
+}
46
+
47
+span.top_menu_item {
48
+  margin: 5px 2px 0 0;
49
+  font-size: 12px;
50
+  background-color: #F0ECE0;
51
+  padding: 1px 5px 1px 5px;
52
+  border-radius: 4px;
53
+  border-style: solid;
54
+  border-color: #888888;
55
+  border-width: 1px;
56
+  font-weight: bold;
57
+  color: #FF5D00;
58
+  line-height: 30px;
59
+}
60
+
61
+span.top_menu_item_selected {
62
+  margin: 5px 2px 0 0;
63
+  font-size: 12px;
64
+  background-color: #FF5D00;
65
+  padding: 1px 5px 1px 5px;
66
+  border-radius: 4px;
67
+  border-style: solid;
68
+  border-color: #888888;
69
+  border-width: 1px;
70
+  font-weight: bold;
71
+  color: #F0ECE0;
72
+  line-height: 30px;
73
+}
74
+
75
+span.top_menu_item:hover, span.top_menu_item_selected:hover {
76
+  background-color: #FFB387;
77
+  color: #555555;
78
+  cursor: pointer;
79
+}
80
+
81
+div.content_wrapper {
82
+  height: 497px;
83
+  width: 1280px;
84
+}
85
+
86
+div.left_menu {
87
+  background-color: #E5E5E5;
88
+  border-style: solid;
89
+  border-color: #AAAAAA;
90
+  border-width: 1px 1px 1px 0;
91
+  overflow-y: auto;
92
+  overflow-x: hidden;
93
+  width: 249px;
94
+  height: 495px;
95
+  line-height: 50px;
96
+}
97
+
98
+div.left_menu_item, div.left_menu_item_selected {
99
+  background-color: #E5E5E5;
100
+  width: 229px;
101
+  height: 40px;
102
+  overflow-y: hidden;
103
+  border-style: solid;
104
+  border-color: #AAAAAA;
105
+  border-width: 0 0 1px 0;
106
+  padding: 10px;
107
+  line-height: 50px;
108
+  font-weight: bold;
109
+  font-size: 20px;
110
+  color: #555555;
111
+}
112
+
113
+div.left_menu_item:hover, div.left_menu_item_selected:hover {
114
+  background-color: #FFB387;
115
+  color: #555555;
116
+  cursor: pointer;
117
+}
118
+
119
+div.left_menu_item_selected {
120
+  color: #F0ECE0;
121
+  background-color: #FF5D00;
122
+  
123
+}
124
+
125
+
126
+div.content {
127
+  position: absolute;
128
+  top: 102px;
129
+  left: 260px;
130
+  width: 1010px;
131
+  height: 475px;
132
+  background-color: #E5E5E5;
133
+  overflow-y: auto;
134
+  padding: 10px;
135
+  border-style: solid;
136
+  border-color: #AAAAAA;
137
+  border-width: 1px 0 1px 0;
138
+  color: #555555;
139
+  text-align: justify;
140
+}
141
+
142
+div.git_desc, pre {
143
+  border-style: solid;
144
+  border-color: #FF5D00;
145
+  border-width: 1px;
146
+  background-color: #FFFFFF;
147
+  padding: 5px;
148
+}
149
+
150
+div.git_desc {
151
+  text-align: justify;
152
+}
153
+
154
+div.error {
155
+  background: url(../images/404.jpg);
156
+  background-repeat: no-repeat;
157
+  background-position: center center;
158
+  background-color: #000000;
159
+  height: 476px;
160
+  padding: 10px;
161
+  text-align: center;
162
+  font-size: 70px;
163
+  font-weight: bold;
164
+  color: #FF5D00;
165
+}
166
+
167
+div.wip {
168
+  background: url(../images/working.jpg);
169
+  background-repeat: no-repeat;
170
+  background-position: center center;
171
+  background-color: #000000;
172
+  height: 476px;
173
+  padding: 10px;
174
+  text-align: center;
175
+  font-size: 70px;
176
+  font-weight: bold;
177
+  color: #FF5D00;
178
+}
179
+
180
+div.footer {
181
+  background-color: #FF5D00;
182
+  font-size: 10px;
183
+  color: #2B2B2B;
184
+  text-align: center;
185
+}
186
+
187
+
188
+/* ***********************************
189
+ *  Classes génériques
190
+*********************************** */
191
+
192
+h3, h4 {
193
+  text-decoration: underline;
194
+}
195
+
196
+a {
197
+  color: #FF5D00;
198
+  text-decoration: none;
199
+  padding: 2px;
200
+}
201
+
202
+a:hover {
203
+  background-color: #FFB387;
204
+}
205
+
206
+span.bold {
207
+  font-weight: bold;
208
+}
209
+
210
+table {
211
+    border-collapse: collapse;
212
+    width: 100%;
213
+}
214
+
215
+th {
216
+  background-color: #FFB387;
217
+}
218
+
219
+th, td {
220
+    text-align: left;
221
+    padding: 8px;
222
+}
223
+
224
+tr:nth-child(even){background-color: #f2f2f2}

+ 43
- 0
stock.sql View File

@@ -0,0 +1,43 @@
1
+CREATE TABLE Stock_users (
2
+  id serial primary key,
3
+  mail text not NULL,
4
+  password text not NULL,
5
+  name text not NULL
6
+);
7
+
8
+
9
+CREATE TABLE Stock_kits (
10
+  id serial primary key,
11
+  name text not NULL,
12
+  description text not NULL
13
+);
14
+
15
+
16
+CREATE TABLE Stock_providers (
17
+  id serial primary key,
18
+  address text not NULL,
19
+  mail text not NULL,
20
+  url text not NULL,
21
+  comment text not NULL
22
+);
23
+
24
+
25
+CREATE TABLE Stock_componants (
26
+  id serial primary key,
27
+  name text not NULL,
28
+  description text not NULL,
29
+  last_price NUMERIC not NULL,
30
+  mean_price NUMERIC not NULL,
31
+  quantity NUMERIC not NULL,
32
+  min_quantity NUMERIC not NULL,
33
+  place text not NULL,
34
+  provider_id integer REFERENCES Stock_providers(id)
35
+);
36
+
37
+
38
+CREATE TABLE Stock_kit_compositions (
39
+  id serial primary key,
40
+  kit_id integer REFERENCES Stock_kits(id),
41
+  componant_id integer REFERENCES Stock_componants(id),
42
+  quantity integer not NULL
43
+);

+ 164
- 0
stock_tetalab.py View File

@@ -0,0 +1,164 @@
1
+#!/usr/bin/env python
2
+# -*- coding: utf-8
3
+
4
+from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
5
+from flask_sqlalchemy import SQLAlchemy
6
+
7
+app = Flask(__name__)
8
+app.config.from_pyfile('config.py')
9
+app.secret_key = app.config.get('446307a5f61c2bb810436b2ee0f903f2')
10
+app.debug = True
11
+app.static_url_path='/static'
12
+db = SQLAlchemy(app)
13
+
14
+class Stock_users(db.Model):
15
+  id = db.Column(db.Integer, primary_key=True)
16
+  mail = db.Column(db.Text, nullable=False)
17
+  password = db.Column(db.Text, nullable=False)
18
+  name = db.Column(db.Text, nullable=False)
19
+
20
+class Stock_componants(db.Model):
21
+  id = db.Column(db.Integer, primary_key=True)
22
+  name = db.Column(db.Text, nullable=False)
23
+  description = db.Column(db.Text, nullable=False)
24
+  last_price = db.Column(db.Float)
25
+  mean_price = db.Column(db.Float)
26
+  quantity = db.Column(db.Integer)
27
+  min_quantity = db.Column(db.Integer)
28
+  place = db.Column(db.Text, nullable=False)
29
+  provider_id = db.Column(db.Integer, nullable=False)
30
+
31
+class Stock_providers(db.Model):
32
+  id = db.Column(db.Integer, primary_key=True)
33
+  name = db.Column(db.Text, nullable=False)
34
+  postal_address = db.Column(db.Text)
35
+  url = db.Column(db.Text)
36
+  comment = db.Column(db.Text)
37
+
38
+class Stock_kits(db.Model):
39
+  id = db.Column(db.Integer, primary_key=True)
40
+  name = db.Column(db.Text, nullable=False)
41
+  description = db.Column(db.Text, nullable=False)
42
+
43
+class Stock_kit_compositions(db.Model):
44
+  id = db.Column(db.Integer, primary_key=True)
45
+  kit_id = db.Column(db.Integer, db.ForeignKey('Stock_kits.id'), nullable=False)
46
+  component_id = db.Column(db.Integer, db.ForeignKey('Stock_componants.id'), nullable=False)
47
+  component_quantity = db.Column(db.Integer, nullable=False)
48
+
49
+@app.errorhandler(404)
50
+def page_not_found(e):
51
+    return render_template('error.html'), 404
52
+
53
+@app.route("/")
54
+def authenticate():
55
+  return render_template('index.html')
56
+
57
+
58
+########################################################################
59
+# Componants
60
+########################################################################
61
+@app.route('/componants')
62
+def get_componants():
63
+  return render_template('wip.html')
64
+
65
+@app.route('/componants/<componant_id>')
66
+def get_componant(componant_id):
67
+  return render_template('wip.html')
68
+
69
+@app.route('/componants/add/<componant_id>')
70
+def add_componant(componant_id):
71
+  return render_template('wip.html')
72
+
73
+@app.route('/componants/edit/<componant_id>')
74
+def edit_componant(componant_id):
75
+  return render_template('wip.html')
76
+
77
+@app.route('/componants/delete/<componant_id>')
78
+def delete_componant(componant_id):
79
+  return render_template('wip.html')
80
+
81
+########################################################################
82
+# Kits
83
+########################################################################
84
+@app.route('/kits')
85
+def get_kits():
86
+  return render_template('wip.html')
87
+
88
+@app.route('/kits/<kit_id>')
89
+def get_kit(kit_id):
90
+  return render_template('wip.html')
91
+
92
+@app.route('/kits/add/<kit_id>')
93
+def add_kit(kit_id):
94
+  return render_template('wip.html')
95
+
96
+@app.route('/kits/edit/<kit_id>')
97
+def edit_kit(kit_id):
98
+  return render_template('wip.html')
99
+
100
+@app.route('/kits/delete/<kit_id>')
101
+def delete_kit(kit_id):
102
+  return render_template('wip.html')
103
+
104
+########################################################################
105
+# Providers
106
+########################################################################
107
+@app.route('/providers')
108
+def get_providers():
109
+  return render_template('wip.html')
110
+
111
+@app.route('/providers/<provider_id>')
112
+def get_provider(provider_id):
113
+  return render_template('wip.html')
114
+
115
+@app.route('/providers/add/<provider_id>')
116
+def add_provider(provider_id):
117
+  return render_template('wip.html')
118
+
119
+@app.route('/providers/edit/<provider_id>')
120
+def edit_provider(provider_id):
121
+  return render_template('wip.html')
122
+
123
+@app.route('/providers/delete/<provider_id>')
124
+def delete_provider(provider_id):
125
+  return render_template('wip.html')
126
+
127
+########################################################################
128
+# Users
129
+########################################################################
130
+@app.route('/users')
131
+def get_users():
132
+  return render_template('wip.html')
133
+
134
+@app.route('/users/<user_id>')
135
+def get_user(user_id):
136
+  return render_template('wip.html')
137
+
138
+@app.route('/users/add/<user_id>')
139
+def add_user(user_id):
140
+  return render_template('wip.html')
141
+
142
+@app.route('/users/edit/<user_id>')
143
+def edit_user(user_id):
144
+  return render_template('wip.html')
145
+
146
+@app.route('/users/delete/<user_id>')
147
+def delete_user(user_id):
148
+  return render_template('wip.html')
149
+
150
+
151
+##############################################
152
+
153
+def get_distinct(query):
154
+  results = []
155
+  for result in query:
156
+    result = result[0]
157
+    if result not in results:
158
+      results.append(result)
159
+  return results
160
+
161
+# Main #######################################
162
+
163
+if __name__ == '__main__':
164
+  app.run()

+ 30
- 0
templates/error.html View File

@@ -0,0 +1,30 @@
1
+<!DOCTYPE html>                                                                                                                                                           
2
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
3
+  <head>
4
+    <title>Référentiel Infrastructure Tetalab - {% block title %}How The Fuck{% endblock %}</title>
5
+    <meta name="viewport" content="initial-scale=1.0">
6
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
7
+    <link rel="stylesheet" type="text/css" href="/static/style/style.css" />
8
+    <script type="text/javascript" src="/static/scripts/tetalab.js"></script>
9
+  </head>
10
+  <body>
11
+    <div class='main_wrapper'>
12
+      <div class='center'>
13
+        <div class='banner' title='Référentiel infrastrusture Tetalab'>
14
+          Référentiel Infrastructure Tetalab
15
+        </div>
16
+        <div class='top_menu'>
17
+          <span class='top_menu_item' onclick='javascript:document.location="/";'>Retour</span>
18
+        </div>
19
+        <div class='content_wrapper'>
20
+          <div class='error'>
21
+            404
22
+          </div>
23
+        </div>
24
+        <div class='footer'>
25
+          Tetalab - Le Hacker Space Toulousain Putaing' Cong' -
26
+        </div>
27
+      </div>
28
+    </div>
29
+  </body>
30
+</html>

+ 56
- 0
templates/index.html View File

@@ -0,0 +1,56 @@
1
+<!DOCTYPE html>
2
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
3
+<head>
4
+  <meta name="generator" content="HTML Tidy for HTML5 for Linux version 5.5.21" />
5
+  <title>Stock Tetalab - {% block title %}Accueil{% endblock %}</title>
6
+  <meta name="viewport" content="initial-scale=1.0" />
7
+  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
8
+  <link rel="stylesheet" type="text/css" href="/static/style/style.css" />
9
+  <script type="text/javascript" src="/static/scripts/tetalab.js"></script>
10
+</head>
11
+<body>
12
+  <div class='main_wrapper'>
13
+    <div class='center'>
14
+      <div class='banner' title='Stock Tetalab'>
15
+        Stock Tetalab
16
+      </div>
17
+      <div class='top_menu'>
18
+        {% block top_menu %} <span class='top_menu_item_selected' onclick='javascript:document.location="./";'>Accueil</span> {% endblock %}
19
+      </div>
20
+      <div class='content_wrapper'>
21
+        <div class='left_menu'>
22
+          {% block left_menu %}
23
+          <div class='left_menu_item_selected' onclick='javascript:document.location="/";'>
24
+            Accueil
25
+          </div>
26
+          <div class='left_menu_item' onclick='javascript:document.location="/componants";'>
27
+            Composants
28
+          </div>
29
+          <div class='left_menu_item' onclick='javascript:document.location="/kits";'>
30
+            Kits
31
+          </div>
32
+          <div class='left_menu_item' onclick='javascript:document.location="/providers";'>
33
+            Fournisseurs
34
+          </div>{% endblock %}
35
+        </div>
36
+        <div class='content'>
37
+          {% block content %}
38
+          <h1>Gestion du stock</h1>
39
+          <p>Ceci est l'outil de gestion de stock du <a href='https://www.tetalab.org'>Tetalab</a>.</p>
40
+          <p>Cet outil vous permet:
41
+            <ul>
42
+              <li>De gérer la liste des composants électroniques en possession du Tetalab</li>
43
+              <li>De gérer la liste des fournisseurs de composants</li>
44
+              <li>De gérer la liste des kits de montage</li>
45
+            </ul>
46
+          </p>
47
+          {% endblock %}
48
+        </div>
49
+      </div>
50
+      <div class='footer'>
51
+        Tetalab - Le Hacker Space Toulousaing' Putaing' Cong' -
52
+      </div>
53
+    </div>
54
+  </div>
55
+</body>
56
+</html>

+ 30
- 0
templates/wip.html View File

@@ -0,0 +1,30 @@
1
+<!DOCTYPE html>                                                                                                                                                           
2
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr">
3
+  <head>
4
+    <title>Référentiel Infrastructure Tetalab - {% block title %}How The Fuck{% endblock %}</title>
5
+    <meta name="viewport" content="initial-scale=1.0">
6
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
7
+    <link rel="stylesheet" type="text/css" href="/static/style/style.css" />
8
+    <script type="text/javascript" src="/static/scripts/tetalab.js"></script>
9
+  </head>
10
+  <body>
11
+    <div class='main_wrapper'>
12
+      <div class='center'>
13
+        <div class='banner' title='Référentiel infrastrusture Tetalab'>
14
+          Référentiel Infrastructure Tetalab
15
+        </div>
16
+        <div class='top_menu'>
17
+          <span class='top_menu_item' onclick='javascript:document.location="/";'>Retour</span>
18
+        </div>
19
+        <div class='content_wrapper'>
20
+          <div class='wip'>
21
+            Work In Progress
22
+          </div>
23
+        </div>
24
+        <div class='footer'>
25
+          Tetalab - Le Hacker Space Toulousain Putaing' Cong' -
26
+        </div>
27
+      </div>
28
+    </div>
29
+  </body>
30
+</html>

Loading…
Cancel
Save