"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);