mirror of
https://github.com/marcogll/TaxHacker_s23.git
synced 2026-01-13 21:35:19 +00:00
BREAKING: postgres + saas
This commit is contained in:
19
lib/previews/generate.ts
Normal file
19
lib/previews/generate.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { resizeImage } from "@/lib/previews/images"
|
||||
import { pdfToImages } from "@/lib/previews/pdf"
|
||||
import { User } from "@prisma/client"
|
||||
|
||||
export async function generateFilePreviews(
|
||||
user: User,
|
||||
filePath: string,
|
||||
mimetype: string
|
||||
): Promise<{ contentType: string; previews: string[] }> {
|
||||
if (mimetype === "application/pdf") {
|
||||
const { contentType, pages } = await pdfToImages(user, filePath)
|
||||
return { contentType, previews: pages }
|
||||
} else if (mimetype.startsWith("image/")) {
|
||||
const { contentType, resizedPath } = await resizeImage(user, filePath)
|
||||
return { contentType, previews: [resizedPath] }
|
||||
} else {
|
||||
return { contentType: mimetype, previews: [filePath] }
|
||||
}
|
||||
}
|
||||
54
lib/previews/images.ts
Normal file
54
lib/previews/images.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
"use server"
|
||||
|
||||
import { fileExists, getUserPreviewsDirectory } from "@/lib/files"
|
||||
import { User } from "@prisma/client"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import sharp from "sharp"
|
||||
|
||||
const MAX_WIDTH = 1800
|
||||
const MAX_HEIGHT = 1800
|
||||
const QUALITY = 90
|
||||
|
||||
export async function resizeImage(
|
||||
user: User,
|
||||
origFilePath: string,
|
||||
maxWidth: number = MAX_WIDTH,
|
||||
maxHeight: number = MAX_HEIGHT
|
||||
): Promise<{ contentType: string; resizedPath: string }> {
|
||||
try {
|
||||
const userPreviewsDirectory = await getUserPreviewsDirectory(user)
|
||||
await fs.mkdir(userPreviewsDirectory, { recursive: true })
|
||||
|
||||
const basename = path.basename(origFilePath, path.extname(origFilePath))
|
||||
const outputPath = path.join(userPreviewsDirectory, `${basename}.webp`)
|
||||
|
||||
if (await fileExists(outputPath)) {
|
||||
const metadata = await sharp(outputPath).metadata()
|
||||
return {
|
||||
contentType: `image/${metadata.format}`,
|
||||
resizedPath: outputPath,
|
||||
}
|
||||
}
|
||||
|
||||
await sharp(origFilePath)
|
||||
.rotate()
|
||||
.resize(maxWidth, maxHeight, {
|
||||
fit: "inside",
|
||||
withoutEnlargement: true,
|
||||
})
|
||||
.webp({ quality: QUALITY })
|
||||
.toFile(outputPath)
|
||||
|
||||
return {
|
||||
contentType: "image/webp",
|
||||
resizedPath: outputPath,
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error resizing image:", error)
|
||||
return {
|
||||
contentType: "image/unknown",
|
||||
resizedPath: origFilePath,
|
||||
}
|
||||
}
|
||||
}
|
||||
59
lib/previews/pdf.ts
Normal file
59
lib/previews/pdf.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
"use server"
|
||||
|
||||
import { fileExists, getUserPreviewsDirectory } from "@/lib/files"
|
||||
import { User } from "@prisma/client"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import { fromPath } from "pdf2pic"
|
||||
|
||||
const MAX_PAGES = 10
|
||||
const DPI = 150
|
||||
const QUALITY = 90
|
||||
const MAX_WIDTH = 1500
|
||||
const MAX_HEIGHT = 1500
|
||||
|
||||
export async function pdfToImages(user: User, origFilePath: string): Promise<{ contentType: string; pages: string[] }> {
|
||||
const userPreviewsDirectory = await getUserPreviewsDirectory(user)
|
||||
await fs.mkdir(userPreviewsDirectory, { recursive: true })
|
||||
|
||||
const basename = path.basename(origFilePath, path.extname(origFilePath))
|
||||
// Check if converted pages already exist
|
||||
const existingPages: string[] = []
|
||||
for (let i = 1; i <= MAX_PAGES; i++) {
|
||||
const convertedFilePath = path.join(userPreviewsDirectory, `${basename}.${i}.webp`)
|
||||
if (await fileExists(convertedFilePath)) {
|
||||
existingPages.push(convertedFilePath)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (existingPages.length > 0) {
|
||||
return { contentType: "image/webp", pages: existingPages }
|
||||
}
|
||||
|
||||
// If not — convert the file as store in previews folder
|
||||
const pdf2picOptions = {
|
||||
density: DPI,
|
||||
saveFilename: basename,
|
||||
savePath: userPreviewsDirectory,
|
||||
format: "webp",
|
||||
quality: QUALITY,
|
||||
width: MAX_WIDTH,
|
||||
height: MAX_HEIGHT,
|
||||
preserveAspectRatio: true,
|
||||
}
|
||||
|
||||
try {
|
||||
const convert = fromPath(origFilePath, pdf2picOptions)
|
||||
const results = await convert.bulk(-1, { responseType: "image" }) // TODO: respect MAX_PAGES here too
|
||||
const paths = results.filter((result) => result && result.path).map((result) => result.path) as string[]
|
||||
return {
|
||||
contentType: "image/webp",
|
||||
pages: paths,
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error converting PDF to image:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user