From e67d39d44bdb7d582964cbd643098b38dddd9c94 Mon Sep 17 00:00:00 2001 From: Sonja Galovic Date: Wed, 18 May 2022 21:55:36 +0200 Subject: Radjeno na otvaranju prediktora na eksperiment strani njegovim izborom u kolekciji. Dodata ruta i fja - poziv beku za prediktor. --- frontend/src/app/_services/models.service.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'frontend/src/app/_services') diff --git a/frontend/src/app/_services/models.service.ts b/frontend/src/app/_services/models.service.ts index fc888556..7c315491 100644 --- a/frontend/src/app/_services/models.service.ts +++ b/frontend/src/app/_services/models.service.ts @@ -58,4 +58,8 @@ export class ModelsService { return this.http.get(`${Configuration.settings.apiURL}/model/publicmodels`, { headers: this.authService.authHeader() }); } + getModelById(modelId: string): Observable { + return this.http.get(`${Configuration.settings.apiURL}/model/byid/${modelId}`, { headers: this.authService.authHeader() }); + } + } -- cgit v1.2.3 From 0dea04df11e9cb5f167473dddaffbc1a0d28bd59 Mon Sep 17 00:00:00 2001 From: Ognjen Cirkovic Date: Wed, 18 May 2022 23:20:15 +0200 Subject: Korisniku omoguceno da preuzme dataset sa front-end-a. --- frontend/src/app/_data/Dataset.ts | 2 +- frontend/src/app/_elements/folder/folder.component.html | 5 ++++- frontend/src/app/_elements/folder/folder.component.ts | 15 +++++++++++++++ frontend/src/app/_services/datasets.service.ts | 4 ++++ 4 files changed, 24 insertions(+), 2 deletions(-) (limited to 'frontend/src/app/_services') diff --git a/frontend/src/app/_data/Dataset.ts b/frontend/src/app/_data/Dataset.ts index 73b77bd0..c8d5771a 100644 --- a/frontend/src/app/_data/Dataset.ts +++ b/frontend/src/app/_data/Dataset.ts @@ -4,7 +4,7 @@ export default class Dataset extends FolderFile { constructor( name: string = 'Novi izvor podataka', public description: string = '', - public fileId?: number, + public fileId?: string, public extension: string = '.csv', public isPublic: boolean = false, public accessibleByLink: boolean = false, diff --git a/frontend/src/app/_elements/folder/folder.component.html b/frontend/src/app/_elements/folder/folder.component.html index da04b219..6293ec7f 100644 --- a/frontend/src/app/_elements/folder/folder.component.html +++ b/frontend/src/app/_elements/folder/folder.component.html @@ -76,7 +76,10 @@ {{file.lastUpdated | date}}
- +
diff --git a/frontend/src/app/_elements/folder/folder.component.ts b/frontend/src/app/_elements/folder/folder.component.ts index 262b3b7d..f13635e9 100644 --- a/frontend/src/app/_elements/folder/folder.component.ts +++ b/frontend/src/app/_elements/folder/folder.component.ts @@ -13,6 +13,7 @@ import { SignalRService } from 'src/app/_services/signal-r.service'; import { FormModelComponent } from '../form-model/form-model.component'; import { ActivatedRoute, Router } from '@angular/router'; import Predictor from 'src/app/_data/Predictor'; +import FileSaver from 'file-saver'; @Component({ selector: 'app-folder', @@ -308,6 +309,20 @@ export class FolderComponent implements AfterViewInit { break; } } + downloadFile(file: FolderFile, event: Event) { + event.stopPropagation(); + if (this.type==FolderType.Dataset) { + const fileId=(file).fileId; + const name=(file).name; + const ext=(file).extension; + if(fileId!=undefined) + this.datasetsService.downloadFile(fileId).subscribe((response)=>{ + FileSaver.saveAs(response,name+ext); + + }); + + } + } addFile(file: FolderFile, event: Event) { event.stopPropagation(); diff --git a/frontend/src/app/_services/datasets.service.ts b/frontend/src/app/_services/datasets.service.ts index 8d07674d..3fb4e8f2 100644 --- a/frontend/src/app/_services/datasets.service.ts +++ b/frontend/src/app/_services/datasets.service.ts @@ -51,4 +51,8 @@ export class DatasetsService { deleteDataset(dataset: Dataset) { return this.http.delete(`${Configuration.settings.apiURL}/dataset/` + dataset._id, { headers: this.authService.authHeader(), responseType: "text" }); } + + downloadFile(id:string):Observable{ + return this.http.get(`${Configuration.settings.apiURL}/file/Download?id=`+id, { headers: this.authService.authHeader(), responseType: 'blob' }); + } } -- cgit v1.2.3 From c1f507071e65903a6efda7285fff096bb7b8a7e5 Mon Sep 17 00:00:00 2001 From: Ivan Ljubisavljevic Date: Thu, 19 May 2022 00:30:50 +0200 Subject: Sredjeno dodavanje public modela u svoje. Takodje sredjeno refreshovanje liste modela i datasetovanja prilikom brisanja. Dodati dijalozi za brisanje i dodavanje --- backend/api/api/Controllers/DatasetController.cs | 19 ++-------- backend/api/api/Controllers/ModelController.cs | 40 ++++++++++++++++++++++ backend/api/api/Models/Model.cs | 6 ---- backend/api/api/Models/Predictor.cs | 25 +------------- backend/api/api/Services/DatasetService.cs | 12 +------ backend/api/api/Services/FillAnEmptyDb.cs | 13 +++---- .../src/app/_elements/folder/folder.component.ts | 32 +++++++++++------ frontend/src/app/_services/models.service.ts | 4 +++ 8 files changed, 76 insertions(+), 75 deletions(-) (limited to 'frontend/src/app/_services') diff --git a/backend/api/api/Controllers/DatasetController.cs b/backend/api/api/Controllers/DatasetController.cs index e4741412..6fb139bd 100644 --- a/backend/api/api/Controllers/DatasetController.cs +++ b/backend/api/api/Controllers/DatasetController.cs @@ -196,7 +196,7 @@ namespace api.Controllers string ext = ".csv"; - //nesto + //Check Directory if (!Directory.Exists(folderPath)) @@ -279,19 +279,4 @@ namespace api.Controllers } } -} - -/* -{ - "_id": "", - "name": "name", - "description": "description", - "header" : ["ag","rt"], - "fileId" : "652", - "extension": "csb", - "isPublic" : true, - "accessibleByLink": true, - "dateCreated": "dateCreated", - "lastUpdated" : "proba12" -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/backend/api/api/Controllers/ModelController.cs b/backend/api/api/Controllers/ModelController.cs index 39eb7830..be30ae6f 100644 --- a/backend/api/api/Controllers/ModelController.cs +++ b/backend/api/api/Controllers/ModelController.cs @@ -211,6 +211,8 @@ namespace api.Controllers return BadRequest("Bad parameters!");*/ model.uploaderId = getUserId(); + model.dateCreated = DateTime.Now; + model.lastUpdated = DateTime.Now; var existingModel = _modelService.GetOneModel(model.uploaderId, model.name); @@ -232,6 +234,44 @@ namespace api.Controllers } } + // POST api//stealModel + [HttpPost("stealModel")] + [Authorize(Roles = "User,Guest")] + public ActionResult StealModel([FromBody] Model model)//, bool overwrite) + { + bool overwrite = false; + //username="" ako je GUEST + //Experiment e = _experimentService.Get(model.experimentId); umesto 1 ide e.inputColumns.Length TODO!!!!!!!!!!!!!!!!! + //model.inputNeurons = e.inputColumns.Length; + /*if (_modelService.CheckHyperparameters(1, model.hiddenLayerNeurons, model.hiddenLayers, model.outputNeurons) == false) + return BadRequest("Bad parameters!");*/ + + model.uploaderId = getUserId(); + model._id = ""; + model.dateCreated = DateTime.Now; + model.lastUpdated = DateTime.Now; + model.isPublic = false; + + var existingModel = _modelService.GetOneModel(model.uploaderId, model.name); + + + if (existingModel != null && !overwrite && model.validationSize < 1 && model.validationSize > 0) + return NotFound($"Model already exisits or validation size is not between 0-1"); + else + { + //_modelService.Create(model); + //return Ok(); + if (existingModel == null) + _modelService.Create(model); + else + { + _modelService.Replace(model); + } + + return CreatedAtAction(nameof(Get), new { id = model._id }, model); + } + } + // PUT api//{name} [HttpPut("{name}")] [Authorize(Roles = "User,Guest")] diff --git a/backend/api/api/Models/Model.cs b/backend/api/api/Models/Model.cs index a807316f..bbbf201e 100644 --- a/backend/api/api/Models/Model.cs +++ b/backend/api/api/Models/Model.cs @@ -14,18 +14,14 @@ namespace api.Models public string name { get; set; } public string description { get; set; } - //datetime public DateTime dateCreated { get; set; } public DateTime lastUpdated { get; set; } - //proveriti id - //public string experimentId { get; set; } //Neural net training public string type { get; set; } public string optimizer { get; set; } public string lossFunction { get; set; } - //public int inputNeurons { get; set; } public int hiddenLayers { get; set; } public string batchSize { get; set; } public string learningRate { get; set; } @@ -36,8 +32,6 @@ namespace api.Models public string[] metrics { get; set; } public int epochs { get; set; } - //public bool isTrained { get; set; } - //public NullValues[] nullValues { get; set; } public bool randomOrder { get; set; } public bool randomTestSet { get; set; } public float randomTestSetDistribution { get; set; } diff --git a/backend/api/api/Models/Predictor.cs b/backend/api/api/Models/Predictor.cs index 530257b2..bfe95a0f 100644 --- a/backend/api/api/Models/Predictor.cs +++ b/backend/api/api/Models/Predictor.cs @@ -29,27 +29,4 @@ namespace api.Models } -} - -/** -* Paste one or more documents here - -{ - "_id": { - "$oid": "625dc348b7856ace8a6f8702" - - }, - "uploaderId" : "6242ea59486c664208d4255c", - "inputs": ["proba", - "proba2", - "proba3" - ], - "output" : "izlaz", - "isPublic" : true, - "accessibleByLink" : true, - "dateCreated" : "2022-04-11T20:33:26.937+00:00", - "experimentId" : "Neki id eksperimenta", - "modelId" : "Neki id eksperimenta", - "h5FileId" : "Neki id eksperimenta", - "metrics" : [{ }] -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/backend/api/api/Services/DatasetService.cs b/backend/api/api/Services/DatasetService.cs index f38a363b..0b84721e 100644 --- a/backend/api/api/Services/DatasetService.cs +++ b/backend/api/api/Services/DatasetService.cs @@ -104,16 +104,6 @@ namespace api.Services return dataset._id; } - /* -public bool CheckDb() -{ - Dataset? dataset = null; - dataset = _dataset.Find(dataset => dataset.username == "igrannonica").FirstOrDefault(); - - if (dataset != null) - return false; - else - return true; -}*/ + } } diff --git a/backend/api/api/Services/FillAnEmptyDb.cs b/backend/api/api/Services/FillAnEmptyDb.cs index 811e723a..cd35dc78 100644 --- a/backend/api/api/Services/FillAnEmptyDb.cs +++ b/backend/api/api/Services/FillAnEmptyDb.cs @@ -54,7 +54,7 @@ namespace api.Services dataset._id = ""; dataset.uploaderId = "000000000000000000000000"; - dataset.name = "Titanik dataset(public)"; + dataset.name = "Titanik dataset (public)"; dataset.description = "Titanik dataset"; dataset.fileId = _fileService.GetFileId(fullPath); dataset.extension = ".csv"; @@ -277,6 +277,7 @@ namespace api.Services model.lossFunction = "sparse_categorical_crossentropy"; model.hiddenLayers = 5; model.batchSize = "64"; + model.learningRate = "1"; model.outputNeurons = 0; model.layers = new[] { @@ -368,7 +369,7 @@ namespace api.Services dataset._id = ""; dataset.uploaderId = "000000000000000000000000"; dataset.name = "IMDB-Movie-Data Dataset (public)"; - dataset.description = "IMDB-Movie-Data Dataset(public)"; + dataset.description = "IMDB-Movie-Data Dataset (public)"; dataset.fileId = _fileService.GetFileId(fullPath); dataset.extension = ".csv"; dataset.isPublic = true; @@ -421,8 +422,8 @@ namespace api.Services model._id = ""; model.uploaderId = "000000000000000000000000"; - model.name = "IMDB model"; - model.description = "IMDB model"; + model.name = "IMDB model (public)"; + model.description = "IMDB model (public)"; model.dateCreated = DateTime.Now; model.lastUpdated = DateTime.Now; model.type = "regresioni"; @@ -579,8 +580,8 @@ namespace api.Services model._id = ""; model.uploaderId = "000000000000000000000000"; - model.name = "Churn model"; - model.description = "Churn model"; + model.name = "Churn model (public)"; + model.description = "Churn model (public)"; model.dateCreated = DateTime.Now; model.lastUpdated = DateTime.Now; model.type = "binarni-klasifikacioni"; diff --git a/frontend/src/app/_elements/folder/folder.component.ts b/frontend/src/app/_elements/folder/folder.component.ts index 262b3b7d..e521f264 100644 --- a/frontend/src/app/_elements/folder/folder.component.ts +++ b/frontend/src/app/_elements/folder/folder.component.ts @@ -139,10 +139,7 @@ export class FolderComponent implements AfterViewInit { _initialized: boolean = false; refreshFiles(selectedDatasetId: string | null = null, selectedModelId: string | null = null) { - this.files = [] - this.filteredFiles.length = 0; - this.folders[TabType.NewFile] = []; - this.folders[TabType.File] = []; + this.tabsToShow.forEach(tab => { this.folders[tab] = []; }); @@ -202,6 +199,7 @@ export class FolderComponent implements AfterViewInit { refreshDatasets(selectedDatasetId: string | null) { this.datasetsService.getMyDatasets().subscribe((datasets) => { this.folders[TabType.MyDatasets] = datasets; + console.log(this.filteredFiles); if (selectedDatasetId) { this.selectFile(datasets.filter(x => x._id == selectedDatasetId)[0]); } @@ -238,7 +236,7 @@ export class FolderComponent implements AfterViewInit { case FolderType.Dataset: this.formDataset!.uploadDataset((dataset: Dataset) => { this.newFile = undefined; - Shared.openDialog("Obaveštenje", "Uspešno ste dodali novi izvor podataka u kolekciju. Molimo sačekajte par trenutaka da se procesira."); + Shared.openDialog("Obaveštenje", "Uspešno ste dodali novi izvor podataka u kolekciju. Molimo sačekajte par trenutaka da se obradi."); this.refreshFiles(); }, () => { @@ -287,17 +285,20 @@ export class FolderComponent implements AfterViewInit { deleteFile(file: FolderFile, event: Event) { event.stopPropagation(); - //console.log('delete'); + this.filteredFiles.splice(this.filteredFiles.indexOf(file), 1); + this.files.splice(this.files.indexOf(file), 1); switch (this.type) { case FolderType.Dataset: this.datasetsService.deleteDataset(file).subscribe((response) => { - this.filteredFiles.splice(this.filteredFiles.indexOf(file), 1); - this.refreshFiles(null); + Shared.openDialog("Obaveštenje", "Uspešno ste obrisali odabrani izvor podataka."); + //this.filteredFiles.splice(this.files.indexOf(file), 1); + //this.refreshFiles(); }); break; case FolderType.Model: this.modelsService.deleteModel(file).subscribe((response) => { - this.refreshFiles(null); + Shared.openDialog("Obaveštenje", "Uspešno ste obrisali odabranu konfiguraciju neuronske mreže."); + //this.refreshFiles(); }); break; case FolderType.Experiment: @@ -317,13 +318,22 @@ export class FolderComponent implements AfterViewInit { (file).isPreProcess = true; (file).isPublic = false; this.datasetsService.stealDataset(file).subscribe((response) => { - this.filteredFiles.splice(this.filteredFiles.indexOf(file), 1); + Shared.openDialog("Obaveštenje", "Uspešno ste dodali javni izvor podataka u vašu kolekciju."); this.refreshFiles(null); + }, (error:any) => { + if (error.error == "Dataset with this name already exists") { + Shared.openDialog("Obaveštenje", "Izvor podataka sa ovim imenom postoji u vašoj kolekciji."); + } }); break; case FolderType.Model: - this.modelsService.addModel(file).subscribe((response) => { + this.modelsService.stealModel(file).subscribe((response) => { + Shared.openDialog("Obaveštenje", "Uspešno ste dodali javnu konfiguraciju neuronske mreže u vašu kolekciju."); this.refreshFiles(null); + }, (error:any) => { + if (error.error == "Model already exisits or validation size is not between 0-1") { + Shared.openDialog("Obaveštenje", "Model sa ovim imenom postoji u vašoj kolekciji."); + } }); break; case FolderType.Experiment: diff --git a/frontend/src/app/_services/models.service.ts b/frontend/src/app/_services/models.service.ts index fc888556..5f7b1947 100644 --- a/frontend/src/app/_services/models.service.ts +++ b/frontend/src/app/_services/models.service.ts @@ -31,6 +31,10 @@ export class ModelsService { addModel(model: Model): Observable { return this.http.post(`${Configuration.settings.apiURL}/model/add`, model, { headers: this.authService.authHeader() }); } + + stealModel(model: Model): Observable { + return this.http.post(`${Configuration.settings.apiURL}/model/stealModel`, model, { headers: this.authService.authHeader() }); + } addDataset(dataset: Dataset): Observable { return this.http.post(`${Configuration.settings.apiURL}/dataset/add`, dataset, { headers: this.authService.authHeader() }); } -- cgit v1.2.3