aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Baines <cbaines8@gmail.com>2012-03-17 23:50:08 +0000
committerChristopher Baines <cbaines8@gmail.com>2012-03-17 23:50:08 +0000
commite8f29f14141e7cdec43f32c8176471e352ce1d8b (patch)
tree75c2d419b7984f2642e7402f76cfa29042c3dd37
downloadsouthampton-university-calendar-applet-e8f29f14141e7cdec43f32c8176471e352ce1d8b.tar
southampton-university-calendar-applet-e8f29f14141e7cdec43f32c8176471e352ce1d8b.tar.gz
Initial Commit.
-rw-r--r--.gitignore9
-rw-r--r--.project17
-rw-r--r--README1
-rw-r--r--libs/backport-util-concurrent.jarbin0 -> 331716 bytes
-rw-r--r--libs/commons-codec-1.6.jarbin0 -> 232771 bytes
-rw-r--r--libs/commons-io-2.1.jarbin0 -> 163151 bytes
-rw-r--r--libs/commons-lang-2.6.jarbin0 -> 284220 bytes
-rw-r--r--libs/commons-logging-1.1.1.jarbin0 -> 60841 bytes
-rw-r--r--libs/httpclient-4.1.3.jarbin0 -> 352585 bytes
-rw-r--r--libs/httpcore-4.1.4.jarbin0 -> 181409 bytes
-rw-r--r--libs/ical4j-1.0.3.jarbin0 -> 988578 bytes
-rw-r--r--src/net/cbaines/suca/CalendarApplet.java82
-rw-r--r--src/net/cbaines/suca/SotonCalendarFetcher.java172
-rw-r--r--src/net/cbaines/suca/SotonCalendarParser.java151
14 files changed, 432 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7cffa4c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+bin/
+*.class
+*.temp
+*.bak
+*~
+*.tmp
+.settings/
+.metadata/
+.classpath
diff --git a/.project b/.project
new file mode 100644
index 0000000..3ea866c
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>SouthamptonUniversityCalendarApplet</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/README b/README
new file mode 100644
index 0000000..56a5d4c
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+Java Applet for using the University of Southampton Student Timetable.
diff --git a/libs/backport-util-concurrent.jar b/libs/backport-util-concurrent.jar
new file mode 100644
index 0000000..3a4c279
--- /dev/null
+++ b/libs/backport-util-concurrent.jar
Binary files differ
diff --git a/libs/commons-codec-1.6.jar b/libs/commons-codec-1.6.jar
new file mode 100644
index 0000000..ee1bc49
--- /dev/null
+++ b/libs/commons-codec-1.6.jar
Binary files differ
diff --git a/libs/commons-io-2.1.jar b/libs/commons-io-2.1.jar
new file mode 100644
index 0000000..b5c7d69
--- /dev/null
+++ b/libs/commons-io-2.1.jar
Binary files differ
diff --git a/libs/commons-lang-2.6.jar b/libs/commons-lang-2.6.jar
new file mode 100644
index 0000000..98467d3
--- /dev/null
+++ b/libs/commons-lang-2.6.jar
Binary files differ
diff --git a/libs/commons-logging-1.1.1.jar b/libs/commons-logging-1.1.1.jar
new file mode 100644
index 0000000..8758a96
--- /dev/null
+++ b/libs/commons-logging-1.1.1.jar
Binary files differ
diff --git a/libs/httpclient-4.1.3.jar b/libs/httpclient-4.1.3.jar
new file mode 100644
index 0000000..dfa8793
--- /dev/null
+++ b/libs/httpclient-4.1.3.jar
Binary files differ
diff --git a/libs/httpcore-4.1.4.jar b/libs/httpcore-4.1.4.jar
new file mode 100644
index 0000000..1606a2e
--- /dev/null
+++ b/libs/httpcore-4.1.4.jar
Binary files differ
diff --git a/libs/ical4j-1.0.3.jar b/libs/ical4j-1.0.3.jar
new file mode 100644
index 0000000..bf38033
--- /dev/null
+++ b/libs/ical4j-1.0.3.jar
Binary files differ
diff --git a/src/net/cbaines/suca/CalendarApplet.java b/src/net/cbaines/suca/CalendarApplet.java
new file mode 100644
index 0000000..2b425fd
--- /dev/null
+++ b/src/net/cbaines/suca/CalendarApplet.java
@@ -0,0 +1,82 @@
+package net.cbaines.suca;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+
+import javax.swing.JApplet;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+import org.apache.commons.io.IOUtils;
+
+@SuppressWarnings("serial")
+public class CalendarApplet extends JApplet {
+
+ JTextField usernameTextField;
+ JPasswordField passwordTextField;
+
+ JTextArea csvTextArea;
+
+ public void init() {
+ // Execute a job on the event-dispatching thread:
+ // creating this applet's GUI.
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ createGUI();
+ }
+ });
+ } catch (Exception e) {
+ System.err.println("createGUI didn't successfully complete");
+ }
+ }
+
+ void createGUI() {
+ JPanel loginPanel = new JPanel();
+ JLabel usernameLabel = new JLabel("Username");
+ loginPanel.add(usernameLabel);
+ usernameTextField = new JTextField(10);
+ loginPanel.add(usernameTextField);
+
+ JLabel passwordLabel = new JLabel("Password");
+ loginPanel.add(passwordLabel);
+ passwordTextField = new JPasswordField(10);
+ loginPanel.add(passwordTextField);
+
+ JButton go = new JButton("Go");
+ loginPanel.add(go);
+
+ JPanel csvPanel = new JPanel();
+ JButton downloadCsv = new JButton("Donwload csv");
+ csvPanel.add(downloadCsv);
+
+ csvTextArea = new JTextArea(100, 100);
+ csvPanel.add(new JScrollPane(csvTextArea));
+
+ loginPanel.add(csvPanel);
+
+ go.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ String csvString = new SotonCalendarFetcher(usernameTextField.getText(), String
+ .valueOf(passwordTextField.getPassword())).fetchAndParseTimetable();
+
+ csvTextArea.setText(csvString);
+
+ }
+ });
+
+ getContentPane().add(loginPanel, BorderLayout.CENTER);
+
+ }
+}
diff --git a/src/net/cbaines/suca/SotonCalendarFetcher.java b/src/net/cbaines/suca/SotonCalendarFetcher.java
new file mode 100644
index 0000000..633b898
--- /dev/null
+++ b/src/net/cbaines/suca/SotonCalendarFetcher.java
@@ -0,0 +1,172 @@
+package net.cbaines.suca;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+public class SotonCalendarFetcher {
+ private String username;
+ private String password;
+
+ public SotonCalendarFetcher(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public String fetchAndParseTimetable() {
+ DefaultHttpClient httpclient = new DefaultHttpClient();
+ try {
+ HttpGet httpget = new HttpGet(
+ "https://www.adminservices.soton.ac.uk/adminweb/servlet/login");
+
+ HttpResponse response = httpclient.execute(httpget);
+ HttpEntity entity = response.getEntity();
+
+ // System.out.println("Login form get: " +
+ // response.getStatusLine());
+ // EntityUtils.consume(entity);
+ if (entity != null) {
+ try {
+ entity.consumeContent();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // System.out.println("Initial set of cookies:");
+ List<Cookie> cookies = httpclient.getCookieStore().getCookies();
+ if (cookies.isEmpty()) {
+ // System.out.println("None");
+ } else {
+ for (int i = 0; i < cookies.size(); i++) {
+ // System.out.println("- " + cookies.get(i).toString());
+ }
+ }
+
+ HttpPost httpost = new HttpPost(
+ "https://www.adminservices.soton.ac.uk/adminweb/servlet/login");
+
+ List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+ nvps.add(new BasicNameValuePair("user", username));
+ nvps.add(new BasicNameValuePair("pwd", password));
+ System.out.println(username + password);
+
+ httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
+
+ response = httpclient.execute(httpost);
+ entity = response.getEntity();
+
+ for (Header header : response.getAllHeaders()) {
+ // System.out.println("header: " + header.getName() + " : " +
+ // header.getValue());
+ }
+
+ // System.out.println("Login form get: " +
+ // response.getStatusLine());
+ // EntityUtils.consume(entity);
+ BufferedReader br = new BufferedReader(new InputStreamReader(
+ entity.getContent()));
+ String line;
+ while ((line = br.readLine()) != null) {
+ // Log.v(TAG, line);
+ }
+
+ // System.out.println("Post logon cookies:");
+ cookies = httpclient.getCookieStore().getCookies();
+ if (cookies.isEmpty()) {
+ // System.out.println("None");
+ } else {
+ for (int i = 0; i < cookies.size(); i++) {
+ // System.out.println("- " + cookies.get(i).toString());
+ }
+ }
+
+ httpost = new HttpPost(
+ "https://www.adminservices.soton.ac.uk/adminweb/jsp/timetables/timetablesController.jsp?comm=studdisplay&style=+format&paramweeks=1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52");
+
+ nvps = new ArrayList<NameValuePair>();
+ nvps.add(new BasicNameValuePair("format", "list"));
+
+ httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
+
+ response = httpclient.execute(httpost);
+ entity = response.getEntity();
+
+ for (Header header : response.getAllHeaders()) {
+ // System.out.println("header: " + header.getName() + " : " +
+ // header.getValue());
+ }
+
+ System.out.println("Second post get: " + response.getStatusLine());
+ // EntityUtils.consume(entity);
+ br = new BufferedReader(new InputStreamReader(entity.getContent()));
+ while ((line = br.readLine()) != null) {
+ // System.out.println(line);
+ }
+
+ httpost = new HttpPost(
+ "https://www.adminservices.soton.ac.uk/adminweb/jsp/timetables/timetablesController.jsp?comm=studdisplay&style=+format&paramweeks=1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52");
+
+ nvps = new ArrayList<NameValuePair>();
+ nvps.add(new BasicNameValuePair("format", "list"));
+
+ httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
+
+ response = httpclient.execute(httpost);
+ entity = response.getEntity();
+
+ for (Header header : response.getAllHeaders()) {
+ // System.out.println("header: " + header.getName() + " : " +
+ // header.getValue());
+ }
+
+ System.out.println("Second post get: " + response.getStatusLine());
+ // EntityUtils.consume(entity);
+ br = new BufferedReader(new InputStreamReader(entity.getContent()));
+ while ((line = br.readLine()) != null) {
+ // Log.v(TAG, line);
+ }
+
+ httpost = new HttpPost(
+ "https://www.adminservices.soton.ac.uk/adminweb/timetables/ttdownload/.csv");
+
+ nvps = new ArrayList<NameValuePair>();
+ nvps.add(new BasicNameValuePair("format", "list"));
+
+ httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
+
+ response = httpclient.execute(httpost);
+ entity = response.getEntity();
+
+ return IOUtils.toString(entity.getContent());
+
+ } catch (IllegalStateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ // When HttpClient instance is no longer needed,
+ // shut down the connection manager to ensure
+ // immediate deallocation of all system resources
+ httpclient.getConnectionManager().shutdown();
+ }
+ return null;
+ }
+}
diff --git a/src/net/cbaines/suca/SotonCalendarParser.java b/src/net/cbaines/suca/SotonCalendarParser.java
new file mode 100644
index 0000000..6e9a9ac
--- /dev/null
+++ b/src/net/cbaines/suca/SotonCalendarParser.java
@@ -0,0 +1,151 @@
+package net.cbaines.suca;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+import java.util.Arrays;
+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.DateTime;
+import net.fortuna.ical4j.model.Property;
+
+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 Calendar startOfYear = new GregorianCalendar(2011,
+ Calendar.SEPTEMBER, 19);
+
+ public void parse(InputStream in, ContentHandler handler)
+ throws IOException, ParserException {
+ parse(new InputStreamReader(in), handler);
+ }
+
+ public void parse(Reader in, ContentHandler handler) throws IOException,
+ ParserException {
+ parse(new BufferedReader(in, 3), handler);
+ }
+
+ public void parse(BufferedReader in, ContentHandler handler)
+ throws IOException, ParserException {
+
+ try {
+ handler.startCalendar();
+ handler.startProperty(Property.NAME);
+ handler.propertyValue("2.0");
+ handler.endProperty(Property.NAME);
+ handler.startProperty(Property.PRODID);
+ handler.propertyValue("-//Chris Baines + Henco Appel//SouthamptonUniversityOrganiser//EN");
+ handler.endProperty(Property.NAME);
+ 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());
+ }
+ for (int week = weeksStart; week <= weeksEnd; week++) {
+ // System.out.println(week +
+ // Arrays.toString(lecture));
+ createEvent(lecture, handler, week);
+ }
+ }
+
+ }
+ }
+ handler.endCalendar();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // 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);
+ }
+ 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);
+ }
+}