diff --git a/api/.env.defaults b/api/.env.defaults index 63d5e94dc49793acee86be230ae90ff3783eff32..e94e8c27922e77468d92961b311feac1c081608b 100644 --- a/api/.env.defaults +++ b/api/.env.defaults @@ -1,3 +1,3 @@ -ENGINE_TYPE=exareme -ENGINE_BASE_URL=http://127.0.0.1:8080/services/ +ENGINE_TYPE=csv +ENGINE_BASE_URL=https://docs.google.com/spreadsheets/d/1yjslZQCOMCxkjr4xQ-NmTMNEjhpdmZgijbn83za80Ak/export?format=tsv GATEWAY_PORT=8081 \ No newline at end of file diff --git a/api/src/engine/connectors/csv/main.connector.ts b/api/src/engine/connectors/csv/main.connector.ts new file mode 100644 index 0000000000000000000000000000000000000000..eedb7ae6b31074fbe1e5c66970aa008f62859004 --- /dev/null +++ b/api/src/engine/connectors/csv/main.connector.ts @@ -0,0 +1,173 @@ +import { firstValueFrom, Observable } from 'rxjs'; +import { IEngineOptions, IEngineService } from 'src/engine/engine.interfaces'; +import { Domain } from 'src/engine/models/domain.model'; +import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input'; +import { + Experiment, + PartialExperiment, +} from 'src/engine/models/experiment/experiment.model'; +import { ListExperiments } from 'src/engine/models/experiment/list-experiments.model'; +import { ExperimentEditInput } from 'src/engine/models/experiment/input/experiment-edit.input'; +import { Algorithm } from 'src/engine/models/experiment/algorithm.model'; +import { HttpService } from '@nestjs/axios'; +import { Group } from 'src/engine/models/group.model'; +import { Dictionary } from 'src/common/interfaces/utilities.interface'; + +export default class CSVService implements IEngineService { + constructor( + private readonly options: IEngineOptions, + private readonly httpService: HttpService, + ) {} + + getAlgorithms(): Algorithm[] | Promise<Algorithm[]> { + throw new Error('Method not implemented.'); + } + + createExperiment( + data: ExperimentCreateInput, + isTransient: boolean, + ): Experiment | Promise<Experiment> { + throw new Error('Method not implemented.'); + } + + listExperiments( + page: number, + name: string, + ): ListExperiments | Promise<ListExperiments> { + throw new Error('Method not implemented.'); + } + + getExperiment(uuid: string): Experiment | Promise<Experiment> { + throw new Error('Method not implemented.'); + } + + removeExperiment( + uuid: string, + ): PartialExperiment | Promise<PartialExperiment> { + throw new Error('Method not implemented.'); + } + + editExperient( + uuid: string, + expriment: ExperimentEditInput, + ): Experiment | Promise<Experiment> { + throw new Error('Method not implemented.'); + } + + async getDomains(): Promise<Domain[]> { + const path = this.options.baseurl; + + const { data } = await firstValueFrom(this.httpService.get<string>(path)); + + const rows = data + .split('\r\n') + .map((row) => row.split('\t').filter((i) => i)) + .filter((row) => row.length >= 2); + + rows.shift(); // remove headers + + const vars = []; + const groups: Dictionary<Group> = {}; + const rootGroup: Group = { + id: 'Global group', + groups: [], + }; + + rows.forEach((row) => { + const variable = { + id: row[0].toLowerCase(), + label: row[0], + }; + + row.shift(); // get ride of the variable name, keep only groups + + vars.push(variable); + + row + .filter((group) => !groups[group.toLowerCase()]) + .forEach((group, i) => { + const groupId = group.toLowerCase(); + if (i === 0) rootGroup.groups.push(groupId); + groups[groupId] = { + id: groupId, + label: group, + variables: [], + groups: [], + }; + }); + + const groupId = row[row.length - 1].toLowerCase(); // group's variable container + + groups[groupId].variables.push(variable.id); // add variable + + row + .reverse() + .map((group) => group.toLowerCase()) + .forEach((group, i) => { + const groupId = group.toLowerCase(); + + if (i !== row.length - 1) { + const parentId = row[i + 1].toLowerCase(); + if (groups[parentId].groups.indexOf(groupId) === -1) + groups[parentId].groups.push(groupId); + } + }); + }); + + rootGroup.groups = [...new Set(rootGroup.groups)]; // get distinct values + + return [ + { + id: 'Dummy', + label: 'Dummy', + datasets: [{ id: 'DummyDataset', label: 'Dummy Dataset' }], + groups: Object.values(groups), + rootGroup: rootGroup, + variables: vars, + }, + ]; + } + + getActiveUser(): string { + const dummyUser = { + username: 'anonymous', + subjectId: 'anonymousId', + fullname: 'anonymous', + email: 'anonymous@anonymous.com', + agreeNDA: true, + }; + return JSON.stringify(dummyUser); + } + + editActiveUser(): Observable<string> { + throw new Error('Method not implemented.'); + } + + getExperimentREST(): Observable<string> { + throw new Error('Method not implemented.'); + } + + deleteExperiment(): Observable<string> { + throw new Error('Method not implemented.'); + } + + editExperimentREST(): Observable<string> { + throw new Error('Method not implemented.'); + } + + startExperimentTransient(): Observable<string> { + throw new Error('Method not implemented.'); + } + + startExperiment(): Observable<string> { + throw new Error('Method not implemented.'); + } + + getExperiments(): string { + return '[]'; + } + + getAlgorithmsREST(): string { + return '[]'; + } +} diff --git a/api/src/engine/connectors/exareme/converters.ts b/api/src/engine/connectors/exareme/converters.ts index 07fb2b4b0cfa378b1950147be5862307d4ff4ea9..ab840843a6c698c24142eb228343d819584ee8a6 100644 --- a/api/src/engine/connectors/exareme/converters.ts +++ b/api/src/engine/connectors/exareme/converters.ts @@ -27,7 +27,9 @@ export const dataToGroup = (data: Hierarchy): Group => { return { id: data.code, label: data.label, - groups: data.groups ? data.groups.map(dataToGroup) : [], + groups: data.groups + ? data.groups.map(dataToGroup).map((group) => group.id) + : [], variables: data.variables ? data.variables.map((data: VariableEntity) => data.code) : [], diff --git a/api/src/engine/models/group.model.ts b/api/src/engine/models/group.model.ts index 6c4880262e3a538114f3e4717d9c4ddabf7a061d..6a23f1983398f81eeca84731c3d8cfe4b92b599a 100644 --- a/api/src/engine/models/group.model.ts +++ b/api/src/engine/models/group.model.ts @@ -6,8 +6,8 @@ export class Group extends Entity { @Field({ nullable: true }) description?: string; - @Field(() => [Group], { defaultValue: [], nullable: true }) - groups?: Group[]; + @Field(() => [String], { defaultValue: [], nullable: true }) + groups?: string[]; @Field(() => [String], { description: "List of variable's ids", diff --git a/api/src/engine/models/variable.model.ts b/api/src/engine/models/variable.model.ts index 8650f48b1044bb07c88964ae36aeb00d0d9a3d1b..bd54afed70a025ce6c5673bf0627a657d77926cb 100644 --- a/api/src/engine/models/variable.model.ts +++ b/api/src/engine/models/variable.model.ts @@ -5,8 +5,8 @@ import { Group } from './group.model'; @ObjectType() export class Variable extends Entity { - @Field() - type: string; + @Field({ nullable: true }) + type?: string; @Field({ nullable: true }) description?: string; diff --git a/api/src/schema.gql b/api/src/schema.gql index c906a1951ce36cba5961ced0c2853ef6ddb2658c..86b31a4d2dcb38a15ab00200462ce2c5bd220d97 100644 --- a/api/src/schema.gql +++ b/api/src/schema.gql @@ -11,7 +11,7 @@ type Group { id: String! label: String description: String - groups: [Group!] + groups: [String!] """List of variable's ids""" variables: [String!] @@ -20,7 +20,7 @@ type Group { type Variable { id: String! label: String - type: String! + type: String description: String enumerations: [Category!] groups: [Group!]