Add server, DB, and image processing modules
Introduce initial project scaffold: Express webhook server (server.js) for Immich uploads, DB pool (modules/database.js) using pg, immich repository (repositories/immichRepo.js) with get/update functions, image processing via sharp (modules/image_processor.js), a small execution helper (modules/execution_helper.js), and package.json + package-lock. Server validates a bearer token, filters non-image assets, waits briefly, compresses the image and updates DB path. Requires env vars: DB_HOST, DB_USER, DB_PORT, DB_NAME, DB_PASS, PASS_CODE, IMMICH_DATA_PATH, IMG_COMPRESSION_OUTPUT_FORMAT, IMG_COMPRESSION_OUTPUT_QUALITY, PORT.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import { Pool } from "pg"
|
||||
|
||||
export const pool = new Pool({
|
||||
host: process.env.DB_HOST,
|
||||
user: process.env.DB_USER,
|
||||
port: process.env.DB_PORT,
|
||||
database: process.env.DB_NAME,
|
||||
password: process.env.DB_PASS,
|
||||
})
|
||||
|
||||
export async function connect() {
|
||||
await pool.connect()
|
||||
}
|
||||
|
||||
export default {
|
||||
pool,
|
||||
connect
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
export default {
|
||||
sleep
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import path from "node:path"
|
||||
import fs from "node:fs/promises"
|
||||
import sharp from "sharp"
|
||||
|
||||
const IMAGE_EXTENSIONS = new Set([ ".jpg", ".jpeg", ".png", ".heic", ".heif", ".gif", ".tiff", ".bmp", ".svg", ".avif", ".raw", ".dng" ])
|
||||
const VIDEO_EXTENSIONS = new Set([ ".mp4", ".mov", ".avi", ".mkv", ".webm", ".flv", ".wmv", ".m4v", ".3gp", ".ts" ])
|
||||
|
||||
function getMediaType(filePath) {
|
||||
if (!filePath) return "unknown"
|
||||
|
||||
const ext = path.extname(filePath).toLowerCase()
|
||||
|
||||
if (IMAGE_EXTENSIONS.has(ext)) return "image"
|
||||
if (VIDEO_EXTENSIONS.has(ext)) return "video"
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
function changeExtension(filePath, newExt) {
|
||||
const formattedExt = newExt.startsWith(".") ? newExt : `.${newExt}`
|
||||
|
||||
const parsed = path.parse(filePath)
|
||||
parsed.base = `${parsed.name}${formattedExt}`
|
||||
parsed.ext = formattedExt
|
||||
|
||||
return path.format(parsed)
|
||||
}
|
||||
|
||||
async function processCompression($file) {
|
||||
const file = $file.replace("/data", process.env.IMMICH_DATA_PATH)
|
||||
const newFilePath = changeExtension(file, process.env.IMG_COMPRESSION_OUTPUT_FORMAT)
|
||||
const compressedFile = await sharp(file)
|
||||
.toFormat(process.env.IMG_COMPRESSION_OUTPUT_FORMAT,
|
||||
{ quality: parseInt(process.env.IMG_COMPRESSION_OUTPUT_QUALITY) || 80 }
|
||||
)
|
||||
.toFile(newFilePath)
|
||||
}
|
||||
|
||||
export default {
|
||||
getMediaType,
|
||||
changeExtension,
|
||||
processCompression
|
||||
}
|
||||
Generated
+1993
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "immich-photo-compressor",
|
||||
"version": "0.0.1-alpha",
|
||||
"description": "a webhook tool to compress file post uploaded on immich",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"email": "gilleslazure04@gmail.com",
|
||||
"name": "azures04",
|
||||
"url": "https://azures.fr"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "node"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "^17.4.2",
|
||||
"express": "^5.2.1",
|
||||
"nodemon": "^3.1.14",
|
||||
"pg": "^8.23.0",
|
||||
"sharp": "^0.35.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { pool } from "../modules/database.js"
|
||||
|
||||
async function getMediaInDatabase(mediaId) {
|
||||
try {
|
||||
const query = "SELECT * FROM asset WHERE id = $1"
|
||||
const values = [mediaId]
|
||||
const response = await pool.query(query, values)
|
||||
return response.rows
|
||||
} catch (error) {
|
||||
console.error("Erreur dans getMediaInDatabase:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function updateMediaPathInDatabase(mediaId, newPath) {
|
||||
try {
|
||||
const query = "UPDATE asset SET \"originalPath\" = $1 WHERE id = $2"
|
||||
const values = [newPath, mediaId]
|
||||
const response = await pool.query(query, values)
|
||||
return response.rows
|
||||
} catch (error) {
|
||||
console.error("Erreur dans updateMediaPathInDatabase:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
getMediaInDatabase,
|
||||
updateMediaPathInDatabase
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import "dotenv/config"
|
||||
import express from "express"
|
||||
import database from "./modules/database.js"
|
||||
import immichDb from "./repositories/immichRepo.js"
|
||||
import execHelper from "./modules/execution_helper.js"
|
||||
import imageProcessor from "./modules/image_processor.js"
|
||||
|
||||
await database.connect()
|
||||
const app = express()
|
||||
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
app.post("/", async (req, res) => {
|
||||
const authorization = req.headers.authorization
|
||||
if (authorization != `Bearer ${process.env.PASS_CODE}`) {
|
||||
res.status(401).send()
|
||||
}
|
||||
const assetType = req.body.data.asset.type
|
||||
if (assetType != "IMAGE") {
|
||||
res.end()
|
||||
}
|
||||
const assetFilePath = req.body.data.asset.originalPath
|
||||
if (imageProcessor.getMediaType(assetFilePath) != "IMAGE") {
|
||||
res.end()
|
||||
}
|
||||
const assetId = req.body.data.asset.id
|
||||
await execHelper.sleep(550)
|
||||
const asset = await immichDb.getMediaInDatabase(assetId)
|
||||
await imageProcessor.processCompression(asset[0].originalPath)
|
||||
immichDb.updateMediaPathInDatabase(assetId, imageProcessor.changeExtension(asset[0].originalPath, process.env.IMG_COMPRESSION_OUTPUT_FORMAT))
|
||||
return res.status(200).send()
|
||||
})
|
||||
|
||||
app.listen(process.env.PORT, () => {
|
||||
return console.log(`Server listening at port : ${process.env.PORT}`)
|
||||
})
|
||||
Reference in New Issue
Block a user