Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script that generates meetup events #251

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 157 additions & 0 deletions make_meetups.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/* eslint-env node */
const getTimezoneOffset = require(`get-timezone-offset`);
const request = require(`request`);

const events = {
'nodeschool': {
reference_event_id: `266012076`,
meetup_urlname: `nodeschool-vancouver`,
timezone: `America/Vancouver`,
heading: `💻 NodeSchool: %season% Is Here Series %emoji%`,
startTime: 12,
duration: 4 * 60 * 60 * 1000, // 4 hours in milliseconds
dayOfWeek: 6, // saturday
week: 2, // second week
ignoreMonths: [],
body: `Part of the %year% %season% Is Here Series %emoji%

Cool! 🙂 Read on...the usual spiel follows.

Are you a beginner at using Node.js and/or JavaScript? Are you wanting a refresher? Are you looking to level up your knowledge?

We don't have set classes, and as such it is considered a self study program. The NodeSchool organization has a lot of workshops for you to learn from, and we help out along the way, but that doesn't mean you have to do the workshops, we are a diverse group of people learning and growing together.

Bring your laptops and, if you can, have Node.js installed before you arrive. It's time for another session of learning!

We have regular mentors to help everyone learn. But we can't ever have too many people who want to help others learn, right?! We promise that by the end of the session you'll know enough to help the person sitting next to you learn too 💪

RSVP "yes" and come learn and/or help others learn Node.js and/or JavaScript over a casual Saturday afternoon!`,
},
// 'intro-to-open-source': { }
};

function getSeason(date) {
// December through February is Winter 🔥,
// March through May is Spring 🌻,
// June through August is Summer 🌦
// September through November is Fall 🍁.
switch (date.getMonth()) {
case 11: // December
case 0: // january
case 1: // feb
return { season: `Winter`, emoji: `🔥` };
case 2: // March
case 3: // April
case 4: // May
return { season: `Spring`, emoji: `🌻` };
case 5: // June
case 6: // July
case 7: // August
return { season: `Summer`, emoji: `🌦` };
case 8: // September
case 9: // October
case 10: // November
return { season: `Fall`, emoji: `🍁` };
}
throw new Error(`somehow different`);
}

function findDayOfWeek(year, month, desiredWeek, desiredDayOfWeek) {
let startingDate = new Date(year, month);
while (startingDate.getDay() != desiredDayOfWeek) {
startingDate.setDate(startingDate.getDate() + 1);
}
// should now be the first $day of the first week
if (desiredWeek == 1) {
return startingDate.getDate();
}

for (let i = 1; i < desiredWeek; i += 1) {
startingDate.setDate(startingDate.getDate() + 7);
}
return startingDate.getDate();
}

function getEventForMonth(type, year, month) {
if (events[type].ignoreMonths.includes(month)) {
return null;
}

const day = findDayOfWeek(year, month, events[type].week, events[type].dayOfWeek);
const offset = getTimezoneOffset(events[type].timezone, new Date(Date.UTC(year, month, day))) * 60000; // convert to milliseconds

const eventStart = new Date(Date.UTC(year, month, day, events[type].startTime) + offset);
const replacements = {
month,
year,
day,
...getSeason(eventStart),
};

const replacer = function(str) {
if (!str) { return str; }
return str.trim().replace(/%(\w+)%/g, function(match, word) {
return replacements[word];
});
};

return {
time: eventStart.getTime(),
duration: events[type].duration,
name: replacer(events[type].heading),
description: replacer(events[type].body),
};
}

const requestPromiseGet = (url) => {
return new Promise(function(resolve, reject) {
request.get(url, (error, response, body) => {
if (error) {
reject(error);
return;
}
resolve(JSON.parse(body));
});
});
};

async function popuplateMissingEvents(year, type) {
const event = events[type];
if (!event) { throw new Error(`unknown type: ${type}`); }

const referenceEvent = await requestPromiseGet(`https://api.meetup.com/${event.meetup_urlname}/events/${event.reference_event_id}/?fields=description_images,featured_photo`);

const yearlyEvents = await requestPromiseGet(`https://api.meetup.com/${event.meetup_urlname}/events?no_earlier_than=${year}-01-01T00:00:00.000&page=50&status=past,upcoming`).then(events => {
return events.reduce(function(all, event) {
all[new Date(event.time).getMonth()] = event;
return all;
}, {});
});

const eventsToCreate = [];
for (let month = 0; month < 12; month += 1) {
if (yearlyEvents[month]) {
continue; // fixme multiple event types per month
}
const data = {
featured_photo_id: referenceEvent.featured_photo.id,
rsvp_limit: referenceEvent.rsvp_limit,
...getEventForMonth(type, year, month),
};
if (!data.time) {
continue; // no event this month
}
eventsToCreate.push(data);
}
return eventsToCreate;
}

if (require.main === module) {
popuplateMissingEvents(2020, `nodeschool`).then(console.log, console.error);
}

module.exports = {
getSeason,
findDayOfWeek,
getEventForMonth,
};
79 changes: 79 additions & 0 deletions make_meetups.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* eslint-env mocha */
/* eslint-disable jest/expect-expect */
const { getSeason, findDayOfWeek, getEventForMonth } = require(`./make_meetups.js`);

const assert = require(`assert`);

const dates = [
{
date: new Date(`April 13, 2019 16:00:00`),
season: `Spring`,
},
{
date: new Date(`May 11, 2019 16:00:00`),
season: `Spring`, // actual meetup is wrong :)
},
{
date: new Date(`June 8, 2019 16:00:00`),
season: `Summer`,
},
{
date: new Date(`July 13, 2019 16:00:00`),
season: `Summer`,
},
{
date: new Date(`August 10, 2019 16:00:00`),
season: `Summer`,
},
{
date: new Date(`Sept 14, 2019 16:00:00`),
season: `Fall`,
},
{
date: new Date(`Nov 9, 2019 16:00:00`),
season: `Fall`,
},
{
date: new Date(`Dec 14, 2019 16:00:00`),
season: `Winter`,
},
{
date: new Date(`Jan 11, 2020 16:00:00`),
season: `Winter`,
},
{
date: new Date(`Feb 8, 2020 16:00:00`),
season: `Winter`,
},
{
date: new Date(`Mar 14, 2020 16:00:00`),
season: `Spring`,
},
];

describe(`make_meetups`, function() {
for (const date of dates) {
it(`getSeason - ${date.date}`, function () {
assert.deepEqual(getSeason(date.date).season, date.season);
});
it(`findDayOfWeek - ${date.date}`, function () {
assert.deepEqual(findDayOfWeek(
date.date.getYear() + 1900,
date.date.getMonth(),
2,
6,
), date.date.getDate());
});
}
it(`getEventForMonth`, function() {
assert.deepEqual(
getEventForMonth(`nodeschool`, 2020, 2 /* March */),
{
"body": `Part of the **2020 Spring** Is Here Series **🌻**\n\nCool! 🙂 Read on...the usual spiel follows.\n\nAre you a beginner at using Node.js and/or JavaScript? Are you wanting a refresher? Are you looking to level up your knowledge?\n\nWe don't have set classes, and as such it is considered a self study program. The NodeSchool organization has a lot of workshops for you to learn from, and we help out along the way, but that doesn't mean you have to do the workshops, we are a diverse group of people learning and growing together.\n\nBring your laptops and, if you can, have Node.js installed before you arrive. It's time for another session of learning!\n\nWe have regular mentors to help everyone learn. But we can't ever have too many people who want to help others learn, right?! We promise that by the end of the session you'll know enough to help the person sitting next to you learn too 💪\n\nRSVP "yes" and come learn and/or help others learn Node.js and/or JavaScript over a casual Saturday afternoon!`,
"duration": 14400000,
"eventStart": new Date(1584212400000), // taken from existing meetup id
"title": `💻 NodeSchool: Spring Is Here Series 🌻`,
},
);
});
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"gatsby-transformer-remark": "^2.6.52",
"gatsby-transformer-sharp": "^2.3.14",
"gatsby-transformer-yaml": "^2.2.25",
"mocha": "^7.1.0",
"node-sass": "^4.13.1",
"prismjs": "^1.19.0",
"prop-types": "^15.7.2",
Expand All @@ -47,7 +48,9 @@
"eslint-plugin-babel": "^5.3.0",
"eslint-plugin-jest": "^23.7.0",
"eslint-plugin-promise": "^4.2.1",
"get-timezone-offset": "^1.0.3",
"gh-pages": "^2.2.0",
"meetup-api": "^1.4.38",
"npm-run-all": "^4.1.5",
"prettier": "^1.19.1",
"prettier-eslint-cli": "^5.0.0"
Expand Down