1 package org.average.whereami;
3 import org.average.whereami.APIBase;
4 import org.average.whereami.Oracle;
5 import org.average.whereami.Utterance;
6 import org.average.whereami.PersistentStore;
7 import org.average.whereami.SayWhen;
9 import java.io.IOException;
10 import java.net.UnknownHostException;
11 import org.apache.http.conn.HttpHostConnectException;
13 import com.google.api.client.googleapis.json.GoogleJsonResponseException;
14 import com.google.api.client.http.HttpResponseException;
15 import com.google.api.client.util.DateTime;
16 import com.google.api.services.calendar.Calendar;
17 import com.google.api.services.calendar.CalendarRequest;
18 import com.google.api.services.calendar.model.CalendarList;
19 import com.google.api.services.calendar.model.CalendarListEntry;
20 import com.google.api.services.calendar.model.Event;
21 import com.google.api.services.calendar.model.Events;
22 import com.google.common.collect.Lists;
24 import android.content.Context;
25 import android.content.res.Resources;
26 import android.text.format.Time;
27 import android.util.Log;
29 public final class PhoneLog extends Oracle {
31 final String TAG = getClass().getName();
33 private String calendar_name;
34 private String peer_name;
35 private String calendar_id;
36 private String nocalendar;
37 private String noevents;
38 private String last_call;
39 private String in_call;
40 private String out_call;
41 private String duration;
42 private String lessthan;
43 private String minutes1;
44 private String minutes2to4;
45 private String minutes5up;
46 private SayWhen sayWhen;
47 private Calendar calendar;
49 public PhoneLog(APIBase base) {
51 nocalendar = base.res.getString(R.string.nocalendar);
52 noevents = base.res.getString(R.string.noevents);
53 last_call = base.res.getString(R.string.last_call);
54 in_call = base.res.getString(R.string.in_call);
55 out_call = base.res.getString(R.string.out_call);
56 duration = base.res.getString(R.string.duration);
57 lessthan = base.res.getString(R.string.lessthan);
58 minutes1 = base.res.getString(R.string.minutes1);
59 minutes2to4 = base.res.getString(R.string.minutes2to4);
60 minutes5up = base.res.getString(R.string.minutes5up);
61 sayWhen = new SayWhen(base.res);
62 calendar_name = base.store.get("calendar_name");
63 peer_name = base.store.get("peer_name");
64 calendar_id = base.store.get("calendar_id");
65 calendar = Calendar.builder(base.httpTransport,
67 .setHttpRequestInitializer(
68 base.accessProtectedResource)
69 .setApplicationName("WhereAmI/1.0").build();
73 public final Utterance getResult() {
75 Log.v(TAG, "entering getResult");
76 if (calendar_id == null || calendar_id == "") {
77 calendar_id = scanCalendars(calendar_name);
79 if (calendar_id == null || calendar_id == "") {
80 return new Utterance(true,
82 calendar_name + "\"");
84 base.store.put("calendar_id", calendar_id);
85 return new Utterance(true,
86 scanEvents(calendar_id, peer_name));
88 } catch (GoogleJsonResponseException e) {
89 Log.e(TAG, "GoogleJsonResponseException: " + e);
90 if (e.getResponse().getStatusCode() == 401) {
91 return new Utterance(false,
92 base.authErrorMessage + "\n" +
95 return new Utterance(false,
98 } catch (HttpResponseException e) {
99 Log.e(TAG, "HttpResponseException: " + e);
100 return new Utterance(false, e.getMessage());
101 } catch (UnknownHostException e) {
102 Log.e(TAG, "UnknownHostException: " + e);
103 return new Utterance(false,
104 base.connectErrorMessage + "\n" +
106 } catch (HttpHostConnectException e) {
107 Log.e(TAG, "HttpHostConnectException: " + e);
108 return new Utterance(false,
109 base.connectErrorMessage + "\n" +
111 } catch (IOException e) {
112 Log.e(TAG, "IOException: " + e);
113 return new Utterance(false, e.getMessage());
117 private String scanCalendars(String calendar_name)
118 throws java.io.IOException {
120 Log.v(TAG, "Entering scanCalendars for \"" +
121 calendar_name + "\"");
123 CalendarList cl = calendar.calendarList().list().execute();
125 String pt = cl.getNextPageToken();
126 Log.v(TAG, "got cl with pt=" + pt);
127 for (CalendarListEntry le : cl.getItems()) {
128 Log.v(TAG, "entry " + le.getId() + ":\"" +
129 le.getSummary() + "\"");
130 if (le.getSummary().equals(calendar_name)) {
132 //break; // get all in the log
135 if (pt != null && pt != "") {
136 cl = calendar.calendarList().list()
137 .setPageToken(pt).execute();
146 private String scanEvents(String calendar_id, String peer_name)
147 throws java.io.IOException {
148 Log.v(TAG, "Entering scanEvents for \"" +
149 peer_name + "\" in \"" + calendar_id + "\"");
151 Time ago = new Time();
152 ago.set(System.currentTimeMillis() - 604800000L);
153 Long latestStartTime = 0L;
154 Long latestStopTime = 0L;
155 Boolean latestWasOutgoing = false;
156 Boolean wasFound = false;
158 Events events = calendar.events().list(calendar_id)
159 .setTimeMin(ago.format3339(false))
163 String pt = events.getNextPageToken();
164 Log.v(TAG, "got events with pt=" + pt);
165 for (Event event : events.getItems()) {
167 String evSummary = event.getSummary();
168 Long evStart = event.getStart()
169 .getDateTime().getValue();
170 Long evStop = event.getEnd()
171 .getDateTime().getValue();
172 Log.v(TAG, "event " + evStart +
174 " : \"" + evSummary + "\"");
175 if ((evSummary.startsWith("Call To ") ||
176 evSummary.startsWith("Call From ")) &&
177 evStart > latestStartTime) {
178 latestStartTime = evStart;
179 latestStopTime = evStop;
180 latestWasOutgoing = evSummary
181 .startsWith("Call To ");
185 if (count < 100 && pt != null && pt != "") {
186 events = calendar.events().list(calendar_id)
187 .setTimeMin(ago.format3339(false))
189 .setPageToken(pt).execute();
196 return makeMessage(latestStartTime, latestStopTime,
203 private String makeMessage(Long latestStartTime, Long latestStopTime,
204 Boolean latestWasOutgoing) {
205 Time stime = new Time();
206 stime.set(latestStartTime);
207 Long dur = (latestStopTime - latestStartTime) / 60000L;
208 Log.v(TAG, "Chosen event: start " + stime +
209 " for " + dur + " min");
211 String howlong = dur.toString();
214 minutes = minutes2to4;
215 } else if ((dur / 10) == 1) {
216 minutes = minutes5up;
217 } else if ((dur % 10) == 1) {
219 } else if ((dur % 10) < 5) {
220 minutes = minutes2to4;
222 minutes = minutes5up;
225 " " + (latestWasOutgoing?out_call:in_call) +
226 " " + sayWhen.say(latestStartTime) +
227 " " + duration + " " + howlong + " " + minutes;