aboutsummaryrefslogtreecommitdiff
path: root/src/net/cbaines/suca/SotonCalendarParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/cbaines/suca/SotonCalendarParser.java')
-rw-r--r--src/net/cbaines/suca/SotonCalendarParser.java581
1 files changed, 492 insertions, 89 deletions
diff --git a/src/net/cbaines/suca/SotonCalendarParser.java b/src/net/cbaines/suca/SotonCalendarParser.java
index 6e9a9ac..beb7aa5 100644
--- a/src/net/cbaines/suca/SotonCalendarParser.java
+++ b/src/net/cbaines/suca/SotonCalendarParser.java
@@ -7,30 +7,36 @@ import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URISyntaxException;
import java.text.ParseException;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.Calendar;
-import java.util.GregorianCalendar;
import net.fortuna.ical4j.data.CalendarParser;
import net.fortuna.ical4j.data.ContentHandler;
import net.fortuna.ical4j.data.ParserException;
import net.fortuna.ical4j.model.Component;
+import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.Property;
+import net.fortuna.ical4j.util.UidGenerator;
+/**
+ * http://www.kanzaki.com/docs/ical/
+ *
+ * @author Henco Appel
+ * @author Christopher Baines <cbaines8@gmail.com>
+ *
+ */
public class SotonCalendarParser implements CalendarParser {
- private final static String TAG = "SotonCalendarParser";
- /**
- * Start dates for the Autumn term's for each Academic Year starting from
- * 2011 to
- */
- // private static final GregorianCalendar[] startOfAutumnTerm = {new
- // GregorianCalendar(2011, Calendar.SEPTEMBER, 19),new
- // GregorianCalendar(2011, Calendar.SEPTEMBER, 19)
+ private boolean MERGE_DUPLICATE_EVENTS_WITH_SEPARATE_LOCATIONS = true;
+
+ private boolean SHOW_SEMESTER_WEEKS = true;
+ private boolean SHOW_SEMESTERS = true;
+ private boolean SHOW_TERMS = true;
- private Calendar startOfYear = new GregorianCalendar(2011,
- Calendar.SEPTEMBER, 19);
+ private boolean MERGE_HEADERS = false;
+
+ private final static String TAG = "SotonCalendarParser";
public void parse(InputStream in, ContentHandler handler)
throws IOException, ParserException {
@@ -42,46 +48,390 @@ public class SotonCalendarParser implements CalendarParser {
parse(new BufferedReader(in, 3), handler);
}
+ /**
+ * Parse the csv file
+ *
+ * Line:
+ * "Monday","09:00","13:00","COMP1004 Comp Lab1/01","Weal, M","25 / 1009"
+ * ,"1-11, 15"
+ *
+ * @param in
+ * @param handler
+ * @throws IOException
+ * @throws ParserException
+ */
public void parse(BufferedReader in, ContentHandler handler)
throws IOException, ParserException {
-
try {
+ log("Year " + Calendar.getInstance().get(Calendar.YEAR));
+ int currentYear = Calendar.getInstance().get(Calendar.YEAR);
+
handler.startCalendar();
handler.startProperty(Property.NAME);
- handler.propertyValue("2.0");
+ handler.propertyValue("Timetable");
handler.endProperty(Property.NAME);
+ handler.startProperty(Property.VERSION);
+ handler.propertyValue("2.0");
+ handler.endProperty(Property.VERSION);
handler.startProperty(Property.PRODID);
handler.propertyValue("-//Chris Baines + Henco Appel//SouthamptonUniversityOrganiser//EN");
handler.endProperty(Property.NAME);
+
+ Calendar startOfTerm = UniTermDates.getStartOf(
+ UniTermDates.SEMESTER_1, currentYear - 1);
+
+ logCalendar("Semester 1 start time ", startOfTerm);
+
+ int day = startOfTerm.get(Calendar.DAY_OF_WEEK);
+ int difference = 0;
+ if (day == Calendar.MONDAY) {
+ difference = 0;
+ } else if (day == Calendar.TUESDAY) {
+ difference = -1;
+ } else if (day == Calendar.WEDNESDAY) {
+ difference = -2;
+ } else if (day == Calendar.THURSDAY) {
+ difference = -3;
+ } else if (day == Calendar.FRIDAY) {
+ difference = -4;
+ } else if (day == Calendar.SATURDAY) {
+ difference = -5;
+ } else if (day == Calendar.SUNDAY) {
+ difference = -6;
+ } else {
+ log("Error calculating difference");
+ }
+ startOfTerm.add(Calendar.DAY_OF_WEEK, difference);
+
+ logCalendar("Week 0 start time ", startOfTerm);
+
+ UidGenerator ug = new UidGenerator("1");
+
+ ArrayList<Event> events = new ArrayList<Event>();
+
String line;
while ((line = in.readLine()) != null) {
if (!line.trim().equals("")) {
- System.out.println("Line: " + line);
- String[] lecture = line.split("\",\"");
- // Remove the starting " off of the date
- lecture[0] = lecture[0].substring(1,
- lecture[0].length() - 1);
- // Remove the trailing " off of the weeks
- lecture[6] = lecture[6].substring(0,
- lecture[0].length() - 1);
- String[] people = lecture[4].split(",");
- String[] weeks = lecture[6].split("[\\-,]");
- // System.out.println(Arrays.toString(lecture));
- for (int i = 0; i < weeks.length; i += 2) {
- int weeksStart = Integer.parseInt(weeks[i].trim());
- int weeksEnd = weeksStart;
- if (i + 1 < weeks.length) {
- weeksEnd = Integer.parseInt(weeks[i + 1].trim());
+ log(line);
+ String[] lectureInfo = line.split("\",\"");
+ lectureInfo[0] = lectureInfo[0].substring(1,
+ lectureInfo[0].length());
+ lectureInfo[6] = lectureInfo[6].substring(0,
+ lectureInfo[6].length() - 1);
+ Event event = new Event(lectureInfo);
+ int index;
+ if ((index = events.indexOf(event)) != -1
+ && MERGE_DUPLICATE_EVENTS_WITH_SEPARATE_LOCATIONS) {
+ event = events.get(index);
+ if (!event.location.equals(lectureInfo[5])) {
+ event.location = event.location + " and "
+ + lectureInfo[5];
}
- for (int week = weeksStart; week <= weeksEnd; week++) {
- // System.out.println(week +
- // Arrays.toString(lecture));
- createEvent(lecture, handler, week);
+ events.set(index, event);
+ } else {
+ events.add(event);
+ }
+ }
+ }
+
+ for (Event event : events) {
+
+ handler.startComponent(Component.VEVENT);
+ // handler.startProperty(Property.UID);
+ // handler.propertyValue(ug.generateUid().toString());
+ // handler.endProperty(Property.UID);
+
+ // Summary
+ handler.startProperty(Property.SUMMARY);
+ handler.propertyValue(event.name);
+ handler.endProperty(Property.SUMMARY);
+
+ log("Looking at lecture " + event.name);
+
+ // Time of creation
+ handler.startProperty(Property.DTSTAMP);
+ handler.propertyValue(new DateTime(java.util.Calendar
+ .getInstance().getTime()).toString());
+ handler.endProperty(Property.DTSTAMP);
+
+ // Start time
+
+ Calendar startTime = (Calendar) startOfTerm.clone();
+
+ if (event.dayOfWeek.equals("Monday")) {
+ // Nothing to do
+ } else if (event.dayOfWeek.equals("Tuesday")) {
+ startTime.add(Calendar.DAY_OF_WEEK, 1);
+ } else if (event.dayOfWeek.equals("Wednesday")) {
+ startTime.add(Calendar.DAY_OF_WEEK, 2);
+ } else if (event.dayOfWeek.equals("Thursday")) {
+ startTime.add(Calendar.DAY_OF_WEEK, 3);
+ } else if (event.dayOfWeek.equals("Friday")) {
+ startTime.add(Calendar.DAY_OF_WEEK, 4);
+ } else {
+ log("ERROR!!!");
+ }
+
+ String startTimeString = event.startTime;
+ String[] startTimeStringParts = startTimeString.split(":");
+ int startHour = Integer.valueOf(startTimeStringParts[0]);
+ int startMinute = Integer.valueOf(startTimeStringParts[1]);
+
+ startTime.set(Calendar.HOUR_OF_DAY, startHour);
+ startTime.set(Calendar.MINUTE, startMinute);
+
+ String[] weeks = event.weeks.split(",");
+
+ String startWeekStr = weeks[0].split("-")[0];
+ int startWeek = Integer.valueOf(startWeekStr);
+
+ startTime.add(Calendar.WEEK_OF_YEAR, startWeek);
+
+ handler.startProperty(Property.DTSTART);
+ handler.propertyValue(new DateTime(startTime.getTime())
+ .toString());
+ handler.endProperty(Property.DTSTART);
+
+ logCalendar(" Start time (week " + startWeek + ") ", startTime);
+
+ // End time
+
+ String endTimeString = event.endTime;
+ String[] endTimeStringParts = endTimeString.split(":");
+ int endHour = Integer.valueOf(endTimeStringParts[0]);
+ int endMinute = Integer.valueOf(endTimeStringParts[1]);
+
+ Calendar endTime = (Calendar) startTime.clone();
+ endTime.set(Calendar.HOUR_OF_DAY, endHour);
+ endTime.set(Calendar.MINUTE, endMinute);
+
+ handler.startProperty(Property.DTEND);
+ handler.propertyValue(new DateTime(endTime.getTime())
+ .toString());
+ handler.endProperty(Property.DTEND);
+
+ logCalendar(" End time ", endTime);
+
+ // Weeks
+
+ StringBuilder rDate = new StringBuilder();
+
+ for (String rule : weeks) {
+ log(" Rule: " + rule);
+ Calendar recurance = null;
+
+ if (rule.contains("-")) {
+ String[] parts = rule.split("\\-");
+
+ String part1Str = parts[0].trim();
+ String part2Str = parts[1].trim();
+
+ int part1 = Integer.valueOf(part1Str);
+ int part2 = Integer.valueOf(part2Str);
+
+ for (int i = part1; i <= part2; i++) {
+ recurance = (Calendar) startOfTerm.clone();
+
+ if (event.dayOfWeek.equals("Monday")) {
+ // Nothing to do
+ } else if (event.dayOfWeek.equals("Tuesday")) {
+ recurance.add(Calendar.DAY_OF_WEEK, 1);
+ } else if (event.dayOfWeek.equals("Wednesday")) {
+ recurance.add(Calendar.DAY_OF_WEEK, 2);
+ } else if (event.dayOfWeek.equals("Thursday")) {
+ recurance.add(Calendar.DAY_OF_WEEK, 3);
+ } else if (event.dayOfWeek.equals("Friday")) {
+ recurance.add(Calendar.DAY_OF_WEEK, 4);
+ } else {
+ log("ERROR!!!");
+ }
+
+ recurance.set(Calendar.HOUR_OF_DAY, startHour);
+ recurance.set(Calendar.MINUTE, startMinute);
+
+ recurance.add(Calendar.WEEK_OF_YEAR, i);
+
+ rDate.append(new DateTime(recurance.getTime())
+ .toString());
+ rDate.append(",");
+
+ logCalendar(" Recurance (week " + i + ") ",
+ recurance);
}
+ } else {
+ int week = Integer.valueOf(rule.trim());
+
+ recurance = (Calendar) startOfTerm.clone();
+ recurance.add(Calendar.WEEK_OF_YEAR, week);
+
+ rDate.append(new DateTime(recurance.getTime())
+ .toString());
+ rDate.append(",");
+
+ logCalendar(" Recurance (week " + week + ") ",
+ recurance);
}
}
+ if (rDate.length() != 0) {
+ rDate.deleteCharAt(rDate.length() - 1); // Delete the last ,
+
+ handler.startProperty(Property.RDATE);
+ handler.propertyValue(rDate.toString());
+ handler.endProperty(Property.RDATE);
+ }
+
+ // handler.startProperty(Property.ORGANIZER);
+ // handler.propertyValue("Organiser");
+ // handler.endProperty(Property.ORGANIZER);
+
+ String[] people = event.lecturer.split(",");
+ for (String person : people) {
+ // log("Person: " + person);
+ }
+
+ String[] locationBits = event.location.split("/");
+
+ handler.startProperty(Property.LOCATION);
+ handler.propertyValue(event.location);
+ handler.endProperty(Property.LOCATION);
+ // The following infomation should be fetched from the
+ // Southampton University Map App, through the content
+ // provider, or from the data.southampton site via a sparqul
+ // query.
+ // handler.startProperty(Property.GEO);
+ // handler.propertyValue(lat + ":" + lng);
+ // handler.endProperty(Property.GEO);
+
+ handler.endComponent(Component.VEVENT);
+
}
+
+ if (MERGE_HEADERS) {
+ for (int year = UniTermDates.YEAR_BEGINING_2011; year < UniTermDates.YEAR_BEGINING_2019; year++) {
+ if (SHOW_SEMESTER_WEEKS) {
+
+ }
+ }
+ } else {
+ ArrayList<Integer> periods = new ArrayList<Integer>(5);
+
+ String[] periodNames = { "Autumn Term", "Spring Term",
+ "Summer Term", "Semester 1", "Semester 2" };
+
+ if (SHOW_SEMESTERS) {
+ periods.add(UniTermDates.SEMESTER_1);
+ periods.add(UniTermDates.SEMESTER_2);
+ }
+
+ if (SHOW_TERMS) {
+ periods.add(UniTermDates.AUTUMN_TERM);
+ periods.add(UniTermDates.SPRING_TERM);
+ periods.add(UniTermDates.SUMMER_TERM);
+ }
+
+ for (int period : periods) {
+ for (int year = UniTermDates.YEAR_BEGINING_2011; year < UniTermDates.YEAR_BEGINING_2019; year++) {
+
+ log("Looking at " + periodNames[period]);
+
+ handler.startComponent(Component.VEVENT);
+ // handler.startProperty(Property.UID);
+ // handler.propertyValue(ug.generateUid().toString());
+ // handler.endProperty(Property.UID);
+
+ // Summary
+ handler.startProperty(Property.SUMMARY);
+ handler.propertyValue(periodNames[period]);
+ handler.endProperty(Property.SUMMARY);
+
+ // Time of creation
+ handler.startProperty(Property.DTSTAMP);
+ handler.propertyValue(new DateTime(java.util.Calendar
+ .getInstance().getTime()).toString());
+ handler.endProperty(Property.DTSTAMP);
+
+ // Start time
+
+ logCalendar(" Start time " + periodNames[period] + " ",
+ UniTermDates.getStartOf(period, year));
+
+ handler.startProperty(Property.DTSTART);
+ handler.parameter("VALUE", "DATE");
+ handler.propertyValue(new Date(UniTermDates.getStartOf(
+ period, year).getTime()).toString());
+ handler.endProperty(Property.DTSTART);
+
+ // End time
+
+ logCalendar(" End time " + periodNames[period] + " ",
+ UniTermDates.getEndOf(period, year));
+
+ handler.startProperty(Property.DTEND);
+ handler.parameter("VALUE", "DATE");
+ handler.propertyValue(new Date(UniTermDates.getEndOf(
+ period, year).getTime()).toString());
+ handler.endProperty(Property.DTEND);
+
+ handler.endComponent(Component.VEVENT);
+ }
+ }
+
+ if (SHOW_SEMESTER_WEEKS) {
+
+ for (int period : periods) {
+ for (int year = UniTermDates.YEAR_BEGINING_2011; year < UniTermDates.YEAR_BEGINING_2019; year++) {
+
+ log("Looking at " + periodNames[period]);
+
+ handler.startComponent(Component.VEVENT);
+ // handler.startProperty(Property.UID);
+ // handler.propertyValue(ug.generateUid().toString());
+ // handler.endProperty(Property.UID);
+
+ // Summary
+ handler.startProperty(Property.SUMMARY);
+ handler.propertyValue(periodNames[period]);
+ handler.endProperty(Property.SUMMARY);
+
+ // Time of creation
+ handler.startProperty(Property.DTSTAMP);
+ handler.propertyValue(new DateTime(
+ java.util.Calendar.getInstance().getTime())
+ .toString());
+ handler.endProperty(Property.DTSTAMP);
+
+ // Start time
+
+ logCalendar(" Start time " + periodNames[period]
+ + " ",
+ UniTermDates.getStartOf(period, year));
+
+ handler.startProperty(Property.DTSTART);
+ handler.parameter("VALUE", "DATE");
+ handler.propertyValue(new Date(UniTermDates
+ .getStartOf(period, year).getTime())
+ .toString());
+ handler.endProperty(Property.DTSTART);
+
+ // End time
+
+ logCalendar(" End time " + periodNames[period]
+ + " ", UniTermDates.getEndOf(period, year));
+
+ handler.startProperty(Property.DTEND);
+ handler.parameter("VALUE", "DATE");
+ handler.propertyValue(new Date(UniTermDates
+ .getEndOf(period, year).getTime())
+ .toString());
+ handler.endProperty(Property.DTEND);
+
+ handler.endComponent(Component.VEVENT);
+ }
+ }
+ }
+ }
+
handler.endCalendar();
} catch (ParseException e) {
e.printStackTrace();
@@ -92,60 +442,113 @@ public class SotonCalendarParser implements CalendarParser {
}
}
- // void String getRecuranceRule(String weeks) {
- // StringBuilder rrule = new StringBuilder(50);
- // rrule.append("RRULE:FREQ=WEEKLY;");
- //
- // }
-
- private void createEvent(String[] lecture, ContentHandler handler, int week)
- throws ParseException, URISyntaxException, IOException,
- NumberFormatException {
- handler.startComponent(Component.VEVENT);
- handler.startProperty(Property.UID);
- handler.propertyValue("email");
- handler.endProperty(Property.UID);
- handler.startProperty(Property.DTSTAMP);
- handler.propertyValue(new DateTime(java.util.Calendar.getInstance()
- .getTime()).toString());
- handler.endProperty(Property.DTSTAMP);
- // handler.startProperty(Property.ORGANIZER);
- // handler.propertyValue("Organiser");
- // handler.endProperty(Property.ORGANIZER);
- Calendar time = (Calendar) startOfYear.clone();
- int day = 0;
- if (lecture[0].equals("Monday")) {
- day = 0;
- } else if (lecture[0].equals("Tuesday")) {
- day = 1;
- } else if (lecture[0].equals("Wednesday")) {
- day = 2;
- } else if (lecture[0].equals("Thursday")) {
- day = 3;
- } else if (lecture[0].equals("Friday")) {
- day = 4;
- } else {
- throw new ParseException(Arrays.toString(lecture), 0);
+ private static void logCalendar(String prefix, Calendar cal) {
+ String hour = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
+ if (hour.length() == 1) {
+ hour = "0" + hour;
+ }
+
+ String minute = String.valueOf(cal.get(Calendar.MINUTE));
+ if (minute.length() == 1) {
+ minute = "0" + minute;
}
- time.add(Calendar.DAY_OF_MONTH, day);
- time.set(Calendar.HOUR_OF_DAY,
- Integer.parseInt(lecture[1].substring(0, 2)));
- time.add(Calendar.WEEK_OF_YEAR, week);
- handler.startProperty(Property.DTSTART);
- handler.propertyValue(new DateTime(time.getTime()).toString());
- handler.endProperty(Property.DTSTART);
- time.set(Calendar.HOUR_OF_DAY,
- Integer.parseInt(lecture[2].substring(0, 2)));
- handler.startProperty(Property.DTEND);
- handler.propertyValue(new DateTime(time.getTime()).toString());
- handler.endProperty(Property.DTEND);
- handler.startProperty(Property.LOCATION);
- handler.propertyValue(lecture[5]);
- handler.endProperty(Property.LOCATION);
- handler.startProperty(Property.SUMMARY);
- handler.propertyValue(lecture[3] + " with " + lecture[4] + " in "
- + lecture[5]);
- handler.endProperty(Property.SUMMARY);
- handler.endComponent(Component.VEVENT);
+
+ log(prefix + hour + ":" + minute + " " + cal.get(Calendar.DAY_OF_MONTH)
+ + "/" + (cal.get(Calendar.MONTH) + 1) + "/"
+ + cal.get(Calendar.YEAR));
+ }
+
+ private static void log(String string) {
+ System.out.println(string);
+ }
+
+ private class Event {
+ String dayOfWeek;
+ String startTime;
+ String endTime;
+ String name;
+ String lecturer;
+ String location;
+ String weeks;
+
+ public Event() {
+ }
+
+ public Event(String[] info) {
+ dayOfWeek = info[0];
+ startTime = info[1];
+ endTime = info[2];
+ name = info[3];
+ lecturer = info[4];
+ location = info[5];
+ weeks = info[6];
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getOuterType().hashCode();
+ result = prime * result
+ + ((dayOfWeek == null) ? 0 : dayOfWeek.hashCode());
+ result = prime * result
+ + ((endTime == null) ? 0 : endTime.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result
+ + ((startTime == null) ? 0 : startTime.hashCode());
+ result = prime * result + ((weeks == null) ? 0 : weeks.hashCode());
+ result = prime * result
+ + ((lecturer == null) ? 0 : lecturer.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Event other = (Event) obj;
+ if (!getOuterType().equals(other.getOuterType()))
+ return false;
+ if (dayOfWeek == null) {
+ if (other.dayOfWeek != null)
+ return false;
+ } else if (!dayOfWeek.equals(other.dayOfWeek))
+ return false;
+ if (endTime == null) {
+ if (other.endTime != null)
+ return false;
+ } else if (!endTime.equals(other.endTime))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (startTime == null) {
+ if (other.startTime != null)
+ return false;
+ } else if (!startTime.equals(other.startTime))
+ return false;
+ if (weeks == null) {
+ if (other.weeks != null)
+ return false;
+ } else if (!weeks.equals(other.weeks))
+ return false;
+ if (lecturer == null) {
+ if (other.lecturer != null)
+ return false;
+ } else if (!lecturer.equals(other.lecturer))
+ return false;
+ return true;
+ }
+
+ private SotonCalendarParser getOuterType() {
+ return SotonCalendarParser.this;
+ }
+
}
-}
+} \ No newline at end of file