From 1749f7edc11b9961b15e790c7d296bacd8d68ff5 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Fri, 23 Mar 2012 19:46:14 +0000 Subject: Updated and now in one case will work, needs more UI work. --- src/net/cbaines/suca/CalendarApplet.java | 212 +++++++-- src/net/cbaines/suca/SotonCalendarFetcher.java | 12 +- src/net/cbaines/suca/SotonCalendarParser.java | 581 +++++++++++++++++++++---- src/net/cbaines/suca/UniTermDates.java | 206 +++++++++ 4 files changed, 888 insertions(+), 123 deletions(-) create mode 100644 src/net/cbaines/suca/UniTermDates.java diff --git a/src/net/cbaines/suca/CalendarApplet.java b/src/net/cbaines/suca/CalendarApplet.java index 2b425fd..f9de766 100644 --- a/src/net/cbaines/suca/CalendarApplet.java +++ b/src/net/cbaines/suca/CalendarApplet.java @@ -1,30 +1,64 @@ package net.cbaines.suca; import java.awt.BorderLayout; +import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; +import java.io.StringReader; +import javax.security.auth.login.LoginException; import javax.swing.JApplet; import javax.swing.JButton; +import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; +import javax.swing.JProgressBar; import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; -import org.apache.commons.io.IOUtils; +import net.fortuna.ical4j.data.CalendarBuilder; +import net.fortuna.ical4j.data.ParserException; +import net.fortuna.ical4j.model.Calendar; @SuppressWarnings("serial") public class CalendarApplet extends JApplet { - JTextField usernameTextField; - JPasswordField passwordTextField; + private String calendarCSVString = null; + private String calendarICALString = null; - JTextArea csvTextArea; + private JTabbedPane stageTabbedPane; + + // The panel used for the file fetch stuff + private JPanel csvFileFetchPanel; + + private JLabel csvFileFetchInstructions; + + private JTextField usernameTextField; + private JPasswordField passwordTextField; + private JButton go; + + private JProgressBar fetchProgress; + + private JButton csvFileSelectorButton; + + private JTextArea csvTextArea; + + private CalendarApplet instance; + + // Panel for the stage controls + + private JPanel controlsPanel; + + // Panel for the calendar creation + + private JPanel calendarCreationPanel; public void init() { // Execute a job on the event-dispatching thread: @@ -41,42 +75,156 @@ public class CalendarApplet extends JApplet { } void createGUI() { - JPanel loginPanel = new JPanel(); - JLabel usernameLabel = new JLabel("Username"); - loginPanel.add(usernameLabel); - usernameTextField = new JTextField(10); - loginPanel.add(usernameTextField); + try { - JLabel passwordLabel = new JLabel("Password"); - loginPanel.add(passwordLabel); - passwordTextField = new JPasswordField(10); - loginPanel.add(passwordTextField); + stageTabbedPane = new JTabbedPane(); - JButton go = new JButton("Go"); - loginPanel.add(go); + // Create the first screen - JPanel csvPanel = new JPanel(); - JButton downloadCsv = new JButton("Donwload csv"); - csvPanel.add(downloadCsv); + csvFileFetchPanel = new JPanel(new GridLayout(1, 2)); - csvTextArea = new JTextArea(100, 100); - csvPanel.add(new JScrollPane(csvTextArea)); + JTabbedPane csvFileFetchMethodsTabbedPane = new JTabbedPane(); - loginPanel.add(csvPanel); + JPanel loginPanel = new JPanel(); + JLabel usernameLabel = new JLabel("Username"); + loginPanel.add(usernameLabel); + usernameTextField = new JTextField(10); + loginPanel.add(usernameTextField); - go.addActionListener(new ActionListener() { + JLabel passwordLabel = new JLabel("Password"); + loginPanel.add(passwordLabel); + passwordTextField = new JPasswordField(10); + loginPanel.add(passwordTextField); - @Override - public void actionPerformed(ActionEvent arg0) { - String csvString = new SotonCalendarFetcher(usernameTextField.getText(), String - .valueOf(passwordTextField.getPassword())).fetchAndParseTimetable(); + go = new JButton("Go"); + loginPanel.add(go); - csvTextArea.setText(csvString); + fetchProgress = new JProgressBar(); + fetchProgress.setIndeterminate(true); + fetchProgress.setVisible(false); + loginPanel.add(fetchProgress); - } - }); + csvFileFetchMethodsTabbedPane.addTab("Download", loginPanel); + + JPanel csvFileLoadPanel = new JPanel(); + + csvFileSelectorButton = new JButton("Load csv file"); + csvFileLoadPanel.add(csvFileSelectorButton); + + csvFileFetchMethodsTabbedPane.addTab("Load", csvFileLoadPanel); + csvFileFetchMethodsTabbedPane.setEnabledAt(1, false); + + csvFileFetchPanel.add(csvFileFetchMethodsTabbedPane); + + csvTextArea = new JTextArea(100, 100); + csvFileFetchPanel.add(new JScrollPane(csvTextArea)); + + go.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + go.setEnabled(false); + new FetchThread().start(); + } + }); + + stageTabbedPane.addTab("Calendar Fetch", csvFileFetchPanel); + + // Calendar creation panel + calendarCreationPanel = new JPanel(); + + JButton createCalendarButton = new JButton("Create Calendar"); + createCalendarButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + + SotonCalendarParser calParser = new SotonCalendarParser(); + + CalendarBuilder builder = new CalendarBuilder(calParser); + try { + Calendar calendar = builder.build(new StringReader(calendarCSVString)); + calendarICALString = calendar.toString(); + System.out.println(calendarICALString); + } catch (ParserException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + calendarCreationPanel.add(createCalendarButton); + + JButton saveCalendarButton = new JButton("Save Calendar"); + saveCalendarButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + + JFileChooser fc = new JFileChooser(); + int returnVal = fc.showSaveDialog(instance); // this = Applet + if (returnVal == JFileChooser.APPROVE_OPTION) { + File aFile = fc.getSelectedFile(); + + try { + BufferedWriter out = new BufferedWriter(new FileWriter(aFile)); + out.write(calendarICALString); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + } + }); + calendarCreationPanel.add(saveCalendarButton); + + stageTabbedPane.addTab("Calendar Creation", calendarCreationPanel); - getContentPane().add(loginPanel, BorderLayout.CENTER); + controlsPanel = new JPanel(); + controlsPanel.add(new JButton("Previous")); + controlsPanel.add(new JButton("Next")); + getContentPane().add(stageTabbedPane, BorderLayout.CENTER); + getContentPane().add(controlsPanel, BorderLayout.SOUTH); + } catch (Exception e) { + e.printStackTrace(); + } } + + private class FetchThread extends Thread { + + public FetchThread() { + super(); + } + + @Override + public void run() { + System.out.println("Starting fetch thread"); + + String csvString; + try { + fetchProgress.setVisible(true); + + csvString = new SotonCalendarFetcher(usernameTextField.getText(), String.valueOf(passwordTextField + .getPassword())).fetchAndParseTimetable(); + + System.out.println("Finished fetch"); + + fetchProgress.setIndeterminate(false); + fetchProgress.setValue(100); + fetchProgress.setString("Finished"); + + calendarCSVString = csvString; + csvTextArea.setText(calendarCSVString); + go.setEnabled(true); + + System.out.println("Finished fetch thread"); + + } catch (LoginException e) { + fetchProgress.setIndeterminate(false); + fetchProgress.setValue(0); + fetchProgress.setString("Login Error"); + } + + } + } + } diff --git a/src/net/cbaines/suca/SotonCalendarFetcher.java b/src/net/cbaines/suca/SotonCalendarFetcher.java index 633b898..40a85ff 100644 --- a/src/net/cbaines/suca/SotonCalendarFetcher.java +++ b/src/net/cbaines/suca/SotonCalendarFetcher.java @@ -6,6 +6,8 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import javax.security.auth.login.LoginException; + import org.apache.commons.io.IOUtils; import org.apache.http.Header; import org.apache.http.HttpEntity; @@ -28,7 +30,7 @@ public class SotonCalendarFetcher { this.password = password; } - public String fetchAndParseTimetable() { + public String fetchAndParseTimetable() throws LoginException { DefaultHttpClient httpclient = new DefaultHttpClient(); try { HttpGet httpget = new HttpGet( @@ -153,7 +155,13 @@ public class SotonCalendarFetcher { response = httpclient.execute(httpost); entity = response.getEntity(); - return IOUtils.toString(entity.getContent()); + String responseString = IOUtils.toString(entity.getContent()); + + if (responseString.contains("Failed Login")) { + throw new LoginException("Login failed"); + } else { + return responseString; + } } catch (IllegalStateException e) { // TODO Auto-generated catch block 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 + * + */ 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 events = new ArrayList(); + 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 periods = new ArrayList(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 diff --git a/src/net/cbaines/suca/UniTermDates.java b/src/net/cbaines/suca/UniTermDates.java new file mode 100644 index 0000000..5c72d47 --- /dev/null +++ b/src/net/cbaines/suca/UniTermDates.java @@ -0,0 +1,206 @@ +package net.cbaines.suca; + +import java.security.InvalidParameterException; +import java.util.Calendar; +import java.util.GregorianCalendar; + +/** + * All info from here + * https://www.soton.ac.uk/studentadmin/academic_year/index.html + * + * @author Christopher Baines + * + */ +public final class UniTermDates { + + /** + * Periods + */ + public static final int AUTUMN_TERM = 0; + public static final int SPRING_TERM = 1; + public static final int SUMMER_TERM = 2; + + public static final int SEMESTER_1 = 3; + public static final int SEMESTER_2 = 4; + + public static final int YEAR_BEGINING_2011 = 2011; + public static final int YEAR_BEGINING_2012 = 2012; + public static final int YEAR_BEGINING_2013 = 2013; + public static final int YEAR_BEGINING_2014 = 2014; + public static final int YEAR_BEGINING_2015 = 2015; + public static final int YEAR_BEGINING_2016 = 2016; + public static final int YEAR_BEGINING_2017 = 2017; + public static final int YEAR_BEGINING_2018 = 2018; + public static final int YEAR_BEGINING_2019 = 2019; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] startOfAutumnTermAndSemester1 = { + new GregorianCalendar(2011, Calendar.SEPTEMBER, 29), + new GregorianCalendar(2012, Calendar.SEPTEMBER, 27), + new GregorianCalendar(2013, Calendar.SEPTEMBER, 26), + new GregorianCalendar(2014, Calendar.SEPTEMBER, 25), + new GregorianCalendar(2015, Calendar.SEPTEMBER, 24), + new GregorianCalendar(2016, Calendar.SEPTEMBER, 29), + new GregorianCalendar(2017, Calendar.SEPTEMBER, 28), + new GregorianCalendar(2018, Calendar.SEPTEMBER, 27), + new GregorianCalendar(2019, Calendar.SEPTEMBER, 26) }; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] endOfAutumnTerm = { + new GregorianCalendar(2011, Calendar.DECEMBER, 17), + new GregorianCalendar(2012, Calendar.DECEMBER, 15), + new GregorianCalendar(2013, Calendar.DECEMBER, 14), + new GregorianCalendar(2014, Calendar.DECEMBER, 13), + new GregorianCalendar(2015, Calendar.DECEMBER, 12), + new GregorianCalendar(2016, Calendar.DECEMBER, 17), + new GregorianCalendar(2017, Calendar.DECEMBER, 16), + new GregorianCalendar(2018, Calendar.DECEMBER, 15), + new GregorianCalendar(2019, Calendar.DECEMBER, 14) }; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] startOfSpringTerm = { + new GregorianCalendar(2012, Calendar.JANUARY, 9), + new GregorianCalendar(2013, Calendar.JANUARY, 7), + new GregorianCalendar(2014, Calendar.JANUARY, 6), + new GregorianCalendar(2015, Calendar.JANUARY, 5), + new GregorianCalendar(2016, Calendar.JANUARY, 4), + new GregorianCalendar(2017, Calendar.JANUARY, 9), + new GregorianCalendar(2018, Calendar.JANUARY, 8), + new GregorianCalendar(2019, Calendar.JANUARY, 7), + new GregorianCalendar(2020, Calendar.JANUARY, 6) }; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] endOfSemester1 = { + new GregorianCalendar(2012, Calendar.JANUARY, 28), + new GregorianCalendar(2013, Calendar.JANUARY, 26), + new GregorianCalendar(2014, Calendar.JANUARY, 25), + new GregorianCalendar(2015, Calendar.JANUARY, 24), + new GregorianCalendar(2016, Calendar.JANUARY, 23), + new GregorianCalendar(2017, Calendar.JANUARY, 28), + new GregorianCalendar(2018, Calendar.JANUARY, 27), + new GregorianCalendar(2019, Calendar.JANUARY, 26), + new GregorianCalendar(2020, Calendar.JANUARY, 25) }; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] startOfSemester2 = { + new GregorianCalendar(2012, Calendar.JANUARY, 30), + new GregorianCalendar(2013, Calendar.JANUARY, 28), + new GregorianCalendar(2014, Calendar.JANUARY, 27), + new GregorianCalendar(2015, Calendar.JANUARY, 26), + new GregorianCalendar(2016, Calendar.JANUARY, 25), + new GregorianCalendar(2017, Calendar.JANUARY, 30), + new GregorianCalendar(2018, Calendar.JANUARY, 29), + new GregorianCalendar(2019, Calendar.JANUARY, 28), + new GregorianCalendar(2020, Calendar.JANUARY, 27) }; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] endOfSpringTerm = { + new GregorianCalendar(2012, Calendar.MARCH, 17), + new GregorianCalendar(2013, Calendar.MARCH, 16), + new GregorianCalendar(2014, Calendar.MARCH, 29), + new GregorianCalendar(2015, Calendar.MARCH, 21), + new GregorianCalendar(2016, Calendar.MARCH, 19), + new GregorianCalendar(2017, Calendar.MARCH, 25), + new GregorianCalendar(2018, Calendar.MARCH, 17), + new GregorianCalendar(2019, Calendar.MARCH, 30), + new GregorianCalendar(2020, Calendar.MARCH, 21) }; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] startOfSummerTerm = { + new GregorianCalendar(2012, Calendar.APRIL, 16), + new GregorianCalendar(2013, Calendar.APRIL, 15), + new GregorianCalendar(2014, Calendar.APRIL, 28), + new GregorianCalendar(2015, Calendar.APRIL, 20), + new GregorianCalendar(2016, Calendar.APRIL, 18), + new GregorianCalendar(2017, Calendar.APRIL, 24), + new GregorianCalendar(2018, Calendar.APRIL, 16), + new GregorianCalendar(2019, Calendar.APRIL, 29), + new GregorianCalendar(2020, Calendar.APRIL, 20) }; + + /** + * Start dates for the Autumn term's for each Academic Year starting from + * 2011 to 2019. + */ + private static final GregorianCalendar[] endOfSummerTermAndSemester2 = { + new GregorianCalendar(2012, Calendar.JUNE, 16), + new GregorianCalendar(2013, Calendar.JUNE, 15), + new GregorianCalendar(2014, Calendar.JUNE, 14), + new GregorianCalendar(2015, Calendar.JUNE, 13), + new GregorianCalendar(2016, Calendar.JUNE, 11), + new GregorianCalendar(2017, Calendar.JUNE, 17), + new GregorianCalendar(2018, Calendar.JUNE, 16), + new GregorianCalendar(2019, Calendar.JUNE, 15), + new GregorianCalendar(2020, Calendar.JUNE, 13) }; + + public static GregorianCalendar getStartOf(int period, int academicYear) { + if (academicYear < YEAR_BEGINING_2011 + || academicYear > YEAR_BEGINING_2019) { + throw new InvalidParameterException(); + } + if (period == AUTUMN_TERM) { + return (GregorianCalendar) startOfAutumnTermAndSemester1[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SPRING_TERM) { + return (GregorianCalendar) startOfSpringTerm[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SUMMER_TERM) { + return (GregorianCalendar) startOfSummerTerm[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SEMESTER_1) { + return (GregorianCalendar) startOfAutumnTermAndSemester1[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SEMESTER_2) { + return (GregorianCalendar) startOfSemester2[academicYear + - YEAR_BEGINING_2011].clone(); + } else { + throw new InvalidParameterException(); + } + } + + public static GregorianCalendar getEndOf(int period, int academicYear) { + if (academicYear < YEAR_BEGINING_2011 + || academicYear > YEAR_BEGINING_2019) { + throw new InvalidParameterException(); + } + if (period == AUTUMN_TERM) { + return (GregorianCalendar) endOfAutumnTerm[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SPRING_TERM) { + return (GregorianCalendar) endOfSpringTerm[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SUMMER_TERM) { + return (GregorianCalendar) endOfSummerTermAndSemester2[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SEMESTER_1) { + return (GregorianCalendar) endOfSemester1[academicYear + - YEAR_BEGINING_2011].clone(); + } else if (period == SEMESTER_2) { + return (GregorianCalendar) endOfSummerTermAndSemester2[academicYear + - YEAR_BEGINING_2011].clone(); + } else { + throw new InvalidParameterException(); + } + } + +} -- cgit v1.2.3