This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Zaimki/server/cleanupImages.js

139 lines
3.9 KiB
JavaScript
Raw Normal View History

const dbConnection = require('./db');
require('dotenv').config({ path:__dirname + '/../.env' });
const awsConfig = require('./aws');
const S3 = require('aws-sdk/clients/s3');
const execute = process.env.EXECUTE === '1';
console.log(execute ? 'WILL REMOVE FILES!' : 'Dry run');
async function cleanup() {
console.log('--- Fetching ids expected to stay ---');
const db = await dbConnection();
const avatars = (await db.all(`
SELECT avatarSource
FROM users
WHERE avatarSource LIKE 'https://pronouns-page.s3-eu-west-1.amazonaws.com/images/%'`
)).map(row => row.avatarSource.match('https://pronouns-page.s3-eu-west-1.amazonaws.com/images/(.*)-thumb.png')[1]);
const flags = [];
for (let row of await db.all(`
SELECT customFlags
FROM profiles
WHERE customFlags != '{}'
`)) {
for (let key of Object.keys(JSON.parse(row.customFlags))) {
flags.push(key);
}
}
const sources = [];
for (let row of await db.all(`
SELECT images
FROM sources
WHERE images is not null AND images != ''
`)) {
for (let key of row.images.split(',')) {
sources.push(key);
}
}
const terms = [];
for (let row of await db.all(`
SELECT images
FROM terms
WHERE images is not null AND images != ''
`)) {
for (let key of row.images.split(',')) {
terms.push(key);
}
}
console.log('Avatars: ' + avatars.length);
console.log('Flags: ' + flags.length);
console.log('Sources: ' + sources.length);
console.log('Terms: ' + terms.length);
await db.close();
console.log('--- Cleaning up S3 ---');
const s3 = new S3(awsConfig);
let overall = 0;
let fresh = 0;
let removed = 0;
let removedSize = 0;
const chunkSize = 1000;
let marker = undefined;
while (true) {
console.log('Making a request');
const objects = await s3.listObjects({
Prefix: `images/`,
MaxKeys: chunkSize,
Marker: marker,
}).promise();
const toRemove = [];
const remove = async (object, reason) => {
console.log(`REMOVING: ${object.Key} (${reason})`);
toRemove.append({Key: object.Key});
removed += 1;
removedSize += object.Size;
}
for (let object of objects.Contents) {
overall++;
marker = object.Key;
if (object.LastModified > new Date() - 60*60*1000) {
fresh++;
continue;
}
const [, id, size] = object.Key.match('images/(.*)-(.*).png');
if (avatars.includes(id)) {
if (size !== 'thumb') {
await remove(object, 'avatar');
}
} else if (flags.includes(id)) {
if (size !== 'flag') {
await remove(object, 'flag');
}
} else if (sources.includes(id)) {
if (size !== 'big' && size !== 'thumb') {
await remove(object, 'source');
}
} else if (terms.includes(id)) {
if (size !== 'big' && size !== 'thumb') {
await remove(object, 'term');
}
} else {
await remove(object, 'not used');
}
}
if (execute && toRemove.length) {
console.log('--- Removal request ---');
await s3.deleteObjects({
Delete: {
Objects: toRemove,
}
});
}
if (objects.Contents.length < chunkSize) {
break;
}
}
console.log('--- Summary ---');
console.log('Overall: ' + overall);
console.log('Fresh: ' + fresh);
console.log('Removed: ' + removed);
console.log(`Removed size: ${Math.round(removedSize / 1024 / 1024)} MB`);
}
cleanup();