mirror of
https://framagit.org/enfance-libre/statistiques
synced 2025-03-12 13:55:02 +00:00
feat: cache basique
This commit is contained in:
parent
9c6d83cbed
commit
3d6b9a873e
2 changed files with 79 additions and 3 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,3 +19,4 @@ node_modules
|
||||||
# outptu stats files
|
# outptu stats files
|
||||||
el-stats*.json
|
el-stats*.json
|
||||||
el-stats*.txt
|
el-stats*.txt
|
||||||
|
notion-data-cache
|
|
@ -1,21 +1,96 @@
|
||||||
import { Client } from "@notionhq/client";
|
import { Client } from "@notionhq/client";
|
||||||
|
import { createHash } from "crypto";
|
||||||
|
import { stat, mkdir, writeFile, readFile } from "fs";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
QueryDatabaseParameters,
|
QueryDatabaseParameters,
|
||||||
QueryDatabaseResponse,
|
QueryDatabaseResponse,
|
||||||
} from "@notionhq/client/build/src/api-endpoints";
|
} from "@notionhq/client/build/src/api-endpoints";
|
||||||
|
import { promisify } from "util";
|
||||||
|
import { dirname } from "path";
|
||||||
|
|
||||||
|
type QueryExtraOptions = {
|
||||||
|
cache: CacheConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
type CacheConfig =
|
||||||
|
| boolean
|
||||||
|
| {
|
||||||
|
ttl: number;
|
||||||
|
};
|
||||||
|
|
||||||
export async function queryAllDbResults(
|
export async function queryAllDbResults(
|
||||||
notion: Client,
|
notion: Client,
|
||||||
dbQuery: QueryDatabaseParameters
|
dbQuery: QueryDatabaseParameters,
|
||||||
|
{ cache: cacheConfig }: QueryExtraOptions = { cache: false }
|
||||||
): Promise<QueryDatabaseResponse["results"]> {
|
): Promise<QueryDatabaseResponse["results"]> {
|
||||||
|
const queryHash = createHash("sha1")
|
||||||
|
.update(JSON.stringify(dbQuery))
|
||||||
|
.digest("hex");
|
||||||
|
const cacheEntryFileName =
|
||||||
|
"./notion-data-cache/queryAllDbResults/" +
|
||||||
|
dbQuery.database_id +
|
||||||
|
"-" +
|
||||||
|
queryHash +
|
||||||
|
".json";
|
||||||
|
if (await shouldReadCacheEntry(cacheConfig, cacheEntryFileName)) {
|
||||||
|
console.log("reading from cache entry " + cacheEntryFileName);
|
||||||
|
return await readCacheEntry(cacheEntryFileName);
|
||||||
|
}
|
||||||
const dbResponse = await notion.databases.query(dbQuery);
|
const dbResponse = await notion.databases.query(dbQuery);
|
||||||
|
let fullResponse = [];
|
||||||
if (dbResponse.has_more && dbResponse.next_cursor) {
|
if (dbResponse.has_more && dbResponse.next_cursor) {
|
||||||
const moreResults = await queryAllDbResults(notion, {
|
const moreResults = await queryAllDbResults(notion, {
|
||||||
...dbQuery,
|
...dbQuery,
|
||||||
start_cursor: dbResponse.next_cursor,
|
start_cursor: dbResponse.next_cursor,
|
||||||
});
|
});
|
||||||
return [...dbResponse.results, ...moreResults];
|
fullResponse = [...dbResponse.results, ...moreResults];
|
||||||
} else {
|
} else {
|
||||||
return dbResponse.results;
|
fullResponse = dbResponse.results;
|
||||||
|
}
|
||||||
|
if (await shouldWriteCacheEntry(cacheConfig)) {
|
||||||
|
await writeCacheEntry(cacheEntryFileName, fullResponse);
|
||||||
|
}
|
||||||
|
return fullResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function shouldReadCacheEntry(
|
||||||
|
cacheConfig: CacheConfig,
|
||||||
|
cacheEntryFileName: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
if (cacheConfig === false) return false;
|
||||||
|
try {
|
||||||
|
const fileStat = await promisify(stat)(cacheEntryFileName);
|
||||||
|
if (cacheConfig === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const lastUpdateAge = new Date().getTime() - fileStat.mtime.getTime();
|
||||||
|
return lastUpdateAge < cacheConfig.ttl;
|
||||||
|
} catch (e) {
|
||||||
|
// Cannot get file stat => it probably doesn't exist yet
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function shouldWriteCacheEntry(
|
||||||
|
cacheConfig: CacheConfig
|
||||||
|
): Promise<boolean> {
|
||||||
|
return cacheConfig !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function writeCacheEntry(
|
||||||
|
cacheEntryFileName: string,
|
||||||
|
response: QueryDatabaseResponse["results"]
|
||||||
|
): Promise<void> {
|
||||||
|
await promisify(mkdir)(dirname(cacheEntryFileName), { recursive: true });
|
||||||
|
|
||||||
|
await promisify(writeFile)(cacheEntryFileName, JSON.stringify(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readCacheEntry(
|
||||||
|
cacheEntryFileName: string
|
||||||
|
): Promise<QueryDatabaseResponse["results"]> {
|
||||||
|
const fileBuffer: Buffer = await promisify(readFile)(cacheEntryFileName);
|
||||||
|
const parsed = JSON.parse(fileBuffer.toString());
|
||||||
|
return parsed as QueryDatabaseResponse["results"];
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue