I need help with a simple Google Apps Script I've written. The script finds days on which no all-day events have been scheduled, across multiple calendars.
I'm fairly certain the main issue is the fact that I'm making an API call to get all owned calendars, then I'm making 5 API calls on each of these calendars to retrieve each day's (Mon - Fri) events.
Currently, it takes about 60 seconds to run on an account with 11 owned calendars. Is there anything that can be done to optimize?
var one_day = 86400000; //24 * 60 * 60 * 1000
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var startDay = nextMonday(new Date());
// Script-as-app template.
function doGet() {
var app = UiApp.createApplication();
var button = app.createButton('Find Blanks').setId('button');
var loader = app.createImage('http://preloaders.net/preloaders/496/Flip%20Flop.gif').setVisible(false).setId('loader');
var blanks = app.createHTML().setId('blanksArea').setHTML('Click button to find calendar blanks for week of ' + startDay);
app.add(button);
app.add(app.createHTML('<br/>'));
app.add(loader);
app.add(blanks);
var clientHandler = app.createClientHandler().forEventSource().setEnabled(false).forTargets(loader).setVisible(true).forTargets(blanks).setHTML('Processing for week of ' + startDay);
var handler = app.createServerHandler('serverHandler');
button.addClickHandler(clientHandler);
button.addClickHandler(handler);
return app;
}
function serverHandler(e) {
var app = UiApp.getActiveApplication();
var button = app.getElementById('button');
var blanks = app.getElementById('blanksArea');
var calendarsWithBlanks = getCalendarsWithBlanks();
blanks.setHTML(calendarsWithBlanks.length ? calendarsWithBlanks.join('<br/>') : 'There are no blanks');
app.getElementById('loader').setVisible(false);
button.setEnabled(true);
app.close();
return app;
}
function getCalendarsWithBlanks()
{
var calendars = CalendarApp.getAllOwnedCalendars();
var calendarsWithBlanks = [];
for(var i = 0; i < calendars.length; i++)
{
var calendar = calendars[i];
var calendarName = calendar.getName();
var blankDays = checkCalendarForBlanks(calendar, startDay);
if(blankDays.length)
{
calendarsWithBlanks.push(calendarName + ' has ' + blankDays.join(', ') + ' blank')
}
}
return calendarsWithBlanks;
}
function checkCalendarForBlanks(calendar, startDay)
{
var blankDays = [];
for(var d = 0; d < 5; d++)
{
var currDay = new Date(startDay.getTime() + (d * one_day));
var events = getEventsForDay(calendar, currDay);
var foundAllDayEvent = false;
for(var e = 0; e < events.length; e++)
{
if(events[e].isAllDayEvent())
{
foundAllDayEvent = true;
break;
}
}
if(!foundAllDayEvent)
{
blankDays.push(days[currDay.getDay()]);
}
}
return blankDays;
}
function nextMonday(date)
{
var today = date;
today.setUTCHours(0);
today.setMinutes(0);
today.setSeconds(0);
today.setMilliseconds(0);
var day = today.getDay();
var offset = 8 - day
var next_monday = new Date(today.getFullYear(), today.getMonth(), today.getDate()+offset);
return next_monday;
}
function getEventsForDay(calendar, date)
{
/* !!!KLUDGE ALERT!!!
* This is a kludge. The API method getEventsForDay is wonky: http://stackoverflow.com/questions/11870304/google-apps-script-geteventsforday-returns-invalid-recurring-events
*/
var startOfDay = new Date(date.getTime());
startOfDay.setUTCHours(0);
startOfDay.setMinutes(0);
startOfDay.setSeconds(0);
startOfDay.setMilliseconds(0);
var endOfDay = new Date(startOfDay.getTime() + one_day);
return calendar.getEvents(startOfDay, endOfDay)
}