[use] plugin = basics plugin = analytics [env] path = number2labelDR value = fix({"01": "DR01 Ile-de-France Villejuif","02": "DR02 Paris-Centre","04": "DR04 Ile-de-France Gif-sur-Yvette","05": "DR05 Ile-de-France Meudon","16": "DR16 Paris-Normandie","06": "DR06 Centre Est","10": "DR10 Alsace","08": "DR08 Centre Limousin Poitou Charente","17": "DR17 Bretagne et Pays de la Loire","18": "DR18 Hauts-de-France","07": "DR07 Rhône Auvergne","11": "DR11 Alpes","12": "DR12 Provence et Corse","20": "DR20 Côte d'Azur","13": "DR13 Occitanie Est","14": "DR14 Occitanie Ouest","15": "DR15 Aquitaine"}) [assign] # Récupère electronicPublicationDate et publicationDate # Prend la plus ancienne (= la plus petite) # Ne garde que l'année path = ApilPublicationDate value = get("host.electronicPublicationDate", "9999") \ .castArray() \ .concat(_.get(self, "host.publicationDate", "9999")) \ .min().toString() \ .thru(str => str.substring(0,4)) [assign] path = ApilFinancement value = get('funders').castArray().filter(Boolean).thru(arr => Boolean(arr.length)) # Quand les RNSR ne sont pas fournis dans authors.*.affiliations.*.rnsr # on utilise les enrichissements et on les met au même niveau dans ApilRnsr [map] path = authors [map/map] path = affiliations [map/map/assign] path = ApilRnsr1 value = get("rnsr") [map/map/swing] test = get("ApilRnsr1").isEmpty() [map/map/swing/assign] path = ApilRnsr value = get("enrichments.rnsr", []) \ .filter(rnsr => !["200612821P", "200018571R", "199812965F", "201523784S"].includes(rnsr)) # On rassemble tous les RNSR au niveau de la notice (ceux en provenance de # authors.*.rnsr et ceux en provenance de authors.*.affiliations.*) # dans allAuthorsRnsr [assign] path=ApilRnsr2 value= get("authors").map("rnsr").flatten() [assign] path = allApilRnsr1 ; value= get("authors").map("affiliations").map("ApilRnsr1") value= get("authors").flatMap("affiliations").flatMap("ApilRnsr1") [assign] path= ApilRnsr value= get("allApilRnsr1").concat(self.ApilRnsr2).compact().uniq() # Garde un identifiant [assign] path = sourceUidChain value = get("business.sourceUidChain") #On ajoute un objet pour attribuer 'OA - Inconnu' aux null ou undefined path = enrichments.openAccess.unpaywall.oaLocations value = get("enrichments.openAccess.unpaywall.oaLocations",[{"hostType":"OA - Inconnu"}]) # Supprime les champs inutiles pour les études bibliométriques [exchange] value = omit(['business','origins','technical','allApilRnsr1','ApilRnsr2']) append = pack # Quand les RNSR ne sont pas fournis dans authors.*.affiliations.*.rnsr # on utilise le Web Service qui les met au même niveau dans wsRnsr # Récupère les infos Loterre 2XK [assign] path = ws.loterre2xk value = get("ApilRnsr").castArray().map((itemApilRnsr, indice) => ({indice, itemApilRnsr, codeRNSR: itemApilRnsr, institut: itemApilRnsr, publicationDate: self.ApilPublicationDate })) [expand] path = ws.loterre2xk [expand/exploding] [expand/expand] path = value.itemApilRnsr size = 100 cacheName = 04-2xk-identify [expand/expand/URLConnect] url = https://loterre-resolvers.services.istex.fr/v1/2XK/identify timeout = 120000 noerror = true [expand/assign] path = value.institut value = get('value.institut').append(`|${self.value.publicationDate}`) [expand/expand] path = value.institut size = 100 cacheName = 04-rnsr-year-instituts-cnrs [expand/expand/URLConnect] url = https://mapping-tools.services.istex.fr/v1/rnsr-year/instituts-cnrs timeout = 90002 noerror = true [expand/assign] path = value.label value = get('value.itemApilRnsr.prefLabel@fr', 'n/a') path = value.labelNormalized value = get('value.itemApilRnsr.prefLabel@fr', 'n/a').thru(item => String(item).normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toUpperCase()) path = value.dr value = get("value.itemApilRnsr.delegationRegionale_dep").castArray().compact().map(n => _.get(env("number2labelDR"), n, `unknow ${n}` )) [expand/aggregate] [assign] path = ApilRnsr value = get("ws.loterre2xk").castArray().map('codeRNSR') path = ApilWsLaboIntitule value = get("ws.loterre2xk").castArray().map('label') path = ApilWsDr value = get("ws.loterre2xk").castArray().map('dr') path = ApilWsInstitutCnrs value = get("ws.loterre2xk").castArray().map('institut') # S'il y a au moins un institut, il y a au moins une affiliation CNRS path = ApilWsIsCnrs value = get("ws.loterre2xk").castArray().map('institut').thru(array => Boolean(array.length)) ; [debug] ; path = ApilRnsr ; path = ApilWsLaboIntitule ; path = ApilWsDr ; path = ApilWsInstitutCnrs ; path = ApilWsIsCnrs ############################################################### #interrogation d'Openalex depuis le champs doi https://biblio-tools.services.istex.fr/v1/openalex/works/expand #Pas d'omit sur ce champs, les valeurs apc peuvent eventuellement servir pour d'autres cas [assign] path=ApilWsOpenalex value = get("doi") [expand] path = ApilWsOpenalex size = 100 [expand/URLConnect] url = https://biblio-tools.services.istex.fr/v1/openalex/works/expand timeout = 90007 noerror = true # Données Open Access host type modifiées à partir d'un champ fulltext, si hal est présent #Transformer des données inconnues de 'HostType' en repository si absence d'un DOI mais présence de Hal dans 'fulltext' [assign] path=ApilOaLocationsHal value=get("enrichments.openAccess.unpaywall.oaLocations").map("hostType").concat([self.fulltextUrl].map((value)=>value && value.replace(/^((?!hal).)*$/,"@@@@").replace(/.*hal.*/,"repository"))).uniq().filter((value, index, collection)=>{if(!(value === "OA - Inconnu" && collection[index+1] === "repository" )){return true}}).filter(value=>value!=="@@@@").compact() #Transformer des données inconnues en "green" si absence d'un DOI mais présence de "repository" dans 'ApilOaLocationsHal' [assign] path=ApilOaStatusHal value=get("enrichments.openAccess.unpaywall.oaStatus").replace(/^$/,"OA - Inconnu").castArray().concat(self.ApilOaLocationsHal).compact().join(",").replace(/OA - Inconnu,repository|OA - Non,repository|closed,repository/g,"green").split(",").head().capitalize().replace("Oa - inconnu","OA - Inconnu") ##Transformer des données inconnues en OA-Oui si absence d'un DOI mais présence de "green" dans 'ApiloaStatusHal' [assign] path=ApilIsOaHal value=get("ApilOaStatusHal","OA - Inconnu").replace("closed","OA - Non").replace(/^((?!OA).)*$/,"OA - Oui") #On traduit les voies d'acces. Sort pour placer "publisher" avant "repository", replace puis si les 2 valeurs sont présentes, on remplace par "commun" [assign] path=ApilTypeDaccesHal value=get("ApilOaLocationsHal").sort().replace("repository","Archive seule").replace("publisher","Editeur seul").replace("Editeur seul,Archive seule","Commun") #on crée un nouveau champ où l'on récupère les valeurs de "apc_list/value". Si value = 0 alors la publi est diamant. On remplace donc "0" par "diamond" et efface tout le reste. On concatène ensuite avec enrichments/openAccess/unpaywall/oaStatus qui donne les couleurs de l'OA. Puis on retire "gold" lorsqu'il est associé à "diamond" [assign] path=ApilOaStatusDiamond value=get("ApilWsOpenalex").castArray().map("apc_list/value").replace(/^(?!0$).*$/,"").replace(/^0$/,"diamond").concat(_.get(self,"enrichments.openAccess.unpaywall.oaStatus")).filter((value, index, collection)=>{if(!(value === "gold" && collection[index-1] === "diamond" )){return true}}).last().capitalize().replace(/^$/,"OA - Inconnu") #on crée un nouveau champ où l'on cumule les nouvelles données de 'ApilOaStatusDiamond' et 'ApilOaStatusHal' [assign] path=ApilOaStatusDiamondHal value=get("ApilOaStatusDiamond").concat(self.ApilOaStatusHal).uniq().filter((value, index, collection)=>{if(!(value === "OA - Inconnu" && collection[index+1] === "Green" )){return true}}).filter((value, index, collection)=>{if(!(value === "Gold" && collection[index-1] === "Diamond" )){return true}}).toString() #Transformations spécifiques pour créer des valuers compatibles avec VEga-lite pour la création de graphiques [assign] path=ApilGraphSourceEditeurIsOa value=get("enrichments.openAccess.unpaywall.isOa").replace(/^((?!Oui).)*$/,"null").prepend("OA=").append((";TypeAcces="+self.ApilTypeDaccesHal).replace(/Commun|Editeur seul/g,"Editeur").replace(/OA - Non|Archive seule|OA - Inconnu/g,"null")) [assign] path=ApilGraphSourceEditeurIsOaHal value=get("ApilIsOaHal").replace(/^((?!Oui).)*$/,"null").prepend("OA=").append((";TypeAcces="+self.ApilTypeDaccesHal).replace(/Commun|Editeur seul/g,"Editeur").replace(/OA - Non|Archive seule|OA - Inconnu/g,"null")) #On détermine l'ordre de provenance des notices composants la notice Conditor [assign] path = ApilProvenance value = get("sourceUidChain").replace(/\$.*?!/g,"!").split("!").compact() #On concatène 'volume', 'issue' et 'pages.range' dans un seul champ [assign] path = ApilCollation value = get("host.volume").concat(_.get(self,"host.issue")).concat(_.get(self,"host.pages.range")).join(" / ") #Récupère les fulltext d'unpaywall si le champs 'fulltexturl' (qui vient de conditor) est nul dans une colonne nommée ApilFullText (je ne sais pas comment on déclare le nom de la colonne dans ce cas précis) [assign] path = fulltextUrl value = get("fulltextUrl").castArray().compact() [swing] test = get("fulltextUrl").isEmpty() [swing/assign] path = fulltextUrl value=get("enrichments.openAccess.unpaywall.oaLocations").filter(item=>item.hostType==="repository").map(item=>item.url) ; [assign] ; path = value ; value = get('fulltextUrl').castArray().uniq() #Homogénéise les types de document [assign] path = ApilWsTypeDoc value = get("originalGenre").trim() [expand] path = ApilWsTypeDoc size = 100 cacheName = 04-homogenize-document-type-json [expand/URLConnect] url = https://mapping-tools.services.istex.fr/v1/homogenize/documentType/json timeout = 90003 noerror = true # Si le WS renvoie un "n/a" [swing] test = get("ApilWsTypeDoc").isEqual("n/a") # On l'écrase avec la valeur de "originalGenre" [swing/assign] path = ApilWsTypeDoc value = get("originalGenre").trim() # Homogénéise les sources [assign] path = ApilWsSource value = get("host.title",_.get(self,"host.conference.name")).trim() # si les champs 'host.title' et 'host.conference.name' ne sont pas vides [expand] path = ApilWsSource size = 100 cacheName = 04-homogenize-source-json [expand/URLConnect] url = https://mapping-tools.services.istex.fr/v1/homogenize/source/json timeout = 90004 noerror = true # si le champ "ApilWsSource" issu du WS est "n/a" [swing] test = get("ApilWsSource").isEqual("n/a") [swing/assign] path = ApilWsSource value = get("host.title",_.get(self,"host.conference.name")).trim() # Traitement des éditeurs [assign] path = ws.ApilRacineDoiPublisher value = get("doi").split('/').filter(i => i.match(/^10./)).pop() [expand] path = ws.ApilRacineDoiPublisher size = 1 cacheName = 04-api-crossref-prefixes-expand [expand/URLFetch] target = value url = fix('https://api.crossref.org/prefixes/').append(self.value) json = true timeout = 60000 noerror = true retries = 2 [expand/assign] path = value value = get('value.message.name', 'n/a') # Dans un champ temporaire, récupérer la valeur host.publisher si elle est présente, sinon récupérer celle du WS DOI. [assign] path = tmp.ApilWsPublisher value = get("host.publisher",_.get(self,"ws.ApilRacineDoiPublisher")) # Homogénéise l'éditeur [assign] path = ApilWsPublisher value = get("tmp.ApilWsPublisher").trim() [expand] path = ApilWsPublisher size = 100 cacheName = 04-homogenize-publisher-json [expand/URLConnect] url = https://mapping-tools.services.istex.fr/v1/homogenize/publisher/json timeout = 90006 noerror = true # Si host.publisher existe et que le ApilWsPublisher vaut n/a, [swing] test = has("host.publisher") test = get("ApilWsPublisher").isEqual("n/a") # On l'écrase avec la valeur de host.publisher [swing/assign] path = ApilWsPublisher value = get("host.publisher") # Enrichissements pays [assign] path = ws.libpostal value = get("authors") \ .flatMap("affiliations") \ .map("address").uniq() \ .map((address, id) => ({ \ id, \ value: address \ })) [map] path = ws.libpostal [map/expand] path = value size = 100 cacheName = 04-address-expand [map/expand/URLConnect] url = https://affiliations-tools.services.istex.fr/v1/addresses/parse timeout = 90007 noerror = true [map/expand/assign] path = value.value.address value = get('value.id') path = value.value.country value = get('value.value.country').replace(/\W/g, ' ').trim() [map/expand/assign] path = value value = get('value.value') [map/expand/expand] path = value.country size = 10 cacheName = 04-country-expand [map/expand/expand/URLConnect] url = https://loterre-resolvers.services.istex.fr/v1/9SD/identify timeout = 90008 [map/exchange] value = get('value') # TODO: si champ state, on est aux États-Unis (United States of America) [assign] path = ApilWsCodeISO value = get("ws.libpostal").castArray().filter(Boolean) \ .map(n => n.country?.cartographyCode) \ .uniq().filter(Boolean) path = ApilWsCountry value = get("ws.libpostal").castArray().filter(Boolean) \ .map(n => n.country?.["prefLabel@en"]) \ .uniq().filter(Boolean) # Suppression des champs non voulus [exchange] value = omit(['tmp'])