intégration de l'analyse des avis dans l'interface admin

This commit is contained in:
Quentin Roussel
2023-04-02 20:28:12 +02:00
parent ef2c3cdce4
commit 1fa3b92e32
13 changed files with 114 additions and 21 deletions

View File

@@ -0,0 +1,18 @@
FROM python:3.8
#Ne pas créer les fichiers .pyc
ENV PYTHONDONTWRITEBYTECODE=1
#Afficher les logs directement dans le terminal
ENV PYTHONUNBUFFERED=1
#Installation des dépendances de opencv
RUN apt-get update
# Installation des dépendances python
COPY requirements.txt .
RUN python -m pip install -r requirements.txt
# Création du répertoire de travail
WORKDIR /app
COPY . /app
CMD ["python", "main.py"]

View File

@@ -101,5 +101,3 @@ def reviewAnalyzer(review):
#Sur demande de Quentin: on ne renvoie que le score de l'avis pour l'instant
return(reviewScore)
print(reviewAnalyzer("Je n'ai pas passé un mauvais moment."))

View File

@@ -0,0 +1,27 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from ScoreOnlyReviewAnalysis import reviewAnalyzer
import os
class Server(BaseHTTPRequestHandler):
def do_POST(self):
self.send_response(200)
self.send_header('Content-type','application/json')
self.end_headers()
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
data = post_data.decode('utf-8')
print(data, reviewAnalyzer(data))
self.wfile.write(bytes(str(reviewAnalyzer(data)), 'utf-8'))
def main():
try:
server = HTTPServer(('', int(os.getenv("PORT"))), Server)
server.serve_forever()
except KeyboardInterrupt:
print('^C received, shutting down the web server')
server.socket.close()
if __name__ == '__main__':
main()

View File

View File

@@ -52,9 +52,10 @@ CREATE TABLE `borne_criteres` (
--
INSERT INTO `borne_criteres` (`id`, `nom`) VALUES
(1, 'proprete'),
(2, 'calme'),
(3, 'attente');
(1, 'analyse');
(2, 'proprete'),
(3, 'calme'),
(4, 'attente');
-- --------------------------------------------------------
@@ -67,7 +68,7 @@ CREATE TABLE `borne_notes_autre` (
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`critere_id` int NOT NULL,
`avis_id` int NOT NULL,
`note` int NOT NULL COMMENT 'Note sur 10'
`note` float NOT NULL COMMENT 'Note sur 10'
) ;
-- --------------------------------------------------------

View File

@@ -18,6 +18,7 @@ services:
start_period: 10s # Estimated time to boot.
environment:
MYSQL_ROOT_PASSWORD: telereview
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: telereview
#Interface d'aministration pour la bdd
@@ -50,6 +51,8 @@ services:
- DB_HOST=db
- DB_NAME=telereview
- PORT=8080
- ANALYZER_HOST=analyseur_texte
- ANALYZER_PORT=2000
depends_on:
db:
condition: service_healthy
@@ -82,6 +85,18 @@ services:
container_name: formulaire
ports:
- 80:80
#Serveur d'analyse de texte
analyseur_texte:
build: ./analyseur_texte
container_name: analyseur_texte
environment:
- PORT=2000
ports:
- 2000:2000
restart: always
# #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

View File

@@ -1,10 +1,19 @@
import React from 'react'
import { Card, Col, Row, Table } from 'react-bootstrap';
import { Alert, Card, Col, Row, Table } from 'react-bootstrap';
import { BsPersonFill } from 'react-icons/bs';
import styles from '../styles/Avis.module.css'
export default function Avis({review}) {
const {date, note_principale,notes_autres, commentaire, sexe_auteur, nom_source, age_auteur} = review;
function getAnalyse() {
let res = "Non calculé"
notes_autres.map(({ critere, note }) => {
if(critere === "analyse") {
res=note.toString();
}
})
return res
}
return (
<Card>
<Card.Title>Avis</Card.Title>
@@ -36,10 +45,12 @@ export default function Avis({review}) {
<td>{note_principale} / 10</td>
</tr>
{notes_autres && notes_autres.map(({ critere, note }) => {
return <tr key={critere}>
<td>{critere}</td>
<td>{note}/10</td>
</tr>
if(critere !== "analyse") {
return <tr key={critere}>
<td>{critere}</td>
<td>{note}/10</td>
</tr>
}
})}
</tbody>
</Table>
@@ -48,6 +59,9 @@ export default function Avis({review}) {
<Card>
<Card.Header>Commentaire</Card.Header>
<Card.Body>
<Alert variant={getAnalyse() > 0 ? "success" : "danger"}>
<p>Score de positivité : {getAnalyse()}</p>
</Alert>
{commentaire}
</Card.Body>
</Card>

View File

@@ -8,7 +8,12 @@ export default function AvisList({ avis }) {
function handleClick(id) {
router.push(`/avis/${id}`);
}
function truncateComment(text) {
if(text.length > 100) {
return text.substring(0, 100) + "..."
}
return text;
}
return (
<Table>
<thead>
@@ -16,15 +21,17 @@ export default function AvisList({ avis }) {
<th>Date</th>
<th>Note globale</th>
<th>Commentaire</th>
<th>Positivité</th>
<th>Source</th>
</tr>
</thead>
<tbody>
{avis.map(({ id, note_principale, commentaire, date, nom_source }) => {
{avis.map(({ id, note_principale, commentaire,analyse, date, nom_source }) => {
return <tr onClick={() => handleClick(id)} key={id} className={styles.row}>
<td>{date}</td>
<td>{note_principale} / 10</td>
<td>{commentaire}</td>
<td>{truncateComment(commentaire)}</td>
<td>{analyse}</td>
<td>{nom_source}</td>
</tr>
})}

View File

@@ -53,5 +53,3 @@
background-color: #C6C6C6;
pointer-events: none;
}

View File

@@ -7,11 +7,14 @@ import conn from '../database.js';
*/
const getLastReviews = (limit = 10) => {
return new Promise((resolve, reject) => {
let sql = `SELECT borne_avis.id,date,note_principale,commentaire,sources.nom as nom_source, borne_auteurs.sexe as sexe_auteur, borne_auteurs.age as age_auteur
FROM borne_avis
JOIN sources ON sources.id = source_id
JOIN borne_auteurs ON borne_auteurs.id = id_auteur
ORDER BY borne_avis.id DESC LIMIT ?`;
let sql = `SELECT borne_avis.id,borne_avis.date as date,note_principale,commentaire,sources.nom as nom_source, borne_auteurs.sexe as sexe_auteur, borne_auteurs.age as age_auteur, borne_notes_autre.note as analyse
FROM borne_avis
JOIN sources ON sources.id = source_id
JOIN borne_auteurs ON borne_auteurs.id = id_auteur
LEFT JOIN borne_notes_autre ON borne_notes_autre.avis_id = borne_avis.id
LEFT JOIN borne_criteres ON borne_criteres.id = borne_notes_autre.critere_id
WHERE borne_criteres.nom = "analyse" OR borne_criteres.nom IS NULL
ORDER BY borne_avis.id DESC LIMIT ?;`;
conn.query(sql, [limit], (err, res) => {
if (err) {
reject(err);

View File

@@ -71,9 +71,11 @@ export const addReviewFromRequest = async (req,res) => {
const author = new Auteur(req.body.auteur_age,req.body.auteur_sexe);
const review = new Review(author, req.body.note, req.body.source, req.body.commentaire, notes_autre)
await review.analyzeComment();
let authorId = await addAuteur(author);
let sourceId = await getSourceId(review.source);
let reviewId = await addReview(review, authorId, sourceId );
console.log(review.notesAutre)
for(let label in review.notesAutre) {
await addSpecificRating(reviewId, label, review.notesAutre[label]);
}

View File

@@ -28,6 +28,16 @@ export class Review {
}
}
}
//Appelle l'API de traitement du langage pour attribuer une note au commentaire
async analyzeComment() {
let res = await fetch("http://"+process.env.ANALYZER_HOST + ":" + process.env.ANALYZER_PORT, {
method: "POST",
body: this.commentaire
})
let grade = await res.text();
this.notesAutre["analyse"] =grade;
}
}
//Classe qui représente l'auteur d'un avis