Compare commits
7 Commits
28772fcd9f
...
2aead46b51
Author | SHA1 | Date | |
---|---|---|---|
2aead46b51 | |||
79af12e526 | |||
cfd4fc3d21 | |||
7a46f31d7f | |||
cf33c4922d | |||
aa75fdd63e | |||
9c0783c607 |
@ -2,6 +2,11 @@
|
||||
|
||||
「中V档案馆」是一个旨在收录与展示「中文歌声合成作品」及有关信息的网站。
|
||||
|
||||
## 新闻 - 测试版本上线
|
||||
|
||||
目前,中V档案馆上线了用于测试的前端网页和API接口,它们分别位于[projectcvsa.com](https://projectcvsa.com)和[api.projectcvsa.com](https://api.projectcvsa.com)。
|
||||
API调用方法请参见[接口文档](https://docs.projectcvsa.com/api-doc/)。
|
||||
|
||||
## 创建背景与关联工作
|
||||
|
||||
纵观整个互联网,对于「中文歌声合成」或「中文虚拟歌手」(常简称为中V或VC)相关信息进行较为系统、全面地整理收集的主要有以下几个网站:
|
||||
@ -31,7 +36,7 @@
|
||||
|
||||
## 技术架构
|
||||
|
||||
参见[CVSA文档](https://cvsa.gitbook.io/)。
|
||||
参见[CVSA文档](https://docs.projectcvsa.com/)。
|
||||
|
||||
## 开放许可
|
||||
|
||||
|
@ -17,4 +17,4 @@ export default {
|
||||
fetch,
|
||||
} satisfies Deno.ServeDefaultExport;
|
||||
|
||||
export const VERSION = "0.2.0";
|
||||
export const VERSION = "0.2.4";
|
@ -6,18 +6,19 @@ import type { VideoSnapshotType } from "@core/db/schema.d.ts";
|
||||
import { boolean, mixed, number, object, ValidationError } from "yup";
|
||||
|
||||
const SnapshotQueryParamsSchema = object({
|
||||
ps: number().optional().positive(),
|
||||
pn: number().optional().positive(),
|
||||
offset: number().optional().positive(),
|
||||
ps: number().integer().optional().positive(),
|
||||
pn: number().integer().optional().positive(),
|
||||
offset: number().integer().optional().positive(),
|
||||
reverse: boolean().optional(),
|
||||
});
|
||||
|
||||
const idSchema = mixed().test(
|
||||
"is-valid-id",
|
||||
'id must be a string starting with "av" followed by digits, or "BV" followed by 10 alphanumeric characters, or a positive integer',
|
||||
(value) => {
|
||||
if (typeof value === "number") {
|
||||
return Number.isInteger(value) && value > 0;
|
||||
async (value) => {
|
||||
if (value && await number().integer().isValid(value)) {
|
||||
const v = parseInt(value as string);
|
||||
return Number.isInteger(v) && v > 0;
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
@ -42,10 +43,13 @@ export const getSnapshotsHanlder = createHandlers(async (c: ContextType) => {
|
||||
|
||||
try {
|
||||
const idParam = await idSchema.validate(c.req.param("id"));
|
||||
let videoId: number | string = idParam as string | number;
|
||||
if (typeof videoId === "string" && videoId.startsWith("av")) {
|
||||
videoId = videoId.slice(2);
|
||||
let videoId: string | number = idParam as string;
|
||||
if (videoId.startsWith("av")) {
|
||||
videoId = parseInt(videoId.slice(2));
|
||||
}
|
||||
else if (await number().isValid(videoId)) {
|
||||
videoId = parseInt(videoId);
|
||||
}
|
||||
const queryParams = await SnapshotQueryParamsSchema.validate(c.req.query());
|
||||
const { ps, pn, offset, reverse = false } = queryParams;
|
||||
|
||||
|
@ -1 +1 @@
|
||||
export const VERSION = "1.2.6";
|
||||
export const VERSION = "1.2.7";
|
||||
|
@ -7,7 +7,7 @@ import "../styles/global.css";
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>CVSA 前端</title>
|
||||
<title>中V档案馆</title>
|
||||
</head>
|
||||
<body class="dark:bg-zinc-900 dark:text-zinc-100">
|
||||
<slot />
|
||||
|
Loading…
Reference in New Issue
Block a user