From 8568a5b878c295026061481763c50404e563dfc0 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Fri, 29 Apr 2022 12:58:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BC=98=E5=8C=96NotionData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/notion.js | 1 - lib/notion/getAllCategories.js | 40 --------- lib/notion/getAllPosts.js | 16 ---- lib/notion/getAllTags.js | 2 +- lib/notion/getNotionData.js | 147 +++++++++++++++++++------------ pages/feed.js | 2 +- pages/index.js | 2 +- pages/tag/[tag].js | 2 +- pages/tag/index.js | 2 +- themes/hexo/components/Header.js | 2 +- themes/next/components/Header.js | 2 +- 11 files changed, 98 insertions(+), 120 deletions(-) delete mode 100644 lib/notion/getAllCategories.js diff --git a/lib/notion.js b/lib/notion.js index a2f19e88..51c02180 100644 --- a/lib/notion.js +++ b/lib/notion.js @@ -1,4 +1,3 @@ export { getAllPosts } from './notion/getAllPosts' export { getAllTags } from './notion/getAllTags' export { getPostBlocks } from './notion/getPostBlocks' -export { getAllCategories } from './notion/getAllCategories' diff --git a/lib/notion/getAllCategories.js b/lib/notion/getAllCategories.js deleted file mode 100644 index b9a543d8..00000000 --- a/lib/notion/getAllCategories.js +++ /dev/null @@ -1,40 +0,0 @@ -import { isIterable } from '../utils' - -/** - * 获取所有文章的分类 - * @param allPosts - * @returns {Promise<{}|*[]>} - */ -export async function getAllCategories({ allPosts, categoryOptions, sliceCount = 0 }) { - if (!allPosts || !categoryOptions) { - return [] - } - // 计数 - let categories = allPosts.map(p => p.category) - categories = [...categories.flat()] - const categoryObj = {} - categories.forEach(category => { - if (category in categoryObj) { - categoryObj[category]++ - } else { - categoryObj[category] = 1 - } - }) - const list = [] - if (isIterable(categoryOptions)) { - for (const c of categoryOptions) { - const count = categoryObj[c.value] - if (count) { - list.push({ id: c.id, name: c.value, color: c.color, count }) - } - } - } - - // 按照数量排序 - // list.sort((a, b) => b.count - a.count) - if (sliceCount && sliceCount > 0) { - return list.slice(0, sliceCount) - } else { - return list - } -} diff --git a/lib/notion/getAllPosts.js b/lib/notion/getAllPosts.js index fbe588da..37a6263f 100644 --- a/lib/notion/getAllPosts.js +++ b/lib/notion/getAllPosts.js @@ -73,19 +73,3 @@ function getPostCover(id, block) { if (pageCover.startsWith('http')) return defaultMapImageUrl(pageCover, block[id].value) } } - -/** - * 获取博文总数 - * @param {*} param0 - * @returns - */ -export async function getAllPostCount({ notionPageData, from }) { - if (!notionPageData) { - notionPageData = await getNotionPageData({ from }) - } - if (!notionPageData) { - return [] - } - const allPosts = await getAllPosts({ notionPageData, from, pageType: ['Post'] }) - return allPosts?.length || 0 -} diff --git a/lib/notion/getAllTags.js b/lib/notion/getAllTags.js index 174055d1..33e82f51 100644 --- a/lib/notion/getAllTags.js +++ b/lib/notion/getAllTags.js @@ -7,7 +7,7 @@ import { isIterable } from '../utils' * @param tagOptions tags的下拉选项 * @returns {Promise<{}|*[]>} */ -export async function getAllTags({ allPosts, sliceCount = 0, tagOptions }) { +export function getAllTags({ allPosts, sliceCount = 0, tagOptions }) { if (!allPosts || !tagOptions) { return [] } diff --git a/lib/notion/getNotionData.js b/lib/notion/getNotionData.js index 55a3d031..58878982 100644 --- a/lib/notion/getNotionData.js +++ b/lib/notion/getNotionData.js @@ -3,9 +3,11 @@ import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager' import { getPostBlocks } from '@/lib/notion/getPostBlocks' import { idToUuid } from 'notion-utils' import { defaultMapImageUrl } from 'react-notion-x' -import { getAllCategories } from './getAllCategories' -import { getAllPosts, getAllPostCount } from './getAllPosts' +import { isIterable } from '../utils' +import getAllPageIds from './getAllPageIds' +import { getAllPosts } from './getAllPosts' import { getAllTags } from './getAllTags' +import getPageProperties from './getPageProperties' /** * 获取博客数据 @@ -15,40 +17,18 @@ import { getAllTags } from './getAllTags' * @param categoryCount * @param tagsCount 截取标签数量 * @param pageType 过滤的文章类型,数组格式 ['Page','Post'] - * @returns { - allPosts, 所有博客 - latestPosts, - categories, 所有分类 - postCount, - customNav, 自定义导航菜单 - tags, 所有标签 - siteInfo:{ - title, - description, - pageCover - } - } + * @returns * */ export async function getGlobalNotionData({ pageId = BLOG.NOTION_PAGE_ID, from, - latestPostCount = 5, - categoryCount = BLOG.PREVIEW_CATEGORY_COUNT, - tagsCount = BLOG.PREVIEW_TAG_COUNT, pageType = ['Post'] }) { const notionPageData = await getNotionPageData({ pageId, from }) - const siteInfo = await getBlogInfo({ notionPageData, from }) - const tagOptions = notionPageData.tagOptions - const categoryOptions = notionPageData.categoryOptions - const customNav = await getCustomNav({ notionPageData }) const allPosts = await getAllPosts({ notionPageData, from, pageType }) - const postCount = await getAllPostCount({ notionPageData, from }) - const categories = await getAllCategories({ allPosts, categoryOptions, sliceCount: categoryCount }) - const tags = await getAllTags({ allPosts, tagOptions, sliceCount: tagsCount }) - const latestPosts = await getLatestPosts({ notionPageData, from, latestPostCount }) - return { allPosts, latestPosts, categories, postCount, customNav, tags, siteInfo } + notionPageData.allPosts = allPosts + return notionPageData } /** @@ -56,8 +36,7 @@ export async function getGlobalNotionData({ * @param {*}} param0 * @returns */ -async function getLatestPosts({ notionPageData, from, latestPostCount }) { - const allPosts = await getAllPosts({ notionPageData, from, pageType: ['Post'] }) +function getLatestPosts({ allPosts, from, latestPostCount }) { const latestPosts = Object.create(allPosts).sort((a, b) => { const dateA = new Date(a?.lastEditedTime || a?.createdTime || a?.date?.start_date) const dateB = new Date(b?.lastEditedTime || b?.createdTime || b?.date?.start_date) @@ -79,7 +58,7 @@ export async function getNotionPageData({ pageId, from }) { // 尝试从缓存获取 const cacheKey = 'page_block_' + pageId const data = await getDataFromCache(cacheKey) - if (data) { + if (data && data.pageIds?.length > 0) { console.log('[请求缓存]:', `from:${from}`, `root-page-id:${pageId}`) return data } @@ -96,14 +75,7 @@ export async function getNotionPageData({ pageId, from }) { * @param notionPageData * @returns {Promise<[]|*[]>} */ -async function getCustomNav({ notionPageData }) { - if (!notionPageData) { - notionPageData = await getNotionPageData({ from: 'custom-nav' }) - } - if (!notionPageData) { - return [] - } - const allPage = await getAllPosts({ notionPageData, from: 'custom-nav', pageType: ['Page'] }) +function getCustomNav({ allPage }) { const customNav = [] if (allPage && allPage.length > 0) { allPage.forEach(p => { @@ -139,23 +111,55 @@ function getCategoryOptions(schema) { return categorySchema?.options || [] } +/** + * 获取所有文章的分类 + * @param allPosts + * @returns {Promise<{}|*[]>} + */ +function getAllCategories({ allPosts, categoryOptions, sliceCount = 0 }) { + if (!allPosts || !categoryOptions) { + return [] + } + // 计数 + let categories = allPosts.map(p => p.category) + categories = [...categories.flat()] + const categoryObj = {} + categories.forEach(category => { + if (category in categoryObj) { + categoryObj[category]++ + } else { + categoryObj[category] = 1 + } + }) + const list = [] + if (isIterable(categoryOptions)) { + for (const c of categoryOptions) { + const count = categoryObj[c.value] + if (count) { + list.push({ id: c.id, name: c.value, color: c.color, count }) + } + } + } + + // 按照数量排序 + // list.sort((a, b) => b.count - a.count) + if (sliceCount && sliceCount > 0) { + return list.slice(0, sliceCount) + } else { + return list + } +} + /** * 站点信息 * @param notionPageData * @param from * @returns {Promise<{title,description,pageCover}>} */ -async function getBlogInfo({ notionPageData, from }) { - if (!notionPageData) { - notionPageData = await getNotionPageData({ from }) - } - if (!notionPageData) { - return null - } - const collection = notionPageData?.collection +function getBlogInfo(collection, block) { const title = collection?.name?.[0][0] || BLOG.TITLE const description = collection?.description?.[0][0] || BLOG.DESCRIPTION - const pageCover = mapCoverUrl(collection?.cover, notionPageData.block) + const pageCover = mapCoverUrl(collection?.cover, block) return { title, description, pageCover } } @@ -183,24 +187,48 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) { if (!pageRecordMap) { return [] } - pageId = idToUuid(pageId) - const collection = Object.values(pageRecordMap.collection)[0]?.value - const collectionQuery = pageRecordMap.collection_query const block = pageRecordMap.block - const schema = collection?.schema const rawMetadata = block[pageId].value - const tagOptions = getTagOptions(schema) - const categoryOptions = getCategoryOptions(schema) - // Check Type Page-Database和Inline-Database if ( rawMetadata?.type !== 'collection_view_page' && - rawMetadata?.type !== 'collection_view' + rawMetadata?.type !== 'collection_view' ) { console.warn(`pageId "${pageId}" is not a database`) return null } + pageId = idToUuid(pageId) + const collection = Object.values(pageRecordMap.collection)[0]?.value + const collectionQuery = pageRecordMap.collection_query + const schema = collection?.schema + const tagOptions = getTagOptions(schema) + const categoryOptions = getCategoryOptions(schema) + + const data = [] + const pageIds = getAllPageIds(collectionQuery) + for (let i = 0; i < pageIds.length; i++) { + const id = pageIds[i] + const properties = (await getPageProperties(id, block, schema)) || null + properties.slug = properties.slug ?? properties.id + delete properties.content + data.push(properties) + } + + const allPage = data.filter(post => { + return post.title && post?.status?.[0] === 'Published' && ['Page'].indexOf(post?.type?.[0]) > -1 + }) + const allPosts = data.filter(post => { + return post.title && post?.status?.[0] === 'Published' && ['Post'].indexOf(post?.type?.[0]) > -1 + }) + + const customNav = getCustomNav({ allPage }) + const postCount = allPosts?.length || 0 + const categories = getAllCategories({ allPosts, categoryOptions, sliceCount: BLOG.PREVIEW_CATEGORY_COUNT }) + const tags = getAllTags({ allPosts, tagOptions, sliceCount: BLOG.PREVIEW_TAG_COUNT }) + const latestPosts = getLatestPosts({ allPosts, from, latestPostCount: 5 }) + const siteInfo = getBlogInfo({ collection, block }) + return { collection, collectionQuery, @@ -208,6 +236,13 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) { schema, tagOptions, categoryOptions, - rawMetadata + rawMetadata, + siteInfo, + customNav, + postCount, + pageIds, + categories, + tags, + latestPosts } } diff --git a/pages/feed.js b/pages/feed.js index ccfe5ff4..127f9402 100644 --- a/pages/feed.js +++ b/pages/feed.js @@ -4,7 +4,7 @@ import { getGlobalNotionData } from '@/lib/notion/getNotionData' export async function getServerSideProps ({ res }) { res.setHeader('Content-Type', 'text/xml') // 获取最新文章 - const globalNotionData = await getGlobalNotionData({ from: 'rss', latestPostCount: 5 }) + const globalNotionData = await getGlobalNotionData({ from: 'rss' }) const xmlFeed = await generateRss(globalNotionData?.latestPosts || []) res.write(xmlFeed) res.end() diff --git a/pages/index.js b/pages/index.js index ec18b11c..fe8de2cb 100644 --- a/pages/index.js +++ b/pages/index.js @@ -16,7 +16,7 @@ export async function getStaticProps() { const meta = { title: `${siteInfo?.title} | ${siteInfo?.description}`, description: siteInfo?.description, - image: siteInfo.pageCover, + image: siteInfo?.pageCover, slug: '', type: 'website' } diff --git a/pages/tag/[tag].js b/pages/tag/[tag].js index b5f36c0a..be89d2fa 100644 --- a/pages/tag/[tag].js +++ b/pages/tag/[tag].js @@ -53,7 +53,7 @@ function getTagNames(tags) { export async function getStaticPaths() { const from = 'tag-static-path' - const { tags } = await getGlobalNotionData({ from, tagsCount: 0 }) + const { tags } = await getGlobalNotionData({ from }) const tagNames = getTagNames(tags) return { diff --git a/pages/tag/index.js b/pages/tag/index.js index a4c28dbf..302511dc 100644 --- a/pages/tag/index.js +++ b/pages/tag/index.js @@ -19,7 +19,7 @@ const TagIndex = props => { export async function getStaticProps() { const from = 'tag-index-props' - const props = await getGlobalNotionData({ from, tagsCount: 0 }) + const props = await getGlobalNotionData({ from }) return { props, revalidate: 1 diff --git a/themes/hexo/components/Header.js b/themes/hexo/components/Header.js index 66770f77..c1e4e71f 100644 --- a/themes/hexo/components/Header.js +++ b/themes/hexo/components/Header.js @@ -103,7 +103,7 @@ const Header = props => { className="duration-500 md:bg-fixed w-full bg-cover bg-center h-screen bg-black text-white" style={{ backgroundImage: - `linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo.pageCover}")` + `linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo?.pageCover}")` }} >
diff --git a/themes/next/components/Header.js b/themes/next/components/Header.js index 37eb5e50..df6db180 100644 --- a/themes/next/components/Header.js +++ b/themes/next/components/Header.js @@ -98,7 +98,7 @@ export default function Header(props) { className="duration-500 md:bg-fixed w-full bg-cover bg-center h-screen bg-black" style={{ backgroundImage: - `linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo.pageCover}")` + `linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo?.pageCover}")` }} >