Skip to content

Commit aa8a9f7

Browse files
authored
Feat: import ademe's formations in baserow (#2124)
Création d'une commande permettant d'ajouter les informations des formations ADEME dans baserow. close #1286
1 parent 1b1e8da commit aa8a9f7

File tree

5 files changed

+59
-17
lines changed

5 files changed

+59
-17
lines changed

libs/data/src/common/baserow/abstractBaserow.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export abstract class AbstractBaserow {
1111
protected readonly __dirname = path.dirname(fileURLToPath(import.meta.url))
1212
private readonly _apiToken = this._setBaserowToken()
1313
private readonly _baseUrl = 'https://api.baserow.io/api'
14+
private readonly _url = `${this._baseUrl}/database/rows/table`
1415
protected readonly _themeTableId = ConfigBaserow.THEME_ID
1516
protected readonly _operatorTableId = ConfigBaserow.OPERATOR_ID
1617
protected readonly _geographicAreasTableId = ConfigBaserow.GEOGRAPHIC_AREAS_ID
@@ -24,7 +25,7 @@ export abstract class AbstractBaserow {
2425

2526
protected async _getTableData<T>(tableId: number): Promise<T[]> {
2627
try {
27-
const response = await axios.get(`${this._baseUrl}/database/rows/table/${tableId}/?user_field_names=true`, this._axiosHeader)
28+
const response = await axios.get(`${this._url}/${tableId}/?user_field_names=true`, this._axiosHeader)
2829
await this._delay(100)
2930
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
3031
let results = response.data.results
@@ -44,7 +45,7 @@ export abstract class AbstractBaserow {
4445

4546
protected async _getRowData<T>(tableId: number, rowId: number): Promise<T | null> {
4647
try {
47-
const response = await axios.get(`${this._baseUrl}/database/rows/table/${tableId}/${rowId}/?user_field_names=true`, this._axiosHeader)
48+
const response = await axios.get(`${this._url}/${tableId}/${rowId}/?user_field_names=true`, this._axiosHeader)
4849

4950
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
5051
return response.data
@@ -75,17 +76,18 @@ export abstract class AbstractBaserow {
7576
throw Error('Baserow token not found.')
7677
}
7778

79+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7880
protected async _patchRow(tableId: number, rowId: number, data: Record<string, any>): Promise<void> {
7981
try {
80-
await axios.patch(`${this._baseUrl}/database/rows/table/${tableId}/${rowId}/?user_field_names=true`, data, this._axiosHeader)
82+
await axios.patch(`${this._url}/${tableId}/${rowId}/?user_field_names=true`, data, this._axiosHeader)
8183
} catch (error) {
8284
console.error(`Error patching row ${rowId} in table ${tableId}:`, error)
8385
}
8486
}
8587

8688
protected async _createRow(tableId: number, data: Record<string, any>): Promise<void> {
8789
try {
88-
await axios.post(`${this._baseUrl}/database/rows/table/${tableId}/?user_field_names=true`, data, this._axiosHeader)
90+
await axios.post(`${this._url}/${tableId}/?user_field_names=true`, data, this._axiosHeader)
8991
} catch (error) {
9092
console.error(`Error creating row in table ${tableId}:`, error)
9193
}

libs/data/src/common/baserow/trainingBaserow.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
11
import { AbstractBaserow } from './abstractBaserow'
22
import { BaserowTraining } from './types'
33
import { Training } from '../../trainings/types'
4+
import ConfigBaserow from '../../configBaserow'
45

56
export class TrainingBaserow extends AbstractBaserow {
6-
private readonly _tableId = 620771
7+
private readonly _tableId = ConfigBaserow.TRAINING_ID
8+
private _trainings: BaserowTraining[] = []
79

810
async getAll(): Promise<BaserowTraining[]> {
9-
return this._getTableData<BaserowTraining>(this._tableId)
11+
return (this._trainings = await this._getTableData<BaserowTraining>(this._tableId))
1012
}
1113

12-
async patchOrCreate(training: Training, existingTrainings: BaserowTraining[]): Promise<void> {
13-
const match = existingTrainings.find((baserowTraining) => baserowTraining['Id Ademe'] === training.id)
14+
async patchOrCreate(training: Training): Promise<void> {
15+
if (!this._trainings.length) {
16+
throw new Error('TrainingBaserow: No trainings loaded. Call getAll() first.')
17+
}
18+
19+
const match = this._trainings.find((baserowTraining) => baserowTraining['Id Ademe'] === training.id)
1420

1521
const payload: Partial<BaserowTraining> = {
1622
'Id Ademe': training.id,
1723
'Futures Sessions': training.session ? JSON.stringify(Array.isArray(training.session) ? training.session : [training.session]) : '',
1824
Titre: training.Libellé_de_la_formation,
1925
Promesse: training.Chapeau_pour_site_web,
2026
'Url ADEME': training.Lien_URL_vers_la_fiche_programme,
21-
Objectifs: training.Objectifs_de_la_formation
27+
Objectifs: training.Objectifs_de_la_formation,
28+
Thématique: training.Thème._,
29+
Modalité: training.Modalité_de_dispense._ + ' | ' + training.Modalités_et_moyens_pédagogiques,
30+
'Codes Sections': Array.isArray(training.Id_section_code) ? training.Id_section_code.map((item) => item.id).join(', ') : '',
31+
Cible: training.Public_cible,
32+
Programme: training.Programme,
33+
Prérequis: training.Prérequis,
34+
Tarif: training.Tarif_net_de_taxes,
35+
Durée: training.Durée_totale_en_heures,
36+
'Nombre de jours': training.Nombre_de_jours_de_formation,
37+
'Nombre de sessions à venir': Array.isArray(training.session) ? training.session.length : training.session ? 1 : 0,
38+
'Nombre de participants par session':
39+
'De ' + training.Nombre_de_participants_minimum + ' à ' + training.Nombre_de_participants_maximum
2240
}
2341

2442
if (match && match.id) {

libs/data/src/common/baserow/types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,17 @@ export interface BaserowTraining extends Id {
140140
Promesse: string
141141
'Url ADEME': string
142142
Objectifs: string
143+
Thématique: string
144+
'Nombre de sessions à venir': number
145+
'Nombre de participants par session': string
146+
Modalité: string
147+
'Codes Sections': string
148+
Cible: string
149+
Programme: string
150+
Prérequis: string
151+
Tarif: string
152+
Durée: string
153+
'Nombre de jours': string
143154
}
144155

145156
export interface ProgramTechField {

libs/data/src/configBaserow.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default class ConfigBaserow extends ConfigCommon {
1010
private static _TABLE_ID_PROJECT = 305253
1111
private static _TABLE_ID_TESTIMONIES = 399896
1212
private static _TABLE_ID_THEME = 305258
13+
private static _TABLE_ID_TRAINING = 620771
1314

1415
public static get TOKEN() {
1516
return this.getEnvValue('BASEROW_TOKEN')
@@ -50,4 +51,8 @@ export default class ConfigBaserow extends ConfigCommon {
5051
public static get THEME_ID() {
5152
return parseInt(this.getEnvValue('BASEROW_TABLE_ID_THEME', this._TABLE_ID_THEME.toString()))
5253
}
54+
55+
public static get TRAINING_ID() {
56+
return parseInt(this.getEnvValue('BASEROW_TABLE_ID_TRAINING', this._TABLE_ID_TRAINING.toString()))
57+
}
5358
}
Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
import { parseStringPromise } from 'xml2js'
22
import axios from 'axios'
33
import { Training } from './types'
4-
import { BaserowTraining } from '../common/baserow/types'
54
import { TrainingBaserow } from '../common/baserow/trainingBaserow'
65

76
export class TrainingFeatures {
8-
async loadTrainings(): Promise<Training[]> {
7+
async loadTrainings(): Promise<void> {
8+
const trainings = await this.getXmlData()
9+
await this.updateDatabase(trainings)
10+
return
11+
}
12+
13+
private async getXmlData(): Promise<Training[]> {
914
const xmlPath = 'https://formations.ademe.fr/tmp/flux_formations_agir.xml'
1015
const xmlContent = await axios.get(xmlPath).then((res) => res.data)
1116
const parsed = await parseStringPromise(xmlContent, { mergeAttrs: true, explicitArray: false })
12-
const formations: Training[] = parsed.formations.module || []
1317

18+
return parsed.formations.module || []
19+
}
20+
21+
private async updateDatabase(trainings: Training[]): Promise<void> {
1422
const trainingBaserow = new TrainingBaserow()
15-
const existingTrainings: BaserowTraining[] = await trainingBaserow.getAll()
16-
for (const formation of formations) {
17-
await trainingBaserow.patchOrCreate(formation, existingTrainings)
23+
await trainingBaserow.getAll()
24+
for (const training of trainings) {
25+
await trainingBaserow.patchOrCreate(training)
1826
await new Promise((res) => setTimeout(res, 200))
1927
}
20-
21-
return []
2228
}
2329
}

0 commit comments

Comments
 (0)