From 2e3465ae456fc07fa76567f3201d85ad3de5e8e5 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Thu, 1 Jun 2023 13:58:43 +0300 Subject: [PATCH] [WIP]: Move indicator sources in IndicatorUtils. Add stats-tool-parser in order to parse json from indicators and convert it to POST request. Add axios library. --- package.json | 3 +- server.ts | 77 ++++++-- src/app/monitor/monitor.component.ts | 4 +- src/app/topic/indicators.component.ts | 22 +-- src/app/utils/indicator-utils.ts | 194 ++++++++++++------- src/app/utils/services/statistics.service.ts | 72 ++----- src/environments/environment.ts | 2 +- src/stats-tool-parser.ts | 93 +++++++++ 8 files changed, 312 insertions(+), 155 deletions(-) create mode 100644 src/stats-tool-parser.ts diff --git a/package.json b/package.json index 6c25054..8fec5bd 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@angular/platform-server": "^14.2.3", "@angular/router": "^14.2.3", "@nguniversal/express-engine": "^14.2.0", + "axios": "^1.4.0", "clipboard": "^1.5.16", "core-js": "^2.5.4", "express": "^4.15.2", @@ -52,12 +53,12 @@ "@angular/compiler-cli": "^14.2.3", "@angular/language-service": "^14.2.3", "@nguniversal/builders": "^14.2.0", + "@types/ckeditor": "^4.9.10", "@types/compression": "^1.7.0", "@types/express": "^4.17.0", "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.3", "@types/node": "^12.11.1", - "@types/ckeditor": "^4.9.10", "codelyzer": "^6.0.0", "jasmine-core": "~3.8.0", "jasmine-spec-reporter": "~5.0.0", diff --git a/server.ts b/server.ts index 65e200f..4ae9f20 100644 --- a/server.ts +++ b/server.ts @@ -1,14 +1,22 @@ import 'zone.js/node'; -import { ngExpressEngine } from '@nguniversal/express-engine'; +import {ngExpressEngine} from '@nguniversal/express-engine'; import * as express from 'express'; import * as compression from 'compression'; -import { join } from 'path'; +import {join} from 'path'; -import { AppServerModule } from './src/main.server'; -import { APP_BASE_HREF } from '@angular/common'; -import { existsSync } from 'fs'; +import {AppServerModule} from './src/main.server'; +import {APP_BASE_HREF} from '@angular/common'; +import {existsSync} from 'fs'; import {REQUEST, RESPONSE} from "./src/app/openaireLibrary/utils/tokens"; +import {properties} from "./src/environments/environment"; +import {statsToolParser} from "./src/stats-tool-parser"; +import axios from "axios"; +import {Stakeholder} from "./src/app/openaireLibrary/monitor/entities/stakeholder"; +import {IndicatorUtils} from "./src/app/utils/indicator-utils"; + +var bodyParser = require('body-parser'); +var jsonParser = bodyParser.json(); // The Express app is exported so that it can be used by serverless Functions. export function app() { @@ -16,23 +24,70 @@ export function app() { server.use(compression()); const distFolder = join(process.cwd(), 'dist/monitor-dashboard/browser'); const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index'; - + // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) server.engine('html', ngExpressEngine({ bootstrap: AppServerModule, inlineCriticalCss: false })); - + server.set('view engine', 'html'); server.set('views', distFolder); - + + server.use('/cache', function (req, res, next) { + res.header('Access-Control-Allow-Origin', req.headers.origin); + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + res.header('Access-Control-Allow-Methods', 'GET, OPTIONS, POST, DELETE'); + res.header('Access-Control-Max-Age', "1800"); + next(); + }); + + server.post('/cache/:alias', jsonParser, async (req, res) => { + let stakeholder:Stakeholder = (await axios.get(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(req.params.alias))).data; + let list = []; + let indicatorUtils = new IndicatorUtils(); + if(stakeholder) { + stakeholder.topics.forEach(topic => { + topic.categories.forEach(category => { + category.subCategories.forEach(subCategory => { + subCategory.numbers.forEach(section => { + section.indicators.forEach(indicator => { + indicator.indicatorPaths.forEach(indicatorPath => { + let url = indicatorUtils.getFullUrl(stakeholder, indicatorPath); + list.push(url); + }); + }); + }); + subCategory.charts.forEach(section => { + section.indicators.forEach(indicator => { + indicator.indicatorPaths.forEach(indicatorPath => { + let url = indicatorUtils.getFullUrl(stakeholder, indicatorPath); + list.push(url); + }); + }); + }); + }); + }); + }); + } else { + res.status(404).send('Stakeholder has not been found'); + } + /*let [url, json] = req.body.url.split('?json='); + json = decodeURIComponent(json); + json = statsToolParser(JSON.parse(json)); + const response = axios.post(url, json).then((data) => { + console.log(data); + });*/ + res.send(list); + }); + // Example Express Rest API endpoints // server.get('/api/**', (req, res) => { }); // Serve static files from /browser server.get('*.*', express.static(distFolder, { maxAge: '1y' })); - + // All regular routes use the Universal engine server.get('*', (req, res) => { res.render(indexHtml, { @@ -51,13 +106,13 @@ export function app() { } ); }); - + return server; } function run() { const port = process.env.PORT || 4000; - + // Start up the Node server const server = app(); server.listen(port, () => { diff --git a/src/app/monitor/monitor.component.ts b/src/app/monitor/monitor.component.ts index 4bf9845..e46ff8c 100644 --- a/src/app/monitor/monitor.component.ts +++ b/src/app/monitor/monitor.component.ts @@ -485,7 +485,7 @@ export class MonitorComponent implements OnInit, OnDestroy { urls.forEach((indexes, pair) => { pair = JSON.parse(pair); let activeSubcategory = this.activeSubCategory._id; - this.subscriptions.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(pair[0]), pair[1]).subscribe(response => { + this.subscriptions.push(this.statisticsService.getNumbers(this.indicatorUtils.getSourceType(pair[0]), pair[1]).subscribe(response => { if(activeSubcategory === this.activeSubCategory._id) { indexes.forEach(([i, j]) => { if( this.activeSubCategory?.numbers[i]?.indicators[j]) { @@ -524,7 +524,7 @@ export class MonitorComponent implements OnInit, OnDestroy { public getUrlByStakeHolder(indicatorPath: IndicatorPath) { return this.sanitizer.bypassSecurityTrustResourceUrl( - this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, indicatorPath, this.getfl0(), this.periodFilter.selectedFromValue, this.periodFilter.selectedToValue, this.getCoFunded()))); + this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, indicatorPath, this.getfl0(), this.periodFilter.selectedFromValue, this.periodFilter.selectedToValue, this.getCoFunded()))); } public setActiveChart(i: number, j: number, type: string) { diff --git a/src/app/topic/indicators.component.ts b/src/app/topic/indicators.component.ts index 0c06fcf..f359d6e 100644 --- a/src/app/topic/indicators.component.ts +++ b/src/app/topic/indicators.component.ts @@ -275,7 +275,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV indicators: this.fb.control(section.indicators) })); section.indicators.forEach((number, j) => { - let url = this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, number.indicatorPaths[0]); + let url = this.indicatorUtils.getFullUrl(this.stakeholder, number.indicatorPaths[0]); const pair = JSON.stringify([number.indicatorPaths[0].source, url]); const indexes = urls.get(pair) ? urls.get(pair) : []; indexes.push([i, j]); @@ -293,7 +293,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV if (response) { this.calculateResults(response, indexes); } else { - this.numberSubscription.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(parsed[0]), parsed[1]).subscribe(response => { + this.numberSubscription.push(this.statisticsService.getNumbers(this.indicatorUtils.getSourceType(parsed[0]), parsed[1]).subscribe(response => { this.calculateResults(response, indexes); this.numberResponses.set(pair, response); })); @@ -469,11 +469,11 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV private getSecureUrlByStakeHolder(indicatorPath: IndicatorPath) { return this.sanitizer.bypassSecurityTrustResourceUrl( - this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); + this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); } private getUrlByStakeHolder(indicatorPath: IndicatorPath) { - return this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)); + return this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)); } public addNumberIndicatorPath(url: string = '', parameters: UntypedFormArray = new UntypedFormArray([]), source: string = 'stats-tool', jsonPath: UntypedFormArray = new UntypedFormArray([]), format: Format = "NUMBER") { @@ -497,7 +497,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { this.numberIndicatorPaths.at(index).get('result').setValue(null); if (this.numberIndicatorPaths.at(index).get('url').valid) { - let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.statisticsService.numberSources.get(this.statisticsService.getNumberSource(value))); + let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); if (!this.isStakeholderParametersValid(indicatorPath)) { // default profile if (this.stakeholder.defaultId == null) { @@ -566,7 +566,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); this.urlSubscriptions.push(this.chartIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { if (this.chartIndicatorPaths.at(index).get('url').valid) { - let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder); + let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder); if (!this.isStakeholderParametersValid(indicatorPath)) { // default profile if (this.stakeholder.defaultId == null) { @@ -653,7 +653,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV defaultId: this.fb.control(this.indicator.defaultId) }); this.indicator.indicatorPaths.forEach(indicatorPath => { - this.addNumberIndicatorPath(this.statisticsService.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath), indicatorPath.format); + this.addNumberIndicatorPath(this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath), indicatorPath.format); }); } else { this.indicator = new Indicator('', '', '', 'number', 'small', 'small', "PUBLIC", []); @@ -1268,7 +1268,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV } if (chart.type == "chart") { - indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(chart.url), chart.url, chart.type, this.stakeholder); + indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(chart.url), chart.url, chart.type, this.stakeholder); for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts) { for (let chart of section.indicators) { if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { @@ -1279,8 +1279,8 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV } } else if (chart.type == "number") { - indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(chart.url), chart.url, this.stakeholder, - chart.jsonPath, this.statisticsService.numberSources.get(this.statisticsService.getNumberSource(chart.url))); + indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(chart.url), chart.url, this.stakeholder, + chart.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(chart.url))); for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers) { for (let chart of section.indicators) { if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { @@ -1347,7 +1347,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV "type": indicator.type, "name": indicator.name, "jsonPath": indicatorPath.jsonPath, "description": indicator.description, "additionalDescription": indicator.additionalDescription, "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, - "url": this.statisticsService.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), + "url": this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), "sectionTitle": section.title, "sectionType": section.type, "sectionIndex": index diff --git a/src/app/utils/indicator-utils.ts b/src/app/utils/indicator-utils.ts index 5212d34..bf8af6c 100644 --- a/src/app/utils/indicator-utils.ts +++ b/src/app/utils/indicator-utils.ts @@ -17,34 +17,35 @@ import {AbstractControl, ValidatorFn, Validators} from "@angular/forms"; import {Option} from "../openaireLibrary/sharedComponents/input/input.component"; import {Session} from "../openaireLibrary/login/utils/helper.class"; import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; +import {properties} from "../../environments/environment"; export class StakeholderUtils { - + statuses: Option[] = [ {value: 'PUBLIC', label: 'Public'}, {value: 'RESTRICTED', label: 'Restricted'}, {value: 'PRIVATE', label: 'Private'} ]; - + types: Option[] = [ {value: 'funder', label: StakeholderEntities.FUNDER}, {value: 'ri', label: StakeholderEntities.RI}, {value: 'project', label: StakeholderEntities.PROJECT}, {value: 'organization', label: StakeholderEntities.ORGANIZATION} ]; - + visibility: Option[] = [ {icon: 'earth', value: "PUBLIC", label: 'Public'}, {icon: 'restricted', value: "RESTRICTED", label: 'Restricted'}, {icon: 'incognito', value: "PRIVATE", label: 'Private'}, ]; - + visibilityIcon: Map = new Map([ ["PUBLIC", 'earth'], ["PRIVATE", 'incognito'], ["RESTRICTED", 'restricted'] ]); - + getTypesByUserRoles(user, id: string = null): Option[] { let types = []; for (let type of this.types) { @@ -54,27 +55,27 @@ export class StakeholderUtils { } return types; } - + public createFunderFromDefaultProfile(funder: Stakeholder, defaultTopics: Topic[], isDefault: boolean = false): Stakeholder { funder.topics = HelperFunctions.copy(defaultTopics); for (let topic of funder.topics) { - topic.defaultId = !isDefault?topic._id:null; + topic.defaultId = !isDefault ? topic._id : null; topic._id = null; for (let category of topic.categories) { - category.defaultId = !isDefault?category._id:null; + category.defaultId = !isDefault ? category._id : null; category._id = null; let subTokeep: SubCategory[] = []; for (let subCategory of category.subCategories) { - subCategory.defaultId = !isDefault?subCategory._id:null; + subCategory.defaultId = !isDefault ? subCategory._id : null; subCategory._id = null; subTokeep.push(subCategory); for (let section of subCategory.charts) { let chartsTokeep: Indicator[] = []; - section.defaultId = !isDefault?section._id:null; + section.defaultId = !isDefault ? section._id : null; section.stakeholderAlias = funder.alias; section._id = null; for (let indicator of section.indicators) { - indicator.defaultId = !isDefault?indicator._id:null; + indicator.defaultId = !isDefault ? indicator._id : null; indicator._id = null; chartsTokeep.push(indicator); for (let indicatorPath of indicator.indicatorPaths) { @@ -94,22 +95,22 @@ export class StakeholderUtils { section.indicators = chartsTokeep; } for (let section of subCategory.numbers) { - section.defaultId = !isDefault?section._id:null; + section.defaultId = !isDefault ? section._id : null; section.stakeholderAlias = funder.alias; section._id = null; for (let indicator of section.indicators) { - indicator.defaultId = !isDefault?indicator._id:null; + indicator.defaultId = !isDefault ? indicator._id : null; indicator._id = null; } } - + } category.subCategories = subTokeep; } } return funder; } - + aliasValidatorString(elements: string[]): ValidatorFn { return (control: AbstractControl): { [key: string]: string } | null => { if (control.value && elements.find(element => @@ -120,7 +121,7 @@ export class StakeholderUtils { return null; } } - + aliasValidator(elements: any[]): ValidatorFn { return (control: AbstractControl): { [key: string]: string } | null => { if (control.value && elements.find(element => @@ -131,7 +132,7 @@ export class StakeholderUtils { return null; } } - + generateAlias(name: string): string { let alias = name.toLowerCase(); while (alias.includes('/') || alias.includes(' ')) { @@ -144,7 +145,7 @@ export class StakeholderUtils { } export class IndicatorUtils { - + allChartTypes: Option[] = [ {value: 'pie', label: 'Pie'}, {value: 'table', label: 'Table'}, @@ -160,27 +161,88 @@ export class IndicatorUtils { {value: 'medium', label: 'Medium'}, {value: 'large', label: 'Large'} ]; - + allSourceTypes: Option[] = [ {value: 'search', label: 'Search'}, {value: 'statistics', label: 'Statistics'}, {value: 'stats-tool', label: 'Statistics tool'} ]; - + formats: Option[] = [ {value: "NUMBER", label: "Number"}, {value: "PERCENTAGE", label: "Percentage"} ]; - + sourceTypes: Option[] = [ {value: 'stats-tool', label: 'Statistics tool'} ]; - + isActive: Option[] = [ {icon: 'brightness_1', iconClass: '', value: true, label: 'Active'}, {icon: 'brightness_1', value: false, label: 'Inactive'}, ]; - + + parametersValidators: Map = new Map([ + ['start_year', [Validators.required, Validators.pattern('^\\d+$')]], + ['end_year', [Validators.required, Validators.pattern('^\\d+$')]] + ]); + ignoredParameters = ['index_name', 'index_id', 'index_shortName']; + statsProfileParameter = 'profile'; + + numberSources: Map = new Map(); + chartSources: Map = new Map(); + + constructor() { + this.numberSources.set('statistics', [properties.statisticsAPIURL]); + this.numberSources.set('search', [properties.searchAPIURLLAst]); + this.numberSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); + this.chartSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); + this.chartSources.set('old', [properties.statisticsFrameAPIURL]); + this.chartSources.set('image', [""]); + } + + getSourceType(source:string): SourceType{ + let sourceType: SourceType = 'search'; + this.numberSources.forEach((values, key) => { + if(key == source) { + sourceType = key; + } + }); + return sourceType; + } + + getChartUrl(source: SourceType, url: string): string { + return this.chartSources.get(source)[0] + url; + } + + getNumberUrl(source: string, url: string): string { + return this.numberSources.get(this.getSourceType(source))[0] + url; + } + + getNumberSource(url: string): SourceType { + let source: SourceType = 'search'; + this.numberSources.forEach((values, key) => { + values.forEach((value) => { + if (value !== '' && url.indexOf(value) !== -1) { + source = key; + } + }); + }); + return source; + } + + getChartSource(url: string): SourceType { + let source: SourceType = 'image'; + this.chartSources.forEach((values, key) => { + values.forEach((value) => { + if (value !== '' && url.indexOf(value) !== -1) { + source = key; + } + }); + }); + return source; + } + getChartTypes(initialType) { let types: Option[] = []; if (this.basicChartTypes.indexOf(initialType) != -1) { @@ -201,15 +263,7 @@ export class IndicatorUtils { return this.allChartTypes; } } - - ignoredParameters = ['index_name', 'index_id', 'index_shortName']; - statsProfileParameter = 'profile'; - - parametersValidators: Map = new Map([ - ['start_year', [Validators.required, Validators.pattern('^\\d+$')]], - ['end_year', [Validators.required, Validators.pattern('^\\d+$')]] - ]); - + public getFullUrl(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null): string { let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url; if (stakeholder.statsProfile) { @@ -233,7 +287,7 @@ export class IndicatorUtils { if (key == "index_shortName") { replacedValue = stakeholder.index_shortName.toLowerCase(); } - + replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue) }); } @@ -251,7 +305,7 @@ export class IndicatorUtils { } if (startYear && indicatorPath.filters["start_year"]) { let newJsonObject = JSON.parse(replacedUrl); - + for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) { queries["query"]["filters"] = []; @@ -272,7 +326,7 @@ export class IndicatorUtils { } replacedUrl = JSON.stringify(newJsonObject); } - + } //For numbers (e.g. from stats-api , search service, etc) if (indicatorPath.url.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) { @@ -286,7 +340,7 @@ export class IndicatorUtils { } return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl); } - + public getFullUrlWithFilters(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, coFunded: boolean = false): string { indicatorPath.filtersApplied = 0; let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url; @@ -315,7 +369,7 @@ export class IndicatorUtils { if (key == "index_shortName") { replacedValue = stakeholder.index_shortName.toLowerCase(); } - + replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue) }); } @@ -347,7 +401,7 @@ export class IndicatorUtils { indicatorPath.filtersApplied += filterResults.filtersApplied; } } - + //For numbers if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) { replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id)) @@ -360,9 +414,9 @@ export class IndicatorUtils { } //Check apply enhancements return this.applySchemaEnhancements( ..); return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl); - + } - + private addFilter(replacedUrl, filterType: FilterType, filterValue) { let newJsonObject = JSON.parse(replacedUrl); let filterApplied: boolean = false; @@ -370,7 +424,7 @@ export class IndicatorUtils { for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { /*Chart with Named Queries*/ if (queries["query"]["name"] && !queries["query"]["select"]) { - + if (queries["query"]["name"].indexOf("monitor.") == -1 || !queries["query"]["parameters"]) { continue; } @@ -481,7 +535,7 @@ export class IndicatorUtils { } return {"url": JSON.stringify(newJsonObject), "filtersApplied": (filterApplied) ? 1 : 0}; } - + isComparingChart(newJsonObject, filter,) { let queriesCount = this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)].length : newJsonObject[this.getDescriptionObjectName(newJsonObject)].length; let values = []; @@ -498,7 +552,7 @@ export class IndicatorUtils { } return values.length > 1; } - + generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type: IndicatorType, addParameters: boolean = true): Indicator { let indicator: Indicator = new Indicator(form.name, form.description, form.additionalDescription, type, form.width, form.height, form.visibility, indicatorPaths, form.defaultId); @@ -517,7 +571,7 @@ export class IndicatorUtils { }); return indicator; } - + generateIndicatorByNumberUrl(source: SourceType, url: string, stakeholder: Stakeholder, jsonPath = [], sourceServices: string[] = []): IndicatorPath { let indicatorPath = new IndicatorPath(null, source, url, null, jsonPath); if (source === 'stats-tool') { @@ -555,7 +609,7 @@ export class IndicatorUtils { } return indicatorPath; } - + generateIndicatorByChartUrl(source: SourceType, url: string, type: IndicatorPathType = null, stakeholder: Stakeholder): IndicatorPath { let indicatorPath = new IndicatorPath(type, source, null, null, []); try { @@ -565,13 +619,13 @@ export class IndicatorUtils { indicatorPath.chartObject = decodeURIComponent(url.split("json=")[1]); let chart = JSON.parse(indicatorPath.chartObject); if (indicatorPath.url == "chart?json=") { - + if (chart["library"] && (chart["library"] == "HighCharts" || chart["library"] == "eCharts" || chart["library"] == "HighMaps")) { indicatorPath.type = this.extractType(chart, indicatorPath); } else { indicatorPath.type = this.defaultChartType; } - + this.extractTitle(chart, indicatorPath); this.extractSubTitle(chart, indicatorPath); this.extractXTitle(chart, indicatorPath); @@ -611,7 +665,7 @@ export class IndicatorUtils { } return indicatorPath; } - + private getQueryObjectName(obj) { if ((obj[this.getDescriptionObjectName(obj)]).hasOwnProperty("queriesInfo")) { return "queriesInfo"; @@ -619,7 +673,7 @@ export class IndicatorUtils { return "queries"; } } - + private getDescriptionObjectName(obj) { if (obj.hasOwnProperty("mapDescription")) { return "mapDescription"; @@ -631,7 +685,7 @@ export class IndicatorUtils { return "series"; } } - + private extractType(obj, indicatorPath: IndicatorPath): IndicatorPathType { let type = (obj[this.getDescriptionObjectName(obj)] && obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"]) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"] : ""; if (this.basicChartTypes.indexOf(type) == -1) { @@ -642,13 +696,13 @@ export class IndicatorUtils { } return type; } - + private extractStakeHolders(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { this.extractFunder(obj, indicatorPath, stakeholder); this.extractRI(obj, indicatorPath, stakeholder); this.extractOrganization(obj, indicatorPath, stakeholder); } - + private extractFunder(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { if (stakeholder.type != "funder") { return; @@ -677,7 +731,7 @@ export class IndicatorUtils { } } } - + private extractRI(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { if (stakeholder.type != "ri") { return; @@ -702,7 +756,7 @@ export class IndicatorUtils { } } } - + private extractOrganization(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { // works for publication.project.organization.name // and publication.organization.name @@ -729,7 +783,7 @@ export class IndicatorUtils { } } } - + private extractStartYear(obj, indicatorPath: IndicatorPath) { let start_year; for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { @@ -747,7 +801,7 @@ export class IndicatorUtils { } } } - + private extractEndYear(obj, indicatorPath: IndicatorPath) { let end_year; for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { @@ -765,7 +819,7 @@ export class IndicatorUtils { } } } - + private parameterizeDefaultQuery(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { let name = ""; for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { @@ -787,7 +841,7 @@ export class IndicatorUtils { } else if (name.split('.')[0] == "monitor" && parameters.length > 0 && name.split('.')[1] == stakeholder.type) { // new parameterized queries //monitor.{{type}}.{{queryname}}.{{param1 - id }}.{{param2 result-type}}.{{fl0}} --> params [start year, end year, id, result type, fl0] - + let index = (name.split('.').slice(3).length + 2 == parameters.length) ? [2] : ((name.split('.').slice(3).length * 2 + 4 == parameters.length) ? [2, name.split('.').slice(3).length + 4] : [0]); for (let i of index) { if (name.split('.').length > 3 && name.split('.')[3] == "id") { @@ -805,7 +859,7 @@ export class IndicatorUtils { } } } - + private extractDataTitle(obj, indicatorPath: IndicatorPath) { let index = 0; if (!obj[this.getDescriptionObjectName(obj)] || !obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { @@ -820,7 +874,7 @@ export class IndicatorUtils { index++; } } - + private extractTitle(obj, indicatorPath: IndicatorPath) { let title = ""; if (obj[this.getDescriptionObjectName(obj)]["title"]) { @@ -832,7 +886,7 @@ export class IndicatorUtils { } indicatorPath.parameters["title"] = title ? title : ""; } - + private extractSubTitle(obj, indicatorPath: IndicatorPath) { let subtitle = ""; if (obj[this.getDescriptionObjectName(obj)]["subtitle"]) { @@ -845,7 +899,7 @@ export class IndicatorUtils { indicatorPath.parameters["subtitle"] = subtitle ? subtitle : ""; } } - + private extractXTitle(obj, indicatorPath: IndicatorPath) { let title = ""; if (obj[this.getDescriptionObjectName(obj)]["xAxis"] && obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]) { @@ -860,7 +914,7 @@ export class IndicatorUtils { } indicatorPath.parameters["xAxisTitle"] = title ? title : ""; } - + private extractYTitle(obj, indicatorPath: IndicatorPath) { let title = ""; if (obj[this.getDescriptionObjectName(obj)]["yAxis"] && obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]) { @@ -875,17 +929,17 @@ export class IndicatorUtils { } indicatorPath.parameters["yAxisTitle"] = title ? title : ""; } - + private extractOldToolTitle(obj, indicatorPath: IndicatorPath) { let title = ""; if (obj["title"]) { title = obj["title"]; obj["title"] = ChartHelper.prefix + "title" + ChartHelper.suffix; indicatorPath.parameters["title"] = title; - + } } - + private extractOldToolXTitle(obj, indicatorPath: IndicatorPath) { let title = ""; if (obj["xaxistitle"]) { @@ -894,7 +948,7 @@ export class IndicatorUtils { indicatorPath.parameters["xAxisTitle"] = title; } } - + private extractOldToolYTitle(obj, indicatorPath: IndicatorPath) { let title = ""; if (obj["fieldsheaders"]) { @@ -907,11 +961,11 @@ export class IndicatorUtils { indicatorPath.parameters["yAxisTitle"] = title; } } - + public checkForSchemaEnhancements(url: string): boolean { return url != this.applySchemaEnhancements(url); } - + public applySchemaEnhancements(url: string): string { let resultEnhancements = [ [".project.acronym", ".project acronym"], @@ -930,7 +984,7 @@ export class IndicatorUtils { } } } - + if (url.split('json=').length > 1) { let obj = JSON.parse(decodeURIComponent(url.split('json=')[1])); for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { diff --git a/src/app/utils/services/statistics.service.ts b/src/app/utils/services/statistics.service.ts index 2a85eda..49defe2 100644 --- a/src/app/utils/services/statistics.service.ts +++ b/src/app/utils/services/statistics.service.ts @@ -3,69 +3,23 @@ import {HttpClient} from "@angular/common/http"; import {Observable} from "rxjs"; import {SourceType} from "../../openaireLibrary/monitor/entities/stakeholder"; import {properties} from "../../../environments/environment"; +import {IndicatorUtils} from "../indicator-utils"; @Injectable({ - providedIn: 'root' + providedIn: 'root' }) export class StatisticsService { - - numberSources: Map = new Map(); - chartSources: Map = new Map(); - - constructor(private http:HttpClient) { - this.numberSources.set('statistics', [properties.statisticsAPIURL]); - this.numberSources.set('search', [properties.searchAPIURLLAst]); - this.numberSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); - this.chartSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); - this.chartSources.set('old', [properties.statisticsFrameAPIURL]); - this.chartSources.set('image', [""]); + + indicatorsUtils = new IndicatorUtils(); + + constructor(private http: HttpClient) {} + + getNumbers(source: SourceType, url: string): Observable { + if (source !== null) { + return this.http.get(this.indicatorsUtils.getNumberUrl(source, url)); + } else { + return this.http.get(url); + } } - getSourceType(source:string):SourceType{ - let sourceType: SourceType = 'search'; - this.numberSources.forEach((values, key) => { - if(key == source) { - sourceType = key; - - } - }); - return sourceType; - } - - getNumbers(source: SourceType, url: string): Observable { - if(source !== null) { - return this.http.get(this.numberSources.get(source)[0] + url); - } else { - return this.http.get(url); - } - } - - getChartUrl(source: SourceType, url: string): string { - return this.chartSources.get(source)[0] + url; - } - getNumberUrl(source: string, url: string): string { - return this.numberSources.get(this.getSourceType(source))[0] + url; - } - getNumberSource(url: string): SourceType { - let source: SourceType = 'search'; - this.numberSources.forEach((values, key) => { - values.forEach((value) => { - if(value !== '' && url.indexOf(value) !== -1) { - source = key; - } - }); - }); - return source; - } - getChartSource(url: string): SourceType { - let source: SourceType = 'image'; - this.chartSources.forEach((values, key) => { - values.forEach((value) => { - if(value !== '' && url.indexOf(value) !== -1) { - source = key; - } - }); - }); - return source; - } } diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 259c6f5..5b23d2a 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -21,7 +21,7 @@ export let properties: EnvProperties = { useNewStatistisTool: true, monitorStatsFrameUrl:"https://stats.madgik.di.uoa.gr/stats-api/", useOldStatisticsSchema: false, - disableFrameLoad: true, + disableFrameLoad: false, claimsAPIURL: "http://scoobydoo.di.uoa.gr:8080/dnet-claims-service-2.0.0-SNAPSHOT/rest/claimsService/", searchAPIURLLAst: "https://beta.services.openaire.eu/search/v2/api/", searchResourcesAPIURL: "https://beta.services.openaire.eu/search/v2/api/resources", diff --git a/src/stats-tool-parser.ts b/src/stats-tool-parser.ts new file mode 100644 index 0000000..1aab686 --- /dev/null +++ b/src/stats-tool-parser.ts @@ -0,0 +1,93 @@ +export function statsToolParser(dataJSONobj: any): any { + let RequestInfoObj = Object.assign({}); + switch(dataJSONobj.library) { + case "GoogleCharts": + //Pass the Chart library to ChartDataFormatter + RequestInfoObj.library = dataJSONobj.library; + RequestInfoObj.orderBy = dataJSONobj.orderBy; + + //Create ChartInfo Object Array + RequestInfoObj.chartsInfo = []; + //Create ChartInfo and pass the Chart data queries to ChartDataFormatter + //along with the requested Chart type + RequestInfoObj.chartsInfo = dataJSONobj.chartDescription.queriesInfo; + break; + case "eCharts": + //Pass the Chart library to ChartDataFormatter + RequestInfoObj.library = dataJSONobj.library; + RequestInfoObj.orderBy = dataJSONobj.orderBy; + + //Create ChartInfo Object Array + RequestInfoObj.chartsInfo = []; + + //Create ChartInfo and pass the Chart data queries to ChartDataFormatter + //along with the requested Chart type + for (let index = 0; index < dataJSONobj.chartDescription.queries.length; index++) { + let element = dataJSONobj.chartDescription.queries[index]; + var ChartInfoObj = Object.assign({}); + + if(element.type === undefined) + ChartInfoObj.type = dataJSONobj.chartDescription.series[index].type; + else + ChartInfoObj.type = element.type; + + if(element.name === undefined) + ChartInfoObj.name = null; + else + ChartInfoObj.name = element.name; + + ChartInfoObj.query = element.query; + RequestInfoObj.chartsInfo.push(ChartInfoObj); + } + break; + case "HighCharts": + RequestInfoObj.library = dataJSONobj.library; + RequestInfoObj.orderBy = dataJSONobj.orderBy; + //Pass the Chart type to ChartDataFormatter + var defaultType = dataJSONobj.chartDescription.chart.type; + //Create ChartInfo Object Array + RequestInfoObj.chartsInfo = []; + //Create ChartInfo and pass the Chart data queries to ChartDataFormatter + //along with the requested Chart type + dataJSONobj.chartDescription.queries. + forEach(element => { + var ChartInfoObj = Object.assign({}); + + if(element.type === undefined) + ChartInfoObj.type = defaultType; + else + ChartInfoObj.type = element.type; + + if(element.name === undefined) + ChartInfoObj.name = null; + else + ChartInfoObj.name = element.name; + + ChartInfoObj.query = element.query; + RequestInfoObj.chartsInfo.push(ChartInfoObj); + }); + break; + case "HighMaps": + RequestInfoObj.library = dataJSONobj.library; + //Create ChartInfo Object Array + RequestInfoObj.chartsInfo = []; + + //Create ChartInfo and pass the Chart data queries to ChartDataFormatter + dataJSONobj.mapDescription.queries. + forEach(element => { + var ChartInfoObj = Object.assign({}); + + if(element.name === undefined) + ChartInfoObj.name = null; + else + ChartInfoObj.name = element.name; + + ChartInfoObj.query = element.query; + RequestInfoObj.chartsInfo.push(ChartInfoObj); + }); + break; + default: + console.log("Unsupported Library: "+ dataJSONobj.library); + } + return RequestInfoObj; +}