Page MenuHomePhabricator

D6334.diff
No OneTemporary

D6334.diff

diff --git a/keyserver/src/cron/cron.js b/keyserver/src/cron/cron.js
--- a/keyserver/src/cron/cron.js
+++ b/keyserver/src/cron/cron.js
@@ -21,6 +21,7 @@
import { deleteExpiredUpdates } from '../deleters/update-deleters';
import { deleteUnassignedUploads } from '../deleters/upload-deleters';
import { backupDB } from './backups';
+import { createDailyUpdatesThread } from './daily-updates';
import { updateAndReloadGeoipDB } from './update-geoip-db';
if (cluster.isMaster) {
@@ -61,7 +62,7 @@
},
);
schedule.scheduleJob(
- '0 3 ? * 0', // every Sunday at 3:00 AM Pacific Time
+ '0 3 ? * 0', // every Sunday at 3:00 AM GMT
async () => {
try {
await updateAndReloadGeoipDB();
@@ -73,4 +74,20 @@
}
},
);
+ schedule.scheduleJob(
+ '0 0 * * *', // every day at midnight GMT
+ async () => {
+ try {
+ if (process.env.RUN_COMM_TEAM_DEV_SCRIPTS) {
+ // This is a job that the Comm internal team uses
+ await createDailyUpdatesThread();
+ }
+ } catch (e) {
+ console.warn(
+ 'encountered error while trying to create daily updates thread',
+ e,
+ );
+ }
+ },
+ );
}
diff --git a/keyserver/src/cron/daily-updates.js b/keyserver/src/cron/daily-updates.js
new file mode 100644
--- /dev/null
+++ b/keyserver/src/cron/daily-updates.js
@@ -0,0 +1,101 @@
+// @flow
+
+import invariant from 'invariant';
+
+import ashoat from 'lib/facts/ashoat';
+import { messageTypes } from 'lib/types/message-types';
+import { threadTypes } from 'lib/types/thread-types';
+import {
+ getDate,
+ dateString,
+ prettyDateWithoutYear,
+ prettyDateWithoutDay,
+} from 'lib/utils/date-utils';
+
+import createMessages from '../creators/message-creator';
+import { createThread } from '../creators/thread-creator';
+import { fetchEntryInfosForThreadThisWeek } from '../fetchers/entry-fetchers';
+import { createScriptViewer } from '../session/scripts';
+
+const devUpdateThread = '1358777';
+const weeklyDevSyncScheduleThread = '4138372';
+
+const dailyUpdateMessage = (dateWithoutYear: string, dateWithoutDay: string) =>
+ `### ${dateWithoutDay} update
+
+Share your updates for ${dateWithoutYear} here please!`;
+
+const dateIsWeekend = (date: Date) =>
+ date.getDay() === 0 || date.getDay() === 6;
+
+// This function will do something four days a week. It skips Saturday and
+// Sunday. The hard part is the third skipped day, which is the day of the
+// weekly dev sync. By default this is Monday, but if the dev sync is on a
+// different day, then an admin will put a calendar entry in the
+// weeklyDevSyncScheduleThread indicating which day to skip.
+async function createDailyUpdatesThread() {
+ if (!process.env.RUN_COMM_TEAM_DEV_SCRIPTS) {
+ // This is a job that the Comm internal team uses
+ return;
+ }
+
+ const viewer = createScriptViewer(ashoat.id);
+ const now = new Date();
+ if (dateIsWeekend(now)) {
+ // nothing happens on Saturday or Sunday
+ return;
+ }
+
+ // Figure out which day the dev sync is on
+ let devSyncDay = 1; // default to Monday
+ const entryInfosInDevSyncScheduleThreadThisWeek = await fetchEntryInfosForThreadThisWeek(
+ viewer,
+ weeklyDevSyncScheduleThread,
+ );
+ for (const entryInfo of entryInfosInDevSyncScheduleThreadThisWeek) {
+ const entryInfoDate = getDate(
+ entryInfo.year,
+ entryInfo.month,
+ entryInfo.day,
+ );
+ if (dateIsWeekend(entryInfoDate)) {
+ // Ignore calendar entries on weekend
+ continue;
+ }
+ devSyncDay = entryInfoDate.getDay();
+ // Use the newest entryInfo. fetchEntryInfos sorts by creation time
+ break;
+ }
+
+ if (devSyncDay === now.getDay()) {
+ // Skip the dev sync day
+ return;
+ }
+
+ const dayString = dateString(now);
+ const dateWithoutYear = prettyDateWithoutYear(dayString);
+ const dateWithoutDay = prettyDateWithoutDay(dayString);
+
+ const [{ id: messageID }] = await createMessages(viewer, [
+ {
+ type: messageTypes.TEXT,
+ threadID: devUpdateThread,
+ creatorID: ashoat.id,
+ time: Date.now(),
+ text: dailyUpdateMessage(dateWithoutYear, dateWithoutDay),
+ },
+ ]);
+ invariant(
+ messageID,
+ 'message returned from createMessages always has ID set',
+ );
+
+ await createThread(viewer, {
+ type: threadTypes.SIDEBAR,
+ parentThreadID: devUpdateThread,
+ name: `${dateWithoutDay} update`,
+ sourceMessageID: messageID,
+ });
+}
+
+export { createDailyUpdatesThread };
diff --git a/keyserver/src/fetchers/entry-fetchers.js b/keyserver/src/fetchers/entry-fetchers.js
--- a/keyserver/src/fetchers/entry-fetchers.js
+++ b/keyserver/src/fetchers/entry-fetchers.js
@@ -21,6 +21,7 @@
threadPermissions,
type ThreadPermission,
} from 'lib/types/thread-types';
+import { dateString } from 'lib/utils/date-utils';
import { ServerError } from 'lib/utils/errors';
import {
@@ -317,6 +318,30 @@
return rawEntryInfoFromRow(result[0]);
}
+function getSunday(weeksFromLastSunday: number) {
+ const date = new Date();
+ const today = date.getDate();
+ const currentDay = date.getDay();
+ const newDate = date.setDate(today - currentDay + 7 * weeksFromLastSunday);
+ return new Date(newDate);
+}
+
+async function fetchEntryInfosForThreadThisWeek(
+ viewer: Viewer,
+ threadID: string,
+): Promise<$ReadOnlyArray<RawEntryInfo>> {
+ const startDate = dateString(getSunday(0));
+ const endDate = dateString(getSunday(1));
+ const filters = [
+ { type: 'not_deleted' },
+ { type: 'threads', threadIDs: [threadID] },
+ ];
+ const { rawEntryInfos } = await fetchEntryInfos(viewer, [
+ { startDate, endDate, filters },
+ ]);
+ return rawEntryInfos;
+}
+
export {
fetchEntryInfo,
fetchEntryInfosByID,
@@ -325,4 +350,5 @@
fetchEntryRevisionInfo,
fetchEntriesForSession,
fetchEntryInfoForLocalID,
+ fetchEntryInfosForThreadThisWeek,
};
diff --git a/lib/types/filter-types.js b/lib/types/filter-types.js
--- a/lib/types/filter-types.js
+++ b/lib/types/filter-types.js
@@ -14,7 +14,7 @@
+type: 'threads',
+threadIDs: $ReadOnlyArray<string>,
};
-export type CalendarFilter = { type: 'not_deleted' } | CalendarThreadFilter;
+export type CalendarFilter = { +type: 'not_deleted' } | CalendarThreadFilter;
export const defaultCalendarFilters: $ReadOnlyArray<CalendarFilter> = [
{ type: calendarThreadFilterTypes.NOT_DELETED },
diff --git a/lib/utils/date-utils.js b/lib/utils/date-utils.js
--- a/lib/utils/date-utils.js
+++ b/lib/utils/date-utils.js
@@ -73,6 +73,10 @@
return dateFormat(dateFromString(dayString), 'mmmm dS, yyyy');
}
+function prettyDateWithoutYear(dayString: string): string {
+ return dateFormat(dateFromString(dayString), 'dddd, mmmm dS');
+}
+
function dateFromString(dayString: string): Date {
const matches = dayString.match(/^([0-9]+)-([0-1][0-9])-([0-3][0-9])$/);
invariant(matches && matches.length === 4, `invalid dayString ${dayString}`);
@@ -160,6 +164,7 @@
fifteenDaysLater,
prettyDate,
prettyDateWithoutDay,
+ prettyDateWithoutYear,
dateFromString,
shortAbsoluteDate,
longAbsoluteDate,

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 24, 8:57 AM (21 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2574755
Default Alt Text
D6334.diff (6 KB)

Event Timeline