Skip to content

Instantly share code, notes, and snippets.

@bewest
Last active December 14, 2015 21:59
Show Gist options
  • Select an option

  • Save bewest/5155286 to your computer and use it in GitHub Desktop.

Select an option

Save bewest/5155286 to your computer and use it in GitHub Desktop.
google calendar events + glucose
{
"kind": "calendar#calendarListEntry",
"etag": "\"vnNL_X_6XYVF-jSag8p74cFkQA8/OvttNTXfCEEhzyF0tWRq2zliBcg\"",
"id": "bewest@gmail.com",
"summary": "Benjamin West",
"timeZone": "America/Los_Angeles",
"colorId": "17",
"backgroundColor": "#9a9cff",
"foregroundColor": "#000000",
"selected": true,
"accessRole": "owner",
"defaultReminders": [
{
"method": "popup",
"minutes": 10
}
],
"primary": true
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
.skeleton {
display: none;
visibility: hidden;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="//apis.google.com/js/client.js?onload=init"></script>
<script type="text/javscript" src="//apis.google.com/js/api.js"></script>
<script type="text/javscript" src="https://apis.google.com/js/auth.js?onload=init"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var key = "AIzaSyDNpgpDX4hLq2TdiBqvrKKyqmuLxqeY-L4";
var appId = 'glucose-calendar';
var clientId = '244880377962.apps.googleusercontent.com';
</script>
</head>
<body>
<h1>javascript only fetch google calendar events</h1>
<img src="1x1.gif" />
<h2>Howdy, <span class="username">???</span></h2>
<p>
This demo doesn't implement glucose fetching, just the google auth + google
query seps.
I'd like to know your email address
<span class="email">, so I can look up your calendars</span>.
In later demos, I'm also going to inspect your profile to see if I can find any
glucose records. Then I'm going to graph both events from your calendar and
your glucose records together. This assumes your are a google plus user, and
have a git <tt>phr</tt> link with a file called sugars.csv.
We use d3 to create a results row in a table for each calendar event.
</p>
<div id="content"></div>
<div id="events">
<div id="range">
<h4>Start: <span id="start"></span></h4>
<h4>End: <span id="end"></span></h4>
</div>
<table id="list">
<tbody class="skeleton">
<tr class="event">
<td><span class="v start"></span></td>
<td><span class="v end"></span></td>
<td><span class="v summary"></span></td>
<td><span class="v location"></span></td>
<td><span class="v detail"></span>
<a class="more htmlLink">more</a>
</td>
<td><span class=""></span></td>
<td> </td>
</tr>
</tbody>
<tbody="target">
</tbody>
</table>
</div>
<script type="text/javascript">
// The default "private/full" feed is used to retrieve events from
// the primary private calendar with full projection
var feedUri = 'https://www.google.com/calendar/feeds/bewest@gmail.com/private/full';
var scope = "https://www.google.com/calendar/feeds/";
scope = scope + ' ' + "https://www.googleapis.com/auth/plus.me";
scope = scope + ' ' + "https://www.googleapis.com/auth/userinfo.email";
scope = scope + ' ' + "https://www.googleapis.com/auth/userinfo.profile";
var loginUrl = 'https://accounts.google.com/o/oauth2/auth';
var cb_url = "http://localhost:4545/#oauthCallback";
var opts = {
};
gapi.load('auth', init);
function init ( ) {
// console.log('init', 'setting api key', this, arguments, gapi);
handleClientLoad( );
// gapi.client.setApiKey(key);
// $(document).trigger('auth');
}
$(document).on('auth', function ( ) {
console.log('got auth event from head');
checkAuth( );
});
// Error handler to be invoked when getEventsFeed() produces an error
var handleError = function(error) {
console.log(error);
}
// google.setOnLoadCallback(setup_login);
function handleClientLoad() {
// console.log('setting api key');
gapi.client.setApiKey(key);
window.setTimeout(checkAuth,1);
}
function checkAuth() {
// console.log('checking auth... performing auth');
gapi.auth.authorize({client_id: clientId, scope: scope }, handleAuthResult);
}
function handleAuthResult(authResult) {
// console.log('auth result', this, arguments);
if (authResult && !authResult.error) {
// console.log('success logging in');
makeApiCall();
} else {
// console.log('error logging in', authResult.error);
}
}
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scope, immediate: false}, handleAuthResult);
return false;
}
var user = { };
function makeApiCall( ) {
// console.log("hooray, can fetch events?");
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp) {
// console.log('resp', resp);
var heading = document.createElement('h4');
var image = document.createElement('img');
image.src = resp.image.url;
heading.appendChild(image);
heading.appendChild(document.createTextNode(resp.displayName));
document.getElementById('content').appendChild(heading);
});
});
gapi.client.load('oauth2', 'v2', function() {
var request = gapi.client.oauth2.userinfo.v2.me.get( );
request.execute(function (resp) {
// console.log('user info', resp);
user.info = resp;
jQuery('.username').text(resp.result.email);
jQuery('.email').text(resp.result.email).trigger('email');
});
});
gapi.client.load('calendar', 'v3', function() {
// console.log('loaded google calendar support?', this, arguments);
var request = gapi.client.calendar.calendarList.list( );
request.execute(function (resp) {
// console.log('got a calendars list response', resp );
});
});
}
jQuery(document).on('email', function ( ) {
// console.log('email known, fetching calendar data', 'user', user);
var email = user.info.email;
gapi.client.load('calendar', 'v3', function() {
var opts = {
calendarId: email,
singleEvents: 'true',
orderBy: 'startTime',
timeMin: '2010-01-01T00:00:00Z'
};
// console.log('entry list opts', opts);
var events_list = gapi.client.calendar.events.list(opts);
events_list.execute(function (resp) {
// console.log('got a events list response', resp);
user.events = resp.result.items;
list_events(user.events);
});
});
});
function dup_row(skel) {
// console.log('return factory for dup row', this, arguments);
return (function (data, i) {
// console.log('dup row', this, arguments);
var row = skel.clone(true).addClass('row');
for (x in data) {
if (data[x].toString( ) != '[object Object]') {
row.find('.v.' + x).text(data[x]);
} else {
// console.log('???', x, data[x]);
}
}
row.find('.end').text(data.end.dateTime || data.end.date);
row.find('.start').text(data.start.dateTime || data.start.date);
row.find('A.htmlLink').attr('href', data.htmlLink);
// console.log('done with row', row);
return d3.select(jQuery(this).append(row)[0]);
});
}
var iso_day = d3.time.format("%Y-%m-%d");
var parse_dt = /(.*)-(\d\d):(\d\d)$/;
var iso_daytime = d3.time.format("%Y-%m-%dT%H:%M:%S");
function parse_date(d) {
if (d.start.dateTime) {
var p = d.start.dateTime.match(parse_dt);
var s = p[1];
return iso_daytime.parse(s);
}
return iso_day.parse(d.start.date);
};
function list_events(list) {
// console.log('working with list', list);
list.forEach(function (d) { d.ts = parse_date(d); });
var skeleton = jQuery('#list .skeleton').clone(true).removeClass('skeleton');
var duper = dup_row(skeleton);
var timeRange = d3.extent(list, function(d) {
// console.log(this, arguments);
return d.ts; });
jQuery('#range #start').text(timeRange[0]);
jQuery('#range #end').text(timeRange[1]);
var rows = d3.select('#list').selectAll('.row').data(list).enter( ).select(duper);
}
</script>
</body>
</html>
@bewest
Copy link
Author

bewest commented Mar 23, 2013

This is a "live" version of the static demo

Running over http is not recommended... need to host this somewhere proper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment