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