diff --git a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts index c64c128017cfe15ccd475c5bb795bae290a6ec97..cdf1392dd20bc280390610aa1f5c7ba42847b9d1 100644 --- a/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts +++ b/src/app/components/shared/_dialogs/spacy-dialog/spacy-dialog.component.ts @@ -2,10 +2,11 @@ import { AfterContentInit, Component, Inject, OnInit, ViewChild } from '@angular import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { CreateCommentComponent } from '../create-comment/create-comment.component'; -import { SpacyService, Model, SpacyKeyword } from '../../../../services/http/spacy.service'; +import { SpacyService, SpacyKeyword } from '../../../../services/http/spacy.service'; import { LanguagetoolService } from '../../../../services/http/languagetool.service'; import { Comment } from '../../../../models/comment'; import { DialogActionButtonsComponent } from '../../dialog/dialog-action-buttons/dialog-action-buttons.component'; +import { Model } from '../../../../services/http/spacy.interface'; export interface Keyword { word: string; diff --git a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog-task.ts b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog-task.ts index b07cef2224808ff33b5cb51e2480c964eb6f0450..c1d9579aae781d024813312a417c2bb93d24c5d3 100644 --- a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog-task.ts +++ b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog-task.ts @@ -1,11 +1,12 @@ import { Room } from '../../../../models/room'; -import { Model, SpacyKeyword, SpacyService } from '../../../../services/http/spacy.service'; +import { SpacyKeyword, SpacyService } from '../../../../services/http/spacy.service'; import { CommentService } from '../../../../services/http/comment.service'; -import { Comment } from '../../../../models/comment'; -import { Language, LanguagetoolService } from '../../../../services/http/languagetool.service'; +import { Comment, Language } from '../../../../models/comment'; +import { Language as Lang, LanguagetoolService } from '../../../../services/http/languagetool.service'; import { CreateCommentKeywords } from '../../../../utils/create-comment-keywords'; import { TSMap } from 'typescript-map'; import { HttpErrorResponse } from '@angular/common/http'; +import { Model } from '../../../../services/http/spacy.interface'; const concurrentCallsPerTask = 4; @@ -66,41 +67,43 @@ export class WorkerDialogTask { } const commentModel = currentComment.language.toLowerCase(); const model = commentModel !== 'auto' ? commentModel.toLowerCase() as Model : - this.languagetoolService.mapLanguageToSpacyModel(result.result.language.detectedLanguage.code as Language); + this.languagetoolService.mapLanguageToSpacyModel(result.result.language.detectedLanguage.code as Lang); if (model === 'auto') { this.finishSpacyCall(FinishType.badSpelled, currentIndex); return; } this.spacyService.getKeywords(result.text, model) - .subscribe(newKeywords => this.finishSpacyCall(FinishType.completed, currentIndex, newKeywords), + .subscribe(newKeywords => + this.finishSpacyCall(FinishType.completed, currentIndex, newKeywords, model.toUpperCase() as Language), __ => this.finishSpacyCall(FinishType.failed, currentIndex)); }, _ => this.finishSpacyCall(FinishType.failed, currentIndex)); } - private finishSpacyCall(finishType: FinishType, index: number, tags?: SpacyKeyword[]): void { + private finishSpacyCall(finishType: FinishType, index: number, tags?: SpacyKeyword[], lang?: Language): void { if (finishType === FinishType.completed) { - this.patchToServer(tags, index); + this.patchToServer(tags, index, lang); } else if (finishType === FinishType.badSpelled) { this.statistics.badSpelled++; - this.patchToServer([], index); + this.patchToServer([], index, Language.auto); } else { this.statistics.failed++; this.callSpacy(index + concurrentCallsPerTask); } } - private patchToServer(tags: SpacyKeyword[], index: number) { + private patchToServer(tags: SpacyKeyword[], index: number, language: Language) { const changes = new TSMap<string, string>(); changes.set('keywordsFromSpacy', JSON.stringify(tags)); + changes.set('language', language); this.commentService.patchComment(this._comments[index], changes).subscribe(_ => { this.statistics.succeeded++; + this.callSpacy(index + concurrentCallsPerTask); }, patchError => { this.statistics.failed++; if (patchError instanceof HttpErrorResponse && patchError.status === 403) { this.error = 'forbidden'; } - }, () => { this.callSpacy(index + concurrentCallsPerTask); }); } diff --git a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.html b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.html index 09e7320f9523027e0795585fc6197f2a992c5c7a..6b4d16332a440e1e39e0146ce131f67752d997f3 100644 --- a/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.html +++ b/src/app/components/shared/_dialogs/worker-dialog/worker-dialog.component.html @@ -16,13 +16,17 @@ <mat-icon matTooltip="{{'worker-dialog.comments' | translate}}">comment</mat-icon> <span>{{task.statistics.succeeded}}/{{ task.statistics.length}}</span> <mat-icon *ngIf="task.statistics.badSpelled" style="color: darkorange" - matTooltip="{{'worker-dialog.bad-spelled' | translate}}">warning</mat-icon> + matTooltip="{{'worker-dialog.bad-spelled' | translate}}">warning + </mat-icon> <span *ngIf="task.statistics.badSpelled"> {{task.statistics.badSpelled}} </span> - <mat-icon *ngIf="task.statistics.failed" style="color: var(--red)" - matTooltip="{{'worker-dialog.failed' | translate}}">error</mat-icon> - <span *ngIf="task.statistics.failed"> + </div> + <div *ngIf="!task.error && task.statistics.failed" class="entryRow"> + <mat-icon style="color: var(--red)" + matTooltip="{{'worker-dialog.failed' | translate}}">error + </mat-icon> + <span> {{task.statistics.failed}} </span> </div> diff --git a/src/app/models/comment.ts b/src/app/models/comment.ts index 5666ae256ff394f9dd3ccdfb7951688f4deda55e..42a2fb55f86e291fb2d3599372f516d0ee7cfb4a 100644 --- a/src/app/models/comment.ts +++ b/src/app/models/comment.ts @@ -1,5 +1,6 @@ -import { Model, SpacyKeyword } from '../services/http/spacy.service'; +import { SpacyKeyword } from '../services/http/spacy.service'; import { CorrectWrong } from './correct-wrong.enum'; +import { Model } from '../services/http/spacy.interface'; export class Comment { id: string; diff --git a/src/app/services/http/languagetool.service.ts b/src/app/services/http/languagetool.service.ts index 5a3fea983bf29a2df95b61759ce242d2f868a177..18ebced281d31496de54c5d66492cc9b64de3ac2 100644 --- a/src/app/services/http/languagetool.service.ts +++ b/src/app/services/http/languagetool.service.ts @@ -2,8 +2,8 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BaseHttpService } from './base-http.service'; import { catchError } from 'rxjs/operators'; -import { Model } from './spacy.service'; import { Observable } from 'rxjs'; +import { Model } from './spacy.interface'; export type Language = 'de' | 'de-AT' | 'de-CH' | 'de-DE' | 'en' | 'en-AU' | 'en-CA' | 'en-GB' | 'en-US' | diff --git a/src/app/services/http/spacy.interface.ts b/src/app/services/http/spacy.interface.ts new file mode 100644 index 0000000000000000000000000000000000000000..7db42d0cea12ef8c1a0173aa4e7c07264feb616f --- /dev/null +++ b/src/app/services/http/spacy.interface.ts @@ -0,0 +1,140 @@ +export type Model = 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'pt' | 'auto'; + +export type EnglishParserLabels = 'ROOT' | //None + 'acl' | //clausal modifier of noun (adjectival clause) + 'acomp' | //adjectival complement + 'advcl' | //adverbial clause modifier + 'advmod' | //adverbial modifier + 'agent' | //agent + 'amod' | //adjectival modifier + 'appos' | //appositional modifier + 'attr' | //attribute + 'aux' | //auxiliary + 'auxpass' | //auxiliary (passive) + 'case' | //case marking + 'cc' | //coordinating conjunction + 'ccomp' | //clausal complement + 'compound' | //compound + 'conj' | //conjunct + 'csubj' | //clausal subject + 'csubjpass' | //clausal subject (passive) + 'dative' | //dative + 'dep' | //unclassified dependent + 'det' | //determiner + 'dobj' | //direct object + 'expl' | //expletive + 'intj' | //interjection + 'mark' | //marker + 'meta' | //meta modifier + 'neg' | //negation modifier + 'nmod' | //modifier of nominal + 'npadvmod' | //noun phrase as adverbial modifier + 'nsubj' | //nominal subject + 'nsubjpass' | //nominal subject (passive) + 'nummod' | //numeric modifier + 'oprd' | //object predicate + 'parataxis' | //parataxis + 'pcomp' | //complement of preposition + 'pobj' | //object of preposition + 'poss' | //possession modifier + 'preconj' | //pre-correlative conjunction + 'predet' | //None + 'prep' | //prepositional modifier + 'prt' | //particle + 'punct' | //punctuation + 'quantmod' | //modifier of quantifier + 'relcl' | //relative clause modifier + 'xcomp'; //open clausal complement + +export type GermanParserLabels = 'ROOT' | 'ac' | 'adc' | 'ag' | 'ams' | 'app' | 'avc' | 'cc' | 'cd' | 'cj' | 'cm' | + 'cp' | 'cvc' | 'da' | 'dep' | 'dm' | 'ep' | 'ju' | 'mnr' | 'mo' | 'ng' | 'nk' | 'nmc' | 'oa' | 'oc' | 'og' | 'op' | + 'par' | 'pd' | 'pg' | 'ph' | 'pm' | 'pnc' | 'punct' | 'rc' | 're' | 'rs' | 'sb' | 'sbp' | 'svp' | 'uc' | 'vo'; + +export type FrenchParserLabels = 'ROOT' | //None + 'acl' | //clausal modifier of noun (adjectival clause) + 'acl:relcl' | //None + 'advcl' | //adverbial clause modifier + 'advmod' | //adverbial modifier + 'amod' | //adjectival modifier + 'appos' | //appositional modifier + 'aux:pass' | //None + 'aux:tense' | //None + 'case' | //case marking + 'cc' | //coordinating conjunction + 'ccomp' | //clausal complement + 'conj' | //conjunct + 'cop' | //copula + 'dep' | //unclassified dependent + 'det' | //determiner + 'expl:comp' | //None + 'expl:pass' | //None + 'expl:subj' | //None + 'fixed' | //fixed multiword expression + 'flat:foreign' | //None + 'flat:name' | //None + 'iobj' | //indirect object + 'mark' | //marker + 'nmod' | //modifier of nominal + 'nsubj' | //nominal subject + 'nsubj:pass' | //None + 'nummod' | //numeric modifier + 'obj' | //object + 'obl:agent' | //None + 'obl:arg' | //None + 'obl:mod' | //None + 'parataxis' | //parataxis + 'punct' | //punctuation + 'vocative' | //vocative + 'xcomp'; //open clausal complement + +export const GERMAN_TRANSLATION = { + // eslint-disable-next-line @typescript-eslint/naming-convention + ROOT: 'Satzkernelement', + ac: 'Adpositionaler Fallmarker', + adc: 'Adjektivkomponente', + ag: 'Genitivattribut', + ams: 'Messargument des Adjektivs', + app: 'Apposition', + avc: 'Adverbiale Satzkomponente', + cc: 'Koordinierende Konjunktion', + cd: 'Koordinierende Konjunktion', + cj: 'Konjunktion', + cm: 'Vergleichende Konjunktion', + cp: 'Komplementierer', + cvc: 'Kollokative Verbkonstruktion', + da: 'Dativ', + dep: 'Nicht klassifizierte Abhängigkeit', + dm: 'Diskursmarker', + ep: 'Kraftausdruck es', + ju: 'Verbindungsstelle', + mnr: 'Postnominaler Modifikator', + mo: 'Modifikator', + ng: 'Negation', + nk: 'Nomen Kernelement', + nmc: 'Numerische Komponente', + oa: 'Akkusativobjekt', + oc: 'Klauselobjekt', + og: 'Genitivobjekt', + op: 'Präpositionalobjekt', + par: 'Klammerelement', + pd: 'Prädikat', + pg: 'Genitiv', + ph: 'Platzhalter', + pm: 'Morphologisches Teilchen', + pnc: 'Eigenname Komponente', + punct: 'Zeichensetzung', + rc: 'Relativsatz', + re: 'Wiederholtes Element', + rs: 'Indirekte Rede', + sb: 'Subjekt', + sbp: 'Passiviertes Subject', + svp: 'Trennbares Verbpräfix', + uc: 'Einheitskomponente', + vo: 'Vokativ', +}; + +export const DEFAULT_NOUN_LABELS = { + de: ['sb', 'op', 'og', 'da', 'oa'] as GermanParserLabels[], + en: [] as EnglishParserLabels[], + fr: [] as FrenchParserLabels[], +}; diff --git a/src/app/services/http/spacy.service.ts b/src/app/services/http/spacy.service.ts index 6cf3fe6169d3c2debea9dc490c49cc306d292785..5b5e155fc38f685b7e0a7978b044edd1122fe05e 100644 --- a/src/app/services/http/spacy.service.ts +++ b/src/app/services/http/spacy.service.ts @@ -4,146 +4,13 @@ import { Observable } from 'rxjs'; import { BaseHttpService } from './base-http.service'; import { catchError, map, tap } from 'rxjs/operators'; import { CreateCommentKeywords } from '../../utils/create-comment-keywords'; - -export type Model = 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'pt' | 'auto'; +import { DEFAULT_NOUN_LABELS, Model } from './spacy.interface'; export interface SpacyKeyword { lemma: string; dep: string[]; } -type EnglishParserLabels = 'ROOT' | //None - 'acl' | //clausal modifier of noun (adjectival clause) - 'acomp' | //adjectival complement - 'advcl' | //adverbial clause modifier - 'advmod' | //adverbial modifier - 'agent' | //agent - 'amod' | //adjectival modifier - 'appos' | //appositional modifier - 'attr' | //attribute - 'aux' | //auxiliary - 'auxpass' | //auxiliary (passive) - 'case' | //case marking - 'cc' | //coordinating conjunction - 'ccomp' | //clausal complement - 'compound' | //compound - 'conj' | //conjunct - 'csubj' | //clausal subject - 'csubjpass' | //clausal subject (passive) - 'dative' | //dative - 'dep' | //unclassified dependent - 'det' | //determiner - 'dobj' | //direct object - 'expl' | //expletive - 'intj' | //interjection - 'mark' | //marker - 'meta' | //meta modifier - 'neg' | //negation modifier - 'nmod' | //modifier of nominal - 'npadvmod' | //noun phrase as adverbial modifier - 'nsubj' | //nominal subject - 'nsubjpass' | //nominal subject (passive) - 'nummod' | //numeric modifier - 'oprd' | //object predicate - 'parataxis' | //parataxis - 'pcomp' | //complement of preposition - 'pobj' | //object of preposition - 'poss' | //possession modifier - 'preconj' | //pre-correlative conjunction - 'predet' | //None - 'prep' | //prepositional modifier - 'prt' | //particle - 'punct' | //punctuation - 'quantmod' | //modifier of quantifier - 'relcl' | //relative clause modifier - 'xcomp'; //open clausal complement - -type GermanParserLabels = 'ROOT' | //None - 'ac' | //adpositional case marker - 'adc' | //adjective component - 'ag' | //genitive attribute - 'ams' | //measure argument of adjective - 'app' | //apposition - 'avc' | //adverbial phrase component - 'cc' | //coordinating conjunction - 'cd' | //coordinating conjunction - 'cj' | //conjunct - 'cm' | //comparative conjunction - 'cp' | //complementizer - 'cvc' | //collocational verb construction - 'da' | //dative - 'dep' | //unclassified dependent - 'dm' | //discourse marker - 'ep' | //expletive es - 'ju' | //junctor - 'mnr' | //postnominal modifier - 'mo' | //modifier - 'ng' | //negation - 'nk' | //noun kernel element - 'nmc' | //numerical component - 'oa' | //accusative object - 'oc' | //clausal object - 'og' | //genitive object - 'op' | //prepositional object - 'par' | //parenthetical element - 'pd' | //predicate - 'pg' | //phrasal genitive - 'ph' | //placeholder - 'pm' | //morphological particle - 'pnc' | //proper noun component - 'punct' | //punctuation - 'rc' | //relative clause - 're' | //repeated element - 'rs' | //reported speech - 'sb' | //subject - 'sbp' | //passivized subject (PP) - 'svp' | //separable verb prefix - 'uc' | //unit component - 'vo'; //vocative - -type FrenchParserLabels = 'ROOT' | //None - 'acl' | //clausal modifier of noun (adjectival clause) - 'acl:relcl' | //None - 'advcl' | //adverbial clause modifier - 'advmod' | //adverbial modifier - 'amod' | //adjectival modifier - 'appos' | //appositional modifier - 'aux:pass' | //None - 'aux:tense' | //None - 'case' | //case marking - 'cc' | //coordinating conjunction - 'ccomp' | //clausal complement - 'conj' | //conjunct - 'cop' | //copula - 'dep' | //unclassified dependent - 'det' | //determiner - 'expl:comp' | //None - 'expl:pass' | //None - 'expl:subj' | //None - 'fixed' | //fixed multiword expression - 'flat:foreign' | //None - 'flat:name' | //None - 'iobj' | //indirect object - 'mark' | //marker - 'nmod' | //modifier of nominal - 'nsubj' | //nominal subject - 'nsubj:pass' | //None - 'nummod' | //numeric modifier - 'obj' | //object - 'obl:agent' | //None - 'obl:arg' | //None - 'obl:mod' | //None - 'parataxis' | //parataxis - 'punct' | //punctuation - 'vocative' | //vocative - 'xcomp'; //open clausal complement - -const LABELS = { - de: ['sb', 'pd', 'og', 'ag', 'app', 'da', 'oa', 'nk', 'mo', 'cj'] as GermanParserLabels[], - en: [] as EnglishParserLabels[], - fr: [] as FrenchParserLabels[], -}; - type KeywordType = 'entity' | 'noun'; interface NounKeyword { @@ -178,7 +45,7 @@ export class SpacyService extends BaseHttpService { } static getLabelsForModel(model: Model): string[] { - return LABELS[model]; + return DEFAULT_NOUN_LABELS[model]; } getKeywords(text: string, model: Model): Observable<SpacyKeyword[]> {