genesis
This commit is contained in:
97
picture-syncer.js
Normal file
97
picture-syncer.js
Normal file
@@ -0,0 +1,97 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { createConnection } from './database.js';
|
||||
|
||||
class PictureSyncer {
|
||||
constructor() {
|
||||
if (PictureSyncer.instance) {
|
||||
return PictureSyncer.instance;
|
||||
}
|
||||
this.cacheBaseDir = process.env.CACHE_LOCATION || '.';
|
||||
PictureSyncer.instance = this;
|
||||
}
|
||||
|
||||
async syncImages(imageIds, groupName) {
|
||||
const groupDir = path.join(this.cacheBaseDir, 'img', groupName);
|
||||
|
||||
// Ensure directory exists
|
||||
await fs.mkdir(groupDir, { recursive: true });
|
||||
|
||||
// Get existing files
|
||||
let existingFiles = [];
|
||||
try {
|
||||
existingFiles = await fs.readdir(groupDir);
|
||||
} catch (err) {
|
||||
// Directory might be empty or new
|
||||
}
|
||||
|
||||
// Filter for image files (assuming we save as {id}.jpg or similar, but let's check just by ID prefix)
|
||||
// Actually, let's assume we save as `${id}.jpg`
|
||||
const existingIds = existingFiles
|
||||
.filter(f => f.endsWith('.jpg'))
|
||||
.map(f => parseInt(f.replace('.jpg', '')));
|
||||
|
||||
const validIds = new Set(imageIds.filter(id => id !== null && id !== undefined));
|
||||
|
||||
// 1. Delete obsolete images
|
||||
const toDelete = existingIds.filter(id => !validIds.has(id));
|
||||
for (const id of toDelete) {
|
||||
const filePath = path.join(groupDir, `${id}.jpg`);
|
||||
await fs.unlink(filePath);
|
||||
console.log(`🗑️ Deleted obsolete image: ${filePath}`);
|
||||
}
|
||||
|
||||
// 2. Download missing images
|
||||
const toDownload = imageIds.filter(id => id !== null && id !== undefined && !existingIds.includes(id));
|
||||
|
||||
if (toDownload.length > 0) {
|
||||
console.log(`📥 Downloading ${toDownload.length} new images for group '${groupName}'...`);
|
||||
await this._downloadImages(toDownload, groupDir);
|
||||
} else {
|
||||
console.log(`✅ No new images to download for group '${groupName}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
async _downloadImages(ids, dir) {
|
||||
let pool;
|
||||
try {
|
||||
pool = await createConnection();
|
||||
|
||||
// Process in chunks to avoid huge queries
|
||||
const chunkSize = 50;
|
||||
for (let i = 0; i < ids.length; i += chunkSize) {
|
||||
const chunk = ids.slice(i, i + chunkSize);
|
||||
const list = chunk.join(',');
|
||||
|
||||
const result = await pool.request().query(`
|
||||
SELECT kBild, bBild
|
||||
FROM tBild
|
||||
WHERE kBild IN (${list})
|
||||
`);
|
||||
|
||||
for (const record of result.recordset) {
|
||||
if (record.bBild) {
|
||||
const filePath = path.join(dir, `${record.kBild}.jpg`);
|
||||
await fs.writeFile(filePath, record.bBild);
|
||||
// console.log(`💾 Saved image: ${filePath}`);
|
||||
}
|
||||
}
|
||||
const processed = Math.min(i + chunkSize, ids.length);
|
||||
if (processed === ids.length) {
|
||||
console.log(`✅ Processed ${processed}/${ids.length} images.`);
|
||||
} else {
|
||||
console.log(`⏳ Processed ${processed}/${ids.length} images...`);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('❌ Error downloading images:', err);
|
||||
} finally {
|
||||
if (pool) {
|
||||
await pool.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const instance = new PictureSyncer();
|
||||
export default instance;
|
||||
Reference in New Issue
Block a user