@data-fair/catalog-onegeo-suite 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type CatalogPlugin from '@data-fair/types-catalogs'
2
- import { importConfigSchema, configSchema, assertConfigValid, type OneGeoSuiteConfig } from '#types'
2
+ import { configSchema, assertConfigValid, type OneGeoSuiteConfig } from '#types'
3
3
  import { type OneGeoCapabilities, capabilities } from './lib/capabilities.ts'
4
4
  import i18n from './lib/i18n.ts'
5
5
 
@@ -30,7 +30,6 @@ const plugin: CatalogPlugin<OneGeoSuiteConfig, OneGeoCapabilities> = {
30
30
  capabilities
31
31
  },
32
32
 
33
- importConfigSchema,
34
33
  configSchema,
35
34
  assertConfigValid
36
35
  }
@@ -11,7 +11,6 @@ export const capabilities = [
11
11
  'pagination',
12
12
 
13
13
  'import',
14
- 'importConfig',
15
14
 
16
15
  ] satisfies Capability[]
17
16
 
package/lib/imports.ts CHANGED
@@ -4,74 +4,38 @@ import { apiList, formatsList, sortList } from './list.ts'
4
4
 
5
5
  import axios from '@data-fair/lib-node/axios.js'
6
6
 
7
- export const getResource = async ({ catalogConfig, importConfig, resourceId, tmpDir, log }: GetResourceContext<OneGeoSuiteConfig>): ReturnType<CatalogPlugin['getResource']> => {
8
- let service: string = importConfig.service
9
- let format: string = service ? importConfig.format : (importConfig.format2 || undefined)
10
- const catalog = (await axios.get(new URL(`fr/indexer/elastic/_search/?q=uuid.keyword:${resourceId}%20AND%20is_metadata:true`, catalogConfig.url).href)).data.hits.hits[0]
11
- if (!format) {
12
- if (!service) {
13
- const links = catalog._source['metadata-fr'].link.filter((x: any) => { return apiList.includes(x.service) && x.formats.find((y: string) => { return formatsList.includes(y) }) })
14
- service = sortList(links.map((x: Link) => x.service), apiList)[0]
15
- }
16
- format = sortList(catalog._source['metadata-fr'].link.find((x: Link) => { return (x.service === service || x.url === service) && x.formats.find((y: string) => { return formatsList.includes(y) }) }).formats, formatsList)[0]
17
- if (!format) throw Error(`resource not found for service ${service}`)
18
- } else {
19
- if (!service) {
20
- const links = catalog._source['metadata-fr'].link.filter((x: Link) => { return x.formats.includes(format) })
21
- service = sortList(links.map((x: Link) => x.service), apiList)[0]
22
- if (!service) throw Error(`resource not found for format ${format}`)
23
- }
24
- }
25
-
26
- if (!catalog) throw Error(`resource not found for ${resourceId} in ${catalogConfig.url}`)
27
- if (!service) throw Error('resource not found')
28
- if (!format) throw Error(`resource not found for service ${service}`)
29
-
30
- // filter links by format and service
31
- const source: Link = catalog._source['metadata-fr'].link.find((x: Link) => {
32
- return x.service === service || x.url === service
33
- })
34
- if (!source) throw Error('resource not found')
35
- // table of format for make WFS url
36
- const wfsTable: Record<string, string> = {
37
- CSV: 'csv',
38
- JSON: 'application/json',
39
- GeoJSON: 'application/json',
40
- 'Shapefile (zip)': 'SHAPE-ZIP',
41
- 'SHAPE-ZIP': 'SHAPE-ZIP',
42
- KML: 'kml',
43
- }
44
- // table of format
45
- const extensionTable: Record<string, string> = {
46
- CSV: '.csv',
47
- GeoJSON: '.geojson',
48
- JSON: '.json',
49
- 'Shapefile (zip)': '.zip',
50
- 'SHAPE-ZIP': '.zip',
51
- KML: '.kml',
52
- 'Excel non structuré': '.xlsx',
53
- 'Microsoft Excel': '.xls',
54
- }
55
-
56
- let downloadUrl: string
57
- if (source.service === 'WS') {
58
- if (extensionTable[format] === undefined) throw Error(`Format ${format} not valid for ${service}`)
59
- downloadUrl = `${source.url}/${source.name}/all${extensionTable[format]}`
60
- } else if (source.service === undefined) {
61
- downloadUrl = `${source.url}`
62
- } else if (source.service === 'WFS') {
63
- if (wfsTable[format] === undefined) throw Error(`Format ${format} not valid for ${service}`)
64
- downloadUrl = `${source.url}?SERVICE=WFS&VERSION=2.0.0&request=GetFeature&typename=${source.name}&outputFormat=${wfsTable[format]}&startIndex=0&sortby=gid`
65
- } else {
66
- downloadUrl = `${source.url}`
67
- }
7
+ // table of format -> extension
8
+ const wfsTable: Record<string, string> = {
9
+ CSV: 'csv',
10
+ JSON: 'application/json',
11
+ GeoJSON: 'application/json',
12
+ 'Shapefile (zip)': 'SHAPE-ZIP',
13
+ 'SHAPE-ZIP': 'SHAPE-ZIP',
14
+ KML: 'kml',
15
+ }
68
16
 
69
- await log.step(`Downloading the file ${downloadUrl}`)
17
+ // table of format -> extension
18
+ const extensionTable: Record<string, string> = {
19
+ CSV: '.csv',
20
+ GeoJSON: '.geojson',
21
+ JSON: '.json',
22
+ 'Shapefile (zip)': '.zip',
23
+ 'SHAPE-ZIP': '.zip',
24
+ KML: '.kml',
25
+ 'Excel non structuré': '.xlsx',
26
+ 'Microsoft Excel': '.xls',
27
+ }
70
28
 
71
- // Download the resource
72
- const fs = await import('node:fs')
73
- const path = await import('path')
29
+ export const getResource = async ({
30
+ catalogConfig,
31
+ resourceId,
32
+ tmpDir,
33
+ log
34
+ }: GetResourceContext<OneGeoSuiteConfig>): ReturnType<CatalogPlugin['getResource']> => {
35
+ const catalog = (await axios.get(new URL(`fr/indexer/elastic/_search/?q=uuid.keyword:${resourceId}%20AND%20is_metadata:true`, catalogConfig.url).href)).data.hits.hits[0]
36
+ if (!catalog) throw Error(`resource not found for ${resourceId} in ${catalogConfig.url}`)
74
37
 
38
+ // get origine url
75
39
  const axiosPortail = axios.create({
76
40
  validateStatus: function (status) {
77
41
  return status >= 200 && status < 500
@@ -86,19 +50,57 @@ export const getResource = async ({ catalogConfig, importConfig, resourceId, tmp
86
50
  }
87
51
  const origin = portail ? `${catalogConfig.url}/${portail}/jeux-de-donnees/${catalog._source.slug}/info` : ''
88
52
 
89
- let response
90
- try {
91
- response = await axios.get(downloadUrl, {
92
- responseType: 'stream',
53
+ const links: Link[] = catalog._source['metadata-fr'].link.filter((x: Link) => {
54
+ return apiList.includes(x.service) && x.formats.find((y: string) => {
55
+ return formatsList.includes(y)
93
56
  })
94
- if (response.headers['content-type'] === 'text/html') {
95
- response = undefined
96
- throw Error('return HTML page')
57
+ })
58
+
59
+ // list all url possible
60
+ let downloadUrls: { url: string, format: string, service: string | undefined, description: string | undefined }[] = []
61
+
62
+ for (const link of links) {
63
+ const formats = link.formats.filter((f: string) => {
64
+ return formatsList.includes(f)
65
+ })
66
+ for (const format of formats) {
67
+ if (link.service === 'WS' && extensionTable[format]) {
68
+ downloadUrls.push({ url: `${link.url}/${link.name}/all${extensionTable[format]}`, format, service: link.service, description: link.description })
69
+ } else if (link.service === undefined) {
70
+ downloadUrls.push({ url: `${link.url}`, format, service: link.service, description: link.description })
71
+ } else if (link.service === 'WFS' && wfsTable[format]) {
72
+ downloadUrls.push({ url: `${link.url}?SERVICE=WFS&VERSION=2.0.0&request=GetFeature&typename=${link.name}&outputFormat=${wfsTable[format]}`, format, service: link.service, description: link.description })
73
+ }
97
74
  }
75
+ }
76
+ downloadUrls = sortList(downloadUrls, apiList, (x: any) => { return x.service })
77
+ downloadUrls = sortList(downloadUrls, formatsList, (x: any) => { return x.format })
98
78
 
99
- await log.info(`Get file with ${downloadUrl} successfully! ${response.status}`)
100
- } catch (e) {
101
- await log.warning(`Get file fail with this url: ${downloadUrl}; ${e}`)
79
+ // Download the resource
80
+ const fs = await import('node:fs')
81
+ const path = await import('path')
82
+ let response
83
+ let format: string
84
+ let description: string | undefined
85
+
86
+ for (const downloadUrl of downloadUrls) {
87
+ await log.step(`Downloading the file ${downloadUrl.url}; format: ${downloadUrl.format}; service: ${downloadUrl.service}`)
88
+
89
+ try {
90
+ response = await axios.get(downloadUrl.url, {
91
+ responseType: 'stream',
92
+ })
93
+ if (response.headers['content-type'] === 'text/html') {
94
+ response = undefined
95
+ throw Error('return HTML page')
96
+ }
97
+ format = downloadUrl.format
98
+ description = downloadUrl.description
99
+ await log.info(`Get file with ${downloadUrl.url} successfully! ${response.status}`)
100
+ } catch (e) {
101
+ await log.warning(`Downloading fail with this url: ${downloadUrl}; ${e}`)
102
+ }
103
+ if (response) break
102
104
  }
103
105
 
104
106
  if (!response) {
@@ -106,7 +108,7 @@ export const getResource = async ({ catalogConfig, importConfig, resourceId, tmp
106
108
  }
107
109
 
108
110
  // Create a filename
109
- const fileName = catalog._source.slug + extensionTable[format]
111
+ const fileName = catalog._source.slug + extensionTable[format!]
110
112
  const filePath = path.join(tmpDir, fileName)
111
113
  await log.info(`Downloading resource to ${fileName}`)
112
114
 
@@ -149,9 +151,9 @@ export const getResource = async ({ catalogConfig, importConfig, resourceId, tmp
149
151
  id: resourceId,
150
152
  slug: catalog._source.slug,
151
153
  title: catalog._source['metadata-fr'].title,
152
- description: source.description ?? catalog._source['metadata-fr'].abstratc,
154
+ description: description ?? catalog._source['metadata-fr'].abstratc,
153
155
  filePath,
154
- format,
156
+ format: format!,
155
157
  frequency,
156
158
  license: {
157
159
  href: '',
@@ -159,7 +161,9 @@ export const getResource = async ({ catalogConfig, importConfig, resourceId, tmp
159
161
  },
160
162
  keywords: catalog._source['metadata-fr'].keyword,
161
163
  updatedAt: catalog._source['metadata-fr'].lastUpdateDate ?? undefined,
162
- image: catalog._source['metadata-fr'].image.find((x: { type: string, url: string | null }) => { return x.type === 'thumbnail' && !!x.url })?.url ?? null,
164
+ image: catalog._source['metadata-fr'].image.find((x: { type: string, url: string | null }) => {
165
+ return x.type === 'thumbnail' && !!x.url
166
+ })?.url ?? null,
163
167
  origin
164
168
  }
165
169
  }
package/lib/list.ts CHANGED
@@ -7,7 +7,7 @@ type ResourceList = Awaited<ReturnType<CatalogPlugin['list']>>['results']
7
7
 
8
8
  export const apiList: Array<string | undefined> = ['WS', 'WFS', undefined]
9
9
  export const formatsList = [
10
- 'CSV', 'Excel non structuré', 'Microsoft Excel', 'Shapefile (zip)', 'SHAPE-ZIP', 'GeoJSON', 'JSON', 'KML']
10
+ 'GeoJSON', 'SHAPE-ZIP', 'Shapefile (zip)', 'CSV', 'JSON', 'Excel non structuré', 'Microsoft Excel', 'KML']
11
11
 
12
12
  const extensionTable: Record<string, string> = {
13
13
  CSV: '.csv',
@@ -20,10 +20,10 @@ const extensionTable: Record<string, string> = {
20
20
  'Microsoft Excel': '.xls',
21
21
  }
22
22
 
23
- export const sortList = (formats: any[], reference: any[]) => {
23
+ export const sortList = (formats: any[], reference: any[], func = (x: any) => { return x }) => {
24
24
  return [...formats].sort((a, b) =>
25
- (reference.indexOf(a) === -1 ? reference.length : reference.indexOf(a)) -
26
- (reference.indexOf(b) === -1 ? reference.length : reference.indexOf(b))
25
+ (reference.indexOf(func(a)) === -1 ? reference.length : reference.indexOf(func(a))) -
26
+ (reference.indexOf(func(b)) === -1 ? reference.length : reference.indexOf(func(b)))
27
27
  )
28
28
  }
29
29
  const baseReqDataset = (input: string = '*', size: number = 500, from: number = 1) => {
@@ -47,7 +47,7 @@ const baseReqDataset = (input: string = '*', size: number = 500, from: number =
47
47
  }
48
48
  }]
49
49
  }
50
- }, { term: { is_metadata: true } }, { term: { 'editorial-metadata.isOpenAccess': true } }, {
50
+ }, { term: { is_metadata: true } }, { term: { 'editorial-metadata.defaultPermissionLevel': 3 } }, {
51
51
  bool: {
52
52
  should: [
53
53
  ...apiList.filter((x: any) => { return x }).map((x: any) => { return { term: { 'metadata-fr.link.service.keyword': x } } }),
@@ -87,7 +87,7 @@ const countReq = (input: string = '*') => {
87
87
  }
88
88
  }]
89
89
  }
90
- }, { term: { is_metadata: true } }, { term: { 'editorial-metadata.isOpenAccess': true } }, {
90
+ }, { term: { is_metadata: true } }, { term: { 'editorial-metadata.defaultPermissionLevel': 3 } }, {
91
91
  bool: {
92
92
  should: [
93
93
  ...apiList.filter((x: any) => x).map((x: any) => ({ term: { 'metadata-fr.link.service.keyword': x } })),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@data-fair/catalog-onegeo-suite",
3
3
  "description": "OneGeoSuite plugin for the Data Fair catalogs service.",
4
- "version": "0.1.6",
4
+ "version": "0.1.8",
5
5
  "main": "index.ts",
6
6
  "type": "module",
7
7
  "scripts": {
package/types/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export { schema as configSchema, assertValid as assertConfigValid, type OneGeoSuiteConfig } from './catalogConfig/index.ts'
2
- export { schema as importConfigSchema } from './importConfig/index.ts'
3
2
 
4
3
  export type Link = {
5
4
  _main: boolean,
@@ -1 +0,0 @@
1
- export * from './.type/index.js'
@@ -1,67 +0,0 @@
1
- {
2
- "$id": "https://github.com/data-fair/catalog-onegeo-suite/import-config",
3
- "x-exports": [
4
- "schema"
5
- ],
6
- "title": "ImportConfig",
7
- "type": "object",
8
- "additionalProperties": false,
9
- "required": [],
10
- "properties": {
11
- "service": {
12
- "type": "string",
13
- "title": "Web Service",
14
- "x-i18n-title": {
15
- "fr": "Service Web"
16
- },
17
- "description": "This resource is available from multiple sources (web services, local files). Select the source you want to use for the import.",
18
- "x-i18n-description": {
19
- "fr": "Cette ressource est disponible via plusieurs sources (services web, fichiers locaux). Sélectionnez la source que vous souhaitez utiliser pour l'import."
20
- },
21
- "layout": {
22
- "cols": 6,
23
- "getItems": {
24
- "url": "${context.catalogConfig.url}/fr/indexer/elastic/_search/?q=uuid.keyword:${context.resourceId}%20AND%20is_metadata:true",
25
- "itemsResults": "(function() { const links = data.hits.hits[0]._source['metadata-fr'].link; return links.filter(l => l.formats.find(f => ['CSV', 'Excel non structuré', 'Microsoft Excel','ZIP', 'Shapefile (zip)', 'SHAPE-ZIP', 'GeoJSON', 'JSON', 'KML'].includes(f)) && ['WS', 'WFS', undefined].includes(l.service)).map((l, i) => [l, i] ); })()",
26
- "itemTitle": "item[0].service?? 'Local N°' + (item[1] + 1)",
27
- "itemValue": "item[0].service?? item[0].url"
28
- }
29
- }
30
- },
31
- "format": {
32
- "type": "string",
33
- "title": "Format",
34
- "description": "Import format, if no service is set, the possible formats are unknown.",
35
- "x-i18n-description": {
36
- "fr": "Format d’importation, si aucun service n’est défini, les formats possibles sont inconnus."
37
- },
38
- "layout": {
39
- "if": "parent.data.service != null",
40
- "cols": 6,
41
- "getItems": {
42
- "url": "${context.catalogConfig.url}/fr/indexer/elastic/_search/?q=${parent.data.service}&q=uuid.keyword:${context.resourceId}%20AND%20is_metadata:true",
43
- "itemsResults": "(function(){ const service = data.hits.hits[0]._source['metadata-fr'].link.find(x => x.service === parent.data.service || x.url === parent.data.service); let formats = service.formats; if (['WS', 'WFS'].includes(service.service) && !formats.includes('CSV')) {formats.push('CSV');} return formats.filter(f => ['CSV', 'Excel non structuré', 'Microsoft Excel','ZIP', 'Shapefile (zip)', 'SHAPE-ZIP', 'GeoJSON', 'JSON', 'KML'].includes(f));})()"
44
- }
45
- }
46
- },
47
- "format2": {
48
- "type": "string",
49
- "title": "Format",
50
- "description": "Import format, if no service is set, the possible formats are unknown.",
51
- "x-i18n-description": {
52
- "fr": "Format d’importation, si aucun service n’est défini, les formats possibles sont inconnus."
53
- },
54
- "layout": {
55
- "if": "parent.data.service == null",
56
- "cols": 6,
57
- "getItems": {
58
- "url": "https://httpbin.org/get",
59
- "itemsResults": "(function(){return ['CSV', 'Excel non structuré', 'Microsoft Excel','ZIP', 'Shapefile (zip)', 'SHAPE-ZIP', 'GeoJSON', 'JSON', 'KML']})()"
60
- }
61
- }
62
- }
63
- },
64
- "layout": {
65
- "title": null
66
- }
67
- }