Commit a48d8cd0 authored by Quentin's avatar Quentin
Browse files

Ajout de CheckCorpusProcess qui permet de voir un CorpusProcess et de...

Ajout de CheckCorpusProcess qui permet de voir un CorpusProcess et de télécharger ses fichiers s'il est fini.
parent cd3f8fc8
...@@ -28,14 +28,11 @@ See [Configuration Reference](https://cli.vuejs.org/config/). ...@@ -28,14 +28,11 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
### Define corpus ### Define corpus
* Prévoir une taille maximum pour les fichiers en input * Prévoir une taille maximum pour les fichiers en input
* Réfléchir comment enregistrer les documents et éviter les doublons (id ?)
* Pouvoir supprimer les fichiers selons certains conditions (utilisateur n'apas été jusqu'au bout de l'UX, au bout de X jours pour un utilisateur anonyme) * Pouvoir supprimer les fichiers selons certains conditions (utilisateur n'apas été jusqu'au bout de l'UX, au bout de X jours pour un utilisateur anonyme)
* Option du corpus devrait apparaître uniquement lorsque "depuis un fichier local" ou "depuis un champ de texte" ?
-> Il apparaîtra à chaque fois, cependant, il sera prérempli dans le cas de corpora déjà précréés
### Define pipeline ### Define pipeline
* Enlever un module quand il est déjà selectionné dans la timeline ? * Enlever un module quand il est déjà selectionné dans la timeline ? (peut-on avoir plusieurs fois un module dans une pipeline?)
* Prévoir les modules affichés en fonction de la langue du corpus * Prévoir les modules affichés en fonction de la langue du corpus
### Prevalidation ### Prevalidation
...@@ -50,7 +47,6 @@ See [Configuration Reference](https://cli.vuejs.org/config/). ...@@ -50,7 +47,6 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
### Display Results (Visualization tool) ### Display Results (Visualization tool)
* Voir comment mieux gérer le redimensionnement -> Check ? * Voir comment mieux gérer le redimensionnement -> Check ?
* Regarder comment avoir un treeview clickable (possible ? ) -> Done
* Faire une transition pour afficher ou cacher le paneau de droite * Faire une transition pour afficher ou cacher le paneau de droite
* Checker pour faire des titres (Paneau d'annotation, Panneau de document...) * Checker pour faire des titres (Paneau d'annotation, Panneau de document...)
- Panneau de droite : Chaque étiquette doit avoir une couleur - Panneau de droite : Chaque étiquette doit avoir une couleur
...@@ -67,96 +63,3 @@ See [Configuration Reference](https://cli.vuejs.org/config/). ...@@ -67,96 +63,3 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
Besoin de garder momentanément potentiellement un fichier lourd. Besoin de garder momentanément potentiellement un fichier lourd.
* Comment gérer le json des paramètres des modules et la traduction ? (import a file, cfshared locale msg in i18n) * Comment gérer le json des paramètres des modules et la traduction ? (import a file, cfshared locale msg in i18n)
### Questions DEV TEAM
* Risque d'avoir du v-html pour la visualisation ?
* Quel livre se concentrer pour les webservices ?
## Morfetik
### Liste des catégories
#### Formes complexes
* Locutions verbales
* Locutions nominales
* Locutions conjonctives
* Locutions determinatives
* Locutions interjectives
* Locutions pronominales
* Locutions phrases
* Locutions prépositionnelles
* Locutions adjectivales
#### Formes simples
* Sigles
* Interjections
* Adjectifs
* Noms
* Verbes
* Adverbes
* Conjonctions
* Déterminants
* Pronoms
* Prépositions
# Next week
Pré-traitement
Export (ConLLU prêt)
Lundi 7 15h (Discussion avec Jorge API)
Mardi 8 16h (DevTeam pour avis API / Smartphone)
Mercredi 9 15h (CheneTAL)
### Annotation de NEOVEILLE
```
NEOVEILLE:NEOLOGISM
* -> Pas de néologisme détecté
_ -> Inconnu
13 -> Nombre d'occurrence du néologisme
ou
1:3 -> ID_NEOLOGISME & Nombre d'occurrences
ou
1:2:13 -> ID_NEOLOGISME, index du l'expression si néologisme de plusieurs tokens, nb d'occurrences
```
### Annotation de SDMC
```
SDMC:MOTIFS
* -> Pas de motifs détectés
_ -> Inconnu
3:15 -> ID de l'occurrence dans la phrase (Si 3 motifs dans la phrase, alors id est compris entre 1 et 3), & nombre d'occurrences du motif dans le corpus
ou
1:3:12 -> ID_MOTIF_PHRASE, MOTIF_TOKEN_IDX, NB_OCCURRENCE
ou
ID_MOTIF, MOTIF_TOKEN_IDX, NB_OCCURRENCE
```
### Annotation de Morfetik
```
MORFETIK:LOCUTIONS
* -> Pas de locutions détectées
_ -> Inconnu
LOCUTION_TYPE, LOCUTION_TOKEN_IDX,LOCUTION_COUNT
LOC_ADV:1:4
```
\ No newline at end of file
<template>
<v-container class="my-5">
<v-card outlined class="my-5 px-6">
<v-card-title class="justify-center py-6">
<h1 class="display-3"> {{ $t('corpus-process-title' )}}</h1>
</v-card-title>
<div v-if="this.corpusProcess">
<!-- État du traitement -->
<v-card outlined class="my-5">
<v-card-title class="justify-center py-6">
<h2 class="display-1"> État du traitement </h2>
</v-card-title>
<v-card-text>
<CorpusProcessCard
class="my-5"
:corpusProcess="corpusProcess"
:corpusProcessFiles="corpusProcessFiles"/>
</v-card-text>
</v-card>
<!-- Corpus -->
<v-card outlined class="my-5">
<v-card-title class="justify-center py-6">
<h2 class="display-1"> Corpus</h2>
</v-card-title>
<v-card-text>
<CorporaCard
class="my-5"
:corpus="corpusSummary"/>
</v-card-text>
</v-card>
<!-- Chaîne de traitement -->
<v-card outlined class="my-5">
<v-card-title class="justify-center py-6">
<h2 class="display-1"> Chaîne de traitement</h2>
</v-card-title>
<v-card-text>
<PipelineCard :pipeline="pipeline"/>
</v-card-text>
</v-card>
</div>
<!-- Alerts -->
<div>
<v-alert type="error" dismissible v-model="errorMessageToggle"> {{ errorMessage }}
</v-alert>
</div>
</v-card>
</v-container>
</template>
<script>
import axios from '@/plugins/axios'
import CorporaCard from '@/components/UserPages/ProfileCorporaList/CorporaCard.vue';
import PipelineCard from '@/components/UserPages/PipelineCard.vue';
import CorpusProcessCard from '@/components/CheckCorpusProcess/CorpusProcessCard.vue';
export default {
name: 'CheckCorpusProcess',
components: {
CorporaCard,
PipelineCard,
CorpusProcessCard
},
data: () => ({
corpusProcess: null,
corpusSummary: null,
pipeline: null,
corpusProcessFiles: null,
errorMessageToggle: false,
errorMessage: null,
}),
async mounted () {
this.corpusProcess = await this.fetchCorpusProcess(this.$route.params.corpusprocessid);
await this.fetchCorpus();
await this.fetchPipeline();
if (this.corpusProcess.status == 'Finished') {
await this.fetchConlluAndProcessOutputsData();
}
},
methods: {
fetchCorpusProcess: async function(corpusProcessId) {
try {
const corpusProcessRes = await axios.get(`/corpusProcesses/${corpusProcessId}`);
console.log(corpusProcessRes);
const corpusProcess = corpusProcessRes.data.data.corpusProcess;
return corpusProcess;
}
catch (error) {
if (error.response) {
this.errorMessageToggle = true;
console.log(error.response);
if (error.response.status == 500) {
this.errorMessage = "Server error, bad request?"
}
else if (error.response.status == 404) {
this.errorMessage = "Corpus Process not found"
}
console.log("Received error response")
}
else if (error.request) {
this.errorMessageToggle = true;
this.errorMessage = "Never received any responses, is server up?";
console.log("Never received any responses, or request never left");
}
else {
console.log("Something else");
}
console.error(error);
return null;
}
},
fetchCorpus: async function() {
// No corpus process retrieved
if (!this.corpusProcess) {
return null;
}
const corpusId = this.corpusProcess.corpusId;
try {
const corpusRes = await axios.get(`/corpora/${corpusId}/summary`);
this.corpusSummary = corpusRes.data.data.corpusSummary;
}
catch(error) {
console.error("There was an error while trying to fetch corpus:");
console.error(error);
}
},
fetchPipeline: async function() {
// No corpus process retrieved
if (!this.corpusProcess) {
return null;
}
const pipelineId = this.corpusProcess.pipelineId;
try {
const pipelineRes = await axios.get(`/pipelines/${pipelineId}`);
this.pipeline = pipelineRes.data.data.pipeline;
}
catch (error) {
console.error('There was an error while trying to fetch pipeline:');
console.error(error);
}
},
fetchConlluAndProcessOutputsData: async function() {
const corpusProcessId = this.corpusProcess._id;
try {
const fetchedDataRes = await axios({
url: 'http://localhost:3001/get-files/'+corpusProcessId,
method: 'GET',
// responseType: 'blob',
});
this.corpusProcessFiles = fetchedDataRes.data.data;
}
catch(error) {
console.error(error);
}
}
}
}
</script>
<i18n>
{
"fr": {
"corpus-process-title": "Traitement de votre corpus",
"next": "Suivant"
},
"en": {
"corpus-process-title": "Your corpus process",
"next": "Next"
}
}
</i18n>
\ No newline at end of file
<template>
<v-card outlined v-if="!!corpusProcess">
<div v-if="corpusProcess.status == 'Finished'">
<v-card-title>Le traitement de votre corpus est fini.</v-card-title>
<v-card-text>
<v-btn color="success" @click="downloadItem(corpusProcessFiles.conllu, 'corpus.conllu')">Télécharger Conllu</v-btn>
<div
v-for="processOutput in corpusProcessFiles.processOutputs"
:key="processOutput._id"
>
<br/>
<v-btn color="success" @click="downloadItem(processOutput.content.data, `${processOutput.moduleName}_processOutput.txt`)">Télécharger {{ processOutput.content.title }}</v-btn>
</div>
</v-card-text>
<div id="download"></div>
</div>
<div v-if="corpusProcess.status == 'Failed'">
<p>Il y a eu une erreur lors du traitement de votre corpus.</p>
</div>
<div v-if="corpusProcess.status == 'Started'">
<v-card-title>Votre corpus est en cours de traitement.</v-card-title>
<v-card-text>
<div v-if="corpusProcess.currentProcessingModule == 'Exporter'">
Génération des fichiers ConLLu en cours.
</div>
<div v-else>
Le corpus est actuellement traité par <b>{{ corpusProcess.currentProcessingModule}}</b>
</div>
</v-card-text>
</div>
<div v-if="corpusProcess.status == 'Not started yet'">
CorpusProcess pas encore commencé
</div>
<div v-if="corpusProcess.status == 'Processing annotations'">
CorpusProcess en cours d'annotations
</div>
</v-card>
</template>
<script>
export default {
props: {
corpusProcess: Object,
corpusProcessFiles: Object
},
mounted() {
console.log(this.corpusProcessFiles);
// let fileURL = window.URL.createObjectURL(new Blob([this.corpusProcessFiles]));
//let divSelection = document.getElementById('download');
//firstLink.href = fileURL;
//firstLink.setAttribute('download', 'test.txt');
//firstLink.innerHTML = 'Lien de téléchargement';
//divSelection.appendChild(firstLink);
},
methods: {
downloadItem(item, fileName) {
const blob = new Blob([item], { type: 'application/txt' })
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = fileName;
link.click();
URL.revokeObjectURL(link.href);
}
}
}
</script>
\ No newline at end of file
...@@ -31,7 +31,22 @@ ...@@ -31,7 +31,22 @@
Si vous ne souhaitez pas laisser votre mail, vous pouvez retrouver l'état du traitement sur <a>ce lien</a>.<br/> Si vous ne souhaitez pas laisser votre mail, vous pouvez retrouver l'état du traitement sur <a>ce lien</a>.<br/>
Gardez-le précieusement. Gardez-le précieusement.
</p> </p>
<v-divider class="mb-6"/>
<br/>
<v-btn color="primary" @click="accessCorpusProcessPage"> Allez sur la page du traitement </v-btn>
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-container> </v-container>
</template> </template>
\ No newline at end of file
<script>
export default {
methods: {
accessCorpusProcessPage() {
// Maybe check that there corpusProcessId is not null
const corpusProcessId = sessionStorage.getItem('corpusProcessId');
this.$router.push('/corpusprocess/'+corpusProcessId);
}
}
}
</script>
\ No newline at end of file
...@@ -117,6 +117,7 @@ export default { ...@@ -117,6 +117,7 @@ export default {
this.corpusParameters = data; this.corpusParameters = data;
}, },
// Evaluate if we have to show the options or not (only for file-input & text-input) // Evaluate if we have to show the options or not (only for file-input & text-input)
// Maybe it should show even for profile corpora or public corpora
evaluateShow(activeTab, isCorpusNotUndefined) { evaluateShow(activeTab, isCorpusNotUndefined) {
if (!isCorpusNotUndefined) { if (!isCorpusNotUndefined) {
this.showParameters = false; this.showParameters = false;
...@@ -126,9 +127,10 @@ export default { ...@@ -126,9 +127,10 @@ export default {
} }
}, },
// Fetch userId if connected, else create it and store it // Fetch userId if connected, else create it and store it
// Not implemented yet, I put connected = true
fetchUserId() { fetchUserId() {
// TODO: verify if user connected // TODO: verify if user connected
const connected = false; const connected = true;
if (connected) { if (connected) {
return "connectedUserId"; return "connectedUserId";
...@@ -167,7 +169,7 @@ export default { ...@@ -167,7 +169,7 @@ export default {
case TEXT_INPUT: case TEXT_INPUT:
this.errorMessageToggle = true; this.errorMessageToggle = true;
this.errorMessage = "NOT IMPLEMENTED YET"; this.errorMessage = "NOT IMPLEMENTED YET";
this.submitTextInput(); //this.submitTextInput();
break; break;
case PROFILE_CORPUS: case PROFILE_CORPUS:
this.errorMessageToggle = true; this.errorMessageToggle = true;
...@@ -218,34 +220,57 @@ export default { ...@@ -218,34 +220,57 @@ export default {
res.data.data.uploadedFiles.forEach( el => { res.data.data.uploadedFiles.forEach( el => {
pathList.push({ source: el.path}); pathList.push({ source: el.path});
}); });
let corpora = { let corpus = {
createdBy: userId, createdBy: userId,
type: 'public', type: 'private',
creationDate: Date.now(), creationDate: Date.now(),
metadata: this.corpusParameters, metadata: this.corpusParameters,
documents: pathList documents: pathList
}; };
axios.post('/corpora', corpora) corpus.metadata.size = res.data.data.size;
.then( res => { this.postCorpus(corpus);
if (res.data.status !== "success") {
this.triggerError(res.data.message);
}
else {
sessionStorage.setItem('corpusId', res.data.data.corpus._id);
this.$router.push('/pipeline');
}
})
} }
}) })
.catch( (error) => { .catch( (error) => {
this.triggerError(error); this.triggerError(error);
}) })
}, },
submitTextInput() {
// Fetch userId or creates a new and store userId
let userId = this.fetchUserId();
if (!userId) {
// ERROR HERE
return;
}
// Il faudrait ici créer un fichier dans le serveur contenant le texte ajouté par l'utilisateur
let corpus = {
createdBy: userId,
type: 'private',
creationDate: Date.now(),
metadata: this.corpusParameters,
//documents: pathList
};
this.postCorpus(corpus);
},
triggerError(errorMessage) { triggerError(errorMessage) {
console.error(errorMessage); console.error(errorMessage);
this.errorMessageToggle = true; this.errorMessageToggle = true;
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
},
postCorpus(corpus) {
try {
axios.post('/corpora', corpus)
.then( res => {
if (res.data.status !== "success") {
this.triggerError(res.data.message);
}
else {
sessionStorage.setItem('corpusId', res.data.data.corpus._id);
this.$router.push('/pipeline');
}
})
}
catch(error) { throw Error(error); }
} }
} }
} }
......
...@@ -104,6 +104,8 @@ export default { ...@@ -104,6 +104,8 @@ export default {
// Create corpus process // Create corpus process
const res = await axios.post('/corpusProcesses', data); const res = await axios.post('/corpusProcesses', data);
const corpusProcessId = res.data.data.corpusProcess._id; const corpusProcessId = res.data.data.corpusProcess._id;
//Stores it
sessionStorage.setItem('corpusProcessId', corpusProcessId);
// Starts it // Starts it
await axios.post(`/corpusProcesses/${corpusProcessId}/start`); await axios.post(`/corpusProcesses/${corpusProcessId}/start`);
this.$router.push('/validation'); this.$router.push('/validation');
......
...@@ -20,13 +20,16 @@ ...@@ -20,13 +20,16 @@
<div v-else> <div v-else>
<p> Aucune option de pré-traitement n'a été sélectionnée</p> <p> Aucune option de pré-traitement n'a été sélectionnée</p>
</div> </div>
<v-divider/>
<br/>
<h3>Modules choisis</h3> <h3>Modules choisis</h3>
<br/> <br/>
<div <div
v-for="process in pipeline.processes" v-for="process in pipeline.processes"
:key="process._id" :key="process._id"
> >
<v-divider/>
<br/>
<h4> {{ process.moduleName }} </h4> <h4> {{ process.moduleName }} </h4>
<br/> <br/>
<div <div
...@@ -36,6 +39,7 @@ ...@@ -36,6 +39,7 @@
<span v-if="parameter.value"><p><span class="font-weight-medium">{{ parameter.name }}</span> : {{ parameter.value }}</p></span> <span v-if="parameter.value"><p><span class="font-weight-medium">{{ parameter.name }}</span> : {{ parameter.value }}</p></span>
<span v-else><p><span class="font-weight-medium">{{ parameter.name }}</span> : Non rempli</p></span> <span v-else><p><span class="font-weight-medium">{{ parameter.name }}</span> : Non rempli</p></span>
</div> </div>
</div> </div>
</v-card-text> </v-card-text>
......
<template> <template>
<v-card outlined v-if="!!corpus"> <v-card outlined v-if="!!corpus">
<v-card-title> <v-card-title>
{{ corpus.metadata.title }} Nom du corpus : {{ corpus.metadata.title }}
</v-card-title> </v-card-title>
<v-card-text> <v-card-text>
<v-row> <v-row>