-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
359 lines (303 loc) · 12.4 KB
/
app.js
File metadata and controls
359 lines (303 loc) · 12.4 KB
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
const express = require('express');
const session = require('express-session');
const fs = require('fs');
const path = require('path');
const sqlite3 = require('sqlite3').verbose();
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const flash = require('connect-flash');
// Load `.env` config file
require("dotenv").config();
// Configuration de la base de données
let db = new sqlite3.Database(path.join(path.join(__dirname, "db"), 'evaluations.db'), sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
if (err) {
return console.error(err.message);
}
console.log('Connected to the SQlite database.');
db.run(`CREATE TABLE IF NOT EXISTS ${process.env.DB_TABLE_NAME} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
folderName TEXT,
gifName TEXT,
ranking INTEGER,
scoreTopRated INTEGER,
scoreLowestRated INTEGER
)`, (err) => {
if (err) {
console.error('Error creating table:', err.message);
} else {
console.log('Table created or already exists.');
startApp(); // Lancer l'application après la création de la table
}
});
});
db.serialize(() => {
// Créer une table si elle n'existe pas déjà
db.run(`CREATE TABLE IF NOT EXISTS ${process.env.DB_TABLE_NAME} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
folderName TEXT,
gifName TEXT,
ranking INTEGER,
scoreTopRated INTEGER,
scoreLowestRated INTEGER
)`, (err) => {
if (err) {
console.error('Error creating table:', err.message);
return;
}
console.log('Table created or already exists.');
});
// Interroger les noms des tables pour vérifier que la création a bien eu lieu
db.all("SELECT name FROM sqlite_master WHERE type='table'", [], (err, tables) => {
if (err) {
console.error('Error fetching tables:', err.message);
return;
}
console.log('Available tables:', tables);
});
});
function startApp() {
// Initialisation de l'application Express
const app = express();
// Configuration des middlewares
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
// Configuration de la session pour Express
app.use(session({
secret: process.env.EXPRESS_SECRET_KEY,
resave: false,
saveUninitialized: false,
cookie: { secure: false }
}));
app.use(flash()); // Utilisation de connect-flash pour les messages flash
// Initialisation de Passport
app.use(passport.initialize());
app.use(passport.session());
// Configuration du moteur de vue EJS
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// Chargement des prompts à partir d'un fichier texte
let prompts = [];
fs.readFile(path.join(__dirname, 'data', 'prompts.txt'), 'utf8', (err, data) => {
if (err) {
console.error('Failed to load prompts:', err);
prompts = []; // Utiliser un tableau vide en cas d'échec du chargement
} else {
prompts = data.split('\n');
}
});
// Configurer la stratégie d'authentification
passport.use(new LocalStrategy(
(username, password, done) => {
if (username === process.env.ADMIN_USERNAME && password === process.env.ADMIN_PASSWORD) { // Remplacer par vos propres méthodes de validation
return done(null, { id: 'admin', name: 'Admin' });
}
return done(null, false, { message: 'Invalid credentials' });
}
));
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {
if (id === 'admin') {
done(null, { id: 'admin', name: 'admin' });
} else {
done(new Error('User not found'));
}
});
app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());
// Function to shuffle an array
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]; // swap elements
}
}
// Définition des routes
app.get('/', (req, res) => {
res.render('home');
});
// Route pour démarrer ou continuer les évaluations
app.get('/evaluation', (req, res) => {
// Initialisation de la session pour les évaluations si elle n'existe pas
if (!req.session.evaluations) {
req.session.evaluations = [];
req.session.usedIndexes = [];
req.session.totalEvaluations = 0; // Nombre total d'évaluations effectuées
}
// Vérifier si tous les dossiers ont été utilisés
if (req.session.usedIndexes.length === 100) {
req.session.usedIndexes = []; // Réinitialiser les indices une fois que tous ont été utilisés
}
// Générer un index de dossier aléatoire qui n'a pas encore été utilisé
let folderIndex;
do {
folderIndex = Math.floor(Math.random() * 100);
} while (req.session.usedIndexes.includes(folderIndex));
// Marquer l'index comme utilisé
req.session.usedIndexes.push(folderIndex);
// Charger les GIFs
const folderPath = path.join(__dirname, `data/${String(folderIndex).padStart(3, '0')}`);
fs.readdir(folderPath, (err, files) => {
if (err) {
console.error('Failed to read directory:', err);
return res.status(500).send('Error loading gifs');
}
let gifs = files.filter(file => file.endsWith('.gif'))
.map(file => `/serve-gif/${String(folderIndex).padStart(3, '0')}/${file}`);
// Mélanger les GIFs ici avant de les afficher
shuffleArray(gifs);
const prompt = prompts[folderIndex];
// Ajouter les gifs et le prompt à la session
req.session.evaluations.push({ prompt, gifs, rankings: [] });
res.render('evaluation', {
gifs,
prompt,
evaluationsLength: req.session.evaluations.length
});
});
});
// Route pour traiter les soumissions des évaluations
app.post('/submit-evaluation', (req, res) => {
//console.log("Received rankings:", req.body.rankOrder);
//console.log("Received top rated score:", req.body.topRatedScore);
//console.log("Received lowest rated score:", req.body.lowestRatedScore);
const rankings = req.body.rankOrder ? req.body.rankOrder.split(',').map(Number) : [];
const topRatedScore = parseInt(req.body.topRatedScore, 10);
const lowestRatedScore = parseInt(req.body.lowestRatedScore, 10);
if (req.session.evaluations && req.session.evaluations.length > 0) {
const lastEvaluation = req.session.evaluations[req.session.evaluations.length - 1];
// Créer une liste de GIFs avec les indices de leurs positions initiales
const gifsInfo = lastEvaluation.gifs.map((gif, index) => ({
gif,
index: index + 1 // l'index initial avant tout tri
}));
// Tri des GIFs selon l'ordre défini par les rankings
gifsInfo.sort((a, b) => rankings.indexOf(a.index) - rankings.indexOf(b.index));
//console.log("Sorted GIFs information:", gifsInfo);
// Enregistrement des données triées avec scores conditionnels
gifsInfo.forEach((item, sortedIndex) => {
let folderName = path.dirname(item.gif);
let gifName = path.basename(item.gif);
let ranking = sortedIndex + 1;
let scoreTopRated = sortedIndex === 0 ? topRatedScore : null;
let scoreLowestRated = sortedIndex === (gifsInfo.length - 1) ? lowestRatedScore : null;
//console.log(`Preparing to insert: Folder: ${folderName}, GIF Name: ${gifName}, Ranking: ${ranking}, Score Top Rated: ${scoreTopRated}, Score Lowest Rated: ${scoreLowestRated}`);
db.run(`INSERT INTO ${process.env.DB_TABLE_NAME} (folderName, gifName, ranking, scoreTopRated, scoreLowestRated) VALUES (?, ?, ?, ?, ?)`,
[folderName, gifName, ranking, scoreTopRated, scoreLowestRated], (err) => {
if (err) {
return console.error(err.message);
}
//console.log(`A row has been inserted with ranking ${ranking} and score for ${gifName}`);
});
});
// Gestion de la redirection ou de l'affichage de la soumission finale
if (req.body.action === 'continue') {
res.redirect('/evaluation');
} else {
res.render('final_submission', { evaluations: req.session.evaluations });
req.session.evaluations = [];
}
}
});
// Route pour afficher la décision finale
app.get('/final-decision', (req, res) => {
if (req.session.evaluations && req.session.evaluations.length >= 3) {
res.render('final_decision', {
evaluations: req.session.evaluations,
batchCount: Math.floor(req.session.evaluations.length / 3),
continueOption: true
});
} else {
res.redirect('/evaluation');
}
});
// Route pour soumettre les évaluations
app.get('/submit-evaluations', (req, res) => {
console.log("Evaluations submitted:", req.session.evaluations);
req.session.destroy();
res.send("Evaluations have been submitted. Thank you!");
});
// Fonction pour mélanger les éléments d'un tableau
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]; // Échange des éléments
}
}
// Route pour servir les GIFs de manière contrôlée
app.get('/serve-gif/:folder/:gifName', (req, res) => {
const folder = req.params.folder;
const gifName = req.params.gifName;
const gifPath = path.join(__dirname, 'data', folder, gifName);
fs.stat(gifPath, (err, stat) => {
if (err) {
console.error('Error accessing file:', gifPath, err);
return res.status(404).send('GIF not found');
}
res.sendFile(gifPath);
});
});
app.get('/export-csv', isLoggedIn, (req, res) => {
const dbPath = path.join(path.join(__dirname, "db"), 'evaluations.db');
const db = new sqlite3.Database(dbPath, sqlite3.OPEN_READONLY, (err) => {
if (err) {
console.error('Error opening database', err.message);
return res.status(500).send("Error accessing the database");
}
});
db.all("SELECT * FROM "+process.env.DB_TABLE_NAME, [], (err, rows) => {
if (err) {
res.status(400).send("Error fetching records: " + err.message);
return;
}
// Convertir en CSV
const headers = "Folder Name, GIF Name, Ranking, Score Top Rated, Score Lowest Rated\n";
const csvContent = rows.map(row => `${row.folderName},${row.gifName},${row.ranking},${row.scoreTopRated},${row.scoreLowestRated}`).join("\n");
res.header('Content-Type', 'text/csv');
res.attachment("evaluations.csv");
res.send(headers + csvContent);
});
});
app.get('/across-lab', isLoggedIn, (req, res) => {
const dbPath = path.join(path.join(__dirname, "db"), 'evaluations.db');
const db = new sqlite3.Database(dbPath, sqlite3.OPEN_READONLY, (err) => {
if (err) {
console.error('Error opening database', err.message);
return res.status(500).send("Error accessing the database");
}
});
db.all("SELECT * FROM "+process.env.DB_TABLE_NAME+";", [], (err, rows) => {
if (err) {
console.error(err.message);
res.status(500).send("Error fetching records from the database");
} else {
//console.log(rows);
res.render('admin', { data: rows });
}
db.close((err) => {
if (err) {
console.error('Error closing database', err.message);
}
});
});
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
app.post('/login', passport.authenticate('local', {
successRedirect: '/across-lab',
failureRedirect: '/login',
failureFlash: 'Invalid username or password.' // Utilisation de flash
}));
app.get('/login', (req, res) => {
const message = req.flash('error'); // Accès au message flash
res.render('login', { message: message });
});
// Démarrage du serveur
app.listen(process.env.EXPRESS_PUBLIC_PORT, '0.0.0.0', () => {
console.log(`Server running on http://0.0.0.0:${process.env.EXPRESS_PUBLIC_PORT}`);
});
}