File size: 4,264 Bytes
1b72d7e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import BLOG from '@/blog.config'
import { NotionAPI } from 'notion-client'
import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager'
import { deepClone, delay } from '../utils'
/**
* 获取文章内容
* @param {*} id
* @param {*} from
* @param {*} slice
* @returns
*/
export async function getPostBlocks(id, from, slice) {
const cacheKey = 'page_block_' + id
let pageBlock = await getDataFromCache(cacheKey)
if (pageBlock) {
console.log('[API<<--缓存]', `from:${from}`, cacheKey)
return filterPostBlocks(id, pageBlock, slice)
}
pageBlock = await getPageWithRetry(id, from)
if (pageBlock) {
await setDataToCache(cacheKey, pageBlock)
return filterPostBlocks(id, pageBlock, slice)
}
return pageBlock
}
export async function getSingleBlock(id, from) {
const cacheKey = 'single_block_' + id
let pageBlock = await getDataFromCache(cacheKey)
if (pageBlock) {
console.log('[API<<--缓存]', `from:${from}`, cacheKey)
return pageBlock
}
pageBlock = await getPageWithRetry(id, from)
if (pageBlock) {
await setDataToCache(cacheKey, pageBlock)
}
return pageBlock
}
/**
* 调用接口,失败会重试
* @param {*} id
* @param {*} retryAttempts
*/
export async function getPageWithRetry(id, from, retryAttempts = 3) {
if (retryAttempts && retryAttempts > 0) {
console.log('[API-->>请求]', `from:${from}`, `id:${id}`, retryAttempts < 3 ? `剩余重试次数:${retryAttempts}` : '')
try {
const authToken = BLOG.NOTION_ACCESS_TOKEN || null
const api = new NotionAPI({ authToken, userTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone })
const start = new Date().getTime()
const pageData = await api.getPage(id)
const end = new Date().getTime()
console.log('[API<<--响应]', `耗时:${end - start}ms - from:${from}`)
return pageData
} catch (e) {
console.warn('[API<<--异常]:', e)
await delay(1000)
const cacheKey = 'page_block_' + id
const pageBlock = await getDataFromCache(cacheKey)
if (pageBlock) {
console.log('[重试缓存]', `from:${from}`, `id:${id}`)
return pageBlock
}
return await getPageWithRetry(id, from, retryAttempts - 1)
}
} else {
console.error('[请求失败]:', `from:${from}`, `id:${id}`)
return null
}
}
/**
* 获取到的页面BLOCK特殊处理
* 1.删除冗余字段
* 2.比如文件、视频、音频、url格式化
* 3.代码块等元素兼容
* @param {*} id 页面ID
* @param {*} blockMap 页面元素
* @param {*} slice 截取数量
* @returns
*/
function filterPostBlocks(id, blockMap, slice) {
const clonePageBlock = deepClone(blockMap)
let count = 0
// 循环遍历文档的每个block
for (const i in clonePageBlock?.block) {
const b = clonePageBlock?.block[i]
if (slice && slice > 0 && count > slice) {
delete clonePageBlock?.block[i]
continue
}
// 当BlockId等于PageId时移除
if (b?.value?.id === id) {
// 此block含有敏感信息
delete b?.value?.properties
continue
}
count++
// 处理 c++、c#、汇编等语言名字映射
if (b?.value?.type === 'code') {
if (b?.value?.properties?.language?.[0][0] === 'C++') {
b.value.properties.language[0][0] = 'cpp'
}
if (b?.value?.properties?.language?.[0][0] === 'C#') {
b.value.properties.language[0][0] = 'csharp'
}
if (b?.value?.properties?.language?.[0][0] === 'Assembly') {
b.value.properties.language[0][0] = 'asm6502'
}
}
// 如果是文件,或嵌入式PDF,需要重新加密签名
if ((b?.value?.type === 'file' || b?.value?.type === 'pdf' || b?.value?.type === 'video' || b?.value?.type === 'audio') &&
b?.value?.properties?.source?.[0][0] &&
b?.value?.properties?.source?.[0][0].indexOf('amazonaws.com') > 0
) {
const oldUrl = b?.value?.properties?.source?.[0][0]
const newUrl = `https://notion.so/signed/${encodeURIComponent(oldUrl)}?table=block&id=${b?.value?.id}`
b.value.properties.source[0][0] = newUrl
}
}
// 去掉不用的字段
if (id === BLOG.NOTION_PAGE_ID) {
return clonePageBlock
}
return clonePageBlock
}
|