diff --git a/code/analyseur_texte/Dockerfile b/code/analyseur_texte/Dockerfile new file mode 100644 index 0000000..16b1ca7 --- /dev/null +++ b/code/analyseur_texte/Dockerfile @@ -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"] \ No newline at end of file diff --git a/code/Traitement Langage Naturel/ScoreOnlyReviewAnalysis.py b/code/analyseur_texte/ScoreOnlyReviewAnalysis.py similarity index 98% rename from code/Traitement Langage Naturel/ScoreOnlyReviewAnalysis.py rename to code/analyseur_texte/ScoreOnlyReviewAnalysis.py index 2e5207e..1988943 100644 --- a/code/Traitement Langage Naturel/ScoreOnlyReviewAnalysis.py +++ b/code/analyseur_texte/ScoreOnlyReviewAnalysis.py @@ -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.")) \ No newline at end of file diff --git a/code/Traitement Langage Naturel/fr_lexicon.txt b/code/analyseur_texte/fr_lexicon.txt similarity index 100% rename from code/Traitement Langage Naturel/fr_lexicon.txt rename to code/analyseur_texte/fr_lexicon.txt diff --git a/code/analyseur_texte/main.py b/code/analyseur_texte/main.py new file mode 100644 index 0000000..615bf00 --- /dev/null +++ b/code/analyseur_texte/main.py @@ -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() \ No newline at end of file diff --git a/code/analyseur_texte/requirements.txt b/code/analyseur_texte/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/code/db/telereview.sql b/code/db/telereview.sql index 2ded268..e2513f5 100644 --- a/code/db/telereview.sql +++ b/code/db/telereview.sql @@ -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' ) ; -- -------------------------------------------------------- diff --git a/code/docker-compose.yaml b/code/docker-compose.yaml index af464b8..0208ad7 100644 --- a/code/docker-compose.yaml +++ b/code/docker-compose.yaml @@ -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 diff --git a/code/interface_admin/components/Avis.jsx b/code/interface_admin/components/Avis.jsx index b2583a0..37f7738 100644 --- a/code/interface_admin/components/Avis.jsx +++ b/code/interface_admin/components/Avis.jsx @@ -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 ( Avis @@ -36,10 +45,12 @@ export default function Avis({review}) { {note_principale} / 10 {notes_autres && notes_autres.map(({ critere, note }) => { - return - {critere} - {note}/10 - + if(critere !== "analyse") { + return + {critere} + {note}/10 + + } })} @@ -48,6 +59,9 @@ export default function Avis({review}) { Commentaire + 0 ? "success" : "danger"}> +

Score de positivité : {getAnalyse()}

+
{commentaire}
diff --git a/code/interface_admin/components/AvisList.jsx b/code/interface_admin/components/AvisList.jsx index 187f349..7a2301d 100644 --- a/code/interface_admin/components/AvisList.jsx +++ b/code/interface_admin/components/AvisList.jsx @@ -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 ( @@ -16,15 +21,17 @@ export default function AvisList({ avis }) { + - {avis.map(({ id, note_principale, commentaire, date, nom_source }) => { + {avis.map(({ id, note_principale, commentaire,analyse, date, nom_source }) => { return handleClick(id)} key={id} className={styles.row}> - + + })} diff --git a/code/interface_admin/styles/AvisListPage.module.css b/code/interface_admin/styles/AvisListPage.module.css index cefd7d5..2ca5069 100644 --- a/code/interface_admin/styles/AvisListPage.module.css +++ b/code/interface_admin/styles/AvisListPage.module.css @@ -53,5 +53,3 @@ background-color: #C6C6C6; pointer-events: none; } - - diff --git a/code/reviews_api/borne/get_handler.js b/code/reviews_api/borne/get_handler.js index ba43329..004efb8 100644 --- a/code/reviews_api/borne/get_handler.js +++ b/code/reviews_api/borne/get_handler.js @@ -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); diff --git a/code/reviews_api/borne/post_handler.js b/code/reviews_api/borne/post_handler.js index 545d745..faf0466 100644 --- a/code/reviews_api/borne/post_handler.js +++ b/code/reviews_api/borne/post_handler.js @@ -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]); } diff --git a/code/reviews_api/borne/structures.js b/code/reviews_api/borne/structures.js index 39af1b9..1337033 100644 --- a/code/reviews_api/borne/structures.js +++ b/code/reviews_api/borne/structures.js @@ -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
Date Note globale CommentairePositivité Source
{date} {note_principale} / 10{commentaire}{truncateComment(commentaire)}{analyse} {nom_source}