diff --git a/code/db/telereview.sql b/code/db/telereview.sql
index 960a0ca..2ded268 100644
--- a/code/db/telereview.sql
+++ b/code/db/telereview.sql
@@ -116,8 +116,7 @@ CREATE TABLE `sources` (
INSERT INTO `sources` (`id`, `nom`) VALUES
(1, 'website'),
-(2, 'borne'),
-(3, 'instagram');
+(2, 'borne');
-- --------------------------------------------------------
@@ -180,11 +179,12 @@ CREATE TABLE `stats_autres_semaine` (
CREATE TABLE `stats_general_annee` (
`id` int NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `moyenne_globale` float NOT NULL,
- `moyenne_site` float NOT NULL,
- `moyenne_borne` float NOT NULL,
- `dist_age` text NOT NULL COMMENT 'Distribution de l''age des auteurs',
- `dist_sexe` text NOT NULL COMMENT 'Distribution du sexe des auteurs'
+ `nb_avis` int NOT NULL,
+ `moyenne_globale` float DEFAULT NULL,
+ `moyenne_site` float DEFAULT NULL,
+ `moyenne_borne` float DEFAULT NULL,
+ `dist_age` text DEFAULT NULL COMMENT 'Distribution de l''age des auteurs',
+ `dist_sexe` text DEFAULT NULL COMMENT 'Distribution du sexe des auteurs'
) ;
-- --------------------------------------------------------
@@ -196,11 +196,12 @@ CREATE TABLE `stats_general_annee` (
CREATE TABLE `stats_general_jour` (
`id` int NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `nb_avis` int NOT NULL,
`moyenne_globale` float DEFAULT NULL,
`moyenne_site` float DEFAULT NULL,
`moyenne_borne` float DEFAULT NULL,
- `dist_age` text COMMENT 'Distribution de l''age des auteurs',
- `dist_sexe` text COMMENT 'Distribution du sexe des auteurs'
+ `dist_age` text DEFAULT NULL COMMENT 'Distribution de l''age des auteurs',
+ `dist_sexe` text DEFAULT NULL COMMENT 'Distribution du sexe des auteurs'
) ;
-- --------------------------------------------------------
@@ -212,11 +213,12 @@ CREATE TABLE `stats_general_jour` (
CREATE TABLE `stats_general_mois` (
`id` int NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `moyenne_globale` float NOT NULL,
- `moyenne_site` float NOT NULL,
- `moyenne_borne` float NOT NULL,
- `dist_age` text NOT NULL COMMENT 'Distribution de l''age des auteurs',
- `dist_sexe` text NOT NULL COMMENT 'Distribution du sexe des auteurs'
+ `nb_avis` int NOT NULL,
+ `moyenne_globale` float DEFAULT NULL,
+ `moyenne_site` float DEFAULT NULL,
+ `moyenne_borne` float DEFAULT NULL,
+ `dist_age` text DEFAULT NULL COMMENT 'Distribution de l''age des auteurs',
+ `dist_sexe` text DEFAULT NULL COMMENT 'Distribution du sexe des auteurs'
) ;
-- --------------------------------------------------------
@@ -228,11 +230,12 @@ CREATE TABLE `stats_general_mois` (
CREATE TABLE `stats_general_semaine` (
`id` int NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `moyenne_globale` float NOT NULL,
- `moyenne_site` float NOT NULL,
- `moyenne_borne` float NOT NULL,
- `dist_age` text NOT NULL COMMENT 'Distribution de l''age des auteurs',
- `dist_sexe` text NOT NULL COMMENT 'Distribution du sexe des auteurs'
+ `nb_avis` int NOT NULL,
+ `moyenne_globale` float DEFAULT NULL,
+ `moyenne_site` float DEFAULT NULL,
+ `moyenne_borne` float DEFAULT NULL,
+ `dist_age` text DEFAULT NULL COMMENT 'Distribution de l''age des auteurs',
+ `dist_sexe` text DEFAULT NULL COMMENT 'Distribution du sexe des auteurs'
) ;
--
diff --git a/code/docker-compose.yaml b/code/docker-compose.yaml
index 5b458b1..2e8b4dd 100644
--- a/code/docker-compose.yaml
+++ b/code/docker-compose.yaml
@@ -55,44 +55,44 @@ services:
restart: always
#Serveur web de l'interface de la borne
- interface_borne:
- image: httpd:latest
- volumes:
- - ./interface_borne:/usr/local/apache2/htdocs/
- container_name: interface_borne
- ports:
- - 8888:80
+ # interface_borne:
+ # image: httpd:latest
+ # volumes:
+ # - ./interface_borne:/usr/local/apache2/htdocs/
+ # container_name: interface_borne
+ # ports:
+ # - 8888:80
- #Serveur web de l'interface admin
- interface_admin:
- image: httpd:latest
- volumes:
- - ./interface_admin:/usr/local/apache2/htdocs/
- container_name: interface_admin
- ports:
- - 80:80
+ # #Serveur web de l'interface admin
+ # interface_admin:
+ # image: httpd:latest
+ # volumes:
+ # - ./interface_admin:/usr/local/apache2/htdocs/
+ # container_name: interface_admin
+ # ports:
+ # - 80:80
- #Backend de la borne : scripts pythons de reconnaissances video et audio
- #Envoient les infos a l'interface de la borne par websocket pour mettre a jour l'interface rapidement
- #Met a jour les avis en faisant des requêtes a l'API
- backend_reconnaissance:
- build: ./backend_reconnaissance
- container_name: backend_reconnaissance
- restart: always
- devices:
- - /dev/video3:/dev/video0
- environment:
- - PORT=5000
- - HOST=backend_reconnaissance
- ports:
- #Ce container est le serveur websocker dont le client est l'interface de la borne qui tourne dans le navigateur
- - 5000:5000
+ # #Backend de la borne : scripts pythons de reconnaissances video et audio
+ # #Envoient les infos a l'interface de la borne par websocket pour mettre a jour l'interface rapidement
+ # #Met a jour les avis en faisant des requêtes a l'API
+ # backend_reconnaissance:
+ # build: ./backend_reconnaissance
+ # container_name: backend_reconnaissance
+ # restart: always
+ # devices:
+ # - /dev/video3:/dev/video0
+ # environment:
+ # - PORT=5000
+ # - HOST=backend_reconnaissance
+ # ports:
+ # #Ce container est le serveur websocker dont le client est l'interface de la borne qui tourne dans le navigateur
+ # - 5000:5000
- video_loopback:
- build: ./video_loopback
- container_name: video_loopback
- restart: always
- devices:
- - /dev/video0:/dev/video0
- - /dev/video2:/dev/video1
- - /dev/video3:/dev/video2
\ No newline at end of file
+ # video_loopback:
+ # build: ./video_loopback
+ # container_name: video_loopback
+ # restart: always
+ # devices:
+ # - /dev/video0:/dev/video0
+ # - /dev/video2:/dev/video1
+ # - /dev/video3:/dev/video2
\ No newline at end of file
diff --git a/code/interface_admin/hooks/stats.js b/code/interface_admin/hooks/stats.js
index 40449bb..4b630ce 100644
--- a/code/interface_admin/hooks/stats.js
+++ b/code/interface_admin/hooks/stats.js
@@ -1,4 +1,4 @@
-import { useEffect } from "react";
+import { useEffect, useState } from "react";
import { api } from "../config/reviewsApi";
export default function useStats(limit, interval) {
@@ -7,7 +7,7 @@ export default function useStats(limit, interval) {
const [error, setError] = useState(false);
async function fetchData(limit, interval) {
- const response = await fetch("http://" + api.HOST + `/get_stats?interval=${interval}&limit=${limit}`)
+ const response = await fetch("http://" + api.HOST + `/borne/get_stats?interval=${interval}&limit=${limit}`)
if(response.ok) {
const data = await response.json();
setStats(data);
@@ -20,7 +20,7 @@ export default function useStats(limit, interval) {
useEffect(() => {
fetchData(limit, interval);
- })
+ }, [])
return {stats, loading, error};
}
\ No newline at end of file
diff --git a/code/interface_admin/package.json b/code/interface_admin/package.json
index 1bc8b7a..d100d6f 100644
--- a/code/interface_admin/package.json
+++ b/code/interface_admin/package.json
@@ -12,6 +12,7 @@
"@next/font": "13.1.6",
"bootstrap": "^5.2.3",
"chart.js": "^4.2.0",
+ "date-fns": "^2.29.3",
"eslint": "8.33.0",
"eslint-config-next": "13.1.6",
"next": "13.1.6",
diff --git a/code/interface_admin/pages/avis/index.js b/code/interface_admin/pages/avis/index.js
index 8044f84..4ff8a39 100644
--- a/code/interface_admin/pages/avis/index.js
+++ b/code/interface_admin/pages/avis/index.js
@@ -57,8 +57,8 @@ export default function AvisListPage() {
diff --git a/code/interface_admin/pages/index.js b/code/interface_admin/pages/index.js
index 8310496..553c24b 100644
--- a/code/interface_admin/pages/index.js
+++ b/code/interface_admin/pages/index.js
@@ -3,74 +3,132 @@ import { Card, Container } from 'react-bootstrap'
import ComparativeBarChart from '../components/ComparativeBarChart'
import { useEffect, useState } from 'react'
import styles from "../styles/Home.module.css"
+import useStats from '../hooks/stats'
+import getDay from 'date-fns/getDay'
+import getWeek from '../util'
export default function Home() {
const [datasets, setDatasets] = useState(null);
const [averages, setAverages] = useState(null);
const [differences, setDifferences] = useState(null);
+
useEffect(() => {
if (datasets) {
let newAverages = []
let newDifferences = []
for (let i = 0; i < datasets.length; i++) {
- newAverages[i] = datasets[i].current.reduce((a, b) => a + b) / datasets[i].current.length
- newDifferences[i] = newAverages[i] - datasets[i].previous.reduce((a, b) => a + b) / datasets[i].previous.length
+ let currentEntriesCount = 0;
+ let previousEntriesCount = 0;
+ for(let x of datasets[i].current) {
+ if(x != null) {
+ currentEntriesCount++;
+ }
+ }
+ for(let x of datasets[i].previous) {
+ if(x != null) {
+ previousEntriesCount++;
+ }
+ }
+
+ if(currentEntriesCount != 0) {
+ newAverages[i] = datasets[i].current.reduce((a, b) => a + b) / currentEntriesCount;
+ if(previousEntriesCount > 0) {
+ newDifferences[i] = newAverages[i] - datasets[i].previous.reduce((a, b) => a + b) / datasets[i].previous.length
+ }else {
+ newDifferences[i] = newAverages[i]
+ }
+ }else {
+ newDifferences[i] = 0;
+ newAverages[i] = 0;
+ }
}
setAverages(newAverages);
setDifferences(newDifferences);
}
}, [datasets]);
-
- useEffect(() => setDatasets([
- { title: "Nombre d'avis", current: [3, 2, 3, 4, 5, 6, 7], previous: [7, 6, 5, 4, 3, 2, 1] },
- { title: "Notes moyennes", current: [1, 2, 3, 4, 5, 6, 7], previous: [7, 6, 5, 4, 3, 2, 1] }
- ]), []);
+
+ const { stats, loading, error } = useStats(14, "jour");
+
+ useEffect(() => {
+ console.log(getDay(new Date("2023-03-20T14:00:00.000Z")))
+ })
+
+ useEffect(() => {
+ if(!error && !loading) {
+ let reviewCount = [null,null,null,null,null,null,null];
+ let reviewCountPrev = [null,null,null,null,null,null,null]
+ let reviewAvg = [null,null,null,null,null,null,null]
+ let reviewAvgPrev = [null,null,null,null,null,null,null]
+
+ for(let i = 0; i < stats.length; i++) {
+ let date = new Date(Date.parse(stats[i].date))
+ let now = new Date();
+ let day = (date.getDay() - 1) % 7;
+ let week = getWeek(date, 1);
+ let thisWeek = getWeek(now, 1);
+ console.log({date,week,thisWeek,day})
+ if(week == thisWeek) {
+ reviewCount[day] = stats[i].nb_avis;
+ reviewAvg[day] = stats[i].moyenne_globale;
+ }else if(week = thisWeek - 1){
+ reviewAvgPrev[day] = stats[i].moyenne_globale;
+ reviewCountPrev[day] = stats[i].nb_avis;
+ }
+ }
+ setDatasets([
+ { title: "Nombre d'avis", current: reviewCount, previous: reviewCountPrev },
+ { title: "Notes moyennes", current: reviewAvg, previous: reviewAvgPrev }
+ ])
+ }
+ }, [stats]);
+
function dataVisualizer(title, current, previous, average, difference) {
return
-
{title}
-
- Moyenne
-
-
- {Math.round(average * 1e2) / 1e2}
-
- = 0 ? styles.averagePositive : styles.averageNegative].join(' ')}
- >
- {(difference >= 0 ? "+" : "-") + Math.round(difference * 1e2) / 1e2}
-
-
-
-
-
+
{title}
+
+ Moyenne
+
+
+ {Math.round(average * 1e2) / 1e2}
+
+ = 0 ? styles.averagePositive : styles.averageNegative].join(' ')}
+ >
+ {(difference >= 0 ? "+" : "-") + Math.round(difference * 1e2) / 1e2}
+
+
+
+
+
}
-
+
return (
<>
-
- Create Next App
-
-
-
-
- Vos performances cette semaine
-
- {datasets && averages && differences && datasets.map((set, i) => dataVisualizer(set.title, set.current, set.previous, averages[i], differences[i]))}
-
-
-
-
-
+
+ Create Next App
+
+
+
+
+ Vos performances cette semaine
+
+ {datasets && averages && differences && datasets.map((set, i) => dataVisualizer(set.title, set.current, set.previous, averages[i], differences[i]))}
+
+
+
+
+
>
- )
-}
+ )
+ }
+
\ No newline at end of file
diff --git a/code/interface_admin/util.js b/code/interface_admin/util.js
new file mode 100644
index 0000000..3018508
--- /dev/null
+++ b/code/interface_admin/util.js
@@ -0,0 +1,34 @@
+/**
+ * Returns the week number for this date. dowOffset is the day of week the week
+ * "starts" on for your locale - it can be from 0 to 6. If dowOffset is 1 (Monday),
+ * the week returned is the ISO 8601 week number.
+ * @param int dowOffset
+ * @return int
+ */
+export default function getWeek (date,dowOffset) {
+/*getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.meanfreepath.com */
+
+ dowOffset = typeof(dowOffset) == 'number' ? dowOffset : 0; //default dowOffset to zero
+ var newYear = new Date(date.getFullYear(),0,1);
+ var day = newYear.getDay() - dowOffset; //the day of week the year begins on
+ day = (day >= 0 ? day : day + 7);
+ var daynum = Math.floor((date.getTime() - newYear.getTime() -
+ (date.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
+ var weeknum;
+ //if the year starts before the middle of a week
+ if(day < 4) {
+ weeknum = Math.floor((daynum+day-1)/7) + 1;
+ if(weeknum > 52) {
+ nYear = new Date(date.getFullYear() + 1,0,1);
+ nday = nYear.getDay() - dowOffset;
+ nday = nday >= 0 ? nday : nday + 7;
+ /*if the next year starts before the middle of
+ the week, it is week #1 of that year*/
+ weeknum = nday < 4 ? 1 : 53;
+ }
+ }
+ else {
+ weeknum = Math.floor((daynum+day-1)/7);
+ }
+ return weeknum;
+};
\ No newline at end of file
diff --git a/code/reviews_api/borne/get_handler.js b/code/reviews_api/borne/get_handler.js
index 9323708..ba43329 100644
--- a/code/reviews_api/borne/get_handler.js
+++ b/code/reviews_api/borne/get_handler.js
@@ -143,13 +143,23 @@ const getStats = (interval, limit = 10) => {
Ces fonction sont des handlers pour les routes express, elles sont appelées par les routes et renvoient les données au format JSON
*/
export const handleGetLastReviews = (req, res) => {
- getLastReviews(req.query.limit)
- .then((reviews) => {
- res.send(reviews);
- })
- .catch((err) => {
- res.status(500).send("Error: " + err.message);
- });
+ if (req.query.limit) {
+ getLastReviews(Number(req.query.limit))
+ .then((reviews) => {
+ res.send(reviews);
+ })
+ .catch((err) => {
+ res.status(500).send("Error: " + err.message);
+ });
+ } else {
+ getLastReviews()
+ .then((reviews) => {
+ res.send(reviews);
+ })
+ .catch((err) => {
+ res.status(500).send("Error: " + err.message);
+ });
+ }
}
export const handleGetReview = (req, res) => {
@@ -176,13 +186,23 @@ export const handleGetCriteres = (req, res) => {
export const handleGetNotesAutres = (req, res) => {
if (req.query.critere) {
- getNotesAutresFromCritere(req.query.critere, req.query.limit)
- .then((notes) => {
- res.send(notes);
- })
- .catch((err) => {
- res.status(500).send("Error: " + err.message);
- });
+ if (req.query.limit) {
+ getNotesAutresFromCritere(req.query.critere, Number(req.query.limit))
+ .then((notes) => {
+ res.send(notes);
+ })
+ .catch((err) => {
+ res.status(500).send("Error: " + err.message);
+ });
+ } else {
+ getNotesAutresFromCritere(req.query.critere)
+ .then((notes) => {
+ res.send(notes);
+ })
+ .catch((err) => {
+ res.status(500).send("Error: " + err.message);
+ });
+ }
} else if (req.query.id) {
getNotesAutresFromReview(req.query.id)
.then((notes) => {
@@ -197,11 +217,21 @@ export const handleGetNotesAutres = (req, res) => {
}
export const handleGetStats = (req, res) => {
- getStats(req.query.interval, req.query.limit)
- .then((stats) => {
- res.send(stats);
- })
- .catch((err) => {
- res.status(500).send("Error: " + err.message);
- });
+ if (req.query.limit) {
+ getStats(req.query.interval, Number(req.query.limit))
+ .then((stats) => {
+ res.send(stats);
+ })
+ .catch((err) => {
+ res.status(500).send("Error: " + err.message);
+ });
+ } else {
+ getStats(req.query.interval)
+ .then((stats) => {
+ res.send(stats);
+ })
+ .catch((err) => {
+ res.status(500).send("Error: " + err.message);
+ });
+ }
}
\ No newline at end of file
diff --git a/code/reviews_api/index.js b/code/reviews_api/index.js
index edbdf88..5d2a760 100644
--- a/code/reviews_api/index.js
+++ b/code/reviews_api/index.js
@@ -3,7 +3,7 @@ import express from 'express';
import bodyParser from 'body-parser';
import { addReviewFromRequest } from './borne/post_handler.js';
import { addSocialReviewFromRequest } from './reseaux_sociaux/post_handler.js';
-import { startCronJobs } from './stats/update_stats.js';
+import { startCronJobs, manualUpdateStats } from './stats/update_stats.js';
import * as borneHandler from './borne/get_handler.js';
import cors from "cors";
@@ -20,6 +20,10 @@ app.get('/borne/get_criteres', borneHandler.handleGetCriteres);
app.get('/borne/notes_autres', borneHandler.handleGetNotesAutres);
app.get('/borne/get_stats', borneHandler.handleGetStats);
+app.get('/update_stats', (req, res) => {
+ manualUpdateStats();
+ res.send("OK");
+})
startCronJobs();
diff --git a/code/reviews_api/stats/update_request.sql b/code/reviews_api/stats/update_request.sql
index bc728b5..b5ea802 100644
--- a/code/reviews_api/stats/update_request.sql
+++ b/code/reviews_api/stats/update_request.sql
@@ -8,6 +8,10 @@ SET @date_limite = DATE_ADD(NOW(), INTERVAL -DAY_COUNT_DELAY DAY);
On récupère les notes notes moyennes sur la periode, en séparant global, borne et site
*/
+SELECT @nb_avis:=COUNT(*)
+ FROM borne_avis
+ WHERE borne_avis.date > @date_limite;
+
SELECT @moyenne_globale:=AVG(note_principale)
FROM borne_avis
WHERE borne_avis.date > @date_limite;
@@ -38,7 +42,7 @@ SELECT @stats_a:=COUNT(*) FROM borne_avis
SET @dist_sexe = CONCAT(@stats_f,",",@stats_h,",",@stats_a);
-INSERT INTO STATS_GENERAL_TABLE_NAME (moyenne_globale, moyenne_borne, moyenne_site, dist_sexe) VALUES (@moyenne_globale, @moyenne_borne, @moyenne_site, @dist_sexe);
+INSERT INTO STATS_GENERAL_TABLE_NAME (moyenne_globale, nb_avis, moyenne_borne, moyenne_site, dist_sexe) VALUES (@moyenne_globale, @nb_avis, @moyenne_borne, @moyenne_site, @dist_sexe);
INSERT INTO STATS_AUTRES_TABLE_NAME (critere_id, note)
SELECT critere_id, AVG(note) as moyenne FROM borne_notes_autre
diff --git a/code/reviews_api/stats/update_stats.js b/code/reviews_api/stats/update_stats.js
index 6bcc30a..2c20668 100644
--- a/code/reviews_api/stats/update_stats.js
+++ b/code/reviews_api/stats/update_stats.js
@@ -66,4 +66,11 @@ export const startCronJobs = () => {
true
)
console.log("All cronjobs initiated")
+}
+
+export function manualUpdateStats() {
+ computeStats(1, "stats_general_jour", "stats_autres_jour");
+ computeStats(7, "stats_general_semaine", "stats_autres_jour");
+ computeStats(30, "stats_general_mois", "stats_autres_mois");
+ computeStats(365, "stats_general_annee", "stats_autres_annee");
}
\ No newline at end of file