Skip to content

Commit 9419ea2

Browse files
committed
fix: patch banner filename error
1 parent b677aaf commit 9419ea2

File tree

4 files changed

+63
-57
lines changed

4 files changed

+63
-57
lines changed

migration/sync-ts/_syncPatchesToS3Dry.ts

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { readdir, mkdir, copyFile, writeFile } from 'fs/promises'
33
import { vndbGetVnById } from './api/vndb'
44
import { parsePatchFileName } from './vn-sync/parse'
55
import sharp from 'sharp'
6+
import { sanitizeFileName } from '../../utils/sanitizeFileName'
67

78
async function ensureDir(dir: string) {
89
await mkdir(dir, { recursive: true })
@@ -35,33 +36,29 @@ export async function syncPatchesToS3Dry(
3536
results.push({ file: name, ok: false, error: 'Unrecognized filename' })
3637
continue
3738
}
38-
// Copy patch file for inspection
39-
const dstPatchPath = path.posix.join(dstPatchDir, name)
39+
// Copy patch file for inspection (sanitized file name)
40+
const sanitized = sanitizeFileName(name)
41+
const dstPatchPath = path.posix.join(dstPatchDir, sanitized)
4042
await copyFile(filePath, dstPatchPath)
4143

42-
// Fetch VN and write banner webp files
44+
// Fetch VN and write banner avif files
4345
const vn = await vndbGetVnById(parsed.vndbId)
4446
const shotUrl = pickSfwScreenshotUrlLocal(vn)
4547
if (shotUrl) {
4648
const res = await fetch(shotUrl)
4749
const ab = await res.arrayBuffer()
4850
const banner = await sharp(ab)
4951
.resize(1920, 1080, { fit: 'inside', withoutEnlargement: true })
50-
.webp({ quality: 70 })
52+
.avif({ quality: 60 })
5153
.toBuffer()
5254
const mini = await sharp(ab)
5355
.resize(460, 259, { fit: 'inside', withoutEnlargement: true })
54-
.webp({ quality: 70 })
56+
.avif({ quality: 60 })
5557
.toBuffer()
56-
const base = `${parsed.vndbId}`
57-
await writeFile(
58-
path.posix.join(dstBannerDir, `${base}-banner.webp`),
59-
banner
60-
)
61-
await writeFile(
62-
path.posix.join(dstBannerDir, `${base}-banner-mini.webp`),
63-
mini
64-
)
58+
const bannerDir = path.posix.join(dstBannerDir, parsed.vndbId)
59+
await ensureDir(bannerDir)
60+
await writeFile(path.posix.join(bannerDir, `banner.avif`), banner)
61+
await writeFile(path.posix.join(bannerDir, `banner-mini.avif`), mini)
6562
}
6663

6764
results.push({ file: name, ok: true })

migration/sync-ts/syncPatchesToS3.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,46 @@
11
import path from 'path'
22
import { readdir } from 'fs/promises'
3-
import { processOnePatchFile } from './vn-sync/index'
3+
import { prisma } from './db/prisma'
4+
import { parsePatchFileName } from './vn-sync/parse'
5+
import {
6+
createPatchIfMissing,
7+
createPatchResourceForFile
8+
} from './vn-sync/index'
49

510
export async function syncPatchesToS3(dir = 'migration/sync-ts/patch') {
611
const files = await readdir(dir)
712
const results: Array<{ file: string; ok: boolean; error?: string }> = []
813
for (const name of files) {
914
const filePath = path.posix.join(dir, name)
1015
try {
11-
const res = await processOnePatchFile(filePath)
12-
if (typeof res === 'string') {
13-
results.push({ file: name, ok: false, error: res })
14-
} else {
15-
results.push({ file: name, ok: true })
16+
const parsed = parsePatchFileName(filePath)
17+
if (!parsed) {
18+
results.push({ file: name, ok: false, error: 'Unrecognized filename' })
19+
continue
1620
}
21+
22+
const patchId = await createPatchIfMissing(parsed)
23+
const resource = await createPatchResourceForFile(patchId, parsed)
24+
25+
const patch = await prisma.patch.findUnique({
26+
where: { id: patchId },
27+
select: { name_ja_jp: true, banner: true }
28+
})
29+
30+
const jaName = patch?.name_ja_jp || ''
31+
const banner = patch?.banner || ''
32+
const bannerMini = banner
33+
? banner.replace(/\/banner\.(avif|webp)$/i, '/banner-mini.$1')
34+
: ''
35+
const fileUrl = (resource as any)?.content || ''
36+
37+
// Print requested details
38+
console.log(`Patch: ${jaName}`)
39+
if (banner) console.log(`banner: ${banner}`)
40+
if (bannerMini) console.log(`banner-mini: ${bannerMini}`)
41+
if (fileUrl) console.log(`file: ${fileUrl}`)
42+
43+
results.push({ file: name, ok: true })
1744
} catch (e: any) {
1845
results.push({ file: name, ok: false, error: e?.message || String(e) })
1946
}

migration/sync-ts/vn-sync/index.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { prisma } from '../db/prisma'
22
import { vndbGetVnById } from '../api/vndb'
33
import { parsePatchFileName, type ParsedPatchFileName } from './parse'
4-
import { uploadBannerForPatchWebp, uploadPatchFileToS3 } from './upload'
4+
import { uploadBannerForPatch, uploadPatchFileToS3 } from './upload'
55
import { generateFileHash } from '../../../app/api/upload/calculateFileStreamHash'
66
import { loadNoteTemplate, renderNoteFromTemplate } from './note'
7-
import sharp from 'sharp'
7+
import { sanitizeFileName } from '../../../utils/sanitizeFileName'
88

99
export async function pickSfwScreenshotUrl(vn: any): Promise<string | null> {
1010
if (!vn?.screenshots?.length) return null
@@ -41,7 +41,7 @@ export async function createPatchIfMissing(parsed: ParsedPatchFileName) {
4141
const nameEn = (vn as any)?.title || ''
4242
const nameJa = parsed.gameName || deriveJaTitle(vn)
4343
const releasedRaw = String((vn as any)?.released || '').trim()
44-
const released = releasedRaw ? formatDateYMD(releasedRaw) : 'unknown'
44+
const released = releasedRaw ? formatDateYYMMDD(releasedRaw) : 'unknown'
4545

4646
const patch = await prisma.patch.create({
4747
data: {
@@ -66,7 +66,7 @@ export async function createPatchIfMissing(parsed: ParsedPatchFileName) {
6666
if (screenshotUrl) {
6767
const res = await fetch(screenshotUrl)
6868
const arrayBuffer = await res.arrayBuffer()
69-
const uploadRes = await uploadBannerForPatchWebp(patch.id, arrayBuffer)
69+
const uploadRes = await uploadBannerForPatch(patch.id, arrayBuffer)
7070
if (typeof uploadRes !== 'string') {
7171
await prisma.patch.update({
7272
where: { id: patch.id },
@@ -102,11 +102,11 @@ export async function createPatchResourceForFile(
102102
gameName: parsed.gameName,
103103
groupName: parsed.groupName,
104104
language: parsed.language,
105-
publishDate: formatDateYMD(parsed.publishDate),
106-
startDate: formatDateYMD(parsed.startDate),
105+
publishDate: formatDateYYMMDD(parsed.publishDate),
106+
startDate: formatDateYYMMDD(parsed.startDate),
107107
vndbId: parsed.vndbId,
108108
platform: parsed.platform,
109-
fileName: parsed.fileName
109+
fileName: sanitizeFileName(parsed.fileName)
110110
})
111111

112112
const resource = await prisma.patch_resource.create({
@@ -159,14 +159,14 @@ export async function processOnePatchFile(filePath: string) {
159159
return await createPatchResourceForFile(patchId, parsed)
160160
}
161161

162-
export function formatDateYMD(s: string) {
162+
export function formatDateYYMMDD(s: string) {
163163
const t = String(s || '').replace(/[^0-9]/g, '')
164164
if (t.length === 8) {
165-
return `${t.slice(0, 4)}-${t.slice(4, 6)}-${t.slice(6, 8)}`
165+
return `${t.slice(2, 4)}-${t.slice(4, 6)}-${t.slice(6, 8)}`
166166
}
167167
if (t.length === 6) {
168-
return `${t.slice(0, 4)}-${t.slice(4, 6)}`
168+
return `${t.slice(2, 4)}-${t.slice(4, 6)}`
169169
}
170-
if (t.length === 4) return t
170+
if (t.length === 4) return t.slice(2, 4)
171171
return s
172172
}

migration/sync-ts/vn-sync/upload.ts

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,13 @@ import { stat } from 'fs/promises'
22
import { uploadSmallFileToS3 } from '../../../lib/s3/uploadSmallFileToS3'
33
import { uploadLargeFileToS3 } from '../../../lib/s3/uploadLargeFileToS3'
44
import { MAX_SMALL_FILE_SIZE } from '../../../config/upload'
5-
import sharp from 'sharp'
6-
import { uploadImageToS3 } from '../../../lib/s3/uploadImageToS3'
7-
import { checkBufferSize } from '../../../app/api/utils/checkBufferSize'
8-
import { MAX_SIZE, COMPRESS_QUALITY } from '../../../app/api/utils/constants'
5+
import { uploadPatchBanner as _uploadPatchBanner } from '../../../app/api/utils/uploadPatchBanner'
6+
import { sanitizeFileName } from '../../../utils/sanitizeFileName'
97

10-
export async function uploadBannerForPatchWebp(
11-
patchId: number,
12-
image: ArrayBuffer
13-
) {
14-
const banner = await sharp(image)
15-
.resize(1920, 1080, { fit: 'inside', withoutEnlargement: true })
16-
.webp({ quality: COMPRESS_QUALITY })
17-
.toBuffer()
18-
const miniBanner = await sharp(image)
19-
.resize(460, 259, { fit: 'inside', withoutEnlargement: true })
20-
.webp({ quality: COMPRESS_QUALITY })
21-
.toBuffer()
22-
23-
if (!checkBufferSize(miniBanner, MAX_SIZE)) {
24-
return '图片太大'
25-
}
26-
27-
const bucketKey = `patch/${patchId}/banner`
28-
await uploadImageToS3(`${bucketKey}/banner.webp`, banner)
29-
await uploadImageToS3(`${bucketKey}/banner-mini.webp`, miniBanner)
30-
const link = `${process.env.KUN_VISUAL_NOVEL_IMAGE_BED_URL}/patch/${patchId}/banner/banner.webp`
8+
export async function uploadBannerForPatch(patchId: number, image: ArrayBuffer) {
9+
const res = await _uploadPatchBanner(image, patchId)
10+
if (typeof res === 'string') return res
11+
const link = `${process.env.KUN_VISUAL_NOVEL_IMAGE_BED_URL}/patch/${patchId}/banner/banner.avif`
3112
return { link }
3213
}
3314

@@ -36,7 +17,8 @@ export async function uploadPatchFileToS3(
3617
hash: string,
3718
filePath: string
3819
) {
39-
const fileName = filePath.split(/[\\/]/).pop()!
20+
const rawName = filePath.split(/[\\/]/).pop()!
21+
const fileName = sanitizeFileName(rawName)
4022
const s3Key = `patch/${patchId}/${hash}/${fileName}`
4123
const st = await stat(filePath)
4224
if (st.size < MAX_SMALL_FILE_SIZE) {

0 commit comments

Comments
 (0)