diff options
Diffstat (limited to 'public')
-rw-r--r-- | public/gapi.js | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/public/gapi.js b/public/gapi.js deleted file mode 100644 index f5ab73e..0000000 --- a/public/gapi.js +++ /dev/null @@ -1,182 +0,0 @@ -/* global chrome */ -const gapi_base = 'https://www.googleapis.com/calendar/v3'; - -const GApiError = { - invalidSyncToken: 1, - otherError: 2, -}; - -function to_params(dict) { - return Object.entries(dict).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&'); -} - -function getAuthToken() { - return new Promise(resolver => - chrome.identity.getAuthToken( - {interactive: true}, token => resolver(token))); -} - -function getCalendars(token) { - return fetch(`${gapi_base}/users/me/calendarList?${to_params({access_token: token})}`, - { method: 'GET', async: true }) - .then(response => response.json()) - .then(data => data.items); -} - -function getColors(token) { - return fetch(`${gapi_base}/colors?${to_params({access_token: token})}`, - { method: 'GET', async: true }) - .then(response => response.json()); -} - -function getEvent(calId, eventId, token) { - return fetch(`${gapi_base}/calendars/${calId}/events/${eventId}?${to_params({access_token: token})}`, - { method: 'GET', async: true }) - .then(response => response.json()); -} - -function getEvents(calId, token, syncToken, resultsPerRequest=100) { - let results = []; - const singleFetch = (pageToken, syncToken) => fetch(`${gapi_base}/calendars/${calId}/events?${to_params({ - access_token: token, - pageToken, - syncToken, - maxResults: resultsPerRequest - })}`, { method: 'GET', async: true }) - .then(response => { - if (response.status === 200) - return response.json(); - else if (response.status == 410) - throw GApiError.invalidSyncToken; - else throw GApiError.otherErrors; - }) - .then(data => { - results.push(...data.items); - if (data.nextPageToken) { - return singleFetch(data.nextPageToken, ''); - } else { - return ({ - nextSyncToken: data.nextSyncToken, - results - }); - } - }) - - return singleFetch('', syncToken); -} - -class GCalendar { - constructor(calId, name) { - this.calId = calId; - this.name = name; - this.token = getAuthToken(); - this.syncToken = ''; - this.cache = {}; - } - - static dateToCacheKey(date) { - return Math.floor(date / 8.64e7); - } - - getSlot(k) { - if (!this.cache[k]) - this.cache[k] = {}; - return this.cache[k]; - } - - static slotStartDate(k) { return new Date(k * 8.64e7); } - static slotEndDate(k) { return new Date((k + 1) * 8.64e7); } - - addEvent(e) { - let ks = GCalendar.dateToCacheKey(e.start); - let ke = GCalendar.dateToCacheKey(new Date(e.end.getTime() - 1)); - if (ks === ke) - this.getSlot(ks)[e.id] = { - start: e.start, - end: e.end, - id: e.id, - summary: e.summary}; - else - { - this.getSlot(ks)[e.id] = { - start: e.start, - end: GCalendar.slotEndDate(ks), - id: e.id, - summary: e.summary}; - this.getSlot(ke)[e.id] = { - start: GCalendar.slotStartDate(ke), - end: e.end, - id: e.id, - summary: e.summary}; - for (let k = ks + 1; k < ke; k++) - this.getSlot(k)[e.id] = { - start: GCalendar.slotStartDate(k), - end: GCalendar.slotEndDate(k), - id: e.id, - summary: e.summary}; - } - } - - removeEvent(e) { - let ks = GCalendar.dateToCacheKey(e.start); - let ke = GCalendar.dateToCacheKey(new Date(e.end.getTime() - 1)); - for (let k = ks; k <= ke; k++) - delete this.getSlot(k)[e.id]; - } - - getSlotEvents(k, start, end) { - let s = this.getSlot(k); - let results = []; - for (let id in s) { - if (!(s[id].start >= end || s[id].end <= start)) - { - results.push({ - id, - start: s[id].start < start ? start: s[id].start, - end: s[id].end > end ? end: s[id].end, - summary: s[id].summary - }); - } - } - return results; - } - - getCachedEvents(start, end) { - let ks = GCalendar.dateToCacheKey(start); - let ke = GCalendar.dateToCacheKey(new Date(end.getTime() - 1)); - let results = this.getSlotEvents(ks, start, end); - for (let k = ks + 1; k < ke; k++) - { - let s = this.getSlot(k); - for (let id in s) - results.push(s[id]); - } - if (ke > ks) - results.push(...this.getSlotEvents(ke, start, end)); - return results; - } - - sync() { - return this.token.then(token => getEvents(this.calId, token, this.syncToken).then(r => { - this.syncToken = r.nextSyncToken; - let pm_results = r.results.map(e => e.start ? Promise.resolve(e) : getEvent(this.calId, e.id, token)); - return Promise.all(pm_results).then(results => results.forEach(e => { - e.start = new Date(e.start.dateTime); - e.end = new Date(e.end.dateTime); - if (e.status === 'confirmed') - this.addEvent(e); - else if (e.status === 'cancelled') - this.removeEvent(e); - })); - })).catch(e => { - if (e == GApiError.invalidSyncToken) { - this.syncToken = ''; - this.sync(); - } else throw e; - }); - } - - getEvents(start, end) { - return this.sync().then(() => this.getCachedEvents(start, end)); - } -} |