]> www.average.org Git - WhereAmI.git/blob - src/org/average/whereami/PhoneLog.java
make one retry on failure
[WhereAmI.git] / src / org / average / whereami / PhoneLog.java
1 package org.average.whereami;
2
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;
8
9 import java.io.IOException;
10
11 import com.google.api.client.googleapis.json.GoogleJsonResponseException;
12 import com.google.api.client.http.HttpResponseException;
13 import com.google.api.client.util.DateTime;
14 import com.google.api.services.calendar.Calendar;
15 import com.google.api.services.calendar.CalendarRequest;
16 import com.google.api.services.calendar.model.CalendarList;
17 import com.google.api.services.calendar.model.CalendarListEntry;
18 import com.google.api.services.calendar.model.Event;
19 import com.google.api.services.calendar.model.Events;
20 import com.google.common.collect.Lists;
21
22 import android.content.Context;
23 import android.content.res.Resources;
24 import android.text.format.Time;
25 import android.util.Log;
26
27 public final class PhoneLog extends Oracle {
28
29         final String TAG = getClass().getName();
30
31         private String calendar_name;
32         private String peer_name;
33         private String calendar_id;
34         private String nocalendar;
35         private String noevents;
36         private String last_call;
37         private String in_call;
38         private String out_call;
39         private String duration;
40         private String lessthan;
41         private String minutes1;
42         private String minutes2to4;
43         private String minutes5up;
44         private SayWhen sayWhen;
45         private Calendar calendar;
46
47         public PhoneLog(APIBase base) {
48                 super(base);
49                 nocalendar = base.res.getString(R.string.nocalendar);
50                 noevents = base.res.getString(R.string.noevents);
51                 last_call = base.res.getString(R.string.last_call);
52                 in_call = base.res.getString(R.string.in_call);
53                 out_call = base.res.getString(R.string.out_call);
54                 duration = base.res.getString(R.string.duration);
55                 lessthan = base.res.getString(R.string.lessthan);
56                 minutes1 = base.res.getString(R.string.minutes1);
57                 minutes2to4 = base.res.getString(R.string.minutes2to4);
58                 minutes5up = base.res.getString(R.string.minutes5up);
59                 sayWhen = new SayWhen(base.res);
60                 calendar_name = base.store.get("calendar_name");
61                 peer_name = base.store.get("peer_name");
62                 calendar_id = base.store.get("calendar_id");
63                 calendar = Calendar.builder(base.httpTransport,
64                                                         base.jsonFactory)
65                         .setHttpRequestInitializer(
66                                                 base.accessProtectedResource)
67                         .setApplicationName("WhereAmI/1.0").build();
68         }
69
70         @Override
71         public final Utterance getResult() {
72                 try {
73                         Log.v(TAG, "entering getResult");
74                         if (calendar_id == null || calendar_id == "") {
75                                 calendar_id = scanCalendars(calendar_name);
76                         }
77                         if (calendar_id == null || calendar_id == "") {
78                                 return new Utterance(true,
79                                         nocalendar + " \"" +
80                                         calendar_name + "\"");
81                         } else {
82                                 base.store.put("calendar_id", calendar_id);
83                                 return new Utterance(true,
84                                         scanEvents(calendar_id, peer_name));
85                         }
86                 } catch (GoogleJsonResponseException e) {
87                         Log.e(TAG, "GoogleJsonResponseException: " + e);
88                         if (e.getResponse().getStatusCode() == 401) {
89                                 return new Utterance(false,
90                                         base.authErrorMessage + "\n" +
91                                         e.getMessage());
92                         } else {
93                                 return new Utterance(false,
94                                         e.getMessage());
95                         }
96                 } catch (HttpResponseException e) {
97                         Log.e(TAG, "HttpResponseException: " + e);
98                         return new Utterance(false, e.getMessage());
99                 } catch (IOException e) {
100                         Log.e(TAG, "IOException: " + e);
101                         return new Utterance(false, e.getMessage());
102                 }
103         }
104
105         private String scanCalendars(String calendar_name)
106                                                 throws java.io.IOException {
107                 String res = "";
108                 Log.v(TAG, "Entering scanCalendars for \"" +
109                         calendar_name + "\"");
110
111                 CalendarList cl = calendar.calendarList().list().execute();
112                 while (true) {
113                         String pt = cl.getNextPageToken();
114                         Log.v(TAG, "got cl with pt=" + pt);
115                         for (CalendarListEntry le : cl.getItems()) {
116                                 Log.v(TAG, "entry " + le.getId() + ":\"" +
117                                         le.getSummary() + "\"");
118                                 if (le.getSummary().equals(calendar_name)) {
119                                         res = le.getId();
120                                         //break; // get all in the log
121                                 }
122                         }
123                         if (pt != null && pt != "") {
124                                 cl = calendar.calendarList().list()
125                                         .setPageToken(pt).execute();
126                         } else {
127                                 break;
128                         }
129                 }
130
131                 return res;
132         }
133
134         private String scanEvents(String calendar_id, String peer_name)
135                                                 throws java.io.IOException {
136                 Log.v(TAG, "Entering scanEvents for \"" +
137                         peer_name + "\" in \"" + calendar_id + "\"");
138                 Integer count = 0;
139                 Time ago = new Time();
140                 ago.set(System.currentTimeMillis() - 604800000L);
141                 Long latestStartTime = 0L;
142                 Long latestStopTime = 0L;
143                 Boolean latestWasOutgoing = false;
144                 Boolean wasFound = false;
145
146                 Events events = calendar.events().list(calendar_id)
147                         .setTimeMin(ago.format3339(false))
148                         .setQ(peer_name)
149                         .execute();
150                 while (true) {
151                         String pt = events.getNextPageToken();
152                         Log.v(TAG, "got events with pt=" + pt);
153                         for (Event event : events.getItems()) {
154                                 count++;
155                                 String evSummary = event.getSummary();
156                                 Long evStart = event.getStart()
157                                                 .getDateTime().getValue();
158                                 Long evStop = event.getEnd()
159                                                 .getDateTime().getValue();
160                                 Log.v(TAG, "event " + evStart +
161                                         " - " + evStop +
162                                         " : \"" + evSummary + "\"");
163                                 if ((evSummary.startsWith("Call To ") ||
164                                      evSummary.startsWith("Call From ")) &&
165                                     evStart > latestStartTime) {
166                                                 latestStartTime = evStart;
167                                                 latestStopTime = evStop;
168                                                 latestWasOutgoing = evSummary
169                                                         .startsWith("Call To ");
170                                                 wasFound = true;
171                                 }
172                         }
173                         if (count < 100 && pt != null && pt != "") {
174                                 events = calendar.events().list(calendar_id)
175                                         .setTimeMin(ago.format3339(false))
176                                         .setQ(peer_name)
177                                         .setPageToken(pt).execute();
178                         } else {
179                                 break;
180                         }
181                 }
182
183                 if (wasFound) {
184                         return makeMessage(latestStartTime, latestStopTime,
185                                                 latestWasOutgoing);
186                 } else {
187                         return noevents;
188                 }
189         }
190
191         private String makeMessage(Long latestStartTime, Long latestStopTime,
192                                         Boolean latestWasOutgoing) {
193                 Time stime = new Time();
194                 stime.set(latestStartTime);
195                 Long dur = (latestStopTime - latestStartTime) / 60000L;
196                 Log.v(TAG, "Chosen event: start " + stime +
197                         " for " + dur + " min");
198                 String minutes;
199                 String howlong = dur.toString();
200                 if (dur == 0) {
201                         howlong = lessthan;
202                         minutes = minutes2to4;
203                 } else if ((dur / 10) == 1) {
204                         minutes = minutes5up;
205                 } else if ((dur % 10) == 1) {
206                         minutes = minutes1;
207                 } else if ((dur % 10) < 5) {
208                         minutes = minutes2to4;
209                 } else {
210                         minutes = minutes5up;
211                 }
212                 return last_call +
213                         " " + (latestWasOutgoing?out_call:in_call) +
214                         " " + sayWhen.say(latestStartTime) +
215                         " " + duration + " " + howlong + " " + minutes;
216         }
217 }