diff --git a/config.json b/config.json index 5746a954e..80b53dbbd 100644 --- a/config.json +++ b/config.json @@ -71,6 +71,7 @@ "json-lines", "query-istex", "query-conditor", + "query-conditor-for-halcnrs", "query-openalex", "rss", "atom", diff --git a/packages/ezsLodex/src/formatOutput.js b/packages/ezsLodex/src/formatOutput.js index 9dcad4f48..40c20f18c 100644 --- a/packages/ezsLodex/src/formatOutput.js +++ b/packages/ezsLodex/src/formatOutput.js @@ -47,7 +47,7 @@ function formatOutput(data, feed) { if (keys.length > 0) { let check = false; keys.forEach((k, index) => { - if (values[index]) { + if (values[index] !== undefined) { feed.write(!check ? ' ' : ','); check = true; feed.write(json(k)); diff --git a/src/app/custom/themes/voscouleurs/index.ejs b/src/app/custom/themes/voscouleurs/index.ejs index b8a3bc9b4..4965d755a 100644 --- a/src/app/custom/themes/voscouleurs/index.ejs +++ b/src/app/custom/themes/voscouleurs/index.ejs @@ -14,7 +14,7 @@ - <% if(custom.font.family){ %> + <% if (custom.font) { %> <% } %> @@ -23,14 +23,13 @@ /* import palette */ <%=theme.cssVariable %> /* import config theme color */ - <% if(custom.font) {%> + <% if (custom.font) {%> :root { --font-title: <%= custom.font.title %>; - --font-text: <%= custom.font.text %>; } - <%}%> + <% } %> /* import config theme color */ - <% if(custom.color) {%> + <% if (custom.color) {%> :root { --bgBody: <%= custom.color.bgBody %>; --bgHeader: <%= custom.color.bgHeader %>; @@ -47,7 +46,7 @@ --textContrast: <%= custom.color.textContrast %>; --bgContrast: <%= custom.color.bgContrast %>; } - <%}%> + <% } %> diff --git a/src/app/custom/themes/voscouleurs/lodex-theme.json b/src/app/custom/themes/voscouleurs/lodex-theme.json index 716dfd91b..bcf05099d 100644 --- a/src/app/custom/themes/voscouleurs/lodex-theme.json +++ b/src/app/custom/themes/voscouleurs/lodex-theme.json @@ -13,44 +13,44 @@ "files": { "index": "index.ejs", "palette": "" - } - }, - "variables": { - "information": "toutes les configurations ci-dessous sont optionnelles.Pour les désactiver, supprimer \"le texte entre les guillemets\"", - "siteTitle": "titre du site", - "summary": "promesse du site, sous-titre", - "logo": { - "file": "url fichier du logo de l'organisme", - "alt": "nom de l'organisme", - "url": "url de l'organisme", - "size": "100" - }, - "font": { - "information": "utiliser strictement https://fonts.google.com/", - "family": "nom d'une famille de googlefont construit le lien dans head ", - "title": "nom de cette font pour les titres déclaration css" }, - "color": { - "info-theme": "EN DEVELOPPEMENT : les trois couleurs suivantes permettent de mémoriser les codes hexadecimaux de 2 couleurs qui font l'identité de votre organisme", - "themePrimary": "code hexa ", - "themeSecondary": "code hexa", - "themeRGBA": "code rgba de primary ou secondary", - "info-fond": "bg, pour 'background' en css, permet de mettre une couleur de fond sur les différents éléments de structure de vos pages", - "bgBody": "#fff", - "bgHeader": "", - "headerTitle": "", - "bgContent": "", - "bgFacet": "", - "titles": "", - "titleGraph": "", - "text": "", - "info-bouton": "ci-dessous, les couleurs des liens et boutons", - "icon": "", - "iconHover": "", - "button": "", - "buttonHover": "", - "textContrast": "", - "bgContrast": "" + "variables": { + "information": "toutes les configurations ci-dessous sont optionnelles.Pour les désactiver, supprimer \"le texte entre les guillemets\"", + "siteTitle": "titre du site", + "summary": "promesse du site, sous-titre", + "logo": { + "file": "url fichier du logo de l'organisme", + "alt": "nom de l'organisme", + "url": "url de l'organisme", + "size": "100" + }, + "font": { + "information": "utiliser strictement https://fonts.google.com/", + "family": "nom d'une famille de googlefont construit le lien dans head ", + "title": "nom de cette font pour les titres déclaration css" + }, + "color": { + "info-theme": "EN DEVELOPPEMENT : les trois couleurs suivantes permettent de mémoriser les codes hexadecimaux de 2 couleurs qui font l'identité de votre organisme", + "themePrimary": "code hexa ", + "themeSecondary": "code hexa", + "themeRGBA": "code rgba de primary ou secondary", + "info-fond": "bg, pour 'background' en css, permet de mettre une couleur de fond sur les différents éléments de structure de vos pages", + "bgBody": "#fff", + "bgHeader": "", + "headerTitle": "", + "bgContent": "", + "bgFacet": "", + "titles": "", + "titleGraph": "", + "text": "", + "info-bouton": "ci-dessous, les couleurs des liens et boutons", + "icon": "", + "iconHover": "", + "button": "", + "buttonHover": "", + "textContrast": "", + "bgContrast": "" + } } } -} \ No newline at end of file +} diff --git a/src/app/custom/translations.tsv b/src/app/custom/translations.tsv index 74c9b5f8e..7150e6a8f 100644 --- a/src/app/custom/translations.tsv +++ b/src/app/custom/translations.tsv @@ -521,6 +521,8 @@ "bib-comment" "BibTeX uses a style-independent text-based file format for lists of bibliography items, such as articles, books, and theses" "BibTeX est format de fichier texte dédié aux références bibliographiques." "query-conditor" "TXT - query for Conditor" "TXT - requête d'interrogation pour Conditor" "query-conditor-comment" "Direct loading of query results for the Conditor database." "Chargement direct des résultats d'une requête d'interrogation pour la base Conditor." +"query-conditor-for-halcnrs" "TXT - query conditor for halcnrs" "TXT - requête Conditor pour traitements hal" +"query-conditor-for-halcnrs-comment" "Direct loading of query results for the Conditor database and needed processing for the HAL CNRS service." "Chargement direct des résultats d'une requête d'interrogation pour la base Conditor et transformations pour exploitation par le service hal cnrs." "query-istex" "TXT - query for ISTEX" "TXT - requête d'interrogation pour ISTEX" "query-istex-comment" "Direct loading of query results for the ISTEX archive." "Chargement direct des résultats d'une requête d'interrogation pour l'archive ISTEX." "query-openalex" "TXT - query for OpenAlex" "TXT - requête d'interrogation pour OpenAlex" diff --git a/workers/loaders/query-conditor-for-halcnrs.ini b/workers/loaders/query-conditor-for-halcnrs.ini new file mode 100644 index 000000000..273181960 --- /dev/null +++ b/workers/loaders/query-conditor-for-halcnrs.ini @@ -0,0 +1,162 @@ +append = pack +label = query-conditor-for-halcnrs +extension = json +mimeType = application/json + +# load some plugins to activate some statements +[use] +plugin = conditor +plugin = basics + +# Toggle ezs traces (see server stderr log) +[debug] +ezs = false + +# {{{ +[TXTConcat] + +[replace] +path = q +value = self().trim() + +[CORHALFetch] +url = https://corhal-api.inist.fr +retries = 3 +timeout = 60000 + +[assign] +path = uri +value = get('business.sourceUidChain') +# }}} + +[assign] +path = typologie +value = get("business.duplicateGenre") + +path = titre +value = get("title.default") + +path = resume +value = get("abstract.default") + +path = auteurs +value = get("authors").map("fullname") + +path = identifiantsAuteurs +value = get("authors").map(author => _.pick(author, ['orcId', 'idRef', 'idHal','viaf'])) + +path = affiliations +value = get("authors").map( author =>_.flatMap(author.affiliations, 'address')) + +path = identifiantsAffiliations +value = get("authors").map("rnsr") + +path = domaine +value = get("classifications") + +path = keywords +value = get("keywords") + +path = ppn +value=get("sourceUids").filter( id => id.startsWith('sudoc')).replace("sudoc-theses$","") + +path = nnt +value = get("fulltextUrl").replace(/^(?!http:\/\/www\.theses\.fr\/).*$/, '').replace("http://www.theses.fr/","").replace("/document","") + +[assign] +path = autresIdentifiants +value = fix({pmcid: self.pmcId,arxiv : self.arxiv,pmid: self.pmId,nnt: self.nnt,ppn : self.ppn}) + +path = funders +value = get("funders").map("fullname") + +path = publicationDate +value = get("host.publicationDate") + +path = electronicPublicationDate +value = get("host.electronicPublicationDate") + +path = volume +value = get("host.volume") + +path = issue +value = get("host.issue") + +path = pages +value = get("host.pages.range") + +path = nomConference +value = get("host.conference.name") + +path = dateDebutConference +value = get("host.conference.date") + +path = villeConference +value = get("host.conference.place") + +path = langueDocument +value = get("host.language") + +path = issn +value = get("host.issn") + +path = nomRevue +value = get("host.title") + +path = publisherRevue +value = get("host.publisher") + +path = isbn +value = get("host.isbn") + +path = editors +value = get("host.editors").map("fullname") + +path = sourceUids +value = get("sourceUids") + +path = halID +value = get("halId") + +path = doublonsHal +value = get("sourceUids").filter(uid => uid.includes('hal')).size().gt(1).replace(true,"Oui").replace(false,"Non") + +[assign] +path=isHal +value=get("business.sourceUidChain").replace(/\$.*?!/g,"!").split("!").compact().some(item=>(/hal/).test(item)).replace(false,"Non").replace(true,"Oui") + +path = fulltextURL +value = get("fulltextUrl") + +# Ensures that each object contains an identification key (required by lodex) +[swing] +test = pick(['URI', 'uri']).pickBy(_.identity).isEmpty() +[swing/identify] + +# Ignore objects with duplicate URI +[dedupe] +ignore = true + +# Prevent keys from containing dot path notation (which is forbidden by nodejs mongoDB driver) +[OBJFlatten] +separator = fix('.') +reverse = true +safe = true + +# Uncomment to see each data sent to the database +#[debug] + +[exchange] +value = omit(["abstract","authors","classifications","business","pii","arxiv","inspire","localRef","pmcId","articleNumber","nnt","ppn","origins","technical","halId","title","originalGenre","pmId","fulltextUrl","enrichments","host"]) + +# Add contextual metadata related to the import +[assign] +path = lodexStamp.importedDate +value = fix(new Date()).thru(d => d.toDateString()) +path = lodexStamp.usedParser +value = env('parser') +path = lodexStamp.uploadedFilename +value = env('source') +path = uri +value = get('uri').trim() + diff --git a/workers/loaders/query-openalex.ini b/workers/loaders/query-openalex.ini index 2a926b38a..6bb070ba7 100644 --- a/workers/loaders/query-openalex.ini +++ b/workers/loaders/query-openalex.ini @@ -6,26 +6,35 @@ #### Enfin l'instruction [C] permet de retirer les notices récupérées par erreur. Il est nécessaire d'annuler cette instruction dans un premier temps, afin de pouvoir tester #### la validité des regex et de connaître les mauvaises affiliations. Les champs "inist_filtered_raw_affiliation_strings" [A] et "inist_filtered_and_tested_raw_affiliation_strings" [B] #### sont ensuite supprimés. Ils peuvent être conservés en les enlevant du tableau dans l'instruction [F]. +#### +#### OpenAlex favorise les utilisations de son API qui déclare une adresse mail. +#### Renseignez votre adresse mail en ligne [G] append = pack label = query-openalex extension = json mimeType = application/json -# load some plugins to activate some statements [use] plugin = conditor plugin = basics plugin = analytics -# Toggle ezs traces (see server stderr log) [debug] -ezs = true +ezs = false -# {{{ [TXTConcat] [env] +; [G] to get more about mailto see https://docs.openalex.org/how-to-use-the-api/rate-limits-and-authentication#the-polite-pool +path = mailto +value = you@example.com + +; before change see https://docs.openalex.org/how-to-use-the-api/get-lists-of-entities/paging +path = per-page +value = 200 + +; before change see https://docs.openalex.org/api-entities/works path = url value = https://api.openalex.org/works @@ -36,6 +45,12 @@ value = self().trim() path = filter value = env('query') +path = per-page +value = env('per-page') + +path = mailto +value = env('mailto') + path = cursor value = * @@ -53,6 +68,9 @@ value = env('query') path = cursor value = get('meta.next_cursor') +path = per-page +value = env('per-page') + [loop/URLRequest] url = env('url') timeout = 60000 @@ -80,7 +98,8 @@ value = env('query').thru(string => string.match(/i\d+/)).toUpper() # {{{ On retire les notices non pertinentes en raison d'erreurs d'affiliations d'OpenAlex. # Exemple pour le laboratoire GANIL -#[A] On récupère dans un premier temps les adresses originales qu'OpenALex a identifié comme relevant du laboratoire requêté. +# [A] On récupère dans un premier temps les adresses originales qu'OpenALex a identifié comme relevant du laboratoire requêté. +# #[assign] #path = inist_filtered_raw_affiliation_strings #value = get("authorships").filter(obj => obj.institutions.some(obj => obj.id === `https://openalex.org/${self.lodexStamp.queryIdentifier}`)).flatMap(obj => obj.raw_affiliation_strings) @@ -90,13 +109,13 @@ value = env('query').thru(string => string.match(/i\d+/)).toUpper() path = inist_filtered_and_tested_raw_affiliation_strings value = get("inist_filtered_raw_affiliation_strings").some(item => /ganil/i.test(item) || /grand acc.*national.*ions.*lourds/i.test(item) || /Large heavy ion Nat.*acc.*/i.test(item)) -#[C] Enfin on supprime les notices non pertinentes. +# [C] Enfin on supprime les notices non pertinentes. #[remove] #test = get("inist_filtered_and_tested_raw_affiliation_strings").isEqual(false) # }}} [assign] -#[D] +# [D] path = uri value = get('id').replace('https://openalex.org/', '') @@ -115,7 +134,7 @@ value = get('keywords').map('display_name') path = author_name value = get('authorships').map("author.display_name") -#[E] On récupère uniquement les auteurs du laboratoire requêté. +# [E] On récupère uniquement les auteurs du laboratoire requêté. path = inist_filtered_author_name value = get("authorships").filter(obj => obj.institutions.some(obj => obj.id === `https://openalex.org/${self.lodexStamp.queryIdentifier}`)).flatMap(obj => obj.author.display_name) @@ -173,8 +192,8 @@ value = get("inist_iso2").map(d => new Intl.DisplayNames(['FR'], { type: 'region # On récupère un tableau d'objets, puis on itère sur chaque objet avec un template string pour en faire une chaîne de caractères. # Chaque chaîne est préfixée par "Goal", on récupère ensuite les derniers chiffres de la variable "id" qui correspond au numéro du goal. # On ajoute enfin la variable "display_name" qui est le nom du goal. -path=inist_sustainable_development_goals -value=get("sustainable_development_goals").map( item => `Goal ${item.id.match(/\/sdg\/(\d+)/)[1]} : ${item.display_name}`).thru(arr => _.isEmpty(arr) ? ["No sustainable development goal"] : arr) +path = inist_sustainable_development_goals +value = get("sustainable_development_goals").map( item => `Goal ${item.id.match(/\/sdg\/(\d+)/)[1]} : ${item.display_name}`).thru(arr => _.isEmpty(arr) ? ["No sustainable development goal"] : arr) path = inist_funder_display_name value = get("grants").map("funder_display_name").uniq() @@ -259,9 +278,10 @@ separator = fix('.') reverse = true safe = true -# Uncomment to see each data sent to the database +# Uncomment to see in server logs, each data sent to the database #[debug] [assign] path = uri value = get('uri').trim() +