From f23355f6a4909454f9a154cc79f5f069f6b42f41 Mon Sep 17 00:00:00 2001 From: sosguns2002 Date: Sat, 10 Mar 2018 19:32:45 +0200 Subject: [PATCH] Userid and server address as parameters --- .../.angular-cli.json | 6 +- .../ng-package.json | 11 + .../package.json | 34 +- .../public_api.ts | 1 + .../src/app/app.component.html | 3 +- .../src/app/app.module.ts | 31 +- .../configuration/configuration.service.ts | 49 +- .../resultspreview.component.ts | 12 +- .../settings/settings.component.ts | 40 +- .../src/app/contents/autosize.directive.ts | 28 + .../src/app/contents/contents.module.ts | 8 +- .../src/app/contents/contents.service.ts | 46 +- .../contentstable/contentstable.component.ts | 7 +- .../interactivemining.component.css | 0 .../interactivemining.component.html | 2 + .../interactivemining.component.spec.ts | 25 + .../interactivemining.component.ts | 31 + .../interactivemining.module.ts | 33 + .../manageprofiles.component.ts | 105 +- .../manageprofiles/manageprofiles.service.ts | 59 +- .../app/saveprofile/saveprofile.service.ts | 13 +- .../src/app/util.ts | 12 +- .../src/assets/css/dl119_files/custom.css | 941 ------------------ .../src/assets/css/interactive-mining.css | 937 +++++++++++++++++ .../src/index.html | 1 - .../madoap/src/madserverv3.py | 332 +++--- 26 files changed, 1467 insertions(+), 1300 deletions(-) create mode 100644 interactive-mining-angular-frontend/ng-package.json create mode 100644 interactive-mining-angular-frontend/public_api.ts create mode 100644 interactive-mining-angular-frontend/src/app/contents/autosize.directive.ts create mode 100644 interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.css create mode 100644 interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.html create mode 100644 interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.spec.ts create mode 100644 interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.ts create mode 100644 interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.module.ts create mode 100644 interactive-mining-angular-frontend/src/assets/css/interactive-mining.css diff --git a/interactive-mining-angular-frontend/.angular-cli.json b/interactive-mining-angular-frontend/.angular-cli.json index 30ba507..e78a577 100644 --- a/interactive-mining-angular-frontend/.angular-cli.json +++ b/interactive-mining-angular-frontend/.angular-cli.json @@ -1,7 +1,7 @@ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "project": { - "name": "interactiveminingv3" + "name": "interactivemining" }, "apps": [ { @@ -19,7 +19,9 @@ "testTsconfig": "tsconfig.spec.json", "prefix": "app", "styles": [ - "styles.css" + "styles.css", + "./assets/css/interactive-mining.css", + "./assets/css/animations.css" ], "scripts": [ "../node_modules/jquery/dist/jquery.min.js", diff --git a/interactive-mining-angular-frontend/ng-package.json b/interactive-mining-angular-frontend/ng-package.json new file mode 100644 index 0000000..4bd9b32 --- /dev/null +++ b/interactive-mining-angular-frontend/ng-package.json @@ -0,0 +1,11 @@ +{ + "$schema": "./node_modules/ng-packagr/ng-package.schema.json", + "name": "interactive-mining", + "ngPackage": { + "lib": { + "entryFile": "public_api.ts", + "comments" : "none" + }, + "dest": "../../dist/interactive-mining-lib" + } +} diff --git a/interactive-mining-angular-frontend/package.json b/interactive-mining-angular-frontend/package.json index 23aeb3f..17aa887 100644 --- a/interactive-mining-angular-frontend/package.json +++ b/interactive-mining-angular-frontend/package.json @@ -1,6 +1,6 @@ { "name": "interactiveminingv3", - "version": "0.0.0", + "version": "0.5.0", "license": "MIT", "scripts": { "ng": "ng", @@ -8,7 +8,8 @@ "build": "ng build", "test": "ng test", "lint": "ng lint", - "e2e": "ng e2e" + "e2e": "ng e2e", + "packagr": "ng-packagr -p ng-package.json" }, "private": true, "dependencies": { @@ -22,34 +23,33 @@ "@angular/platform-browser-dynamic": "^4.2.4", "@angular/router": "^4.2.4", "core-js": "^2.4.1", + "rxjs": "^5.5.6", + "zone.js": "^0.8.19", "file-saver": "^1.3.3", "jquery": "^3.2.1", - "ngx-cookie-service": "^1.0.10", "ngx-pagination": "^3.1.0", - "ngx-textarea-autosize": "^1.1.1", - "rxjs": "^5.4.2", - "uikit": "^3.0.0-beta.38", - "zone.js": "^0.8.14" + "uikit": "^3.0.0-beta.38" }, "devDependencies": { - "@angular/cli": "1.3.0", + "@angular/cli": "^1.3.0", "@angular/compiler-cli": "^4.2.4", "@angular/language-service": "^4.2.4", - "@types/jasmine": "~2.5.53", + "@types/jasmine": "~2.8.3", "@types/jasminewd2": "~2.0.2", - "@types/node": "~6.0.60", - "codelyzer": "~3.1.1", - "jasmine-core": "~2.6.2", - "jasmine-spec-reporter": "~4.1.0", - "karma": "~1.7.0", - "karma-chrome-launcher": "~2.1.1", + "@types/node": "~8.0.30", + "codelyzer": "^4.0.1", + "jasmine-core": "~2.8.0", + "jasmine-spec-reporter": "~4.2.1", + "karma": "~2.0.0", + "karma-chrome-launcher": "~2.2.0", "karma-cli": "~1.0.1", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", + "ng-packagr": "^1.6.0", "protractor": "~5.1.2", - "ts-node": "~3.2.0", - "tslint": "~5.3.2", + "ts-node": "~4.1.0", + "tslint": "~5.9.1", "typescript": "~2.3.3" } } diff --git a/interactive-mining-angular-frontend/public_api.ts b/interactive-mining-angular-frontend/public_api.ts new file mode 100644 index 0000000..ee00306 --- /dev/null +++ b/interactive-mining-angular-frontend/public_api.ts @@ -0,0 +1 @@ +export * from './src/app/interactivemining/interactivemining.module'; diff --git a/interactive-mining-angular-frontend/src/app/app.component.html b/interactive-mining-angular-frontend/src/app/app.component.html index 01f14ce..cc7d99a 100644 --- a/interactive-mining-angular-frontend/src/app/app.component.html +++ b/interactive-mining-angular-frontend/src/app/app.component.html @@ -1,2 +1 @@ - - + diff --git a/interactive-mining-angular-frontend/src/app/app.module.ts b/interactive-mining-angular-frontend/src/app/app.module.ts index 377ceaa..584d9e9 100644 --- a/interactive-mining-angular-frontend/src/app/app.module.ts +++ b/interactive-mining-angular-frontend/src/app/app.module.ts @@ -1,33 +1,16 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; -import { HttpClientModule } from '@angular/common/http'; +import {NgModule} from '@angular/core'; -import { AppComponent } from './app.component'; -import { CookieService } from 'ngx-cookie-service'; -import { ContentModule } from './contents/contents.module'; -import { AppRoutingModule } from './app-routing.module'; -import { StepsnvabarComponent } from './stepsnvabar/stepsnvabar.component'; -import {ConfigurationModule} from './configuration/configuration.module'; -import {SaveprofileModule} from './saveprofile/saveprofile.module'; -import {ManagprofilesModule} from './manageprofiles/manageprofiles.module'; -import {HttpModule} from '@angular/http'; +import {AppComponent} from './app.component'; +import {InteractiveMiningModule} from './interactivemining/interactivemining.module'; @NgModule({ declarations: [ - AppComponent, - StepsnvabarComponent + AppComponent ], imports: [ - BrowserModule, - ManagprofilesModule, - ContentModule, - ConfigurationModule, - SaveprofileModule, - HttpClientModule, - HttpModule, - AppRoutingModule + InteractiveMiningModule ], - providers: [CookieService], bootstrap: [AppComponent] }) -export class AppModule { } +export class AppModule { +} diff --git a/interactive-mining-angular-frontend/src/app/configuration/configuration.service.ts b/interactive-mining-angular-frontend/src/app/configuration/configuration.service.ts index 419d7ea..1b05e51 100644 --- a/interactive-mining-angular-frontend/src/app/configuration/configuration.service.ts +++ b/interactive-mining-angular-frontend/src/app/configuration/configuration.service.ts @@ -1,8 +1,7 @@ -import { Injectable } from '@angular/core'; +import {Injectable} from '@angular/core'; import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; import {Util} from '../util'; import {Observable} from 'rxjs/Observable'; -import {ProfileData} from '../manageprofiles/profile-data'; import {Settings} from './settings/settings'; import {DocSamplesMetadata} from './doc-samples-metadata'; @@ -11,25 +10,23 @@ export class ConfigurationService { private util: Util = new Util(); - private getDocSamplesUrl = 'http://localhost:8080/getdocsamples'; - private uploadDocumentsUrl = 'http://localhost:8080/uploaddocuments'; - private chooseSampleUrl = 'http://localhost:8080/choosedocsample'; - private alreadyDocumentsUrl = 'http://localhost:8080/alreadydocuments'; - private runMiningUrl = 'http://localhost:8080/runmining'; - private prepareSavedProfileUrl = 'http://localhost:8080/preparesavedprofile'; + private userId = ''; + private backendServerAddress = ''; - constructor(private http: HttpClient) { } + private getDocSamplesUrl = '/getdocsamples'; + private uploadDocumentsUrl = '/uploaddocuments'; + private chooseSampleUrl = '/choosedocsample'; + private alreadyDocumentsUrl = '/alreadydocuments'; + private runMiningUrl = '/runmining'; + private prepareSavedProfileUrl = '/preparesavedprofile'; - private _getHeaders(): Headers { - const header = new Headers({ - 'Content-Type': 'application/json' - }); - - return header; + constructor(private http: HttpClient) { + this.userId = this.util.getUserId(); + this.backendServerAddress = this.util.getBackendServerAddress(); } getDocSamples(): Observable { - return this.http.get(this.getDocSamplesUrl, { withCredentials: true }) + return this.http.get(this.backendServerAddress + this.getDocSamplesUrl + `?user=${this.userId}`) .map(data => data['documents']) .catch(this.util.handleError); } @@ -37,37 +34,39 @@ export class ConfigurationService { uploadDocuments(file: File): Observable { const formData: FormData = new FormData(); formData.append('upload', file, file.name); + formData.append('user', this.userId); const params = new HttpParams(); const options = { headers: new HttpHeaders().set('Accept', 'application/json').delete('Content-Type'), params: params, - reportProgress: true, - withCredentials: true, + reportProgress: true }; - return this.http.post(this.uploadDocumentsUrl, formData, options) + return this.http.post(this.backendServerAddress + this.uploadDocumentsUrl, formData, options) .map(res => res['data']) .catch(this.util.handleError); } chooseDocumentsSample(choise: string): Observable { - return this.http.post(this.chooseSampleUrl, {docsample: choise}, { withCredentials: true }) + return this.http.post(this.backendServerAddress + this.chooseSampleUrl, {user: this.userId, docsample: choise}) .map(res => res['data']) .catch(this.util.handleError); } getLoadedDocumentsNumber(): Observable { - return this.http.get(this.alreadyDocumentsUrl, { withCredentials: true }) + return this.http.get(this.backendServerAddress + this.alreadyDocumentsUrl + `?user=${this.userId}`) .catch(this.util.handleError); } - runMining(parameters: string): Observable { - return this.http.post(this.runMiningUrl, - parameters, { withCredentials: true }) + runMining(parameters: Settings): Observable { + return this.http.post(this.backendServerAddress + this.runMiningUrl, + {user: this.userId, parameters: parameters}) .catch(this.util.handleError); } saveProfileParameters(parameters: Settings): Observable { - return this.http.post(this.prepareSavedProfileUrl, parameters, { withCredentials: true }) + const concepts = localStorage.getItem('concepts'); + return this.http.post(this.backendServerAddress + this.prepareSavedProfileUrl, + {user: this.userId, concepts: concepts, parameters: parameters}) .catch(this.util.handleError); } diff --git a/interactive-mining-angular-frontend/src/app/configuration/resultspreview/resultspreview.component.ts b/interactive-mining-angular-frontend/src/app/configuration/resultspreview/resultspreview.component.ts index 48a062f..46ae878 100644 --- a/interactive-mining-angular-frontend/src/app/configuration/resultspreview/resultspreview.component.ts +++ b/interactive-mining-angular-frontend/src/app/configuration/resultspreview/resultspreview.component.ts @@ -134,7 +134,7 @@ export class ResultspreviewComponent implements OnInit { // display wait message this.runingMining = true; // document.getElementById('wait-spinner-modal-center').addClass("uk-open"); - this.configurationService.runMining(JSON.stringify(this.getSettingsFromLocalStorage())) + this.configurationService.runMining(this.getSettingsFromLocalStorage()) .subscribe( res => { // hide wait message this.runingMining = false; @@ -149,8 +149,9 @@ export class ResultspreviewComponent implements OnInit { console.log(res.matches.length); this.resultsArray.length = 0; let matchcounter = 0; - Object.entries(res.matches).forEach( - ([title, matches]) => { + for (let title in res.matches) { + if (title) { + const matches = res.matches[title]; let resultClass: DocumentResult = new DocumentResult(); resultClass.docTitle = title; let matchesArray: Array = []; @@ -169,7 +170,7 @@ export class ResultspreviewComponent implements OnInit { // hightlight acknowledgment keywords for (let ackn of values.acknmatch) { const search_regexp = new RegExp(ackn, 'g'); - context = context.replace(search_regexp, '' + ackn + ''); + context = context.replace(search_regexp, '' + ackn + ''); } // hightlight negative words for (let negword of JSON.parse(localStorage.getItem('negwords'))) { @@ -184,7 +185,8 @@ export class ResultspreviewComponent implements OnInit { this.resultsArray.push(resultClass); this.prev_matches_number = this.matches_number; this.matches_number = matchcounter + ''; - }); + } + } }); } } diff --git a/interactive-mining-angular-frontend/src/app/configuration/settings/settings.component.ts b/interactive-mining-angular-frontend/src/app/configuration/settings/settings.component.ts index 0534a71..67cfa5e 100644 --- a/interactive-mining-angular-frontend/src/app/configuration/settings/settings.component.ts +++ b/interactive-mining-angular-frontend/src/app/configuration/settings/settings.component.ts @@ -59,24 +59,26 @@ export class SettingsComponent implements OnInit { }; // show positive phrases this.positivePhrasesArray.length = 0; - Object.entries(JSON.parse(localStorage.getItem('poswords'))).forEach( - ([key, value]) => { + const posphrases = JSON.parse(localStorage.getItem('poswords')); + for (let key in posphrases) { + if (key) { const content = new Phrase(); content.phrase = key; - content.weight = value; + content.weight = posphrases[key]; this.positivePhrasesArray.push(content); } - ); + } // show negative phrases this.negativePhrasesArray.length = 0; - Object.entries(JSON.parse(localStorage.getItem('negwords'))).forEach( - ([key, value]) => { + const negphrases = JSON.parse(localStorage.getItem('negwords')); + for (let key in negphrases) { + if (key) { const content = new Phrase(); content.phrase = key; - content.weight = value; - this.negativePhrasesArray.push(content); + content.weight = negphrases[key]; + this.positivePhrasesArray.push(content); } - ); + } } getSettingsFromLocalStorage(): Settings { @@ -116,25 +118,27 @@ export class SettingsComponent implements OnInit { if (positive) { localStorage.setItem('poswords', phrases); this.positivePhrasesArray.length = 0; - Object.entries(JSON.parse(localStorage.getItem('poswords'))).forEach( - ([key, value]) => { + const posphrases = JSON.parse(localStorage.getItem('poswords')); + for (let key in posphrases) { + if (key) { const content = new Phrase(); content.phrase = key; - content.weight = value; + content.weight = posphrases[key]; this.positivePhrasesArray.push(content); } - ); + } } else { localStorage.setItem('negwords', phrases); this.negativePhrasesArray.length = 0; - Object.entries(JSON.parse(localStorage.getItem('negwords'))).forEach( - ([key, value]) => { + const negphrases = JSON.parse(localStorage.getItem('negwords')); + for (let key in negphrases) { + if (key) { const content = new Phrase(); content.phrase = key; - content.weight = value; - this.negativePhrasesArray.push(content); + content.weight = negphrases[key]; + this.positivePhrasesArray.push(content); } - ); + } } } diff --git a/interactive-mining-angular-frontend/src/app/contents/autosize.directive.ts b/interactive-mining-angular-frontend/src/app/contents/autosize.directive.ts new file mode 100644 index 0000000..c486a68 --- /dev/null +++ b/interactive-mining-angular-frontend/src/app/contents/autosize.directive.ts @@ -0,0 +1,28 @@ +import { AfterContentChecked, Directive, ElementRef, HostListener } from '@angular/core'; + +@Directive({ + selector: 'textarea[autosize]' +}) +export class AutosizeDirective implements AfterContentChecked { + + constructor(public element: ElementRef) {} + + @HostListener('input', ['$event.target']) + public onInput() { + this.resize(); + } + + public ngAfterContentChecked() { + this.resize(); + } + + public resize() { + const style = this.element.nativeElement.style; + style.overflow = 'hidden'; + style.height = 'auto'; + + const height = this.element.nativeElement.scrollHeight; + style.height = `${height}px`; + } + +} diff --git a/interactive-mining-angular-frontend/src/app/contents/contents.module.ts b/interactive-mining-angular-frontend/src/app/contents/contents.module.ts index 69bb9bb..cb97f9e 100644 --- a/interactive-mining-angular-frontend/src/app/contents/contents.module.ts +++ b/interactive-mining-angular-frontend/src/app/contents/contents.module.ts @@ -4,8 +4,8 @@ import { CommonModule } from '@angular/common'; import { ContentstableComponent } from './contentstable/contentstable.component'; import { ContentComponent } from './contents.component'; import {ContentsService} from './contents.service'; -import { TextareaAutosizeModule } from 'ngx-textarea-autosize'; import {FileUploadDirective} from '../file-upload.directive'; +import {AutosizeDirective} from './autosize.directive'; @NgModule({ exports: [ @@ -16,13 +16,13 @@ import {FileUploadDirective} from '../file-upload.directive'; ], imports: [ CommonModule, - FormsModule, - TextareaAutosizeModule + FormsModule ], declarations: [ ContentstableComponent, ContentComponent, - FileUploadDirective + FileUploadDirective, + AutosizeDirective ] }) export class ContentModule { } diff --git a/interactive-mining-angular-frontend/src/app/contents/contents.service.ts b/interactive-mining-angular-frontend/src/app/contents/contents.service.ts index 587c04f..eee251a 100644 --- a/interactive-mining-angular-frontend/src/app/contents/contents.service.ts +++ b/interactive-mining-angular-frontend/src/app/contents/contents.service.ts @@ -1,12 +1,10 @@ -import { Injectable } from '@angular/core'; -import { Content } from './content'; +import {Injectable} from '@angular/core'; +import {Content} from './content'; import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import {Observable} from 'rxjs/Observable'; import {Util} from '../util'; -import UIkit from 'uikit'; -import {ProfileData} from '../manageprofiles/profile-data'; @Injectable() @@ -14,42 +12,50 @@ export class ContentsService { private util: Util = new Util(); - private getContentUrl = 'http://localhost:8080/alreadyconcept'; - private uploadContentFileUrl = 'http://localhost:8080/uploadcontentfile'; - private updateContentUrl = 'http://localhost:8080/updateconcept'; + private userId = ''; + private backendServerAddress = ''; + private concepts = ''; - constructor(private http: HttpClient) { } + private getContentUrl = '/alreadyconcept'; + private uploadContentFileUrl = '/uploadcontentfile'; + private updateContentUrl = '/updateconcept'; + + constructor(private http: HttpClient) { + this.userId = this.util.getUserId(); + this.backendServerAddress = this.util.getBackendServerAddress(); + } getContent(): Observable { - return this.http.get(this.getContentUrl, { withCredentials: true }) + this.concepts = localStorage.getItem('concepts'); + return this.http.get(this.backendServerAddress + this.getContentUrl + `?user=${this.userId}&concepts=${this.concepts}`) .map((data) => this.contentsJsonToArray(data['data'])) .catch(this.util.handleError); } contentsJsonToArray(json): Content[] { const contentArray: Array = []; - Object.entries(json).forEach( - ([key, value]) => { + for (let key in json) { + if (key) { const content = new Content(); content.keyword = key; - content.context = value; + content.context = json[key]; contentArray.push(content); } - ); + } return contentArray; } uploadFile(file: File): Observable { const formData: FormData = new FormData(); formData.append('upload', file, file.name); + formData.append('user', this.userId); const params = new HttpParams(); const options = { headers: new HttpHeaders().set('Accept', 'application/json').delete('Content-Type'), params: params, - reportProgress: true, - withCredentials: true, + reportProgress: true }; - return this.http.post(this.uploadContentFileUrl, formData, options) + return this.http.post(this.backendServerAddress + this.uploadContentFileUrl, formData, options) .map((data) => this.contentsJsonToArray(data['data'])) .catch(this.util.handleError); } @@ -57,13 +63,11 @@ export class ContentsService { updateContent(content: Array): Observable { // transform data to json string var hashmap = {}; - content.forEach(function(element) { + content.forEach(function (element) { hashmap[element.keyword] = element.context; }); - console.log(JSON.stringify(hashmap)); - return this.http.post(this.updateContentUrl, { - concepts: JSON.stringify(hashmap) - }, { withCredentials: true }) + return this.http.post(this.backendServerAddress + this.updateContentUrl, {user: this.userId, concepts: JSON.stringify(hashmap)}) + .map((data) => data['concepts']) .catch(this.util.handleError); } diff --git a/interactive-mining-angular-frontend/src/app/contents/contentstable/contentstable.component.ts b/interactive-mining-angular-frontend/src/app/contents/contentstable/contentstable.component.ts index 1ed68d1..f7f0876 100644 --- a/interactive-mining-angular-frontend/src/app/contents/contentstable/contentstable.component.ts +++ b/interactive-mining-angular-frontend/src/app/contents/contentstable/contentstable.component.ts @@ -79,6 +79,7 @@ export class ContentstableComponent implements OnInit { .subscribe(contents => { if (contents.length !== 0) { this.contentArray = contents; + localStorage.setItem('concepts', contents.length.toString()); } }); } else { @@ -94,7 +95,11 @@ export class ContentstableComponent implements OnInit { } saveAndContinue(): void { - this.contentsService.updateContent(this.contentArray).subscribe(value => this.router.navigate(['/configure-profile'])); + this.contentsService.updateContent(this.contentArray) + .subscribe(value => { + localStorage.setItem('concepts', value); + this.router.navigate(['/configure-profile']); + }); } } diff --git a/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.css b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.css new file mode 100644 index 0000000..e69de29 diff --git a/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.html b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.html new file mode 100644 index 0000000..01f14ce --- /dev/null +++ b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.html @@ -0,0 +1,2 @@ + + diff --git a/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.spec.ts b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.spec.ts new file mode 100644 index 0000000..2aae1cc --- /dev/null +++ b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InteractiveminingComponent } from './interactivemining.component'; + +describe('InteractiveminingComponent', () => { + let component: InteractiveminingComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ InteractiveminingComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(InteractiveminingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.ts b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.ts new file mode 100644 index 0000000..36ff692 --- /dev/null +++ b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.component.ts @@ -0,0 +1,31 @@ +import {Component, Input, OnInit} from '@angular/core'; + +@Component({ + selector: 'app-interactivemining', + templateUrl: './interactivemining.component.html', + styleUrls: ['./interactivemining.component.css'] +}) +export class InteractiveminingComponent implements OnInit { + + private _userid = 'None'; + private _backendserveraddress = 'None'; + + constructor() { } + + ngOnInit() { + } + + @Input('userid') + set userid(userid: string) { + localStorage.setItem('user_id', userid); + this._userid = userid; + } + + @Input('backendserveraddress') + set backendserveraddress(backendserveraddress: string) { + localStorage.setItem('backendaddress', backendserveraddress); + this._backendserveraddress = backendserveraddress; + + } + +} diff --git a/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.module.ts b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.module.ts new file mode 100644 index 0000000..c4241c5 --- /dev/null +++ b/interactive-mining-angular-frontend/src/app/interactivemining/interactivemining.module.ts @@ -0,0 +1,33 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {InteractiveminingComponent} from './interactivemining.component'; +import {ConfigurationModule} from '../configuration/configuration.module'; +import {ManagprofilesModule} from '../manageprofiles/manageprofiles.module'; +import {SaveprofileModule} from '../saveprofile/saveprofile.module'; +import {BrowserModule} from '@angular/platform-browser'; +import {ContentModule} from '../contents/contents.module'; +import {AppRoutingModule} from '../app-routing.module'; +import {HttpClientModule} from '@angular/common/http'; +import {StepsnvabarComponent} from '../stepsnvabar/stepsnvabar.component'; + +@NgModule({ + imports: [ + CommonModule, + BrowserModule, + ManagprofilesModule, + ContentModule, + ConfigurationModule, + SaveprofileModule, + HttpClientModule, + AppRoutingModule + ], + exports: [ + InteractiveminingComponent + ], + declarations: [ + InteractiveminingComponent, + StepsnvabarComponent + ] +}) +export class InteractiveMiningModule { +} diff --git a/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.component.ts b/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.component.ts index f7468d2..1e7a4b5 100644 --- a/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.component.ts +++ b/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.component.ts @@ -1,12 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {ManageprofilesService} from './manageprofiles.service'; import {Router} from '@angular/router'; import UIkit from 'uikit'; -import {CookieService} from 'ngx-cookie-service'; import {PaginationInstance} from 'ngx-pagination'; import {ProfileMetadata} from './profile-metadata'; import {ExampleProfilesMetadata} from './example-profiles-metadata'; -import {getFileNameFromResponseContentDisposition, saveFile} from '../util'; +import {saveFile} from '../util'; @Component({ selector: 'app-manageprofiles', @@ -26,16 +25,16 @@ export class ManageprofilesComponent implements OnInit { currentPage: 1 }; - constructor(private manageProfilesService: ManageprofilesService, private router: Router, private cookieService: CookieService) { } - - ngOnInit() { - this.getUserId(); + constructor(private manageProfilesService: ManageprofilesService, private router: Router) { } - getUserId(): void { - this.manageProfilesService.getUserId() - .subscribe(res => { - localStorage.setItem('user_id', res); + ngOnInit() { + this.initialServerhandshake(); + } + + initialServerhandshake(): void { + this.manageProfilesService.initialServerHandshake() + .subscribe(() => { this.getSavedProfiles(); this.getExampleProfiles(); }); @@ -53,28 +52,26 @@ export class ManageprofilesComponent implements OnInit { loadSavedProfile(id: string, name: string): void { this.manageProfilesService.loadSavedProfile(id) .subscribe(res => { - console.log(res); - // backup user_id from localstorage and clear all storage data - const userId: string = localStorage.getItem('user_id'); - localStorage.clear(); - localStorage.setItem('user_id', userId); - // store to client all profile data - localStorage.setItem('profilename', name); - localStorage.setItem('profileid', id); - localStorage.setItem('docname', res.docname); - localStorage.setItem('docsnumber', res.docsnumber); - localStorage.setItem('precision', res.precision); - localStorage.setItem('concepts', res.concepts); - localStorage.setItem('poswords', JSON.stringify(res.poswords)); - localStorage.setItem('negwords', JSON.stringify(res.negwords)); - localStorage.setItem('contextprev', res.contextprev); - localStorage.setItem('contextmiddle', res.contextmiddle); - localStorage.setItem('contextnext', res.contextnext); - localStorage.setItem('wordssplitnum', res.wordssplitnum); - localStorage.setItem('punctuation', res.punctuation); - localStorage.setItem('stopwords', res.stopwords); - localStorage.setItem('lettercase', res.lettercase); - this.router.navigate(['/upload-content']); + console.log(res); + // clear localstorage values + this.clearLocalStorage(); + // store to client all profile data + localStorage.setItem('profilename', name); + localStorage.setItem('profileid', id); + localStorage.setItem('docname', res.docname); + localStorage.setItem('docsnumber', res.docsnumber); + localStorage.setItem('precision', res.precision); + localStorage.setItem('concepts', res.concepts); + localStorage.setItem('poswords', JSON.stringify(res.poswords)); + localStorage.setItem('negwords', JSON.stringify(res.negwords)); + localStorage.setItem('contextprev', res.contextprev); + localStorage.setItem('contextmiddle', res.contextmiddle); + localStorage.setItem('contextnext', res.contextnext); + localStorage.setItem('wordssplitnum', res.wordssplitnum); + localStorage.setItem('punctuation', res.punctuation); + localStorage.setItem('stopwords', res.stopwords); + localStorage.setItem('lettercase', res.lettercase); + this.router.navigate(['/upload-content']); }); } @@ -88,25 +85,21 @@ export class ManageprofilesComponent implements OnInit { deleteProfilePrompt(index) { UIkit.modal.confirm('' + 'Are you sure you want to delete this profile? This action cannot be undone!', {escClose: true}).then(() => { - this.manageProfilesService.deleteProfile(this.userSavedProfiles[index].id) - .subscribe(() => this.userSavedProfiles.splice(index, 1)); + this.manageProfilesService.deleteProfile(this.userSavedProfiles[index].id) + .subscribe(() => this.userSavedProfiles.splice(index, 1)); }); } createNewProfile(): void { - // backup user_id from localstorage and clear all storage data - const userId: string = localStorage.getItem('user_id'); - localStorage.clear(); - localStorage.setItem('user_id', userId); + // clear localstorage values + this.clearLocalStorage(); this.manageProfilesService.createNewProfile() .subscribe(() => this.router.navigate(['/upload-content'])); } fileChangeUpload(event): void { - // backup user_id from localstorage and clear all storage data - const userId: string = localStorage.getItem('user_id'); - localStorage.clear(); - localStorage.setItem('user_id', userId); + // clear localstorage values + this.clearLocalStorage(); const fileList: FileList = event.target.files; if (fileList && fileList.length === 1) { const file: File = fileList[0]; @@ -136,10 +129,8 @@ export class ManageprofilesComponent implements OnInit { } loadExampleProfile(name: string): void { - // backup user_id from localstorage and clear all storage data - const userId: string = localStorage.getItem('user_id'); - localStorage.clear(); - localStorage.setItem('user_id', userId); + // clear localstorage values + this.clearLocalStorage(); // get new profile data this.manageProfilesService.loadExampleProfile(name) .subscribe(res => { @@ -161,4 +152,24 @@ export class ManageprofilesComponent implements OnInit { }); } + clearLocalStorage(): void { + // clear localstorage values + localStorage.removeItem('grants'); + localStorage.removeItem('profilename'); + localStorage.removeItem('profileid'); + localStorage.removeItem('docname'); + localStorage.removeItem('docsnumber'); + localStorage.removeItem('precision'); + localStorage.removeItem('concepts'); + localStorage.removeItem('poswords'); + localStorage.removeItem('negwords'); + localStorage.removeItem('contextprev'); + localStorage.removeItem('contextmiddle'); + localStorage.removeItem('contextnext'); + localStorage.removeItem('wordssplitnum'); + localStorage.removeItem('punctuation'); + localStorage.removeItem('stopwords'); + localStorage.removeItem('lettercase'); + } + } diff --git a/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.service.ts b/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.service.ts index 8d96d4b..bdc222e 100644 --- a/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.service.ts +++ b/interactive-mining-angular-frontend/src/app/manageprofiles/manageprofiles.service.ts @@ -1,84 +1,87 @@ -import { Injectable } from '@angular/core'; +import {Injectable} from '@angular/core'; import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; import {ProfileData} from './profile-data'; import {Util} from '../util'; import {Observable} from 'rxjs/Observable'; import {ProfileMetadata} from './profile-metadata'; import {ExampleProfilesMetadata} from './example-profiles-metadata'; -import {RequestOptions, ResponseContentType} from '@angular/http'; @Injectable() export class ManageprofilesService { private util: Util = new Util(); - private getUserIdUrl = 'http://localhost:8080/getuserid'; - private getSavedProfilesUrl = 'http://localhost:8080/getuserprofiles'; - private downloadProfileUrl = 'http://localhost:8080/downloadprofile'; - private DeleteuserProfileUrl = 'http://localhost:8080/deleteuserprofile'; - private createNewProfileUrl = 'http://localhost:8080/createnewprofile'; - private loadSavedProfileUrl = 'http://localhost:8080/loaduserprofile'; - private getExampleProfilesUrl = 'http://localhost:8080/getexampleprofiles'; - private loadExampleProfileUrl = 'http://localhost:8080/loadexampleprofile'; - private uploadProfileUrl = 'http://localhost:8080/uploadprofile'; + private userId = ''; + private backendServerAddress = ''; - constructor(private http: HttpClient) { } + private initServerHandshake = '/initialhandshake'; + private getSavedProfilesUrl = '/getuserprofiles'; + private downloadProfileUrl = '/downloadprofile'; + private DeleteuserProfileUrl = '/deleteuserprofile'; + private createNewProfileUrl = '/createnewprofile'; + private loadSavedProfileUrl = '/loaduserprofile'; + private getExampleProfilesUrl = '/getexampleprofiles'; + private loadExampleProfileUrl = '/loadexampleprofile'; + private uploadProfileUrl = '/uploadprofile'; - getUserId(): Observable { - return this.http.get(this.getUserIdUrl, { withCredentials: true }) - .map(res => res['user_id']) - .catch(this.util.handleError); + constructor(private http: HttpClient) { + this.userId = this.util.getUserId(); + this.backendServerAddress = this.util.getBackendServerAddress(); + } + + initialServerHandshake(): Observable { + return this.http.get(this.backendServerAddress + this.initServerHandshake + `?user=${this.userId}`) + .catch(this.util.handleError); } downloadProfile(profileId: string): Observable { - return this.http.post(this.downloadProfileUrl, {id: profileId}, { responseType: 'blob', withCredentials: true }) + return this.http.post(this.backendServerAddress + this.downloadProfileUrl, + {user: this.userId, id: profileId}, {responseType: 'blob', withCredentials: true}) .catch(this.util.handleError); } deleteProfile(profileId: string): Observable { - return this.http.post(this.DeleteuserProfileUrl, {id: profileId}, { withCredentials: true }) + return this.http.post(this.backendServerAddress + this.DeleteuserProfileUrl, {user: this.userId, id: profileId}) .catch(this.util.handleError); } createNewProfile(): Observable { - return this.http.get(this.createNewProfileUrl, { withCredentials: true }) + return this.http.get(this.backendServerAddress + this.createNewProfileUrl + `?user=${this.userId}`) .catch(this.util.handleError); } loadSavedProfile(profileId: string): Observable { - return this.http.post(this.loadSavedProfileUrl, { - id: profileId - }, { withCredentials: true }) + return this.http.post(this.backendServerAddress + this.loadSavedProfileUrl, {user: this.userId, id: profileId}) .catch(this.util.handleError); } loadExampleProfile(name: string): Observable { - return this.http.get(this.loadExampleProfileUrl, { withCredentials: true }) + return this.http.get(this.backendServerAddress + this.loadExampleProfileUrl + `?user=${this.userId}`) .catch(this.util.handleError); } uploadFile(file: File): Observable { const formData: FormData = new FormData(); formData.append('upload', file, file.name); + formData.append('user', this.userId); const params = new HttpParams(); const options = { headers: new HttpHeaders().set('Accept', 'application/json').delete('Content-Type'), params: params, - reportProgress: true, - withCredentials: true, + reportProgress: true }; - return this.http.post(this.uploadProfileUrl, formData, options) + return this.http.post(this.backendServerAddress + this.uploadProfileUrl, formData, options) .catch(this.util.handleError); } getSavedProfiles(): Observable { - return this.http.get(this.getSavedProfilesUrl, { withCredentials: true }) + return this.http.get(this.backendServerAddress + this.getSavedProfilesUrl + `?user=${this.userId}`) .map(data => data['profiles']) .catch(this.util.handleError); } getExampleProfiles(): Observable { - return this.http.get(this.getExampleProfilesUrl, { withCredentials: true }) + return this.http.get(this.backendServerAddress + this.getExampleProfilesUrl) .map(data => data['profiles']) .catch(this.util.handleError); } diff --git a/interactive-mining-angular-frontend/src/app/saveprofile/saveprofile.service.ts b/interactive-mining-angular-frontend/src/app/saveprofile/saveprofile.service.ts index c1dd506..2833b0e 100644 --- a/interactive-mining-angular-frontend/src/app/saveprofile/saveprofile.service.ts +++ b/interactive-mining-angular-frontend/src/app/saveprofile/saveprofile.service.ts @@ -8,12 +8,19 @@ export class SaveprofileService { private util: Util = new Util(); - private saveProfileUrl = 'http://localhost:8080/saveprofile'; + private userId = ''; + private backendServerAddress = ''; - constructor(private http: HttpClient) { } + private saveProfileUrl = '/saveprofile'; + + constructor(private http: HttpClient) { + this.userId = this.util.getUserId(); + this.backendServerAddress = this.util.getBackendServerAddress(); + } saveProfile(name: string, id: string, docName: string, dosNumber: number): Observable { - return this.http.post(this.saveProfileUrl, {name: name, id: id, docname: docName, docsnumber: dosNumber }, { withCredentials: true }) + return this.http.post(this.backendServerAddress + this.saveProfileUrl, + {user: this.userId, name: name, id: id, docname: docName, docsnumber: dosNumber }) .catch(this.util.handleError); } diff --git a/interactive-mining-angular-frontend/src/app/util.ts b/interactive-mining-angular-frontend/src/app/util.ts index c015ec8..70490c8 100644 --- a/interactive-mining-angular-frontend/src/app/util.ts +++ b/interactive-mining-angular-frontend/src/app/util.ts @@ -3,15 +3,17 @@ import UIkit from 'uikit'; import {HttpErrorResponse} from '@angular/common/http'; import { saveAs } from 'file-saver/FileSaver'; import { Response } from '@angular/http'; +import {ErrorObservable} from 'rxjs/observable/ErrorObservable'; export class Util { - public handleError (err: HttpErrorResponse) { + public handleError (err: HttpErrorResponse): ErrorObservable { if (err.error instanceof Error) { console.error('Client-side error occured.'); } else { console.error('Server-side error occured.'); } + console.log(err); UIkit.notification({ message: err.message, status: 'danger', @@ -20,6 +22,14 @@ export class Util { }); return Observable.throw(err || 'Server error'); } + + public getUserId(): string { + return localStorage.getItem('user_id'); + } + + public getBackendServerAddress(): string { + return localStorage.getItem('backendaddress'); + } } /** diff --git a/interactive-mining-angular-frontend/src/assets/css/dl119_files/custom.css b/interactive-mining-angular-frontend/src/assets/css/dl119_files/custom.css index acb7a77..96d66bc 100644 --- a/interactive-mining-angular-frontend/src/assets/css/dl119_files/custom.css +++ b/interactive-mining-angular-frontend/src/assets/css/dl119_files/custom.css @@ -600,944 +600,3 @@ font-family: 'Open Sans', sans-serif !important; } .readon-button:hover { } - - -/* TASOS css */ - -/* Custom controls - ========================================================================== */ -/* - * 1. Container fits its content - * 2. Create position context - * 3. Prevent content overflow - * 4. Behave like most inline-block elements - */ -.uk-form-custom { - /* 1 */ - display: inline-block; - /* 2 */ - position: relative; - /* 3 */ - max-width: 100%; - /* 4 */ - vertical-align: middle; -} -/* - * 1. Position and resize the form control to always cover its container - * 2. Required for Firefox for positioning to the left - * 3. Required for Webkit to make `height` work - * 4. Hide controle and show cursor - * 5. Needed for the cursor - * 6. Clip height caused by 5. Needed for Webkit only - */ -.uk-form-custom select, -.uk-form-custom input[type="file"] { - /* 1 */ - position: absolute; - top: 0; - z-index: 1; - width: 100%; - height: 100%; - /* 2 */ - left: 0; - /* 3 */ - -webkit-appearance: none; - /* 4 */ - opacity: 0; - cursor: pointer; -} -.uk-form-custom input[type="file"] { - /* 5 */ - font-size: 500px; - /* 6 */ - overflow: hidden; -} -/* - * Horizontal - */ -/* Tablet portrait and smaller */ -@media (max-width: 959px) { - /* Behave like `uk-form-stacked` */ - .uk-form-horizontal .uk-form-label { - display: block; - margin-bottom: 5px; - } -} -/* Tablet landscape and bigger */ -@media (min-width: 960px) { - .uk-form-horizontal .uk-form-label { - width: 200px; - margin-top: 7px; - float: left; - } - .uk-form-horizontal .uk-form-controls { - margin-left: 215px; - } - /* Better vertical alignment if controls are checkboxes and radio buttons with text */ - .uk-form-horizontal .uk-form-controls-text { - padding-top: 7px; - } -} - -/* Custom Buttons - ========================================================================== */ -.cm-main-button { - background-color: #ffc800; - color: #2c2b5d; - box-shadow: 0 3px 12px rgba(0,0,0,0.12); -} - -.cm-main-button:hover:not([disabled]) { - background-color: #f7c200; - color: #2c2b5d; - box-shadow: 0 6px 50px rgba(0,0,0,0.08); -} -.cm-phrases-button { - padding: 0px; - margin: 6px; - height: 33px; - width: 70px; - line-height: inherit; -} -.cm-white-button { - background-color: #ffffff; - width: 103px; - margin: 0; -} -.cm-close-btn { - color: #ffffffaa; -} -.cm-close-btn:hover, .cm-close-btn:focus { - color: #ffffff; -} -/* Custom Navigation - ========================================================================== */ - .cm-navigation { -border-bottom: 5px solid #05007A; -position:relative; -color: #fff; -padding-top: 0px; -padding-bottom:0px; -background:rgba(255,255,255, 0.0); -/*background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,0)), url(/images/toolbar_bg.png);*/ - -} -.cm-navigation .forimage { -background:rgba(255,255,255, 0.4); -} - -.uk-section-overlap { - /*margin-top:-40px!important;*/ -} -.uk-sticky{ -} - -.tm-header .uk-navbar-left {position:relative;z-index:9999!important;} -.tm-header .uk-logo {padding: 5px 10px 10px 10px; position:relative;z-index:1000!important;} -.tm-header .uk-navbar-transparent{ - /* background:rgba(255,255,255, 0.7);*/ - padding-top:4px; -} -.cm-navigation .uk-container { - padding-right:0px; -} - -.cm-navigation ul.uk-subnav.uk-subnav-line{ - background-color: #05007A; - padding-top:0px; - transform: skew(25deg); - padding-right:0px; - margin-right:10px; - padding-left:0px; -} - -.cm-navigation .uk-subnav-line li { - /*transition: background 0.2s;*/ - /* display:inline-block;*/ - font-family:Roboto!important; - font-weight:900!important; - text-transform:uppercase!important; - font-size:12px!important; - opacity:1!important; - display:inline-block; -} -.cm-navigation .uk-subnav-line > :before { - content: none; - display: block; - /* display: inline-block*/ - height: 10px; - vertical-align: middle -} - -.uk-subnav-line > :nth-child(n + 2):before { - margin-right: 10px; - border-left: 0px ; -} - -.cm-navigation .uk-subnav-line li a{ - display: block; - text-decoration:none; - transform: skew(-25deg); - font-family:Roboto 900 !important; - text-transform:uppercase!important; - font-size:13px!important; - opacity:1!important; - color:#05007A!important; - -} -.cm-navigation .uk-subnav-line li:hover { - color:#05007A!important; - background:#fff; - display: block; -} - - - -.cm-navigation .uk-subnav-line li a:hover, -.cm-navigation .uk-subnav-line li:hover a{ - display: block; - color:#05007A!important; -} - -.cm-navigation .uk-dotnav, .cm-navigation .uk-subnav { - margin-bottom:0px!important; -} -.cm-nav-container { - width: 100%; - border-style: solid; - border-width: 0px 0px 5px 0px; - border-bottom-color: #ffc800 !important; - box-shadow: 0px 10px 16px 0px #fff3d1; -} -.cm-left-box { - background-color: #ffc800; - padding: 10px 89px 10px 41px; -} -.cm-nav-toolbar { - border-width: 0px 0px 0px 0px; -} -.cm-nav-toolbar ul.uk-subnav.uk-subnav-line { - background-color: #ffc800 !important; -} -/*.cm-navigation .uk-subnav-line .cm-nav-li { - color: #05007A !important; - background: #fff; - display: block; -}*/ -.cm-nav-li { - padding: 0; - background-color: #ffc800 !important; -} -.cm-nav-li:hover { - background-color: #fff !important; -} -.cm-nav-li:hover { - background-color: #fff !important; -} -.cm-nav-li a { - padding: 0; -} -.cm-nav-number-container { - margin-left: -1px; - padding: 8px 13px 3px 40px; - background-color: #ffc800; - transform: skew(25deg); - display: inline-block; - color: #05007A; -} -.cm-nav-li-number { - padding: 5px 15px 5px 25px; -} -.cm-nav-number { - font-size: x-large; - font-weight: bold; - display: inline-block; - line-height: 1.5; - transform: skew(-25deg); -} -.cm-nav-title { - display: inline-block; - padding: 0px 20px 0px 20px; - line-height: 1.4; -} -.cm-nav-active { - background-color: #fff !important; -} -.cm-nav-active .cm-nav-title { - color: #05007A !important; -} -.cm-nav-disabled, -.cm-nav-disabled:hover, -.cm-nav-disabled .cm-nav-number-container { - background-color: #fce39a !important; - color: #91919d; - cursor: default; -} -.cm-nav-disabled a { - cursor: default; -} -.cm-nav-disabled span.cm-nav-title { - color: #91919d; -} - -/* Custom Navigation V2 - ========================================================================== */ -:root { - --cm-nav2-theme-1: #245bcc; - --cm-nav2-theme-2: #fff; - --cm-nav2-theme-3: #ffc800; - --cm-nav2-theme-4: #cbcbcb; - --cm-nav2-theme-5: #537fdf; -} -.cm-nav2 { - text-align: center; - display: inline-block; - overflow: hidden; - counter-reset: flag; -} -.cm-nav2-step { - text-decoration: none; - outline: none; - display: block; - float: left; - font-family: Roboto; - font-size: 15px; - line-height: 50px; - padding: 0 16px 0 60px; - position: relative; - background: var(--cm-nav2-theme-2); - color: var(--cm-nav2-theme-1); - transition: background 0.3s; - border: 2px solid var(--cm-nav2-theme-1); -} -.cm-nav2-step:first-child { - padding-left: 46px; - border-radius: 2px 0 0 2px; -} -.cm-nav2-step:first-child::before { - left: 14px; -} -.cm-nav2-step:last-child { - border-radius: 0 2px 2px 0; - padding-right: 20px; -} -.cm-nav2-step:last-child::after { - content: none; -} -.cm-nav2-step::before { - content: counter(flag); - counter-increment: flag; - width: 20px; - height: auto; - line-height: 32px; - margin: 8px 0; - position: absolute; - top: 0; - left: 30px; - font-size: 24px; - font-weight: bold; -} -.cm-nav2-step::after { - content: ''; - position: absolute; - top: 0; - right: -25px; - width: 50px; - height: 50px; - transform: scale(0.707) rotate(45deg); - z-index: 1; - border-radius: 0 5px 0 50px; - background: var(--cm-nav2-theme-2); - transition: background 0.3s; - box-shadow: 2px -2px 0 1px var(--cm-nav2-theme-1); -} -.cm-nav2-step:hover, -.cm-nav2-step-active, -.cm-nav2-step:hover::after, -.cm-nav2-step-active::after{ - background: var(--cm-nav2-theme-5); - color: var(--cm-nav2-theme-2); -} -.cm-nav2-step:hover::before, -.cm-nav2-step-active::before { - color: var(--cm-nav2-theme-2); -} -.cm-nav2-step-disabled, -.cm-nav2-step-disabled:hover { - border: 2px solid var(--cm-nav2-theme-4); -} -.cm-nav2-step-disabled::after { - box-shadow: 2px -2px 0 1px var(--cm-nav2-theme-4); -} -.cm-nav2-step-disabled, -.cm-nav2-step-disabled:hover, -.cm-nav2-step-disabled:hover::before, -.cm-nav2-step-disabled:hover::after { - background: var(--cm-nav2-theme-2); - color: var(--cm-nav2-theme-4); - cursor: default; -} - -/* Custom File drop Area Upload - ========================================================================== */ -.cm-file-drop-area { - background-color: #fef4d7; - border: 1px dashed #f9c735; - font-weight: 500; -} -/* Custom Inputs - ========================================================================== */ -#initial-type-input { - border: 2px solid #f9c735; - font-weight: bold !important; - padding: 28px; - border-radius: 3px; - font: inherit; -} -.cm-text-input:-ms-input-placeholder { - color: #aaa !important; -} -.cm-text-input::-moz-placeholder { - color: #aaa; - opacity: 1; -} -.cm-text-input::-webkit-input-placeholder { - color: #aaa; -} - -/* Custom Table - ========================================================================== */ -.cm-table { - border-collapse: collapse; -} -.cm-table th { - padding: 16px 14px; - -webkit-transition: color .1s linear; - transition: color .1s linear; -} -.cm-table tbody tr, .cm-table tfoot tr { - border: 1px solid #cbcbcb; -} -.cm-table td { - padding: 0px; - font-size: 14px; - line-height: 24px; - -webkit-transition: .2s ease-in-out; - transition: .2s ease-in-out; - -webkit-transition-property: color,background-color,border-color,box-shadow; - transition-property: color,background-color,border-color,box-shadow; -} -.cm-table td.keyword:hover, .cm-table td.context:hover { - background-color: #fdfcc3; - } -.cm-table td.delete { - padding: 14px; -} -.cm-table td.keyword, .cm-table td.context, .cm-table td.delete, .cm-table td.edit, .cm-table-footer { - border-top: 1px solid #cbcbcb; - font-weight: 400; -} -.cm-table td.keyword, .cm-table td.context { - border-right: 1px solid #cbcbcb; -} -.cm-table tr.editing td.keyword, .cm-table tr.editing td.context { - background-color: #ffd149 !important; -} -.cm-table tr.editing td.keyword.editing, .cm-table tr.editing td.context.editing { - background-color: #ffc800 !important; -} -.cm-table td.keyword input, .cm-table td.keyword input:focus { - background: transparent; - border: none; - padding: 14px; -} -.cm-table td.context textarea { - background: transparent; - border: none; - word-break: normal; - width: 100%; - resize: none; - overflow: hidden; - padding: 8px 14px; -} -.cm-table tr.editing td.keyword input, .cm-table tr.editing td.context textarea { - color: #555555; -} -.cm-table tr.editing td.keyword.editing input, .cm-table tr.editing td.context.editing textarea { - font-weight: 600; - color: #444444; -} -/*.cm-table td.keyword:hover, .cm-table td.context:hover, .cm-table td.edit:hover a {*/ - /*color: #55546d;*/ -/*}*/ -.cm-table tr th { - color: #5b6065; - font-weight: bold; -} -.cm-table-number { - background-color: #fbe39a; - border-right: 1px solid #f7c800; -} -.empty:before { - content: "Empty field"; - color: #ccc; -} -.cm-tooltip { - width: 15px; - display: inline-flex; -} -/* Custom config section - ========================================================================== */ -.cm-config-settings-section { - /*overflow: auto; - -webkit-overflow-scrolling: touch; - height: 841px;*/ - max-width: 850px !important; - min-width: 460px !important; - width: 35% !important; -} -.cm-config-section { - -} -.cm-easy-config-section { - padding: 30px 20px 20px 20px; -} -.cm-config-options-container { - display: block; - margin-top: -10px; -} -.cm-config-options-connect-line { - margin: auto; - display: block; - position: relative; - top: 29px; - background-color: #ececec; - z-index: -1; - width: 70%; - height: 8px; - box-shadow: 0px 2px 0px #dedede; - /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#72bbd6+0,617dd3+50,5243a7+100 */ - background: #72bbd6; /* Old browsers */ - background: -moz-linear-gradient(left, #72bbd6 0%, #617dd3 50%, #5243a7 100%); /* FF3.6-15 */ - background: -webkit-linear-gradient(left, #72bbd6 0%,#617dd3 50%,#5243a7 100%); /* Chrome10-25,Safari5.1-6 */ - background: linear-gradient(to right, #72bbd6 0%,#617dd3 50%,#5243a7 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#72bbd6', endColorstr='#5243a7',GradientType=1 ); /* IE6-9 */ -} -.cm-config-option { - display: block; -} -/*.cm-config-light .cm-circle-button { - background-color: #58bd87; -} -.cm-config-medium .cm-circle-button { - background-color: #269487; -} -.cm-config-hard .cm-circle-button { - background-color: #324b7f; -} -.cm-config-advance .cm-circle-button { - background-color: #161264; -}*/ -.cm-config-light .cm-circle-button, .cm-config-option:hover.cm-config-light .cm-outer-circle-button, .cm-config-option.cm-config-light.active .cm-outer-circle-button { - background-color: #72bbd6; -} -.cm-config-medium .cm-circle-button, .cm-config-option:hover.cm-config-medium .cm-outer-circle-button, .cm-config-option.cm-config-medium.active .cm-outer-circle-button { - background-color: #617dd3; -} -.cm-config-hard .cm-circle-button, .cm-config-option:hover.cm-config-hard .cm-outer-circle-button, .cm-config-option.cm-config-hard.active .cm-outer-circle-button { - background-color: #5243a7; -} -.cm-config-advance .cm-circle-button, .cm-config-option:hover.cm-config-advance .cm-outer-circle-button, .cm-config-option.cm-config-advance.active .cm-outer-circle-button { - background-color: #161264; -} -.cm-config-option:hover .cm-circle-button, .cm-config-option.active .cm-circle-button { - background-color: #efefef; -} -/*.cm-config-option:hover .cm-circle-button-fill, .cm-config-option.active .cm-circle-button-fill { - background-color: rgba(255, 255, 255, 0.39); -}*/ -.cm-outer-circle-button { - background-color: transparent; - margin: 0 auto; - height: 50px; - width: 50px; - border-radius: 45px; - position: relative; - -webkit-transition: .1s ease-in-out; - transition: .1s ease-in-out; -} -.cm-circle-button { - height: 30px; - width: 30px; - top: 10px; - left: 10px; - border-radius: 45px; - position: absolute; - -webkit-transition: .1s ease-in-out; - transition: .1s ease-in-out; -} -.cm-circle-button-fill { - width: 16px; - height: 16px; - border-radius: 45px; - position: absolute; - top: 7px; - left: 7px; - background-color: #efefef; -} -.cm-config-option span { - font-weight: normal; - font-family: Roboto; - text-transform: uppercase; - vertical-align: middle; - font-size: 13px; - text-align: center; - -webkit-transition: .1s ease-in-out; - transition: .1s ease-in-out; - color: #c7c6c6; -} -.cm-config-option:hover span, .cm-config-option.active span { - color: #565656; - text-decoration: none; -} -.cm-config-option-check { - display: none; - position: absolute; - left: -1px; - top: -1px; - color: black; -} -.cm-config-option.active .cm-config-option-check { - display: block; -} -.cm-advanced-tools-section { - padding: 0px 20px 20px 20px; - min-height: 160px; -} -.cm-advanced-tools-section .uk-accordion-title { - font-size: 16px; -} -.cm-advaned-tools-label { - line-height: 1.4; - font-size: 18px; - font-weight: 700; - text-transform: uppercase; -} -/*.cm-prhases { - min-width: 350px !important; - margin-top: 40px !important; -}*/ -.cm-phrases-container { - border-collapse: collapse; - border-radius: 3px; - border-style: hidden; /* hide standard table (collapsed) border */ - box-shadow: 0 0 0 1px #f7c800; /* this draws the table border */ -} -.cm-phrases-container header { - background-color: #fafafa; - color: #5b6065; - font-weight: bold; - border-bottom: 1px solid #e8e8e8; -} -.cm-phrases-container ul { - height: 180px; - overflow-y: scroll; - overflow-x: hidden; - margin: 0; -} -.cm-phrases-container ul li { - padding: 0; - border: none; -} -.cm-number-space, .cm-phrases-container ul li .num { - background-color: #fafafa; - border-right: 1px solid #e8e8e8; - width: 40px; - padding: 12px 0px; - font-size: 14px; -} -.cm-text-input-phrase, .cm-text-input-weight { - height: 34px; - border: 1px solid #f7c800; - font-weight: bold !important; - text-indent: 8px; - border-radius: 5px; - font: inherit; - margin: 5px 0px 5px 5px; -} -.cm-text-input-weight { - width: 80px; -} -.cm-phrases-container .weight { - width: 95px; -} -.cm-phrases-container footer { - padding: 6px 6px 6px 20px; -} -.cm-phrases-container footer.positive { - background-color: #c0ff94; -} -.cm-phrases-container footer.negative { - background-color: #ffbfc9; -} -.cm-phrases-container ul { - padding: 0; - list-style: none; -} -.cm-phrases-container ul li:hover { - background: #ffd; -} -.cm-phrases-container ul li input:hover, .cm-phrases-container ul li input[type=number]:hover { - background-color: #fdfcc3; -} -.cm-phrases-container ul li.editing input, .cm-phrases-container ul li.editing input[type=number] { - background-color: #ffd149; - color: #555555; -} -.cm-phrases-container ul li.editing input:focus { - background-color: #ffc800 !important; - font-weight: 600; - color: #444444; -} -.cm-phrases-container ul li .phrase, .cm-phrases-container ul li .weight { - line-height: 1.5; - border-bottom: 1px solid #e8e8e8; - border-right: 1px solid #e8e8e8; - font-weight: 400; -} -.cm-phrases-container ul li input, .cm-phrases-container ul li input[type=number] { - border: none; - padding-left: 12px; - background: transparent; - height: 100%; -} -.cm-phrases-container ul li input:focus, .cm-phrases-container ul li input[type=number]:focus { - background: transparent; -} -.cm-phrases-container ul li .phrase:hover, .cm-phrases-container ul li .weight:hover { - color: #00a0de; - text-decoration: underline; - cursor: default; -} -.cm-phrases-container ul li .erase { - width: 55px; - padding: 5px; - border-bottom: 1px solid #e8e8e8; -} -.cm-match-area { - padding: 7px; - border: 1px solid #f7c800; - margin-top: -1px; -} -.cm-match-area.left, .cm-match-area.right { - background-color: #ffff94; -} -.cm-match-area.middle { - background-color: #bedfff; -} - -/* Custom Results Section - ========================================================================== */ -.cm-results-section { - background-color: #f5f5f5; - min-height: 686px; - position: relative; - border: 1px dashed #cbcbcb; - margin-left: 20px; -} -.cm-results-section header { - padding: 0; - -webkit-transition: box-shadow 500ms; - transition: box-shadow 500ms; -} -.cm-results-section header.uk-sticky-fixed { - background-color: transparent !important; - box-shadow: rgba(0, 0, 0, 0.07) 0px 3px 0px; -} -.cm-results-controls { - padding: 20px 20px 20px 20px; -} -header.uk-sticky-fixed .cm-results-controls { - background-color: rgb(242, 242, 242) !important; - padding: 20px; -} -.cm-results-count-section { - padding: 5px 20px 20px 20px; -} -header.uk-sticky-fixed .cm-results-count-section { - background-color: rgba(245, 245, 245, 0.8) !important; - padding: 5px 20px 5px 20px; -} -#cm-run-test-section { - padding: 0px 20px 40px 20px; -} -#cm-run-test-section.uk-sticky-fixed { - padding: 20px 20px 20px 20px; - background-color: rgba(245, 245, 245, 0.9) !important; - box-shadow: rgba(0, 0, 0, 0.07) 0px 3px 0px; -} -.cm-text-muted { - color: #737373 !important; -} -.cm-results-rows { - /*overflow: auto; - -webkit-overflow-scrolling: touch; - height: 600px;*/ - padding: 0px 20px 40px 20px; -} -.cm-results-rows .match { - font-weight: bold; - color: #336699; -} -.cm-document-result { - margin-top: 5px; -} -.cm-document-result .textwindow { - background-color: #ffff94; - color: #555; -} -.cm-document-result .highlight { - font-weight: bold; - background-color: #bedfff; - padding: 2px 8px; - color: #222; -} -.cm-document-result .negative { - background-color: #ffbfc9; -} -.cm-document-result .positive { - background-color: #c0ff94; -} -.cm-results-hide-pannel { - height: 100%; - width: 100%; - position: absolute; - top: 0; - right: 0; - background-color: rgba(0, 0, 0, 0.5); -} -.cm-header-hide-pannel { - display: none; - height: 100%; - width: 100%; - position: absolute; - top: 0; - right: 0; - background-color: rgba(0, 0, 0, 0.5); -} -.uk-sticky-fixed .cm-header-hide-pannel.cm-header-shown { - display: block; -} -.cm-save-profile-step { - /*position: absolute; - bottom: -60px; - right: 0;*/ - line-height: 38px; -} -/* Custom Docs selection form - ========================================================================== */ -.cm-docs-selection-form { - margin: 0 auto; - display: block; - position: relative; - z-index: 1020; - box-sizing: border-box; - min-width: 500px; - padding: 35px; - background: #fff; - color: #767779; - border-radius: 2px; - box-shadow: 0 3px 12px rgba(0,0,0,0.07); -} -.cm-docs-selection-form-dialog { - min-width: 700px; -} -.cm-doc-selected, .cm-doc-selected:hover, .cm-doc-selected:focus { - cursor: default; - position: relative; - padding: 0px 35px 0px 25px; - color: #000; - background-color: #FFFFFF; - border: 2px solid #54c0ff; - margin: -2px 0px 0px 0px; -} -.cm-doc-selected span { - position: absolute; - bottom: 0px; - right: 0px; - background-color: #54c0ff; - color: #FFFFFF; - border-radius: 15px 0px 0px 0px; - padding: 3px 0px 0px 4px; -} -.cm-slidenav, .cm-slidenav:hover { - color: #5a5a5a; - background-color: #ffffff8f; -} -.cm-slidenav-left { - border-radius: 0px 25px 25px 0px; - padding: 8px 8px 8px 4px; - /*margin-left: 0px;*/ -} -.cm-slidenav-right { - border-radius: 25px 0px 0px 25px; - padding: 8px 4px 8px 8px; - margin-right: 0px; -} -/* Custom labels - ========================================================================== */ -.cm-label { - display: inline-block; - padding: 1px 7px; - background: #8688a5; - line-height: 1.625; - font-size: 12px; - color: #fff; - vertical-align: middle; - white-space: nowrap; - font-family: Roboto; - font-weight: normal; - text-transform: uppercase; - border-radius: 2px; - margin-right: 5px; -} -/* Custom text - ========================================================================== */ -.cm-coloured-text { - color: #64667f; -} - -#parent { - position: relative; - display: -webkit-flex; - display: flex; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - -ms-flex-align: start; - -webkit-align-items: start; - align-items: start; - margin-bottom: 64px; -} -#child1 { - -webkit-flex: 0.35; - flex: 0.35; - will-change: min-height; -} -#child1.is-affixed { - padding-top: 0px; -} -#child1-inner { - transform: translate(0, 0); /* For browsers don't support translate3d. */ - transform: translate3d(0, 0, 0); - will-change: position, transform; - padding-bottom: 20px; - /*border: 1px solid #f7c800;*/ - /*padding-top: 20px;*/ - min-height: 667px; -} -#child2 { - position: relative; - -webkit-flex: 1; - flex: 1; - right: 0; -} diff --git a/interactive-mining-angular-frontend/src/assets/css/interactive-mining.css b/interactive-mining-angular-frontend/src/assets/css/interactive-mining.css new file mode 100644 index 0000000..378ba21 --- /dev/null +++ b/interactive-mining-angular-frontend/src/assets/css/interactive-mining.css @@ -0,0 +1,937 @@ +/* Custom controls + ========================================================================== */ +/* + * 1. Container fits its content + * 2. Create position context + * 3. Prevent content overflow + * 4. Behave like most inline-block elements + */ +.uk-form-custom { + /* 1 */ + display: inline-block; + /* 2 */ + position: relative; + /* 3 */ + max-width: 100%; + /* 4 */ + vertical-align: middle; +} +/* + * 1. Position and resize the form control to always cover its container + * 2. Required for Firefox for positioning to the left + * 3. Required for Webkit to make `height` work + * 4. Hide controle and show cursor + * 5. Needed for the cursor + * 6. Clip height caused by 5. Needed for Webkit only + */ +.uk-form-custom select, +.uk-form-custom input[type="file"] { + /* 1 */ + position: absolute; + top: 0; + z-index: 1; + width: 100%; + height: 100%; + /* 2 */ + left: 0; + /* 3 */ + -webkit-appearance: none; + /* 4 */ + opacity: 0; + cursor: pointer; +} +.uk-form-custom input[type="file"] { + /* 5 */ + font-size: 500px; + /* 6 */ + overflow: hidden; +} +/* + * Horizontal + */ +/* Tablet portrait and smaller */ +@media (max-width: 959px) { + /* Behave like `uk-form-stacked` */ + .uk-form-horizontal .uk-form-label { + display: block; + margin-bottom: 5px; + } +} +/* Tablet landscape and bigger */ +@media (min-width: 960px) { + .uk-form-horizontal .uk-form-label { + width: 200px; + margin-top: 7px; + float: left; + } + .uk-form-horizontal .uk-form-controls { + margin-left: 215px; + } + /* Better vertical alignment if controls are checkboxes and radio buttons with text */ + .uk-form-horizontal .uk-form-controls-text { + padding-top: 7px; + } +} + +/* Custom Buttons + ========================================================================== */ +.cm-main-button { + background-color: #ffc800; + color: #2c2b5d; + box-shadow: 0 3px 12px rgba(0,0,0,0.12); +} + +.cm-main-button:hover:not([disabled]) { + background-color: #f7c200; + color: #2c2b5d; + box-shadow: 0 6px 50px rgba(0,0,0,0.08); +} +.cm-phrases-button { + padding: 0px; + margin: 6px; + height: 33px; + width: 70px; + line-height: inherit; +} +.cm-white-button { + background-color: #ffffff; + width: 103px; + margin: 0; +} +.cm-close-btn { + color: #ffffffaa; +} +.cm-close-btn:hover, .cm-close-btn:focus { + color: #ffffff; +} +/* Custom Navigation + ========================================================================== */ +.cm-navigation { + border-bottom: 5px solid #05007A; + position:relative; + color: #fff; + padding-top: 0px; + padding-bottom:0px; + background:rgba(255,255,255, 0.0); + /*background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,0)), url(/images/toolbar_bg.png);*/ + +} +.cm-navigation .forimage { + background:rgba(255,255,255, 0.4); +} + +.uk-section-overlap { + /*margin-top:-40px!important;*/ +} +.uk-sticky{ +} + +.tm-header .uk-navbar-left {position:relative;z-index:9999!important;} +.tm-header .uk-logo {padding: 5px 10px 10px 10px; position:relative;z-index:1000!important;} +.tm-header .uk-navbar-transparent{ + /* background:rgba(255,255,255, 0.7);*/ + padding-top:4px; +} +.cm-navigation .uk-container { + padding-right:0px; +} + +.cm-navigation ul.uk-subnav.uk-subnav-line{ + background-color: #05007A; + padding-top:0px; + transform: skew(25deg); + padding-right:0px; + margin-right:10px; + padding-left:0px; +} + +.cm-navigation .uk-subnav-line li { + /*transition: background 0.2s;*/ + /* display:inline-block;*/ + font-family:Roboto!important; + font-weight:900!important; + text-transform:uppercase!important; + font-size:12px!important; + opacity:1!important; + display:inline-block; +} +.cm-navigation .uk-subnav-line > :before { + content: none; + display: block; + /* display: inline-block*/ + height: 10px; + vertical-align: middle +} + +.uk-subnav-line > :nth-child(n + 2):before { + margin-right: 10px; + border-left: 0px ; +} + +.cm-navigation .uk-subnav-line li a{ + display: block; + text-decoration:none; + transform: skew(-25deg); + font-family:Roboto 900 !important; + text-transform:uppercase!important; + font-size:13px!important; + opacity:1!important; + color:#05007A!important; + +} +.cm-navigation .uk-subnav-line li:hover { + color:#05007A!important; + background:#fff; + display: block; +} + + + +.cm-navigation .uk-subnav-line li a:hover, +.cm-navigation .uk-subnav-line li:hover a{ + display: block; + color:#05007A!important; +} + +.cm-navigation .uk-dotnav, .cm-navigation .uk-subnav { + margin-bottom:0px!important; +} +.cm-nav-container { + width: 100%; + border-style: solid; + border-width: 0px 0px 5px 0px; + border-bottom-color: #ffc800 !important; + box-shadow: 0px 10px 16px 0px #fff3d1; +} +.cm-left-box { + background-color: #ffc800; + padding: 10px 89px 10px 41px; +} +.cm-nav-toolbar { + border-width: 0px 0px 0px 0px; +} +.cm-nav-toolbar ul.uk-subnav.uk-subnav-line { + background-color: #ffc800 !important; +} +/*.cm-navigation .uk-subnav-line .cm-nav-li { + color: #05007A !important; + background: #fff; + display: block; +}*/ +.cm-nav-li { + padding: 0; + background-color: #ffc800 !important; +} +.cm-nav-li:hover { + background-color: #fff !important; +} +.cm-nav-li:hover { + background-color: #fff !important; +} +.cm-nav-li a { + padding: 0; +} +.cm-nav-number-container { + margin-left: -1px; + padding: 8px 13px 3px 40px; + background-color: #ffc800; + transform: skew(25deg); + display: inline-block; + color: #05007A; +} +.cm-nav-li-number { + padding: 5px 15px 5px 25px; +} +.cm-nav-number { + font-size: x-large; + font-weight: bold; + display: inline-block; + line-height: 1.5; + transform: skew(-25deg); +} +.cm-nav-title { + display: inline-block; + padding: 0px 20px 0px 20px; + line-height: 1.4; +} +.cm-nav-active { + background-color: #fff !important; +} +.cm-nav-active .cm-nav-title { + color: #05007A !important; +} +.cm-nav-disabled, +.cm-nav-disabled:hover, +.cm-nav-disabled .cm-nav-number-container { + background-color: #fce39a !important; + color: #91919d; + cursor: default; +} +.cm-nav-disabled a { + cursor: default; +} +.cm-nav-disabled span.cm-nav-title { + color: #91919d; +} + +/* Custom Navigation V2 + ========================================================================== */ +:root { + --cm-nav2-theme-1: #245bcc; + --cm-nav2-theme-2: #fff; + --cm-nav2-theme-3: #ffc800; + --cm-nav2-theme-4: #cbcbcb; + --cm-nav2-theme-5: #537fdf; +} +.cm-nav2 { + text-align: center; + display: inline-block; + overflow: hidden; + counter-reset: flag; +} +.cm-nav2-step { + text-decoration: none; + outline: none; + display: block; + float: left; + font-family: Roboto; + font-size: 15px; + line-height: 50px; + padding: 0 16px 0 60px; + position: relative; + background: var(--cm-nav2-theme-2); + color: var(--cm-nav2-theme-1); + transition: background 0.3s; + border: 2px solid var(--cm-nav2-theme-1); +} +.cm-nav2-step:first-child { + padding-left: 46px; + border-radius: 2px 0 0 2px; +} +.cm-nav2-step:first-child::before { + left: 14px; +} +.cm-nav2-step:last-child { + border-radius: 0 2px 2px 0; + padding-right: 20px; +} +.cm-nav2-step:last-child::after { + content: none; +} +.cm-nav2-step::before { + content: counter(flag); + counter-increment: flag; + width: 20px; + height: auto; + line-height: 32px; + margin: 8px 0; + position: absolute; + top: 0; + left: 30px; + font-size: 24px; + font-weight: bold; +} +.cm-nav2-step::after { + content: ''; + position: absolute; + top: 0; + right: -25px; + width: 50px; + height: 50px; + transform: scale(0.707) rotate(45deg); + z-index: 1; + border-radius: 0 5px 0 50px; + background: var(--cm-nav2-theme-2); + transition: background 0.3s; + box-shadow: 2px -2px 0 1px var(--cm-nav2-theme-1); +} +.cm-nav2-step:hover, +.cm-nav2-step-active, +.cm-nav2-step:hover::after, +.cm-nav2-step-active::after{ + background: var(--cm-nav2-theme-5); + color: var(--cm-nav2-theme-2); +} +.cm-nav2-step:hover::before, +.cm-nav2-step-active::before { + color: var(--cm-nav2-theme-2); +} +.cm-nav2-step-disabled, +.cm-nav2-step-disabled:hover { + border: 2px solid var(--cm-nav2-theme-4); +} +.cm-nav2-step-disabled::after { + box-shadow: 2px -2px 0 1px var(--cm-nav2-theme-4); +} +.cm-nav2-step-disabled, +.cm-nav2-step-disabled:hover, +.cm-nav2-step-disabled:hover::before, +.cm-nav2-step-disabled:hover::after { + background: var(--cm-nav2-theme-2); + color: var(--cm-nav2-theme-4); + cursor: default; +} + +/* Custom File drop Area Upload + ========================================================================== */ +.cm-file-drop-area { + background-color: #fef4d7; + border: 1px dashed #f9c735; + font-weight: 500; +} +/* Custom Inputs + ========================================================================== */ +#initial-type-input { + border: 2px solid #f9c735; + font-weight: bold !important; + padding: 28px; + border-radius: 3px; + font: inherit; +} +.cm-text-input:-ms-input-placeholder { + color: #aaa !important; +} +.cm-text-input::-moz-placeholder { + color: #aaa; + opacity: 1; +} +.cm-text-input::-webkit-input-placeholder { + color: #aaa; +} + +/* Custom Table + ========================================================================== */ +.cm-table { + border-collapse: collapse; +} +.cm-table th { + padding: 16px 14px; + -webkit-transition: color .1s linear; + transition: color .1s linear; +} +.cm-table tbody tr, .cm-table tfoot tr { + border: 1px solid #cbcbcb; +} +.cm-table td { + padding: 0px; + font-size: 14px; + line-height: 24px; + -webkit-transition: .2s ease-in-out; + transition: .2s ease-in-out; + -webkit-transition-property: color,background-color,border-color,box-shadow; + transition-property: color,background-color,border-color,box-shadow; +} +.cm-table td.keyword:hover, .cm-table td.context:hover { + background-color: #fdfcc3; +} +.cm-table td.delete { + padding: 14px; +} +.cm-table td.keyword, .cm-table td.context, .cm-table td.delete, .cm-table td.edit, .cm-table-footer { + border-top: 1px solid #cbcbcb; + font-weight: 400; +} +.cm-table td.keyword, .cm-table td.context { + border-right: 1px solid #cbcbcb; +} +.cm-table tr.editing td.keyword, .cm-table tr.editing td.context { + background-color: #ffd149 !important; +} +.cm-table tr.editing td.keyword.editing, .cm-table tr.editing td.context.editing { + background-color: #ffc800 !important; +} +.cm-table td.keyword input, .cm-table td.keyword input:focus { + background: transparent; + border: none; + padding: 14px; +} +.cm-table td.context textarea { + background: transparent; + border: none; + word-break: normal; + width: 100%; + resize: none; + overflow: hidden; + padding: 8px 14px; +} +.cm-table tr.editing td.keyword input, .cm-table tr.editing td.context textarea { + color: #555555; +} +.cm-table tr.editing td.keyword.editing input, .cm-table tr.editing td.context.editing textarea { + font-weight: 600; + color: #444444; +} +/*.cm-table td.keyword:hover, .cm-table td.context:hover, .cm-table td.edit:hover a {*/ +/*color: #55546d;*/ +/*}*/ +.cm-table tr th { + color: #5b6065; + font-weight: bold; +} +.cm-table-number { + background-color: #fbe39a; + border-right: 1px solid #f7c800; +} +.empty:before { + content: "Empty field"; + color: #ccc; +} +.cm-tooltip { + width: 15px; + display: inline-flex; +} +/* Custom config section + ========================================================================== */ +.cm-config-settings-section { + /*overflow: auto; + -webkit-overflow-scrolling: touch; + height: 841px;*/ + max-width: 850px !important; + min-width: 460px !important; + width: 35% !important; +} +.cm-config-section { + +} +.cm-easy-config-section { + padding: 30px 20px 20px 20px; +} +.cm-config-options-container { + display: block; + margin-top: -10px; +} +.cm-config-options-connect-line { + margin: auto; + display: block; + position: relative; + top: 29px; + background-color: #ececec; + z-index: -1; + width: 70%; + height: 8px; + box-shadow: 0px 2px 0px #dedede; + /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#72bbd6+0,617dd3+50,5243a7+100 */ + background: #72bbd6; /* Old browsers */ + background: -moz-linear-gradient(left, #72bbd6 0%, #617dd3 50%, #5243a7 100%); /* FF3.6-15 */ + background: -webkit-linear-gradient(left, #72bbd6 0%,#617dd3 50%,#5243a7 100%); /* Chrome10-25,Safari5.1-6 */ + background: linear-gradient(to right, #72bbd6 0%,#617dd3 50%,#5243a7 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#72bbd6', endColorstr='#5243a7',GradientType=1 ); /* IE6-9 */ +} +.cm-config-option { + display: block; +} +/*.cm-config-light .cm-circle-button { + background-color: #58bd87; +} +.cm-config-medium .cm-circle-button { + background-color: #269487; +} +.cm-config-hard .cm-circle-button { + background-color: #324b7f; +} +.cm-config-advance .cm-circle-button { + background-color: #161264; +}*/ +.cm-config-light .cm-circle-button, .cm-config-option:hover.cm-config-light .cm-outer-circle-button, .cm-config-option.cm-config-light.active .cm-outer-circle-button { + background-color: #72bbd6; +} +.cm-config-medium .cm-circle-button, .cm-config-option:hover.cm-config-medium .cm-outer-circle-button, .cm-config-option.cm-config-medium.active .cm-outer-circle-button { + background-color: #617dd3; +} +.cm-config-hard .cm-circle-button, .cm-config-option:hover.cm-config-hard .cm-outer-circle-button, .cm-config-option.cm-config-hard.active .cm-outer-circle-button { + background-color: #5243a7; +} +.cm-config-advance .cm-circle-button, .cm-config-option:hover.cm-config-advance .cm-outer-circle-button, .cm-config-option.cm-config-advance.active .cm-outer-circle-button { + background-color: #161264; +} +.cm-config-option:hover .cm-circle-button, .cm-config-option.active .cm-circle-button { + background-color: #efefef; +} +/*.cm-config-option:hover .cm-circle-button-fill, .cm-config-option.active .cm-circle-button-fill { + background-color: rgba(255, 255, 255, 0.39); +}*/ +.cm-outer-circle-button { + background-color: transparent; + margin: 0 auto; + height: 50px; + width: 50px; + border-radius: 45px; + position: relative; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; +} +.cm-circle-button { + height: 30px; + width: 30px; + top: 10px; + left: 10px; + border-radius: 45px; + position: absolute; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; +} +.cm-circle-button-fill { + width: 16px; + height: 16px; + border-radius: 45px; + position: absolute; + top: 7px; + left: 7px; + background-color: #efefef; +} +.cm-config-option span { + font-weight: normal; + font-family: Roboto; + text-transform: uppercase; + vertical-align: middle; + font-size: 13px; + text-align: center; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; + color: #c7c6c6; +} +.cm-config-option:hover span, .cm-config-option.active span { + color: #565656; + text-decoration: none; +} +.cm-config-option-check { + display: none; + position: absolute; + left: -1px; + top: -1px; + color: black; +} +.cm-config-option.active .cm-config-option-check { + display: block; +} +.cm-advanced-tools-section { + padding: 0px 20px 20px 20px; + min-height: 160px; +} +.cm-advanced-tools-section .uk-accordion-title { + font-size: 16px; +} +.cm-advaned-tools-label { + line-height: 1.4; + font-size: 18px; + font-weight: 700; + text-transform: uppercase; +} +/*.cm-prhases { + min-width: 350px !important; + margin-top: 40px !important; +}*/ +.cm-phrases-container { + border-collapse: collapse; + border-radius: 3px; + border-style: hidden; /* hide standard table (collapsed) border */ + box-shadow: 0 0 0 1px #f7c800; /* this draws the table border */ +} +.cm-phrases-container header { + background-color: #fafafa; + color: #5b6065; + font-weight: bold; + border-bottom: 1px solid #e8e8e8; +} +.cm-phrases-container ul { + height: 180px; + overflow-y: scroll; + overflow-x: hidden; + margin: 0; +} +.cm-phrases-container ul li { + padding: 0; + border: none; +} +.cm-number-space, .cm-phrases-container ul li .num { + background-color: #fafafa; + border-right: 1px solid #e8e8e8; + width: 40px; + padding: 12px 0px; + font-size: 14px; +} +.cm-text-input-phrase, .cm-text-input-weight { + height: 34px; + border: 1px solid #f7c800; + font-weight: bold !important; + text-indent: 8px; + border-radius: 5px; + font: inherit; + margin: 5px 0px 5px 5px; +} +.cm-text-input-weight { + width: 80px; +} +.cm-phrases-container .weight { + width: 95px; +} +.cm-phrases-container footer { + padding: 6px 6px 6px 20px; +} +.cm-phrases-container footer.positive { + background-color: #c0ff94; +} +.cm-phrases-container footer.negative { + background-color: #ffbfc9; +} +.cm-phrases-container ul { + padding: 0; + list-style: none; +} +.cm-phrases-container ul li:hover { + background: #ffd; +} +.cm-phrases-container ul li input:hover, .cm-phrases-container ul li input[type=number]:hover { + background-color: #fdfcc3; +} +.cm-phrases-container ul li.editing input, .cm-phrases-container ul li.editing input[type=number] { + background-color: #ffd149; + color: #555555; +} +.cm-phrases-container ul li.editing input:focus { + background-color: #ffc800 !important; + font-weight: 600; + color: #444444; +} +.cm-phrases-container ul li .phrase, .cm-phrases-container ul li .weight { + line-height: 1.5; + border-bottom: 1px solid #e8e8e8; + border-right: 1px solid #e8e8e8; + font-weight: 400; +} +.cm-phrases-container ul li input, .cm-phrases-container ul li input[type=number] { + border: none; + padding-left: 12px; + background: transparent; + height: 100%; +} +.cm-phrases-container ul li input:focus, .cm-phrases-container ul li input[type=number]:focus { + background: transparent; +} +.cm-phrases-container ul li .phrase:hover, .cm-phrases-container ul li .weight:hover { + color: #00a0de; + text-decoration: underline; + cursor: default; +} +.cm-phrases-container ul li .erase { + width: 55px; + padding: 5px; + border-bottom: 1px solid #e8e8e8; +} +.cm-match-area { + padding: 7px; + border: 1px solid #f7c800; + margin-top: -1px; +} +.cm-match-area.left, .cm-match-area.right { + background-color: #ffff94; +} +.cm-match-area.middle { + background-color: #bedfff; +} + +/* Custom Results Section + ========================================================================== */ +.cm-results-section { + background-color: #f5f5f5; + min-height: 686px; + position: relative; + border: 1px dashed #cbcbcb; + margin-left: 20px; +} +.cm-results-section header { + padding: 0; + -webkit-transition: box-shadow 500ms; + transition: box-shadow 500ms; +} +.cm-results-section header.uk-sticky-fixed { + background-color: transparent !important; + box-shadow: rgba(0, 0, 0, 0.07) 0px 3px 0px; +} +.cm-results-controls { + padding: 20px 20px 20px 20px; +} +header.uk-sticky-fixed .cm-results-controls { + background-color: rgb(242, 242, 242) !important; + padding: 20px; +} +.cm-results-count-section { + padding: 5px 20px 20px 20px; +} +header.uk-sticky-fixed .cm-results-count-section { + background-color: rgba(245, 245, 245, 0.8) !important; + padding: 5px 20px 5px 20px; +} +#cm-run-test-section { + padding: 0px 20px 40px 20px; +} +#cm-run-test-section.uk-sticky-fixed { + padding: 20px 20px 20px 20px; + background-color: rgba(245, 245, 245, 0.9) !important; + box-shadow: rgba(0, 0, 0, 0.07) 0px 3px 0px; +} +.cm-text-muted { + color: #737373 !important; +} +.cm-results-rows { + /*overflow: auto; + -webkit-overflow-scrolling: touch; + height: 600px;*/ + padding: 0px 20px 40px 20px; +} +.cm-results-rows .match { + font-weight: bold; + color: #336699; +} +.cm-document-result { + margin-top: 5px; +} +.cm-document-result .textwindow { + background-color: #ffff94; + color: #555; +} +.cm-document-result .highlight { + font-weight: bold; + background-color: #bedfff; + padding: 2px 8px; + color: #222; +} +.cm-document-result .negative { + background-color: #ffbfc9; +} +.cm-document-result .positive { + background-color: #c0ff94; +} +.cm-results-hide-pannel { + height: 100%; + width: 100%; + position: absolute; + top: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.5); +} +.cm-header-hide-pannel { + display: none; + height: 100%; + width: 100%; + position: absolute; + top: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.5); +} +.uk-sticky-fixed .cm-header-hide-pannel.cm-header-shown { + display: block; +} +.cm-save-profile-step { + /*position: absolute; + bottom: -60px; + right: 0;*/ + line-height: 38px; +} +/* Custom Docs selection form + ========================================================================== */ +.cm-docs-selection-form { + margin: 0 auto; + display: block; + position: relative; + z-index: 1020; + box-sizing: border-box; + min-width: 500px; + padding: 35px; + background: #fff; + color: #767779; + border-radius: 2px; + box-shadow: 0 3px 12px rgba(0,0,0,0.07); +} +.cm-docs-selection-form-dialog { + min-width: 700px; +} +.cm-doc-selected, .cm-doc-selected:hover, .cm-doc-selected:focus { + cursor: default; + position: relative; + padding: 0px 35px 0px 25px; + color: #000; + background-color: #FFFFFF; + border: 2px solid #54c0ff; + margin: -2px 0px 0px 0px; +} +.cm-doc-selected span { + position: absolute; + bottom: 0px; + right: 0px; + background-color: #54c0ff; + color: #FFFFFF; + border-radius: 15px 0px 0px 0px; + padding: 3px 0px 0px 4px; +} +.cm-slidenav, .cm-slidenav:hover { + color: #5a5a5a; + background-color: #ffffff8f; +} +.cm-slidenav-left { + border-radius: 0px 25px 25px 0px; + padding: 8px 8px 8px 4px; + /*margin-left: 0px;*/ +} +.cm-slidenav-right { + border-radius: 25px 0px 0px 25px; + padding: 8px 4px 8px 8px; + margin-right: 0px; +} +/* Custom labels + ========================================================================== */ +.cm-label { + display: inline-block; + padding: 1px 7px; + background: #8688a5; + line-height: 1.625; + font-size: 12px; + color: #fff; + vertical-align: middle; + white-space: nowrap; + font-family: Roboto; + font-weight: normal; + text-transform: uppercase; + border-radius: 2px; + margin-right: 5px; +} +/* Custom text + ========================================================================== */ +.cm-coloured-text { + color: #64667f; +} + +#parent { + position: relative; + display: -webkit-flex; + display: flex; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-align: start; + -webkit-align-items: start; + align-items: start; + margin-bottom: 64px; +} +#child1 { + -webkit-flex: 0.35; + flex: 0.35; + will-change: min-height; +} +#child1.is-affixed { + padding-top: 0px; +} +#child1-inner { + transform: translate(0, 0); /* For browsers don't support translate3d. */ + transform: translate3d(0, 0, 0); + will-change: position, transform; + padding-bottom: 20px; + /*border: 1px solid #f7c800;*/ + /*padding-top: 20px;*/ + min-height: 667px; +} +#child2 { + position: relative; + -webkit-flex: 1; + flex: 1; + right: 0; +} diff --git a/interactive-mining-angular-frontend/src/index.html b/interactive-mining-angular-frontend/src/index.html index 9a55424..ff55006 100644 --- a/interactive-mining-angular-frontend/src/index.html +++ b/interactive-mining-angular-frontend/src/index.html @@ -10,7 +10,6 @@ -
diff --git a/interactive-mining-backend/madoap/src/madserverv3.py b/interactive-mining-backend/madoap/src/madserverv3.py index 8944696..aacbd35 100644 --- a/interactive-mining-backend/madoap/src/madserverv3.py +++ b/interactive-mining-backend/madoap/src/madserverv3.py @@ -67,7 +67,7 @@ msettings.viswidgetmap=viswidgetmap class Application(tornado.web.Application): def __init__(self): handlers = [ - (r"/getuserid", GetUserIdHandler), + (r"/initialhandshake", InitialClientHandshakeHandler), (r"/getuserprofiles", GetUserProfilesHandler), (r"/loaduserprofile", LoadUserProfileHandler), (r"/deleteuserprofile", DeleteUserProfileHandler), @@ -150,7 +150,7 @@ def loadProfile(profileLocation, user_id): file_name = "/tmp/p%s.tsv" % (user_id) if os.path.isfile(file_name): numberOfGrants = sum(1 for line in open(file_name)) - data['grants'] = numberOfGrants + data['concepts'] = numberOfGrants # write to json the poswords if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='poswords'")]): results = [r for r in cursor.execute("select c1, c2 from poswords")] @@ -381,10 +381,10 @@ URIdemultiplex = {r"/" + msettings.APPDIRNAME + "/analyze":'projects' , r"/" + msettings.APPDIRNAME + "/interactivemining":'interactivemining'} -class GetUserIdHandler(BaseHandler): +class InitialClientHandshakeHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -395,25 +395,25 @@ class GetUserIdHandler(BaseHandler): self.finish() def get(self): try: - # check if we already gave client a user_id, and it exists on the server - user_id = self.get_secure_cookie('madgikmining') - database_file_name = "/tmp/OAMiningProfilesDatabase_{0}.db".format(user_id) - if user_id is None or not os.path.isfile(database_file_name): - # give him a unique user_id - user_id = getNewUserId() - self.set_secure_cookie('madgikmining', user_id) - # create a database where the user stores his profiles info - import sys - sys.path.append(msettings.MADIS_PATH) - import madis - # get the database cursor + if 'user' in self.request.arguments and self.request.arguments['user'][0] != '': + user_id = self.request.arguments['user'][0] database_file_name = "/tmp/OAMiningProfilesDatabase_{0}.db".format(user_id) - cursor=madis.functions.Connection(database_file_name).cursor() - # Create database table - cursor.execute("drop table if exists database", parse=False) - cursor.execute("create table database(id,name,datecreated,status,matches,docname,docsnumber)", parse=False) - cursor.close() - self.write({'user_id': user_id}) + if (not os.path.isfile(database_file_name)): + # create a database where the user stores his profiles info + import sys + sys.path.append(msettings.MADIS_PATH) + import madis + # get the database cursor + cursor=madis.functions.Connection(database_file_name).cursor() + # Create database table + cursor.execute("drop table if exists database", parse=False) + cursor.execute("create table database(id,name,datecreated,status,matches,docname,docsnumber)", parse=False) + cursor.close() + else: + self.set_status(400) + self.write("Missing cookie containing user's id...") + return + self.write({}) self.finish() except Exception as ints: self.set_status(400) @@ -426,7 +426,7 @@ class GetUserIdHandler(BaseHandler): class GetUserProfilesHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -437,12 +437,12 @@ class GetUserProfilesHandler(BaseHandler): self.finish() def get(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] # extract data from database import sys sys.path.append(msettings.MADIS_PATH) @@ -475,7 +475,7 @@ class GetUserProfilesHandler(BaseHandler): class LoadUserProfileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -486,14 +486,19 @@ class LoadUserProfileHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from body. Must have + request_arguments = json.loads(self.request.body) + if 'user' not in request_arguments or request_arguments['user'] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id argument") return + user_id = request_arguments['user'] # get data - profile_id = json.loads(self.request.body)['id'] + if 'id' not in request_arguments or request_arguments['id'] == '': + self.set_status(400) + self.write("Missing profiles id argument") + return + profile_id = request_arguments['id'] # delete profile from database import sys sys.path.append(msettings.MADIS_PATH) @@ -522,7 +527,6 @@ class LoadUserProfileHandler(BaseHandler): data = loadProfile(file_name, user_id) data['docname'] = profile_data[0][0] data['docsnumber'] = profile_data[0][1] - self.set_secure_cookie('madgikmining_grantsuploaded', str(data['grants'])) self.write(json.dumps(data)) self.finish() except Exception as ints: @@ -536,7 +540,7 @@ class LoadUserProfileHandler(BaseHandler): class DeleteUserProfileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -547,14 +551,19 @@ class DeleteUserProfileHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from body. Must have + request_arguments = json.loads(self.request.body) + if 'user' not in request_arguments or request_arguments['user'] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id argument") return + user_id = request_arguments['user'] # get data - profile_id = json.loads(self.request.body)['id'] + if 'id' not in request_arguments or request_arguments['id'] == '': + self.set_status(400) + self.write("Missing profiles id argument") + return + profile_id = request_arguments['id'] # delete profile from database import sys sys.path.append(msettings.MADIS_PATH) @@ -583,7 +592,7 @@ class DeleteUserProfileHandler(BaseHandler): class GetExampleProfilesHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -614,7 +623,7 @@ class GetExampleProfilesHandler(BaseHandler): class CreateNewProfileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -625,12 +634,12 @@ class CreateNewProfileHandler(BaseHandler): self.finish() def get(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] deleteAllUserFiles(user_id) self.write(json.dumps({})) self.finish() @@ -645,7 +654,7 @@ class CreateNewProfileHandler(BaseHandler): class LoadExampleProfileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -656,12 +665,12 @@ class LoadExampleProfileHandler(BaseHandler): self.finish() def get(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] # reset everything deleteAllUserFiles(user_id) # load example data @@ -669,7 +678,6 @@ class LoadExampleProfileHandler(BaseHandler): data = loadExampleProfile(user_id) data['docname'] = 'Example' data['docsnumber'] = '26' - self.set_secure_cookie('madgikmining_grantsuploaded', str(data['grants'])) self.write(json.dumps(data)) self.finish() except Exception as ints: @@ -683,7 +691,7 @@ class LoadExampleProfileHandler(BaseHandler): class UploadProfileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -694,12 +702,12 @@ class UploadProfileHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] # get file info and body from post data fileinfo = self.request.files['upload'][0] fname = fileinfo['filename'] @@ -714,7 +722,6 @@ class UploadProfileHandler(BaseHandler): fh.write(fileinfo['body']) fh.close() data = loadProfile(cname, user_id) - self.set_secure_cookie('madgikmining_grantsuploaded', str(data['grants'])) self.write(json.dumps(data)) self.finish() except Exception as ints: @@ -728,7 +735,7 @@ class UploadProfileHandler(BaseHandler): class AlreadyConceptsHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -739,12 +746,12 @@ class AlreadyConceptsHandler(BaseHandler): self.finish() def get(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] data = {} data['data'] = {} file_name = "/tmp/p%s.tsv" % (user_id) @@ -760,8 +767,8 @@ class AlreadyConceptsHandler(BaseHandler): elif len(columns) == 1: codes[columns[0]] = '' num_lines += 1 - cookie = self.get_secure_cookie('madgikmining_grantsuploaded') - if cookie and str(num_lines) == cookie: + # get user id from arguments. Must have + if 'concepts' in self.request.arguments and self.request.arguments['concepts'][0] == str(num_lines): data['data'] = codes self.write(json.dumps(data)) self.finish() @@ -776,7 +783,7 @@ class AlreadyConceptsHandler(BaseHandler): class UploadContentFileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -787,12 +794,12 @@ class UploadContentFileHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] # get file info and body from post data fileinfo = self.request.files['upload'][0] fname = fileinfo['filename'] @@ -819,7 +826,7 @@ class UploadContentFileHandler(BaseHandler): else: data['data'] = codes data['respond'] = "{0} Codes loaded successfully!".format(len(lines)) - self.set_secure_cookie('madgikmining_grantsuploaded', str(len(lines))) + data['concepts'] = str(len(lines)) self.write(json.dumps(data)) self.finish() except Exception as ints: @@ -833,7 +840,7 @@ class UploadContentFileHandler(BaseHandler): class UpdateConceptsHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -844,12 +851,13 @@ class UpdateConceptsHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from body. Must have + request_arguments = json.loads(self.request.body) + if 'user' not in request_arguments or request_arguments['user'] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id argument") return + user_id = request_arguments['user'] # get data concepts = json.loads(json.loads(self.request.body)['concepts']) # write data to physical file @@ -870,7 +878,7 @@ class UpdateConceptsHandler(BaseHandler): return else: data['respond'] = "{0} Codes loaded successfully!".format(concepts_len) - self.set_secure_cookie('madgikmining_grantsuploaded', str(concepts_len)) + data['concepts'] = str(concepts_len) self.write(json.dumps(data)) self.finish() except Exception as ints: @@ -884,7 +892,7 @@ class UpdateConceptsHandler(BaseHandler): class GetDocSamplesHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -895,12 +903,12 @@ class GetDocSamplesHandler(BaseHandler): self.finish() def get(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] data = {} doc_samples = [] doc_samples.append({'name': 'Egi', 'documents': 104}) @@ -933,7 +941,7 @@ class GetDocSamplesHandler(BaseHandler): class UploadDocumentsHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -944,12 +952,12 @@ class UploadDocumentsHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] fileinfo = self.request.files['upload'][0] fname = fileinfo['filename'] extn = os.path.splitext(fname)[1] @@ -1017,7 +1025,7 @@ class UploadDocumentsHandler(BaseHandler): class ChooseDocSampleHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -1028,17 +1036,18 @@ class ChooseDocSampleHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from body. Must have + request_arguments = json.loads(self.request.body) + if 'user' not in request_arguments or request_arguments['user'] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id argument") return - doc_sample = json.loads(self.request.body)['docsample'] - if doc_sample == '': + user_id = request_arguments['user'] + if 'docsample' not in request_arguments or request_arguments['docsample'] == '': self.set_status(400) self.write("A doc sample name must be provided") return + user_id = request_arguments['docsample'] sample_file_name = "" if doc_sample == "Egi": sample_file_name = "static/egi_sample.tsv" @@ -1084,7 +1093,7 @@ class ChooseDocSampleHandler(BaseHandler): class AlreadyDocumentsHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'GET, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -1095,12 +1104,12 @@ class AlreadyDocumentsHandler(BaseHandler): self.finish() def get(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from arguments. Must have + if 'user' not in self.request.arguments or self.request.arguments['user'][0] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id parameter") return + user_id = self.request.arguments['user'][0] data = {} if msettings.RESET_FIELDS == 1: data['data'] = -1 @@ -1123,7 +1132,7 @@ class AlreadyDocumentsHandler(BaseHandler): class RunMiningHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -1134,14 +1143,14 @@ class RunMiningHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: - self.set_status(400) - self.write("Missing cookie containing user's id...") - return + # get user id from body. Must have request_arguments = json.loads(self.request.body) - print request_arguments + if 'user' not in request_arguments or request_arguments['user'] == '': + self.set_status(400) + self.write("Missing user's id argument") + return + user_id = request_arguments['user'] + mining_parameters = request_arguments['parameters'] # get the database cursor cursor=msettings.Connection.cursor() # data to be sent @@ -1154,14 +1163,14 @@ class RunMiningHandler(BaseHandler): # Automatically find middle size from grant codes white spaces querygrantsize = "select max(p1) from (select regexpcountwords('\s',stripchars(p1)) as p1 from (setschema 'p1,p2' file '/tmp/p{0}.tsv' dialect:tsv))".format(user_id) contextmiddle = [r for r in cursor.execute(querygrantsize)][0][0]+1 - if 'contextprev' in request_arguments and request_arguments['contextprev'] != '': - contextprev = int(request_arguments['contextprev']) + if 'contextprev' in mining_parameters and mining_parameters['contextprev'] != '': + contextprev = int(mining_parameters['contextprev']) if contextprev < 0 or contextprev > 20: self.set_status(400) self.write("Context size must be in its limits...") return - if 'contextnext' in request_arguments and request_arguments['contextnext'] != '': - contextnext = int(request_arguments['contextnext']) + if 'contextnext' in mining_parameters and mining_parameters['contextnext'] != '': + contextnext = int(mining_parameters['contextnext']) if contextnext < 0 or contextnext > 20: self.set_status(400) self.write("Context size must be in its limits...") @@ -1199,10 +1208,10 @@ class RunMiningHandler(BaseHandler): # create positive and negative words weighted regex text pos_set = neg_set = conf = whr_conf = '' - if 'poswords' in request_arguments and request_arguments['poswords'] != '{}': + if 'poswords' in mining_parameters and mining_parameters['poswords'] != '{}': data['poswords'] = [] # construct math string for positive words matching calculation with weights - pos_words = json.loads(request_arguments['poswords']) + pos_words = json.loads(mining_parameters['poswords']) for key, value in pos_words.iteritems(): # MONO GIA TO EGI pos_set += r'regexpcountuniquematches("%s",%s)*%s + ' % (key,j2scontext,value) @@ -1210,10 +1219,10 @@ class RunMiningHandler(BaseHandler): # pos_set += r'regexpcountuniquematches("(?:\b)%s(?:\b)",j2s(prev,middle,next))*%s + ' % (key,value) data['poswords'].append(key) pos_set += "0" - if 'negwords' in request_arguments and request_arguments['negwords'] != '{}': + if 'negwords' in mining_parameters and mining_parameters['negwords'] != '{}': data['negwords'] = [] # construct math string for negative words matching calculation with weights - neg_words = json.loads(request_arguments['negwords']) + neg_words = json.loads(mining_parameters['negwords']) for key, value in neg_words.iteritems(): # MONO GIA TO EGI neg_set += r'regexpcountuniquematches("%s",%s)*%s + ' % (key,j2scontext,value) @@ -1234,17 +1243,17 @@ class RunMiningHandler(BaseHandler): if numberOfDocsUploaded(user_id) != 0: doc_filters = "comprspaces(regexpr('[\n|\r]',d2,' '))" ackn_filters = "comprspaces(regexpr(\"\\'\", p2,''))" - if 'punctuation' in request_arguments and request_arguments['punctuation'] == "1": + if 'punctuation' in mining_parameters and mining_parameters['punctuation'] == "1": doc_filters = 'keywords('+doc_filters+')' ackn_filters = 'keywords('+ackn_filters+')' - if 'lettercase' in request_arguments and request_arguments['lettercase'] != '' and request_arguments['lettercase'] != 'none': - if request_arguments['lettercase'] == 'lowercase': + if 'lettercase' in mining_parameters and mining_parameters['lettercase'] != '' and mining_parameters['lettercase'] != 'none': + if mining_parameters['lettercase'] == 'lowercase': doc_filters = 'lower('+doc_filters+')' ackn_filters = 'lower('+ackn_filters+')' - elif request_arguments['lettercase'] == 'uppercase': + elif mining_parameters['lettercase'] == 'uppercase': doc_filters = 'upper('+doc_filters+')' ackn_filters = 'upper('+ackn_filters+')' - if 'stopwords' in request_arguments and request_arguments['stopwords'] == "1": + if 'stopwords' in mining_parameters and mining_parameters['stopwords'] == "1": doc_filters = 'filterstopwords('+doc_filters+')' ackn_filters = 'filterstopwords('+ackn_filters+')' print "DOCCC", doc_filters @@ -1261,8 +1270,8 @@ class RunMiningHandler(BaseHandler): list(cursor.execute("drop table if exists grants"+user_id, parse=False)) # string concatenation workaround because of the special characters conflicts - if 'wordssplitnum' in request_arguments and request_arguments['wordssplitnum'] != '': - words_split = int(request_arguments['wordssplitnum']) + if 'wordssplitnum' in mining_parameters and mining_parameters['wordssplitnum'] != '': + words_split = int(mining_parameters['wordssplitnum']) # MONO GIA TO EGI if 0 < words_split and words_split <= 10: acknowledgment_split = r'textwindow2s(gt2,0,'+str(words_split)+r',0)' @@ -1311,7 +1320,7 @@ class RunMiningHandler(BaseHandler): class PrepareSavedProfileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -1322,12 +1331,14 @@ class PrepareSavedProfileHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from body. Must have + request_arguments = json.loads(self.request.body) + if 'user' not in request_arguments or request_arguments['user'] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id argument") return + user_id = request_arguments['user'] + profile_parameters = request_arguments['parameters'] import sys sys.path.append(msettings.MADIS_PATH) import madis @@ -1347,42 +1358,41 @@ class PrepareSavedProfileHandler(BaseHandler): # Create grants table cursor.execute("drop table if exists grants", parse=False) cursor.execute("create table grants(c1,c2)", parse=False) - request_arguments = json.loads(self.request.body) - if 'poswords' in request_arguments and request_arguments['poswords'] != '{}': + if 'poswords' in profile_parameters and profile_parameters['poswords'] != '{}': # construct math string for positive words matching calculation with weights - pos_words = json.loads(request_arguments['poswords']) + pos_words = json.loads(profile_parameters['poswords']) cursor.executemany("insert into poswords(c1,c2) values(?,?)", ( (key, value,) for key, value in pos_words.iteritems() ) ) - if 'negwords' in request_arguments and request_arguments['negwords'] != '{}': + if 'negwords' in profile_parameters and profile_parameters['negwords'] != '{}': # construct math string for negative words matching calculation with weights - neg_words = json.loads(request_arguments['negwords']) + neg_words = json.loads(profile_parameters['negwords']) cursor.executemany("insert into negwords(c1,c2) values(?,?)", ( (key, value,) for key, value in neg_words.iteritems() ) ) filters = {} - if 'contextprev' in request_arguments and request_arguments['contextprev'] != '': - filters['contextprev'] = request_arguments['contextprev'] - if 'contextnext' in request_arguments and request_arguments['contextnext'] != '': - filters['contextnext'] = request_arguments['contextnext'] - if 'lettercase' in request_arguments and request_arguments['lettercase'] != '': - filters['lettercase'] = request_arguments['lettercase'] - if 'wordssplitnum' in request_arguments and request_arguments['wordssplitnum'] != '': - filters['wordssplitnum'] = request_arguments['wordssplitnum'] - if 'stopwords' in request_arguments and request_arguments['stopwords'] != '': - filters['stopwords'] = request_arguments['stopwords'] - if 'stopwords' in request_arguments and request_arguments['stopwords'] != '': - filters['punctuation'] = request_arguments['punctuation'] + if 'contextprev' in profile_parameters and profile_parameters['contextprev'] != '': + filters['contextprev'] = profile_parameters['contextprev'] + if 'contextnext' in profile_parameters and profile_parameters['contextnext'] != '': + filters['contextnext'] = profile_parameters['contextnext'] + if 'lettercase' in profile_parameters and profile_parameters['lettercase'] != '': + filters['lettercase'] = profile_parameters['lettercase'] + if 'wordssplitnum' in profile_parameters and profile_parameters['wordssplitnum'] != '': + filters['wordssplitnum'] = profile_parameters['wordssplitnum'] + if 'stopwords' in profile_parameters and profile_parameters['stopwords'] != '': + filters['stopwords'] = profile_parameters['stopwords'] + if 'stopwords' in profile_parameters and profile_parameters['stopwords'] != '': + filters['punctuation'] = profile_parameters['punctuation'] cursor.executemany("insert into filters(c1,c2) values(?,?)", ( (key, value,) for key, value in filters.iteritems() ) ) - if numberOfGrantsUploaded(user_id, self.get_secure_cookie('madgikmining_grantsuploaded')) != 0: + if numberOfGrantsUploaded(user_id, request_arguments['concepts']) != 0: cursor.execute("insert into grants select stripchars(c1) as c1, stripchars(c2) as c2 from (file '/tmp/p{0}.tsv')".format(user_id)) cursor.close() @@ -1402,7 +1412,7 @@ class PrepareSavedProfileHandler(BaseHandler): class SaveProfileToDatabaseHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -1413,17 +1423,18 @@ class SaveProfileToDatabaseHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from body. Must have + request_arguments = json.loads(self.request.body) + if 'user' not in request_arguments or request_arguments['user'] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id argument") return + user_id = request_arguments['user'] # get data - profile_id = json.loads(self.request.body)['id'] - profile_name = json.loads(self.request.body)['name'] - doc_name = json.loads(self.request.body)['docname'] - docs_number = json.loads(self.request.body)['docsnumber'] + profile_id = request_arguments['id'] + profile_name = request_arguments['name'] + doc_name = request_arguments['docname'] + docs_number = request_arguments['docsnumber'] # copy profile file to a unique user profile file profile_file_name = "/tmp/OAMiningProfile_{0}.oamp".format(user_id) # check if profile has already an id @@ -1467,7 +1478,7 @@ class SaveProfileToDatabaseHandler(BaseHandler): class DownloadProfileHandler(BaseHandler): passwordless=True def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "http://localhost:4200") + self.set_header("Access-Control-Allow-Origin", "*") self.set_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") self.set_header('Access-Control-Allow-Methods', 'POST, OPTIONS') self.set_header('Access-Control-Allow-Credentials', 'true') @@ -1478,13 +1489,14 @@ class DownloadProfileHandler(BaseHandler): self.finish() def post(self): try: - # get user id from cookie. Must have - user_id = self.get_secure_cookie('madgikmining') - if user_id is None: + # get user id from body. Must have + request_arguments = json.loads(self.request.body) + if 'user' not in request_arguments or request_arguments['user'] == '': self.set_status(400) - self.write("Missing cookie containing user's id...") + self.write("Missing user's id argument") return - profile_id = json.loads(self.request.body)['id'] + user_id = request_arguments['user'] + profile_id = request_arguments['id'] unique_profile_file_name = "/tmp/OAMiningProfile_{0}_{1}.oamp".format(user_id,profile_id) buf_size = 4096 self.set_header('Content-Type', 'application/octet-stream')