1 package de.dhbwloe.campusapp.vorlesungen;
4 import android.util.Log;
6 import net.fortuna.ical4j.model.Calendar;
7 import net.fortuna.ical4j.model.Component;
8 import net.fortuna.ical4j.model.Property;
10 import java.text.DateFormat;
11 import java.text.ParseException;
12 import java.text.SimpleDateFormat;
13 import java.util.ArrayList;
14 import java.util.Date;
15 import java.util.ListIterator;
16 import java.util.Locale;
18 import de.dhbwloe.campusapp.CampusAppContext;
19 import de.dhbwloe.campusapp.network.IscRequestHelper;
20 import de.dhbwloe.campusapp.search.SearchIndices;
23 * Created by pk910 on 19.01.2016.
25 public class CalendarManager extends IscRequestHelper {
26 private static final String[][] PLAN_SOURCES = {
27 {"STUV", "https://www.google.com/calendar/ical/asta.dhbw.de_c0g35t6hrh16kr4ankrqg2rdm4%40group.calendar.google.com/public/basic.ics"},
30 private CampusAppContext AppContext;
31 private boolean bRequestRunning = false;
32 private boolean bFastSynchronisation = false;
33 private String sCourseName;
34 private String source[];
35 private ArrayList<CalendarManagerInterface> aCallbackInterfaces = new ArrayList<CalendarManagerInterface>();
37 public CalendarManager(CampusAppContext context, String courseName) {
39 sCourseName = courseName;
41 for(String src[] : PLAN_SOURCES) {
42 if(src[0].equalsIgnoreCase(courseName)) {
49 public void performFastSynchronisation(CalendarManagerInterface callback) {
50 performSynchronisation(callback, false);
53 public void performFullSynchronisation(CalendarManagerInterface callback) {
54 performSynchronisation(callback, true);
57 private void performSynchronisation(CalendarManagerInterface callback, boolean fullsync) {
58 if(sCourseName.length() == 0) {
59 callback.onCalendarUpdateFail("no course name");
63 aCallbackInterfaces.add(callback);
67 bFastSynchronisation = !fullsync;
68 bRequestRunning = true;
69 String courseCalendarUrl;
71 courseCalendarUrl = "https://webmail.dhbw-loerrach.de/owa/calendar/kal-" + sCourseName + "@dhbw-loerrach.de/Kalender/calendar.ics";
73 courseCalendarUrl = source[1];
75 requestCalenderFromWeb(courseCalendarUrl);
79 protected void onCalendarReceived(Calendar calendar) {
80 long timeFrom, timeTo;
81 long now = (new Date()).getTime() / 1000;
82 if(bFastSynchronisation) {
83 timeFrom = now - (86400 * 5);
84 timeTo = now + (86400 * 7 * 4);
86 timeFrom = now - (86400 * 365 * 3);
87 timeTo = now + (86400 * 365 * 4);
89 CourseEvent[] events = AppContext.getDatabaseManager().getCourseCalendarEvents(sCourseName, timeFrom, timeTo);
90 Log.i("CMSync", "Event count: " + events.length);
91 ArrayList<CourseEvent> newEvents = new ArrayList<CourseEvent>();
92 ArrayList<SearchIndices> newIndices = new ArrayList<SearchIndices>();
93 int lastEventIndex = 0;
94 ListIterator cIterator = calendar.getComponents().listIterator();
96 while (cIterator.hasNext()) {
97 Component event = (Component)cIterator.next();
101 prop = event.getProperty("UID");
104 uid = prop.getValue();
108 prop = event.getProperty("SEQUENCE");
111 sequence = Integer.parseInt(prop.getValue());
115 long startTime = 0, endTime = 0;
116 prop = event.getProperty("DTSTART");
118 startTime = getTimeFromTimestamp(prop.getValue());
120 Log.i("CMSync", "Parse Event: DTSTART not found!");
122 prop = event.getProperty("DTEND");
124 endTime = getTimeFromTimestamp(prop.getValue());
126 Log.i("CMSync", "Parse Event: DTEND not found!");
128 if(!(endTime > timeFrom && startTime < timeTo)) {
129 Log.i("CMSync", "Skip Entry: ("+timeFrom+" - "+timeTo+") Filter: "+startTime+" - "+endTime);
134 for(int i = lastEventIndex; i < events.length; i++) {
135 if(events[i].getUniqueId().equalsIgnoreCase(uid)) {
140 if(dbEvent == null && lastEventIndex > 0) {
141 for(int i = 0; i < lastEventIndex; i++) {
142 if(events[i].getUniqueId().equalsIgnoreCase(uid)) {
148 if(dbEvent == null) {
149 for(CourseEvent cevent : newEvents) {
150 if(cevent.getUniqueId().equalsIgnoreCase(uid)) {
157 if(dbEvent == null) {
159 Log.i("CMSync", "New Event "+uid);
160 dbEvent = new CourseEvent(sCourseName, uid, sequence, true);
161 newEvents.add(dbEvent);
163 Log.i("CMSync", "Existing Event "+uid+" ("+dbEvent.getSequenceId()+" >= "+sequence+")");
164 if(dbEvent.getSequenceId() >= sequence) {
165 continue; // skip event
167 dbEvent.setSequenceId(sequence);
170 prop = event.getProperty("SUMMARY");
172 dbEvent.setEventTitle(prop.getValue());
174 Log.i("CMSync", "Parse Event: SUMMARY not found!");
176 dbEvent.setEventFrom(startTime);
177 dbEvent.setEventTo(endTime);
179 prop = event.getProperty("LOCATION");
181 dbEvent.setEventLocation(prop.getValue());
183 Log.i("CMSync", "Parse Event: LOCATION not found!");
185 prop = event.getProperty("STATUS");
187 dbEvent.setEventStatus(prop.getValue());
189 Log.i("CMSync", "Parse Event: STATUS not found!");
191 prop = event.getProperty("RRULE");
193 dbEvent.setRecurRule(prop.getValue());
195 dbEvent.setRecurRule("");
197 prop = event.getProperty("EXDATE");
199 dbEvent.setExcludeDates(prop.getValue());
201 dbEvent.setExcludeDates("");
203 CourseGroup group = CourseGroup.GetCourseGroupByName(AppContext.getDatabaseManager(), sCourseName, dbEvent.getGroupTitle().trim());
205 dbEvent.setCourseGroup(group);
207 if(group.isNewGroup(true)) {
208 for(CalendarManagerInterface callback : aCallbackInterfaces) {
209 SearchIndices indices = callback.onGenerateCalendarSearchIndices(dbEvent);
210 if(indices != null) {
211 newIndices.add(indices);
216 dbEvent.update(AppContext.getDatabaseManager());
217 Log.i("CMSync", "Update Event: "+dbEvent.getUniqueId());
220 SearchIndices[] newIndicesArr = new SearchIndices[newIndices.size()];
221 newIndicesArr = newIndices.toArray(newIndicesArr);
222 AppContext.addSearchIndices(newIndicesArr);
224 for(CalendarManagerInterface callback : aCallbackInterfaces) {
225 callback.onCalendarUpdateDone();
227 aCallbackInterfaces.clear();
228 bRequestRunning = false;
231 private long getTimeFromTimestamp(String timestamp) {
234 DateFormat df = new SimpleDateFormat("yyyyMMdd'T'kkmmss", Locale.ENGLISH);
236 Date result = df.parse(timestamp);
237 return result.getTime()/1000;
238 } catch (ParseException e) {
239 df = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
241 Date result = df.parse(timestamp);
242 return result.getTime()/1000;
243 } catch (ParseException e2) {
244 Log.i("CMSync", "Failed parsing: "+timestamp);
251 protected void onCalendarRequestFail(int statusCode, String errorMessage) {
252 Log.i("CMSync", "Calendar Error: "+statusCode);
253 for(CalendarManagerInterface callback : aCallbackInterfaces) {
254 callback.onCalendarUpdateFail("error " + statusCode + ": " + errorMessage);
256 aCallbackInterfaces.clear();
257 bRequestRunning = false;