From 9051371503299de634de1110446712b7f675c276 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 19 Nov 2012 20:50:26 +0100 Subject: [PATCH] finally fixed algo --- index.php | 141 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 61 deletions(-) diff --git a/index.php b/index.php index 43e4058..31b5305 100644 --- a/index.php +++ b/index.php @@ -2,18 +2,19 @@ require_once 'google-api/Google_Client.php'; require_once 'google-api/contrib/Google_CalendarService.php'; +error_reporting(E_ALL); session_start(); $client = new Google_Client(); -$client->setApplicationName("Google Calendar PHP Starter Application"); +$client->setApplicationName("aLAZYsis"); // Visit https://code.google.com/apis/console?api=calendar to generate your // client id, client secret, and to register your redirect uri. $client->setClientId('881243075742.apps.googleusercontent.com'); $client->setClientSecret('xBRiQQeDPjBF1hR6PO71ju0h'); -$client->setRedirectUri('http://www.steffenvogel.de/demos/lazymeter'); +$client->setRedirectUri('http://t0.0l.de/aLAZYsis'); $client->setDeveloperKey('AIzaSyCgi7GeXk0FQpYgROFnVmd5lG0_t1USM-M'); -$cal = new Google_CalendarService($client); +$service['cal'] = new Google_CalendarService($client); if (isset($_GET['logout'])) { unset($_SESSION['token']); @@ -30,8 +31,9 @@ if (isset($_SESSION['token'])) { } if ($client->getAccessToken()) { - $busy = array(); - $calItems = array(); + $sum = array('total' => 0); + $active = array(); + $calBlacklist = array( "#contacts@group.v.calendar.google.com", "#weeknum@group.v.calendar.google.com", @@ -40,93 +42,110 @@ if ($client->getAccessToken()) { ); // filter calendars - $calList = array_filter($cal->calendarList->listCalendarList()['items'], function($cal) use ($calBlacklist) { + $calList = array_filter($service['cal']->calendarList->listCalendarList()->getItems(), function($cal) { + global $calBlacklist; + global $sum; + global $active; + foreach ($calBlacklist as $black) { - if (strpos($cal['id'], $black) !== false) { + if (strpos($cal->getId(), $black) !== false) { return false; } } + $sum[$cal->getId()] = 0; + $active[$cal->getId()] = 0; + return true; }); - // fetch free/busy times - foreach ($calList as $calendar) { - $item = new Google_FreeBusyRequestItem(); - $item->setId($calendar['id']); - array_push($calItems, $item); - } - - $fbReq = new Google_FreeBusyRequest(); - $timezone = new DateTimeZone($cal->settings->get('timezone')['value']); + // fetch events + $timezone = new DateTimeZone($service['cal']->settings->get('timezone')->getValue()); $midnight = new DateTime("today", $timezone); $tomorrow = new DateTime("tomorrow", $timezone); - $fbReq->setTimeMin(date('c', $midnight->getTimestamp())); - $fbReq->setTimeMax(date('c', $tomorrow->getTimestamp())); - $fbReq->setItems($calItems); + $options = array( + 'timeMin' => date('c', $midnight->getTimestamp()), + 'timeMax' => date('c', $tomorrow->getTimestamp()), + 'singleEvents' => true + ); - $fb = $cal->freebusy->query($fbReq); + // parse & aggregate event list + $stack = array(); + foreach ($calList as $cal) { + $pageToken = ''; + do { + $events = $service['cal']->events->listEvents($cal->getId(), + ($pageToken) ? array('pageToken' => $pageToken) : $options); - // aggregate free/busy events - foreach ($fb['calendars'] as $id => $cal) { - array_walk($cal['busy'], function(&$entry) use ($id) { - $entry['cal'] = $id; + if ($events->getItems()) { + foreach ($events->getItems() as $item) { + if ($item->getStart()->getDateTime()) { + $event['calId'] = $cal->getId(); + $event['summary'] = $item->getSummary(); - // convert rfc datetime strings to unix timestamps - $entry['start_ts'] = new DateTime($entry['start']); - $entry['end_ts'] = new DateTime($entry['end']); - }); + $event['action'] = 'start'; + $event['ts'] = new DateTime($item->getStart()->getDateTime()); + array_push($stack, $event); + + $event['action'] = 'end'; + $event['ts'] = new DateTime($item->getEnd()->getDateTime()); + array_push($stack, $event); + } + } + } + + $pageToken = $events->getNextPageToken(); + } while ($pageToken); - $busy = array_merge($busy, $cal['busy']); } - // filter full-time events - $busy = array_filter($busy, function() { - return true; + // sort according to event start time, then end time + usort($stack, function($a, $b) { + if ($a['ts'] == $b['ts']) return 0; + else return ($a['ts'] < $b['ts']) ? -1 : 1; }); - // sort with start time - usort($busy, function($a, $b) { - if ($a['start_ts'] == $b['start_ts']) return 0; - else return ($a['start_ts'] < $b['start_ts']) ? -1 : 1; - }); - $duration = 0; - for ($i = 0; $i < count($busy); $i++) { - $start = $busy[$i]['start_ts']->getTimestamp(); - $end = $busy[$i]['end_ts']->getTimestamp(); + // start analysis + for ($i = 0; $i < count($stack); $i++) { + $current = $stack[$i]; - for ($j = $i+1; $j < count($busy); $j++) { - if ($busy[$j]['start_ts'] <= $end && $busy[$j]['end_ts'] > $end) { - echo "found overlap between $i and $j
"; + if ($i >= 1) { + $filtered = array_filter($active); + $count = count($filtered); - $end = $busy[$j]['end_ts']; - $i = $j; + $prev = $stack[$i-1]; + $diff = $current['ts']->getTimestamp() - $prev['ts']->getTimestamp(); + + foreach (array_keys($filtered) as $calId) { + $sum[$calId] += $diff / $count; + } + + if ($count > 0) { + $sum['total'] += $diff; } } - $diff = $end - $start; + if ($current['action'] == 'start') { + $active[$current['calId']]++; + } - echo "adding $i with dur = " . $diff . "
"; - - $duration += $diff; + if ($current['action'] == 'end') { + $active[$current['calId']]--; + } } - $sleep = 7*60*60; - $awake = $duration - $sleep; - $percentage = $awake / (24*60*60-$sleep); + $json = array(); + foreach ($sum as $id => $hours) { + if ($id == 'total') continue; - print "

Busy

"; - print_pre($busy); - print "

Result

- "; + array_push($json, array($id, $hours/3600)); + } + header('Content-Type: application/json'); + echo json_encode($json); $_SESSION['token'] = $client->getAccessToken(); } else {