diff --git a/app/cron.mjs b/app/cron.mjs index 3babc13..4f64747 100644 --- a/app/cron.mjs +++ b/app/cron.mjs @@ -1,12 +1,12 @@ import { CronJob } from "cron"; import { updateAll } from "./data/index.mjs"; import { warmCaches } from "./splatnet/index.mjs"; -import { sendTweets } from "./twitter/index.mjs"; +import { sendStatuses } from "./social/index.mjs"; export default function() { new CronJob('5,20,35,50 * * * *', warmCaches, null, true); new CronJob('15 0,2,5,10,15,30,45 * * * *', async () => { await updateAll(); - await sendTweets(); + await sendStatuses(); }, null, true); } diff --git a/app/index.mjs b/app/index.mjs index 65f5ca0..dd41d58 100644 --- a/app/index.mjs +++ b/app/index.mjs @@ -1,7 +1,7 @@ import dotenv from 'dotenv'; import consoleStamp from 'console-stamp'; import cron from './cron.mjs'; -import { sendTweets, testTweets } from './twitter/index.mjs'; +import { sendStatuses, testStatuses } from './social/index.mjs'; import { updateAll } from './data/index.mjs'; import { warmCaches } from "./splatnet/index.mjs"; @@ -10,8 +10,8 @@ dotenv.config(); const actions = { cron, - twitter: sendTweets, - twitterTest: testTweets, + social: sendStatuses, + socialTest: testStatuses, splatnet: updateAll, warmCaches, } diff --git a/app/twitter/Media.mjs b/app/social/Media.mjs similarity index 100% rename from app/twitter/Media.mjs rename to app/social/Media.mjs diff --git a/app/twitter/Tweet.mjs b/app/social/Status.mjs similarity index 55% rename from app/twitter/Tweet.mjs rename to app/social/Status.mjs index a313c72..db954c5 100644 --- a/app/twitter/Tweet.mjs +++ b/app/social/Status.mjs @@ -1,4 +1,4 @@ -export default class Tweet +export default class Status { status = null; media = []; diff --git a/app/twitter/TwitterManager.mjs b/app/social/StatusGeneratorManager.mjs similarity index 66% rename from app/twitter/TwitterManager.mjs rename to app/social/StatusGeneratorManager.mjs index ba0e1bf..d5d8f79 100644 --- a/app/twitter/TwitterManager.mjs +++ b/app/social/StatusGeneratorManager.mjs @@ -1,12 +1,12 @@ import fs from 'fs/promises'; import mkdirp from 'mkdirp'; import ScreenshotHelper from "../screenshots/ScreenshotHelper.mjs"; -import TweetGenerator from "./generators/TweetGenerator.mjs"; +import StatusGenerator from "./generators/StatusGenerator.mjs"; import TwitterClient from "./TwitterClient.mjs"; -export default class TwitterManager +export default class StatusGeneratorManager { - /** @type {TweetGenerator[]} */ + /** @type {StatusGenerator[]} */ generators; /** @type {TwitterClient} */ @@ -21,34 +21,34 @@ export default class TwitterManager this.screenshotHelper = new ScreenshotHelper; } - async sendTweets() { + async sendStatuses() { for (let generator of this.generators) { - if (!(await generator.shouldTweet())) { + if (!(await generator.shouldPost())) { continue; } - await generator.sendTweet(this.screenshotHelper, this.client); + await generator.sendStatus(this.screenshotHelper, this.client); } await this.screenshotHelper.close(); } - async testTweets() { + async testStatuses() { for (let generator of this.generators) { let dir = 'temp'; await mkdirp(dir); - let tweet = await generator.getTweet(this.screenshotHelper); + let status = await generator.getStatus(this.screenshotHelper); let imgFilename = `temp/${generator.key}.png`; - await fs.writeFile(imgFilename, tweet.media[0].file); + await fs.writeFile(imgFilename, status.media[0].file); let text = [ 'Status:', - tweet.status, + status.status, '', 'Alt text:', - tweet.media[0].altText, + status.media[0].altText, ].join('\n'); let textFilename = `temp/${generator.key}.txt`; diff --git a/app/twitter/TwitterClient.mjs b/app/social/TwitterClient.mjs similarity index 77% rename from app/twitter/TwitterClient.mjs rename to app/social/TwitterClient.mjs index 71fdf2a..e87b270 100644 --- a/app/twitter/TwitterClient.mjs +++ b/app/social/TwitterClient.mjs @@ -1,5 +1,5 @@ import { TwitterApi } from "twitter-api-v2"; -import Tweet from "./Tweet.mjs"; +import Status from "./Status.mjs"; export default class TwitterClient { @@ -16,12 +16,12 @@ export default class TwitterClient } /** - * @param {Tweet} tweet + * @param {Status} status */ - async send(tweet) { + async send(status) { // Upload images let mediaIds = await Promise.all( - tweet.media.map(async m => { + status.media.map(async m => { let id = await this.#api.v1.uploadMedia(m.file, { mimeType: m.type }); if (m.altText) { @@ -32,7 +32,7 @@ export default class TwitterClient }), ); - // Send tweet - await this.#api.v1.tweet(tweet.status, { media_ids: mediaIds }); + // Send status + await this.#api.v1.tweet(status.status, { media_ids: mediaIds }); } } diff --git a/app/twitter/generators/CountdownTweet.mjs b/app/social/generators/CountdownStatus.mjs similarity index 87% rename from app/twitter/generators/CountdownTweet.mjs rename to app/social/generators/CountdownStatus.mjs index d1792c0..af1b28f 100644 --- a/app/twitter/generators/CountdownTweet.mjs +++ b/app/social/generators/CountdownStatus.mjs @@ -1,12 +1,12 @@ -import TweetGenerator from "./TweetGenerator.mjs"; +import StatusGenerator from "./StatusGenerator.mjs"; import Media from "../Media.mjs"; import ScreenshotHelper from "../../screenshots/ScreenshotHelper.mjs"; const releaseDate = new Date('2022-09-09'); -export default class CountdownTweet extends TweetGenerator +export default class CountdownStatus extends StatusGenerator { - shouldTweet() { + shouldPost() { const now = new Date; const cutoff = new Date('2022-09-10'); diff --git a/app/twitter/generators/DailyDropGearTweet.mjs b/app/social/generators/DailyDropGearStatus.mjs similarity index 90% rename from app/twitter/generators/DailyDropGearTweet.mjs rename to app/social/generators/DailyDropGearStatus.mjs index 9943fb2..3dba14c 100644 --- a/app/twitter/generators/DailyDropGearTweet.mjs +++ b/app/social/generators/DailyDropGearStatus.mjs @@ -1,9 +1,9 @@ -import TweetGenerator from "./TweetGenerator.mjs"; +import StatusGenerator from "./StatusGenerator.mjs"; import Media from "../Media.mjs"; import { useGearStore } from "../../../src/stores/gear.mjs"; import { getGearIcon } from "../../common/util.mjs"; -export default class DailyDropGearTweet extends TweetGenerator +export default class DailyDropGearStatus extends StatusGenerator { key = 'gear.dailydrop'; name = 'Daily Drop Gear'; @@ -19,7 +19,7 @@ export default class DailyDropGearTweet extends TweetGenerator async getDataTime() { let { brand } = await this.getData(); - // We only have end times for gear, so use that to track the tweet time + // We only have end times for gear, so use that to track the status time return Date.parse(brand.saleEndTime); } diff --git a/app/twitter/generators/RegularGearTweet.mjs b/app/social/generators/RegularGearStatus.mjs similarity index 89% rename from app/twitter/generators/RegularGearTweet.mjs rename to app/social/generators/RegularGearStatus.mjs index b2b2f9b..1ae1907 100644 --- a/app/twitter/generators/RegularGearTweet.mjs +++ b/app/social/generators/RegularGearStatus.mjs @@ -1,9 +1,9 @@ -import TweetGenerator from "./TweetGenerator.mjs"; +import StatusGenerator from "./StatusGenerator.mjs"; import Media from "../Media.mjs"; import { useGearStore } from "../../../src/stores/gear.mjs"; import { getGearIcon } from "../../common/util.mjs"; -export default class RegularGearTweet extends TweetGenerator +export default class RegularGearStatus extends StatusGenerator { key = 'gear.regular'; name = 'Regular Gear'; @@ -17,7 +17,7 @@ export default class RegularGearTweet extends TweetGenerator async getDataTime() { let gear = await this.getLatestGear(); - // We only have end times for gear, so use that to track the tweet time + // We only have end times for gear, so use that to track the status time return Date.parse(gear.saleEndTime); } diff --git a/app/twitter/generators/SalmonRunGearTweet.mjs b/app/social/generators/SalmonRunGearStatus.mjs similarity index 81% rename from app/twitter/generators/SalmonRunGearTweet.mjs rename to app/social/generators/SalmonRunGearStatus.mjs index 4e7ae29..988246c 100644 --- a/app/twitter/generators/SalmonRunGearTweet.mjs +++ b/app/social/generators/SalmonRunGearStatus.mjs @@ -1,8 +1,8 @@ -import TweetGenerator from "./TweetGenerator.mjs"; +import StatusGenerator from "./StatusGenerator.mjs"; import Media from "../Media.mjs"; import { useCoopGearStore } from "../../../src/stores/gear.mjs"; -export default class SalmonRunGearTweet extends TweetGenerator +export default class SalmonRunGearStatus extends StatusGenerator { key = 'gear.salmonrun'; name = 'Salmon Run Gear'; @@ -19,10 +19,10 @@ export default class SalmonRunGearTweet extends TweetGenerator return gear?.__splatoon3ink_id; } - async shouldTweet() { + async shouldPost() { let gear = await this.getGear(); - let cachedId = await this.lastTweetCache.getData(); + let cachedId = await this.lastPostCache.getData(); return gear?.__splatoon3ink_id && gear?.__splatoon3ink_id !== cachedId; } diff --git a/app/twitter/generators/SalmonRunTweet.mjs b/app/social/generators/SalmonRunStatus.mjs similarity index 91% rename from app/twitter/generators/SalmonRunTweet.mjs rename to app/social/generators/SalmonRunStatus.mjs index 7cda5d7..8abc4ec 100644 --- a/app/twitter/generators/SalmonRunTweet.mjs +++ b/app/social/generators/SalmonRunStatus.mjs @@ -1,8 +1,8 @@ -import TweetGenerator from "./TweetGenerator.mjs"; +import StatusGenerator from "./StatusGenerator.mjs"; import Media from "../Media.mjs"; import { useSalmonRunSchedulesStore } from "../../../src/stores/schedules.mjs"; -export default class SalmonRunTweet extends TweetGenerator +export default class SalmonRunStatus extends StatusGenerator { key = 'salmonrun'; name = 'Salmon Run'; diff --git a/app/twitter/generators/SchedulesTweet.mjs b/app/social/generators/SchedulesStatus.mjs similarity index 96% rename from app/twitter/generators/SchedulesTweet.mjs rename to app/social/generators/SchedulesStatus.mjs index 31f74bb..006c7c5 100644 --- a/app/twitter/generators/SchedulesTweet.mjs +++ b/app/social/generators/SchedulesStatus.mjs @@ -1,8 +1,8 @@ -import TweetGenerator from "./TweetGenerator.mjs"; +import StatusGenerator from "./StatusGenerator.mjs"; import Media from "../Media.mjs"; import { useAnarchyOpenSchedulesStore, useAnarchySeriesSchedulesStore, useLeagueSchedulesStore, useRegularSchedulesStore, useSplatfestSchedulesStore, useXSchedulesStore } from "../../../src/stores/schedules.mjs"; import { useUSSplatfestsStore } from '../../../src/stores/splatfests.mjs'; -export default class SchedulesTweet extends TweetGenerator +export default class SchedulesStatus extends StatusGenerator { key = 'schedules'; name = 'Schedules'; diff --git a/app/twitter/generators/SplatfestResultsTweet.mjs b/app/social/generators/SplatfestResultsStatus.mjs similarity index 88% rename from app/twitter/generators/SplatfestResultsTweet.mjs rename to app/social/generators/SplatfestResultsStatus.mjs index 07132df..7333ee1 100644 --- a/app/twitter/generators/SplatfestResultsTweet.mjs +++ b/app/social/generators/SplatfestResultsStatus.mjs @@ -1,8 +1,8 @@ -import TweetGenerator from "./TweetGenerator.mjs"; +import StatusGenerator from "./StatusGenerator.mjs"; import Media from "../Media.mjs"; import { useUSSplatfestsStore } from '../../../src/stores/splatfests.mjs'; -export default class SplatfestResultsTweet extends TweetGenerator +export default class SplatfestResultsStatus extends StatusGenerator { key = 'splatfestResults'; name = 'Splatfest Results'; diff --git a/app/twitter/generators/TweetGenerator.mjs b/app/social/generators/StatusGenerator.mjs similarity index 77% rename from app/twitter/generators/TweetGenerator.mjs rename to app/social/generators/StatusGenerator.mjs index 6b260be..45c78e6 100644 --- a/app/twitter/generators/TweetGenerator.mjs +++ b/app/social/generators/StatusGenerator.mjs @@ -2,14 +2,14 @@ import fs from 'fs/promises'; import { createPinia, setActivePinia } from 'pinia'; import { useCoopDataStore, useFestivalsDataStore, useGearDataStore, useSchedulesDataStore } from '../../../src/stores/data.mjs'; import prefixedConsole from '../../common/prefixedConsole.mjs'; -import Tweet from '../Tweet.mjs'; +import Status from '../Status.mjs'; import TwitterClient from '../TwitterClient.mjs'; import ScreenshotHelper from '../../screenshots/ScreenshotHelper.mjs'; import { getTopOfCurrentHour } from '../../common/util.mjs'; import { useTimeStore } from '../../../src/stores/time.mjs'; import ValueCache from '../../common/ValueCache.mjs'; -export default class TweetGenerator +export default class StatusGenerator { key = null; name = null; @@ -21,10 +21,10 @@ export default class TweetGenerator return this._console; } - get lastTweetCache() { - this._lastTweetCache ??= new ValueCache(`twitter.${this.key}`); + get lastPostCache() { + this._lastPostCache ??= new ValueCache(`twitter.${this.key}`); - return this._lastTweetCache; + return this._lastPostCache; } async preparePinia() { @@ -50,43 +50,43 @@ export default class TweetGenerator return useTimeStore().now; } - async shouldTweet() { + async shouldPost() { let currentTime = await this.getDataTime(); - let cachedTime = await this.lastTweetCache.getData(); + let cachedTime = await this.lastPostCache.getData(); return currentTime && (!cachedTime || (currentTime > cachedTime)); } - async updateLastTweetCache() { + async updatelastPostCache() { let currentTime = await this.getDataTime(); - await this.lastTweetCache.setData(currentTime); + await this.lastPostCache.setData(currentTime); } /** * @param {ScreenshotHelper} screenshotHelper * @param {TwitterClient} twitterClient */ - async sendTweet(screenshotHelper, twitterClient) { - let tweet = await this.getTweet(screenshotHelper); + async sendStatus(screenshotHelper, twitterClient) { + let status = await this.getStatus(screenshotHelper); - await twitterClient.send(tweet); + await twitterClient.send(status); - await this.updateLastTweetCache(); + await this.updatelastPostCache(); } /** @param {ScreenshotHelper} screenshotHelper */ - async getTweet(screenshotHelper) { - const tweet = new Tweet; - tweet.status = await this._getStatus(); + async getStatus(screenshotHelper) { + const status = new Status; + status.status = await this._getStatus(); let media = await this.getMedia(screenshotHelper); if (media && !Array.isArray(media)) { media = [media]; } - tweet.media = media; + status.media = media; - return tweet; + return status; } async _prepareScreenshotHelper(screenshotHelper) { diff --git a/app/social/index.mjs b/app/social/index.mjs new file mode 100644 index 0000000..9356e8a --- /dev/null +++ b/app/social/index.mjs @@ -0,0 +1,26 @@ +import DailyDropGearStatus from "./generators/DailyDropGearStatus.mjs"; +import RegularGearStatus from "./generators/RegularGearStatus.mjs"; +import SalmonRunGearStatus from "./generators/SalmonRunGearStatus.mjs"; +import SalmonRunStatus from "./generators/SalmonRunStatus.mjs"; +import SchedulesStatus from "./generators/SchedulesStatus.mjs"; +import SplatfestResultsStatus from "./generators/SplatfestResultsStatus.mjs"; +import StatusGeneratorManager from "./StatusGeneratorManager.mjs" + +export function defaultTwitterManager() { + return new StatusGeneratorManager([ + new SchedulesStatus, + new DailyDropGearStatus, + new RegularGearStatus, + new SalmonRunStatus, + new SalmonRunGearStatus, + new SplatfestResultsStatus, + ]); +} + +export function sendStatuses() { + return defaultTwitterManager().sendStatuses(); +} + +export function testStatuses() { + return defaultTwitterManager().testStatuses(); +} diff --git a/app/twitter/index.mjs b/app/twitter/index.mjs deleted file mode 100644 index bf0cd90..0000000 --- a/app/twitter/index.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import DailyDropGearTweet from "./generators/DailyDropGearTweet.mjs"; -import RegularGearTweet from "./generators/RegularGearTweet.mjs"; -import SalmonRunGearTweet from "./generators/SalmonRunGearTweet.mjs"; -import SalmonRunTweet from "./generators/SalmonRunTweet.mjs"; -import SchedulesTweet from "./generators/SchedulesTweet.mjs"; -import SplatfestResultsTweet from "./generators/SplatfestResultsTweet.mjs"; -import TwitterManager from "./TwitterManager.mjs" - -export function defaultTwitterManager() { - return new TwitterManager([ - new SchedulesTweet, - new DailyDropGearTweet, - new RegularGearTweet, - new SalmonRunTweet, - new SalmonRunGearTweet, - new SplatfestResultsTweet, - ]); -} - -export function sendTweets() { - return defaultTwitterManager().sendTweets(); -} - -export function testTweets() { - return defaultTwitterManager().testTweets(); -} diff --git a/package.json b/package.json index 2f186f5..6c8bc48 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "preview": "vite preview --port 5050", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore", "cron": "node app/index.mjs cron", - "twitter": "node app/index.mjs twitter", - "twitter:test": "node app/index.mjs twitterTest", + "social": "node app/index.mjs social", + "social:test": "node app/index.mjs socialTest", "splatnet": "node app/index.mjs splatnet", "warmCaches": "node app/index.mjs warmCaches" },