Skip to content

Commit

Permalink
Add S3 syncer
Browse files Browse the repository at this point in the history
  • Loading branch information
misenhower committed Nov 18, 2024
1 parent 98bccc2 commit cb76f65
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 3 deletions.
6 changes: 6 additions & 0 deletions app/data/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import CoopUpdater from './updaters/CoopUpdater.mjs';
import FestivalUpdater from './updaters/FestivalUpdater.mjs';
import XRankUpdater from './updaters/XRankUpdater.mjs';
import StagesUpdater from './updaters/StagesUpdater.mjs';
import S3Syncer from '../sync/S3Syncer.mjs';
import { canSync } from '../sync/index.mjs';

function updaters() {
return [
Expand Down Expand Up @@ -50,5 +52,9 @@ export async function update(config = 'default') {
}
}

if (canSync()) {
await (new S3Syncer).upload();
}

console.info(`Done running ${config} updaters`);
}
4 changes: 4 additions & 0 deletions app/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import BlueskyClient from './social/clients/BlueskyClient.mjs';
import ThreadsClient from './social/clients/ThreadsClient.mjs';
import { archiveData } from './data/DataArchiver.mjs';
import { sentryInit } from './common/sentry.mjs';
import { sync, syncUpload, syncDownload } from './sync/index.mjs';

consoleStamp(console);
dotenv.config();
Expand All @@ -26,6 +27,9 @@ const actions = {
splatnet: update,
warmCaches,
dataArchive: archiveData,
sync,
syncUpload,
syncDownload,
};

const command = process.argv[2];
Expand Down
10 changes: 8 additions & 2 deletions app/social/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import EggstraWorkUpcomingStatus from './generators/EggstraWorkUpcomingStatus.mj
import BlueskyClient from './clients/BlueskyClient.mjs';
import ChallengeStatus from './generators/ChallengeStatus.mjs';
import ThreadsClient from './clients/ThreadsClient.mjs';
import S3Syncer from '../sync/S3Syncer.mjs';
import { canSync } from '../sync/index.mjs';

function defaultStatusGenerators() {
return [
Expand Down Expand Up @@ -63,8 +65,12 @@ export function testStatusGeneratorManager(additionalClients) {
);
}

export function sendStatuses() {
return defaultStatusGeneratorManager().sendStatuses();
export async function sendStatuses() {
await defaultStatusGeneratorManager().sendStatuses();

if (canSync()) {
await (new S3Syncer).upload();
}
}

export function testStatuses(additionalClients = []) {
Expand Down
77 changes: 77 additions & 0 deletions app/sync/S3Syncer.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import path from 'path';
import { S3Client } from '@aws-sdk/client-s3';
import { S3SyncClient } from 's3-sync-client';
import mime from 'mime-types';

export default class S3Syncer
{
download() {
this.log('Downloading files...');

return Promise.all([
this.syncClient.sync(this.publicBucket, `${this.localPath}/dist`, {
filters: this.filters,
}),
this.syncClient.sync(this.privateBucket, `${this.localPath}/storage`),
]);
}

upload() {
this.log('Uploading files...');

return Promise.all([
this.syncClient.sync(`${this.localPath}/dist`, this.publicBucket, {
filters: this.filters,
commandInput: input => ({
ACL: 'public-read',
ContentType: mime.lookup(input.Key),
CacheControl: input.Key.startsWith('data/')
? 'no-cache, stale-while-revalidate=5, stale-if-error=86400'
: undefined,
}),
}),
this.syncClient.sync(`${this.localPath}/storage`, this.privateBucket),
]);
}

get s3Client() {
return this._s3Client ??= new S3Client({
endpoint: process.env.AWS_S3_ENDPOINT,
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
});
}

/** @returns {S3SyncClient} */
get syncClient() {
return this._syncClient ??= new S3SyncClient({ client: this.s3Client });
}

get publicBucket() {
return `s3://${process.env.AWS_S3_BUCKET}`;
}

get privateBucket() {
return `s3://${process.env.AWS_S3_PRIVATE_BUCKET}`;
}

get localPath() {
return path.resolve('.');
}

get filters() {
return [
{ exclude: () => true }, // Exclude everything by default
{ include: (key) => key.startsWith('assets/splatnet/') },
{ include: (key) => key.startsWith('data/') },
{ include: (key) => key.startsWith('status-screenshots/') },
];
}

log(message) {
console.log(`[S3] ${message}`);
}
}
41 changes: 41 additions & 0 deletions app/sync/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import S3Syncer from './S3Syncer.mjs';

export function canSync() {
return !!(
process.env.AWS_ACCESS_KEY_ID &&
process.env.AWS_SECRET_ACCESS_KEY &&
process.env.AWS_S3_BUCKET &&
process.env.AWS_S3_PRIVATE_BUCKET
);
}

async function doSync(download, upload) {
if (!canSync()) {
console.warn('Missing S3 connection parameters');
return;
}

const syncer = new S3Syncer();

if (download) {
console.info('Downloading files...');
await syncer.download();
}

if (upload) {
console.info('Uploading files...');
await syncer.upload();
}
}

export function sync() {
return doSync(true, true);
}

export function syncUpload() {
return doSync(false, true);
}

export function syncDownload() {
return doSync(true, false);
}
55 changes: 55 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
"splatnet": "node app/index.mjs splatnet default",
"splatnet:all": "node app/index.mjs splatnet all",
"warmCaches": "node app/index.mjs warmCaches",
"data:archive": "node app/index.mjs dataArchive"
"data:archive": "node app/index.mjs dataArchive",
"sync": "node app/index.mjs sync",
"sync:upload": "node app/index.mjs syncUpload",
"sync:download": "node app/index.mjs syncDownload"
},
"dependencies": {
"@atproto/api": "^0.11.2",
Expand All @@ -40,6 +43,7 @@
"nxapi": "^1.4.0",
"pinia": "^2.0.22",
"puppeteer-core": "^23.8.0",
"s3-sync-client": "^4.3.1",
"sharp": "^0.32.0",
"threads-api": "^1.4.0",
"twitter-api-v2": "^1.12.7",
Expand Down

0 comments on commit cb76f65

Please sign in to comment.