diff options
Diffstat (limited to 'src/net/cbaines/suca/SotonCalendarParser.java')
-rw-r--r-- | src/net/cbaines/suca/SotonCalendarParser.java | 581 |
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 |