mirror of
https://git.roussel.pro/telecom-paris/pact.git
synced 2026-02-09 02:20:17 +01:00
intégration de l'analyse des avis dans l'interface admin
This commit is contained in:
18
code/analyseur_texte/Dockerfile
Normal file
18
code/analyseur_texte/Dockerfile
Normal 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"]
|
||||||
@@ -101,5 +101,3 @@ def reviewAnalyzer(review):
|
|||||||
#Sur demande de Quentin: on ne renvoie que le score de l'avis pour l'instant
|
#Sur demande de Quentin: on ne renvoie que le score de l'avis pour l'instant
|
||||||
return(reviewScore)
|
return(reviewScore)
|
||||||
|
|
||||||
|
|
||||||
print(reviewAnalyzer("Je n'ai pas passé un mauvais moment."))
|
|
||||||
27
code/analyseur_texte/main.py
Normal file
27
code/analyseur_texte/main.py
Normal 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()
|
||||||
0
code/analyseur_texte/requirements.txt
Normal file
0
code/analyseur_texte/requirements.txt
Normal file
@@ -52,9 +52,10 @@ CREATE TABLE `borne_criteres` (
|
|||||||
--
|
--
|
||||||
|
|
||||||
INSERT INTO `borne_criteres` (`id`, `nom`) VALUES
|
INSERT INTO `borne_criteres` (`id`, `nom`) VALUES
|
||||||
(1, 'proprete'),
|
(1, 'analyse');
|
||||||
(2, 'calme'),
|
(2, 'proprete'),
|
||||||
(3, 'attente');
|
(3, 'calme'),
|
||||||
|
(4, 'attente');
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ CREATE TABLE `borne_notes_autre` (
|
|||||||
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`critere_id` int NOT NULL,
|
`critere_id` int NOT NULL,
|
||||||
`avis_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'
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ services:
|
|||||||
start_period: 10s # Estimated time to boot.
|
start_period: 10s # Estimated time to boot.
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: telereview
|
MYSQL_ROOT_PASSWORD: telereview
|
||||||
|
MYSQL_ROOT_HOST: '%'
|
||||||
MYSQL_DATABASE: telereview
|
MYSQL_DATABASE: telereview
|
||||||
|
|
||||||
#Interface d'aministration pour la bdd
|
#Interface d'aministration pour la bdd
|
||||||
@@ -50,6 +51,8 @@ services:
|
|||||||
- DB_HOST=db
|
- DB_HOST=db
|
||||||
- DB_NAME=telereview
|
- DB_NAME=telereview
|
||||||
- PORT=8080
|
- PORT=8080
|
||||||
|
- ANALYZER_HOST=analyseur_texte
|
||||||
|
- ANALYZER_PORT=2000
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -82,6 +85,18 @@ services:
|
|||||||
container_name: formulaire
|
container_name: formulaire
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 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
|
# #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
|
# #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
|
# #Met a jour les avis en faisant des requêtes a l'API
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
import React from 'react'
|
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 { BsPersonFill } from 'react-icons/bs';
|
||||||
import styles from '../styles/Avis.module.css'
|
import styles from '../styles/Avis.module.css'
|
||||||
|
|
||||||
export default function Avis({review}) {
|
export default function Avis({review}) {
|
||||||
const {date, note_principale,notes_autres, commentaire, sexe_auteur, nom_source, age_auteur} = 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 (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<Card.Title>Avis</Card.Title>
|
<Card.Title>Avis</Card.Title>
|
||||||
@@ -36,10 +45,12 @@ export default function Avis({review}) {
|
|||||||
<td>{note_principale} / 10</td>
|
<td>{note_principale} / 10</td>
|
||||||
</tr>
|
</tr>
|
||||||
{notes_autres && notes_autres.map(({ critere, note }) => {
|
{notes_autres && notes_autres.map(({ critere, note }) => {
|
||||||
return <tr key={critere}>
|
if(critere !== "analyse") {
|
||||||
<td>{critere}</td>
|
return <tr key={critere}>
|
||||||
<td>{note}/10</td>
|
<td>{critere}</td>
|
||||||
</tr>
|
<td>{note}/10</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
@@ -48,6 +59,9 @@ export default function Avis({review}) {
|
|||||||
<Card>
|
<Card>
|
||||||
<Card.Header>Commentaire</Card.Header>
|
<Card.Header>Commentaire</Card.Header>
|
||||||
<Card.Body>
|
<Card.Body>
|
||||||
|
<Alert variant={getAnalyse() > 0 ? "success" : "danger"}>
|
||||||
|
<p>Score de positivité : {getAnalyse()}</p>
|
||||||
|
</Alert>
|
||||||
{commentaire}
|
{commentaire}
|
||||||
</Card.Body>
|
</Card.Body>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ export default function AvisList({ avis }) {
|
|||||||
function handleClick(id) {
|
function handleClick(id) {
|
||||||
router.push(`/avis/${id}`);
|
router.push(`/avis/${id}`);
|
||||||
}
|
}
|
||||||
|
function truncateComment(text) {
|
||||||
|
if(text.length > 100) {
|
||||||
|
return text.substring(0, 100) + "..."
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Table>
|
<Table>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -16,15 +21,17 @@ export default function AvisList({ avis }) {
|
|||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
<th>Note globale</th>
|
<th>Note globale</th>
|
||||||
<th>Commentaire</th>
|
<th>Commentaire</th>
|
||||||
|
<th>Positivité</th>
|
||||||
<th>Source</th>
|
<th>Source</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<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}>
|
return <tr onClick={() => handleClick(id)} key={id} className={styles.row}>
|
||||||
<td>{date}</td>
|
<td>{date}</td>
|
||||||
<td>{note_principale} / 10</td>
|
<td>{note_principale} / 10</td>
|
||||||
<td>{commentaire}</td>
|
<td>{truncateComment(commentaire)}</td>
|
||||||
|
<td>{analyse}</td>
|
||||||
<td>{nom_source}</td>
|
<td>{nom_source}</td>
|
||||||
</tr>
|
</tr>
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -53,5 +53,3 @@
|
|||||||
background-color: #C6C6C6;
|
background-color: #C6C6C6;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,14 @@ import conn from '../database.js';
|
|||||||
*/
|
*/
|
||||||
const getLastReviews = (limit = 10) => {
|
const getLastReviews = (limit = 10) => {
|
||||||
return new Promise((resolve, reject) => {
|
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
|
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
|
FROM borne_avis
|
||||||
JOIN sources ON sources.id = source_id
|
JOIN sources ON sources.id = source_id
|
||||||
JOIN borne_auteurs ON borne_auteurs.id = id_auteur
|
JOIN borne_auteurs ON borne_auteurs.id = id_auteur
|
||||||
ORDER BY borne_avis.id DESC LIMIT ?`;
|
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) => {
|
conn.query(sql, [limit], (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
|
|||||||
@@ -71,9 +71,11 @@ export const addReviewFromRequest = async (req,res) => {
|
|||||||
|
|
||||||
const author = new Auteur(req.body.auteur_age,req.body.auteur_sexe);
|
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)
|
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 authorId = await addAuteur(author);
|
||||||
let sourceId = await getSourceId(review.source);
|
let sourceId = await getSourceId(review.source);
|
||||||
let reviewId = await addReview(review, authorId, sourceId );
|
let reviewId = await addReview(review, authorId, sourceId );
|
||||||
|
console.log(review.notesAutre)
|
||||||
for(let label in review.notesAutre) {
|
for(let label in review.notesAutre) {
|
||||||
await addSpecificRating(reviewId, label, review.notesAutre[label]);
|
await addSpecificRating(reviewId, label, review.notesAutre[label]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
//Classe qui représente l'auteur d'un avis
|
||||||
|
|||||||
Reference in New Issue
Block a user