-
Notifications
You must be signed in to change notification settings - Fork 1
/
CodeGuide.txt
289 lines (230 loc) · 8.88 KB
/
CodeGuide.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
This website is made up of six sqlalchemy tables:
-User
+Id
+email
+password_hash
+factors
+ratings
+results
-PasswordRecovery
+email
+verificationCode
-Participant
+Id
+f_name: First Name
+l_name: Last Name
+email
+telephone
+user_id
+user
-Factors
+Id
+title
+description
+votes
+user_id
+user
-Rating
+Id
+factor_leading: Leading Factor
+factor_following:Following Factor
+rating
+user_id
+user
-Result
+ID
+factor_leading:Leading Factor
+factor_following: Factor Following
+rating
+user_id
+user
Note: These tables have been created on Alchemy.py.
Note: Any changes to this table may require deleting the database cache for the database to be updated. The cache is called "data.sqlite3"
--------------------------------#Database_access.py#----------------------------------------
All functions related to querying from these tables are located in the python file "database_access.py".
This is done by creating a function which returns what you need
Example Query:
rating_count=__DATABASE_CONNECTION.query(RatingsTBL).all()
Example Function:
def get_rating_by_id(user_id):
"""
Retrieves ratings associated with a specific user.
Args:
user_id: Identifier of the user.
Returns:
List: List of ratings associated with the user.
"""
ratings = __DATABASE_CONNECTION.query(RatingsTBL).filter_by(
user_id=user_id).all()
return ratings
**Any function that modifies the database such as deleting any entreies need to have a __DATABASE_CONNECTION.commit()
Example:
# Deletes existing factor based on unique id
def delete_factor(id, user_id):
try:
factor = __DATABASE_CONNECTION.query(
FactorTBL).filter_by(id=id, user_id=user_id).first()
if factor:
__DATABASE_CONNECTION.delete(factor)
__DATABASE_CONNECTION.commit()
else:
print(f"Factor with ID {id} not found for user {user_id}")
except Exception as e:
print(f"Could not delete factor for user {user_id}: {e}")
-----------------------------------------#App.py#----------------------------
This file contains all the routes for the website. A route is essentially the path the website takes for each task.
Example:
@app.route("/", methods=['GET', 'POST'])
def front():
return render_template("front.html")
@app.route('/factor/<num>', methods=['POST', 'GET'])
def factor(num):
if current_user.is_authenticated:
current_user_id = current_user.id
# Getting all the current factors
if num == '-1':
factor = database_access.get_all_factors(current_user_id)
return render_template('factor.html', factor=factor)
elif num == '1':
factor = database_access.ascendingOrder(current_user_id)
elif num == '2':
factor = database_access.descendingOrder(current_user_id)
return render_template('factor.html', factor=factor)
else:
return page_not_found("error")
else:
return unauthorized("error")
Note: Python function that will act as a page requires @app.route('/') on top.
If a function located in database_acess is required to be used on App.py the format is database_access.function name
Function call from database_acess is returned as a 1D list
---------------------------------#templates#---------------------------------------------
Any html file needs to be in the template folder
Example HTML File
{{% extends 'base.html' %}
{# Extends the 'base.html' template #}
{% import "bootstrap/wtf.html" as wtf %}
{# Imports 'wtf.html' from the 'bootstrap' directory with an alias 'wtf' #}
{% block title %}
Factor Page
{# Sets the title of the page to "Factor Page" #}
{% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='css/factor.css') }}">
{% endblock %}
<link rel="stylesheet" href="factor.css">
{% block content %}
<div class="grid-container">
<div class="factorPage">
<h1 class="pt-5 pb-2">Factors</h1>
<h3>Here is where you add all of your factors/issues into the application. Some examples include "High Turnover Rate", or "Bad Management".
Add a description, see how many votes there are, and input into the program.
Select edit to go back and fix any errors, or delete to remove a factor.
Add as many as you please! <h4>Click <a href="{{ url_for('pick_factors', num=-1) }}">here</a> to continue once you have added all factors.</h4>
</h3>
{# Heading for the factor page #}
</div>
<div class="table">
<!-- Table of factors that include: ID, Order, Factor -->
<table style="width: 100%">
<!-- Table row for header-->
<tr>
<th>Factor</th>
<th>Frequency</th>
<th>Edit</th>
<th>Delete</th>
</tr>
{% for i in factor %}
<tr>
<td class="f_box">{{ i.title }}</td>
<td class="f_box">{{ i.votes }}</td>
<!-- Send to edit with id -->
<td class="f_box">
<br>
<a href="{{ url_for('edit_factor',id=i.id) }}">Edit</a>
</td>
<!-- Send to edit with id -->
<td class="f_box">
<br>
<a href="{{ url_for('delete_factor',id=i.id) }}">Delete</a>
</td>
</tr>
{% endfor %}
</table>
</div>
<input type="file" id="fileInput" style="display: none;" accept=".csv" onchange="uploadFile(this.getAttribute('data-type'))">
<div class="load">
<button onclick="triggerFileInput('factor')" class="loadButton">Upload Existing File</button>
<button type="Delete" onclick="DeleteData()">Delete All Factors</button>
</div>
<div class = "addFact">
<h5>Add New Factor</h5>
<form action="{{ url_for('insert_factor') }}" method="post" onsubmit="return validateForm()">
<label for="f_title"></label>
<input type="text" name="f_title" class = "inputText" placeholder="Factor Title"><br>
<label for="f_description"></label>
<input type="text" name="f_description" class = "inputText" placeholder="Optional Description"><br>
<label for="f_votes"></label>
<input type="number" name="f_votes" class = "inputNumber" placeholder="Optional Frequency"><br>
<button type="submit" class="save">Save</button>
</form>
</div>
<h4>Click <a href="{{ url_for('pick_factors', num=-1) }}">here</a> to continue once you have added all factors.</h4>
<script>
function DeleteData()
{
let confirmDelete=confirm("Are you sure you want to delete ALL the factors; This is not reversible");
if(confirmDelete)
{
window.location.href = "/deleteFactorButton";
}
}
function triggerFileInput(type) {
var fileInput = document.getElementById('fileInput');
fileInput.setAttribute('data-type', type); // Set the type of data to upload
fileInput.click();
}
function uploadFile(dataType) {
var fileInput = document.getElementById('fileInput');
if(fileInput.files.length > 0) {
var formData = new FormData();
formData.append('csv_upload', fileInput.files[0]);
formData.append('data_type', dataType); // Include the data type in the FormData
fetch('/upload_csv', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(data);
if (data.success) {
window.location.reload();
} else {
alert('Upload failed: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
}
</script>
{% endblock %}
-----Base templates---------
For html file that contains the same flow/design extending a base html file might be helpful
ex.
{% extends 'base.html' %} {# Extends the 'base.html' template #}
{% import "bootstrap/wtf.html" as wtf %} {# Imports 'wtf.html' from the 'bootstrap' directory with an alias 'wtf' #}
This allows for an easier integration of the same design aspect among multiple files
----CSS--------
CSS Filed are located in the static folder and needs to be linked with the html page
ex.
<link rel="stylesheet" href="{{ url_for('static', filename='css/factor.css') }}">
---------------------------------#Flow#---------------------------------------------
This website contains a pre and post login view
Pre Login
Users are greeted with a website that contains general information about ISM including sponsors.
Pre login in view also contains a login page which allows users to register, login, and recover forgotten passwords
Post Login:
After login users are given access to the a part of the website that follows the ISM process
Here users are able to upload factors, participants and rate relationship between factors. After Rating users can also access a visualization of the rating between factors