diff --git a/src/scheduler/scheduler.js b/src/scheduler/scheduler.js
index 0227211..45003f2 100644
--- a/src/scheduler/scheduler.js
+++ b/src/scheduler/scheduler.js
@@ -1,5 +1,5 @@
-import { buildTable, formatNumber, truncateString } from '../util/table.js';
-import { daysBetween, formatDateInTz, formatDateTimeInTz, weekdayInTz } from '../util/time.js';
+import { buildTable } from '../util/table.js';
+import { daysBetween, formatDateInTz, weekdayInTz } from '../util/time.js';
import { resolveDaysWarning } from '../util/group-settings.js';
// One-shot daily check, invoked from api/cron.js. The cron schedule lives in
@@ -38,7 +38,8 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
}
const threshold = resolveDaysWarning(group, config);
- const stale = [];
+ const staleApple = [];
+ const staleGoogle = [];
for (const info of group.appleApps) {
try {
@@ -48,15 +49,10 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
if (Number.isNaN(updatedMs)) continue;
const days = daysBetween(updatedMs, now.getTime());
if (days > threshold) {
- stale.push({
+ staleApple.push({
appId: info.appId,
- title: app.title,
days,
updated: formatDateInTz(new Date(updatedMs), config.timezone),
- score: app.score,
- reviews: Number(app.reviews ?? 0),
- ratings: Number(app.ratings ?? 0),
- isApple: true,
});
}
} catch (err) {
@@ -72,15 +68,10 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
if (!Number.isFinite(updatedMs)) continue;
const days = daysBetween(updatedMs, now.getTime());
if (days > threshold) {
- stale.push({
+ staleGoogle.push({
appId: info.appId,
- title: app.title,
days,
updated: formatDateInTz(new Date(updatedMs), config.timezone),
- score: app.score,
- reviews: Number(app.reviews ?? 0),
- ratings: Number(app.ratings ?? 0),
- isApple: false,
});
}
} catch (err) {
@@ -88,31 +79,27 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
}
}
- if (stale.length === 0) {
+ const total = staleApple.length + staleGoogle.length;
+ if (total === 0) {
logger.info({ groupId }, 'All apps up-to-date');
return;
}
- const message = buildReport(groupId, stale, now, config, threshold);
+ const message = buildReport(staleApple, staleGoogle);
if (silent) await sender.sendMessageSilent(groupId, message);
else await sender.sendMessage(groupId, message);
}
-function buildReport(groupId, apps, now, config, threshold) {
- const headers = ['App', 'Store', 'Days', 'Updated', 'Score', 'Reviews', 'Ratings'];
- const rows = apps.map((a) => [
- truncateString(a.title || '', 30),
- a.isApple ? 'Apple' : 'Google',
- String(a.days),
- a.updated,
- Number(a.score ?? 0).toFixed(1),
- String(a.reviews),
- formatNumber(a.ratings),
- ]);
- return (
- `Daily App Check Report\n` +
- `Date: ${formatDateTimeInTz(now, config.timezone)}\n` +
- `Group: ${groupId}\n` +
- `Apps not updated in >${threshold} days: ${apps.length}\n\n` +
- `
${buildTable(headers, rows)}`
- );
+function buildReport(staleApple, staleGoogle) {
+ const total = staleApple.length + staleGoogle.length;
+ const headers = ['#', 'AppId', 'Updated', 'Days'];
+ let out = `You have ${total} app(s) need to be updated!\n`;
+ if (staleApple.length > 0) {
+ const rows = staleApple.map((a, i) => [String(i + 1), a.appId, a.updated, String(a.days)]);
+ out += `${staleApple.length} Apple Apps:\n\n${buildTable(headers, rows)}\n\n`;
+ }
+ if (staleGoogle.length > 0) {
+ const rows = staleGoogle.map((a, i) => [String(i + 1), a.appId, a.updated, String(a.days)]);
+ out += `${staleGoogle.length} Google Apps:\n\n${buildTable(headers, rows)}\n`;
+ }
+ return out;
}
diff --git a/src/util/table.js b/src/util/table.js
index 77c7b37..b86e48e 100644
--- a/src/util/table.js
+++ b/src/util/table.js
@@ -51,16 +51,3 @@ function writeSeparator(widths) {
function padRight(s, len) {
return s.length >= len ? s : s + ' '.repeat(len - s.length);
}
-
-export function truncateString(s, maxLen) {
- if (s.length <= maxLen) return s;
- if (maxLen <= 3) return s.slice(0, maxLen);
- return s.slice(0, maxLen - 3) + '...';
-}
-
-export function formatNumber(n) {
- const v = Number(n);
- if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;
- if (v >= 1_000) return `${(v / 1_000).toFixed(1)}K`;
- return String(v);
-}
diff --git a/src/util/time.js b/src/util/time.js
index 8980cc2..923d187 100644
--- a/src/util/time.js
+++ b/src/util/time.js
@@ -9,21 +9,6 @@ export function formatDateInTz(date, timezone) {
return fmt.format(date);
}
-// Format datetime as "YYYY-MM-DD HH:MM" in given IANA timezone.
-export function formatDateTimeInTz(date, timezone) {
- const fmt = new Intl.DateTimeFormat('en-CA', {
- timeZone: timezone,
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- hour: '2-digit',
- minute: '2-digit',
- hour12: false,
- });
- // en-CA produces "YYYY-MM-DD, HH:MM" — strip the comma.
- return fmt.format(date).replace(', ', ' ');
-}
-
// Day-of-week (0=Sun..6=Sat) for `date` in given timezone.
export function weekdayInTz(date, timezone) {
const fmt = new Intl.DateTimeFormat('en-US', { timeZone: timezone, weekday: 'short' });