forked from cory/tildefriends
187 lines
4.5 KiB
JavaScript
187 lines
4.5 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
//! {"permissions": ["network"], "require": ["libencoding", "libhttp"]}
|
||
|
|
||
|
let libhttp = require("libhttp");
|
||
|
|
||
|
async function getEvents() {
|
||
|
let now = new Date();
|
||
|
let cacheVersion = "1-" + now.toDateString();
|
||
|
if (await database.get("cacheVersion") != cacheVersion) {
|
||
|
terminal.print("Refreshing database...");
|
||
|
let keys = await database.getAll();
|
||
|
await Promise.all(keys.map(x => database.remove(x)));
|
||
|
await database.set("cacheVersion", cacheVersion);
|
||
|
}
|
||
|
let events = [];
|
||
|
let url = "https://api.meetup.com/The-Most-Informal-Running-Club-Ever-TMIRCE-Upstate/events?&sign=true&photo-host=public&status=past";
|
||
|
let done = false;
|
||
|
while (!done) {
|
||
|
let response;
|
||
|
response = await database.get(url);
|
||
|
if (response) {
|
||
|
response = JSON.parse(response);
|
||
|
}
|
||
|
if (!response) {
|
||
|
response = await libhttp.get(url);
|
||
|
await database.set(url, JSON.stringify(response));
|
||
|
}
|
||
|
let nextLink;
|
||
|
let theseEvents = JSON.parse(response.body);
|
||
|
for (let j in theseEvents) {
|
||
|
if (new Date(theseEvents[j].time) < now) {
|
||
|
events.push(theseEvents[j]);
|
||
|
} else {
|
||
|
done = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
for (let j in response.headerArray) {
|
||
|
let link = response.headerArray[j];
|
||
|
if (link[0] == "Link" && link[1].split("; ")[1] == 'rel="next"') {
|
||
|
link = link[1].split("; ")[0];
|
||
|
link = link.substring(1, link.length - 1);
|
||
|
nextLink = link;
|
||
|
}
|
||
|
}
|
||
|
if (nextLink) {
|
||
|
url = nextLink;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return events;
|
||
|
}
|
||
|
|
||
|
async function trackWorkouts(events) {
|
||
|
let results = [];
|
||
|
for (let i in events) {
|
||
|
let event = events[i];
|
||
|
if (event && event.venue && event.venue.name
|
||
|
&& new Date(event.time).getDay() == 1) {
|
||
|
let match = /follow (?:my|our) (.*?) workout/.exec(event.description);
|
||
|
let workout;
|
||
|
if (match) {
|
||
|
workout = match[1];
|
||
|
} else if (/snowshoe/.exec(event.description)
|
||
|
|| /No run/.exec(event.description)) {
|
||
|
// nothing
|
||
|
} else {
|
||
|
results.push(event.description);
|
||
|
}
|
||
|
if (workout) {
|
||
|
results.push(workout);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return results;
|
||
|
}
|
||
|
|
||
|
async function locationByDay(day, events) {
|
||
|
let results = [];
|
||
|
for (let i in events) {
|
||
|
let event = events[i];
|
||
|
if (event && event.venue && event.venue.name
|
||
|
&& new Date(event.time).getDay() == day) {
|
||
|
results.push(event.venue.name);
|
||
|
}
|
||
|
}
|
||
|
return results;
|
||
|
}
|
||
|
|
||
|
async function redisplay(action, filter, actions, filters, events) {
|
||
|
//terminal.cork();
|
||
|
terminal.clear();
|
||
|
if (actions[action]) {
|
||
|
terminal.setHash(action);
|
||
|
terminal.print({style: "font-size: xx-large", value: action});
|
||
|
}
|
||
|
terminal.print("What:");
|
||
|
for (let i in actions) {
|
||
|
terminal.print(action == i ? "-> " : " * ", {command: i});
|
||
|
}
|
||
|
terminal.print("How:");
|
||
|
for (let i in filters) {
|
||
|
terminal.print(filter == i ? "-> " : " * ", {command: i});
|
||
|
}
|
||
|
terminal.print("--");
|
||
|
if (actions[action]) {
|
||
|
filters[filter](await actions[action](events));
|
||
|
}
|
||
|
//terminal.uncork();
|
||
|
}
|
||
|
|
||
|
function rawFilter(items) {
|
||
|
for (let i in items) {
|
||
|
terminal.print(items[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function histogramFilter(items) {
|
||
|
let table = {};
|
||
|
for (let i in items) {
|
||
|
if (!table[items[i]]) {
|
||
|
table[items[i]] = 0;
|
||
|
}
|
||
|
table[items[i]] += 1;
|
||
|
}
|
||
|
|
||
|
let results = [];
|
||
|
for (let i in table) {
|
||
|
results.push([table[i], i]);
|
||
|
}
|
||
|
results.sort((x, y) => y[0] - x[0]);
|
||
|
|
||
|
for (let i in results) {
|
||
|
terminal.print(results[i][0].toString(), " ", results[i][1]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async function main() {
|
||
|
terminal.print("loading events...");
|
||
|
let events = await getEvents();
|
||
|
terminal.print("loaded ", events.length.toString(), " events");
|
||
|
|
||
|
let actions = {
|
||
|
"Sunday Locations": locationByDay.bind(null, 0),
|
||
|
"Monday Track Workouts": trackWorkouts,
|
||
|
"Tuesday Locations": locationByDay.bind(null, 2),
|
||
|
"Wednesday Locations": locationByDay.bind(null, 3),
|
||
|
"Thursday Locations": locationByDay.bind(null, 4),
|
||
|
"Friday Locations": locationByDay.bind(null, 5),
|
||
|
"Saturday Locations": locationByDay.bind(null, 6),
|
||
|
}
|
||
|
|
||
|
let filters = {
|
||
|
"Chronological": rawFilter,
|
||
|
"Histogram": histogramFilter,
|
||
|
};
|
||
|
|
||
|
let action = null;
|
||
|
let filter = "Chronological";
|
||
|
|
||
|
core.register("hashChange", function(event) {
|
||
|
if (event.hash && event.hash[0] == '#') {
|
||
|
terminal.clear();
|
||
|
let hash = event.hash.substring(1);
|
||
|
if (filters[hash]) {
|
||
|
filter = hash;
|
||
|
} else if (actions[hash]) {
|
||
|
action = hash;
|
||
|
}
|
||
|
redisplay(action, filter, actions, filters, events);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
while (true) {
|
||
|
redisplay(action, filter, actions, filters, events);
|
||
|
let command = await terminal.readLine();
|
||
|
if (filters[command]) {
|
||
|
filter = command;
|
||
|
} else if (actions[command]) {
|
||
|
action = command;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
main().catch(terminal.print);
|