Skip to content
Snippets Groups Projects
Commit 662aef63 authored by Remi  PLANEL's avatar Remi PLANEL
Browse files

Fix fetch articles from zotero file

parent 69e21bb1
No related branches found
No related tags found
2 merge requests!131Merge relevant Abstract and references,!123Resolve "Wizzard to create db filters"
Pipeline #117289 failed
......@@ -272,10 +272,10 @@ get-zotero:
extends: .df-wiki-cli-run
stage: get-data
script:
- df-wiki-cli articles --key ${ZOTERO_API_KEY} --output public/articles.json
- df-wiki-cli articles --key ${ZOTERO_API_KEY} --output content/_data/_articles.json
artifacts:
paths:
- public/articles.json
- content/_data/_articles.json
rules:
- if: $CI_COMMIT_BRANCH == "main"
......
<script setup lang="ts">
import { useDisplay } from "vuetify";
import { useArticlesStore } from '@/stores/articles'
export interface Props {
index?: number;
......@@ -14,10 +15,27 @@ const props = withDefaults(defineProps<Props>(), {
enumerate: true,
divider: false,
});
// onBeforeMount(async () => {
// await useArticlesStore().initialize()
// })
const { article } = useFetchArticle(props.doi);
const { mobile } = useDisplay();
const show = ref(false);
// const computedArticle = computed(() => { return { ...article.value } })
// watch(article, (newArticle) => {
// console.log("article updated")
// }, { deep: true })
console.log("aritcle dans composant")
console.log(article)
const articleTitle = computed(() => {
return props?.title ?? article?.value?.title ?? props.doi;
});
......@@ -26,8 +44,8 @@ const articleAbstract = computed(() => {
});
</script>
<template>
<v-list-item :href="article?.href" :id="props.doi" :target="article?.target" density="compact" color="transparent"
class="px-1">
<v-list-item :href="article?.href" :id="props.doi" :target="article?.target" density="compact"
color="transparent" class="px-1">
<template #prepend v-if="!mobile && enumerate">
<v-avatar color="primary" size="small" density="compact" variant="tonal">
{{ props?.index ?? "#" }}
......
......@@ -2,17 +2,19 @@ import { useArticlesStore, type CslJson } from '../stores/articles'
import { ref, computed, watchEffect, toValue } from "vue"
// import { useFetch } from '#app';
// import { useFetch } from "nuxt"
import { useFetch } from '#imports'
import { type MaybeRef, useFetch } from '#imports'
import article from "@/public/articles.json"
export interface ArticleMessage {
export interface CrossrefArticle {
DOI: string;
issue: number;
title: string | string[];
type: string;
title: string[];
author: Array<{ family: string; given: string }>;
"container-title-short": string;
// "container-title-short": string;
"short-container-title": string;
"container-title": string;
abstract: string;
abstract?: string;
published: {
"date-parts": string[];
};
......@@ -23,7 +25,7 @@ export interface ArticleMessage {
export interface Article {
export interface WikiArticle {
DOI: string
title: string
subtitle: string
......@@ -36,115 +38,125 @@ export interface Article {
prependIcon: string
}
export interface RawArticle {
message: ArticleMessage
message: CrossrefArticle
}
type SrcArticle = ArticleMessage | CslJson
type SrcArticle = CrossrefArticle | CslJson
export function useFetchArticle(doi: string) {
export function useFetchArticle(doi: MaybeRef<string> = ref("")) {
// const article = ref<Article>()
// const rawArticle = ref<RawArticle>()
const srcArticle = ref<SrcArticle | null>(null)
const store = useArticlesStore()
const pending = ref(false)
const doiBaseUrl = ref(new URL("https://doi.org/"));
const url = ref(new URL(`/works/${doi}`, " https://api.crossref.org/").href);
const article = computed(() => {
if (srcArticle.value != undefined) {
const url = ref(new URL(`/works/${toValue(doi)}`, " https://api.crossref.org/").href);
const article = ref()
const zoteroArticles = ref()
function toAuthorsString(authors: Array<{ family: string; given: string }>) {
return authors
.map((curr) => {
return `${curr.family} ${curr.given}`;
})
.join(", ");
}
function getReferenceUrl(doi: string) {
return new URL(doi, doiBaseUrl.value).href;
}
function zoteroArticleToArticle(zoteroArticle: CslJson) {
if (zoteroArticle != undefined) {
const {
DOI,
title,
"container-title-short": cts,
"container-title": ct,
journalAbbreviation,
abstract,
published,
issued,
author,
...rest
} = srcArticle.value;
let sanitizedAbstract = abstract
if (sanitizedAbstract) {
sanitizedAbstract = /(?:\<jats\:p\>)?(.*)(?:\<\/jats\:p\>)?/.exec(sanitizedAbstract)?.[1] ?? ''
}
const sanitizedTitle = (Array.isArray(title)) ? title[0] : title
const sanitizedContainerTitle = (Array.isArray(ct)) ? cts?.length > 0 ? cts[0] : ct?.length > 0 ? ct[0] : "" : journalAbbreviation || ct
} = zoteroArticle;
return {
DOI,
title: sanitizedTitle,
title,
subtitle: toAuthorsString(author || []),
author,
containerTitle: sanitizedContainerTitle,
abstract: sanitizedAbstract,
year: published?.["date-parts"][0][0] ?? issued?.["date-parts"][0][0] ?? '',
containerTitle: ct,
abstract,
year: issued?.["date-parts"][0][0] ?? '',
href: getReferenceUrl(DOI),
target: "_blank",
prependIcon: "mdi-newspaper-variant-outline",
}
} else { return srcArticle.value }
})
const zoteroArticles = ref([])
// const config = useRuntimeConfig()
// console.log(config.value)
const fetchLocalArticles = () => {
useFetch<RawArticle[]>(
"/articles.json",
{ lazy: true, server: false }
).then(({ data }) => {
zoteroArticles.value = data.value
}) // localPending.value = articlesPending.value
if (zoteroArticles.value?.length > 0) {
for (const article of zoteroArticles.value) {
// console.log("article files : ", article.DOI)
store.add(article)
}
}
}
const fetchCrossRef = () => {
useFetch<RawArticle>(toValue(url), {
lazy: true, server: false,
}).then(({ data, pending: pendingUseFetch }) => {
if (data.value?.message) {
srcArticle.value = data.value.message
}
pending.value = pendingUseFetch.value
})
}
watchEffect(() => {
// no article in the store
if (store.articles.size === 0) {
fetchLocalArticles()
function crossrefToArticle(article: CrossrefArticle): WikiArticle {
const { title, DOI, type, "container-title": ct, "short-container-title": sct, abstract, author, issued } = article
// let sanitizedAbstract = abstract
const sanitizedAbstract = abstract ? /(?:\<jats\:p\>)?(.*)(?:\<\/jats\:p\>)?/.exec(abstract)?.[1] ?? '' : ''
const sanitizedContainerTitle = sct?.length > 0 ? sct[0] : ct?.length > 0 ? ct[0] : ""
return {
title: title?.length > 0 ? title[0] : "",
DOI,
abstract: sanitizedAbstract,
containerTitle: sanitizedContainerTitle,
subtitle: toAuthorsString(author || []),
author,
year: issued?.["date-parts"][0][0] ?? '',
href: getReferenceUrl(DOI),
target: "_blank",
prependIcon: "mdi-newspaper-variant-outline"
}
}
if (store.articles.has(doi)) {
srcArticle.value = store.articles.get(doi)
return
} else {
fetchCrossRef()
}
function crossrefToCsl(article: CrossrefArticle): CslJson {
const { title, DOI, type, "container-title": ct, "short-container-title": sct, abstract, author, issued } = article
// let sanitizedAbstract = abstract
const sanitizedAbstract = abstract ? /(?:\<jats\:p\>)?(.*)(?:\<\/jats\:p\>)?/.exec(abstract)?.[1] ?? '' : ''
const sanitizedContainerTitle = sct?.length > 0 ? sct[0] : ct?.length > 0 ? ct[0] : ""
return {
title: title?.length > 0 ? title[0] : "",
type,
DOI,
abstract: sanitizedAbstract,
author,
"container-title": sanitizedContainerTitle,
issued
})
function toAuthorsString(authors: Array<{ family: string; given: string }>) {
return authors
.map((curr) => {
return `${curr.family} ${curr.given}`;
})
.join(", ");
}
}
function getReferenceUrl(doi: string) {
return new URL(doi, doiBaseUrl.value).href;
if (store.articles.has(toValue(doi))) {
const cslArticle = store.articles.get(toValue(doi))
article.value = cslArticle ? zoteroArticleToArticle(cslArticle) : undefined
}
else {
useFetch<RawArticle>(toValue(url), {
lazy: true, server: false,
}).then(({ data, pending: pendingUseFetch }) => {
if (data.value?.message) {
article.value = crossrefToArticle(data.value.message)
store.add(crossrefToCsl(data.value.message))
}
pending.value = pendingUseFetch.value
})
}
// const fetchCrossRef = () => {
// useFetch<RawArticle>(toValue(url), {
// lazy: true, server: false,
// }).then(({ data, pending: pendingUseFetch }) => {
// if (data.value?.message) {
// srcArticle.value = data.value.message
// }
// pending.value = pendingUseFetch.value
// })
// }
return { article, pending }
}
......
This diff is collapsed.
<script setup lang="ts"></script>
<script setup lang="ts">
import { useArticlesStore } from '@/stores/articles'
const store = useArticlesStore()
const { data } = await useAsyncData('zotero-articles', async () => queryContent('_data/_articles').where({ _partial: true }).findOne())
if (data.value) {
const dataValue = toValue(data)?.body
for (const cslArticle of dataValue) {
if (cslArticle?.DOI) {
store.add(cslArticle)
}
}
}
</script>
<template>
<LayoutWrapper>
<slot />
......
import { defineStore } from 'pinia'
import { ref } from 'vue'
// import jsonArticles from '@/assets/articles.json'
export interface CslJson {
id: string
// id: string
type: string
title: string
"container-title": string
page: string,
volume: string,
// page: string,
// volume: string,
abstract: string
URL: string
// URL: string
DOI: string
journalAbbreviation: string
language: string
// journalAbbreviation: string
// language: string
author: Array<{ family: string, given: string }>
issued: {
"date-parts": Array<string>
......@@ -21,12 +21,15 @@ export interface CslJson {
}
export const useArticlesStore = defineStore('articles', () => {
const articles = ref(new Map<string, CslJson>())
const articleMap = new Map([])
const articles = ref(articleMap)
function add(article: CslJson) {
const doi = article.DOI
if (articles.value.has(doi)) return
articles.value.set(article.DOI, article)
}
return { articles, add }
})
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment