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
Branches
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.
Please register or to comment