diff options
-rw-r--r-- | src/net/cbaines/suca/CalendarApplet.java | 221 | ||||
-rw-r--r-- | src/net/cbaines/suca/SotonCalendarFetcher.java | 57 | ||||
-rw-r--r-- | src/net/cbaines/suca/SotonCalendarParser.java | 24 | ||||
-rw-r--r-- | web/SouthamptonUniversityCalendarApplet.jar | bin | 0 -> 2300603 bytes | |||
-rw-r--r-- | web/applet-fu.js | 95 | ||||
-rw-r--r-- | web/suca.html | 33 |
6 files changed, 252 insertions, 178 deletions
diff --git a/src/net/cbaines/suca/CalendarApplet.java b/src/net/cbaines/suca/CalendarApplet.java index 5569285..816084f 100644 --- a/src/net/cbaines/suca/CalendarApplet.java +++ b/src/net/cbaines/suca/CalendarApplet.java @@ -1,7 +1,7 @@ package net.cbaines.suca; -import java.awt.BorderLayout; -import java.awt.GridLayout; +import java.awt.Container; +import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedWriter; @@ -11,17 +11,17 @@ import java.io.IOException; import java.io.StringReader; import javax.security.auth.login.LoginException; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JLabel; +import javax.swing.JOptionPane; 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 net.fortuna.ical4j.data.CalendarBuilder; @@ -31,38 +31,22 @@ import net.fortuna.ical4j.model.Calendar; @SuppressWarnings("serial") public class CalendarApplet extends JApplet { - private String calendarCSVString = null; - private String calendarICALString = null; + private CalendarApplet instance; - private JTabbedPane stageTabbedPane; + // The panel holding the stages + private Container stages; - // The panel used for the file fetch stuff - private JPanel csvFileFetchPanel; + // Load University Calendar + private JPanel calendarLoadingPanel; 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; + private JButton fetchCalendarButton; + private JProgressBar fetchCalendarProgress; + // iCal Calendar Creation Options private JPanel calendarCreationOptions; - private JProgressBar creationProgress; - private JButton createCalendarButton; private JCheckBox mergeDuplicateEventsWithSeperateLocations = new JCheckBox( "Merge Duplicate Events with Seperate Locations", true); private JCheckBox showTerms = new JCheckBox("Show Terms", true); @@ -70,8 +54,13 @@ public class CalendarApplet extends JApplet { private JCheckBox showSemesterWeeks = new JCheckBox("Show Semester Weeks", true); private JCheckBox mergeHeaders = new JCheckBox("Merge Headers", false); - // This is more of a development feature....? - private JTextArea calendarPreviewTextArea; + // Download Calendar + private JPanel downloadCalendarPanel; + private JButton donwloadCalendarButton; + + // Data + private volatile String calendarCSVString = null; + private volatile String calendarICALString = null; public void init() { // Execute a job on the event-dispatching thread: @@ -90,82 +79,76 @@ public class CalendarApplet extends JApplet { void createGUI() { try { - stageTabbedPane = new JTabbedPane(); + stages = getContentPane(); + stages.setLayout(new BoxLayout(stages, BoxLayout.PAGE_AXIS)); - // Create the first screen + // Load University Calendar Stage - csvFileFetchPanel = new JPanel(new GridLayout(1, 2)); + calendarLoadingPanel = new JPanel(); + calendarLoadingPanel.setBorder(BorderFactory.createTitledBorder("Load University Calendar")); - JTabbedPane csvFileFetchMethodsTabbedPane = new JTabbedPane(); - - JPanel loginPanel = new JPanel(); - JLabel usernameLabel = new JLabel("Username"); - loginPanel.add(usernameLabel); + JPanel usernamePanel = new JPanel(); + usernamePanel.add(new JLabel("Username")); usernameTextField = new JTextField(10); - loginPanel.add(usernameTextField); + usernamePanel.add(usernameTextField); + calendarLoadingPanel.add(usernamePanel); - JLabel passwordLabel = new JLabel("Password"); - loginPanel.add(passwordLabel); + JPanel passwordPanel = new JPanel(); + passwordPanel.add(new JLabel("Password")); passwordTextField = new JPasswordField(10); - loginPanel.add(passwordTextField); - - go = new JButton("Go"); - loginPanel.add(go); - - fetchProgress = new JProgressBar(); - fetchProgress.setIndeterminate(true); - fetchProgress.setVisible(false); - loginPanel.add(fetchProgress); + passwordPanel.add(passwordTextField); + calendarLoadingPanel.add(passwordPanel); - 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() { + fetchCalendarButton = new JButton("Fetch Calendar"); + fetchCalendarButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { - go.setEnabled(false); new FetchThread().start(); } }); + calendarLoadingPanel.add(fetchCalendarButton); + + fetchCalendarProgress = new JProgressBar(); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + calendarLoadingPanel.add(fetchCalendarProgress); - stageTabbedPane.addTab("Calendar Fetch", csvFileFetchPanel); + stages.add(calendarLoadingPanel); - // Calendar creation panel - calendarCreationPanel = new JPanel(new GridLayout(1, 2)); + // iCal Calendar Creation Options calendarCreationOptions = new JPanel(); + calendarCreationOptions.setBorder(BorderFactory.createTitledBorder("Calendar Options")); - createCalendarButton = new JButton("Create Calendar"); - createCalendarButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - createCalendarButton.setEnabled(false); - new CreationThread().start(); - } - }); - calendarCreationOptions.add(createCalendarButton); + calendarCreationOptions.add(mergeDuplicateEventsWithSeperateLocations); + calendarCreationOptions.add(showTerms); + calendarCreationOptions.add(showSemesters); + calendarCreationOptions.add(showSemesterWeeks); + calendarCreationOptions.add(mergeHeaders); + + stages.add(calendarCreationOptions); - JButton saveCalendarButton = new JButton("Save Calendar"); - saveCalendarButton.addActionListener(new ActionListener() { + // Calendar Download + + downloadCalendarPanel = new JPanel(); + downloadCalendarPanel.setBorder(BorderFactory.createTitledBorder("Download Calendar (iCal)")); + + donwloadCalendarButton = new JButton("Download Calendar"); + donwloadCalendarButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { + CreationThread creationThread = new CreationThread(); + creationThread.start(); JFileChooser fc = new JFileChooser(); int returnVal = fc.showSaveDialog(instance); // this = Applet if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); + try { + creationThread.join(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } try { BufferedWriter out = new BufferedWriter(new FileWriter(file)); @@ -180,32 +163,10 @@ public class CalendarApplet extends JApplet { } }); - calendarCreationOptions.add(saveCalendarButton); - - calendarCreationOptions.add(mergeDuplicateEventsWithSeperateLocations); - calendarCreationOptions.add(showTerms); - calendarCreationOptions.add(showSemesters); - calendarCreationOptions.add(showSemesterWeeks); - calendarCreationOptions.add(mergeHeaders); - creationProgress = new JProgressBar(); - creationProgress.setIndeterminate(true); - creationProgress.setVisible(false); - calendarCreationOptions.add(creationProgress); + downloadCalendarPanel.add(donwloadCalendarButton); - calendarCreationPanel.add(calendarCreationOptions); + stages.add(downloadCalendarPanel); - calendarPreviewTextArea = new JTextArea(); - - calendarCreationPanel.add(new JScrollPane(calendarPreviewTextArea)); - - stageTabbedPane.addTab("Calendar Creation", calendarCreationPanel); - - 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(); } @@ -219,35 +180,43 @@ public class CalendarApplet extends JApplet { @Override public void run() { - System.out.println("Starting fetch thread"); + System.out.println("Start of fetch thread"); + fetchCalendarButton.setEnabled(false); + fetchCalendarProgress.setIndeterminate(true); + fetchCalendarProgress.setValue(0); String csvString; try { - fetchProgress.setValue(0); - fetchProgress.setIndeterminate(true); - 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"); + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(100); + } catch (LoginException e) { - fetchProgress.setIndeterminate(false); - fetchProgress.setValue(0); - fetchProgress.setString("Login Error"); - } + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + + JOptionPane.showMessageDialog(instance, + "LoginException: Error logging in, try again, and perhaps also try logging in to SUSSED", + "Inane error", JOptionPane.ERROR_MESSAGE); + } catch (IOException e) { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + JOptionPane.showMessageDialog(instance, + "IOException: Error logging in, try again, and perhaps also try logging in to SUSSED", + "Inane error", JOptionPane.ERROR_MESSAGE); + } } } @@ -261,10 +230,6 @@ public class CalendarApplet extends JApplet { public void run() { System.out.println("Starting creation thread"); - creationProgress.setVisible(true); - creationProgress.setValue(0); - creationProgress.setIndeterminate(true); - SotonCalendarParser calParser = new SotonCalendarParser(); calParser.setMergeDuplicateEventsWithSeperateLocations(mergeDuplicateEventsWithSeperateLocations .isSelected()); @@ -277,12 +242,6 @@ public class CalendarApplet extends JApplet { try { Calendar calendar = builder.build(new StringReader(calendarCSVString)); calendarICALString = calendar.toString(); - calendarPreviewTextArea.setText(calendarICALString); - createCalendarButton.setEnabled(true); - - creationProgress.setIndeterminate(false); - creationProgress.setValue(100); - creationProgress.setString("Finished"); } catch (ParserException e) { e.printStackTrace(); } catch (IOException e) { diff --git a/src/net/cbaines/suca/SotonCalendarFetcher.java b/src/net/cbaines/suca/SotonCalendarFetcher.java index 40a85ff..846faf1 100644 --- a/src/net/cbaines/suca/SotonCalendarFetcher.java +++ b/src/net/cbaines/suca/SotonCalendarFetcher.java @@ -30,11 +30,13 @@ public class SotonCalendarFetcher { this.password = password; } - public String fetchAndParseTimetable() throws LoginException { + @SuppressWarnings("deprecation") + public String fetchAndParseTimetable() throws IOException, LoginException { DefaultHttpClient httpclient = new DefaultHttpClient(); + Exception exception = null; + try { - HttpGet httpget = new HttpGet( - "https://www.adminservices.soton.ac.uk/adminweb/servlet/login"); + HttpGet httpget = new HttpGet("https://www.adminservices.soton.ac.uk/adminweb/servlet/login"); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); @@ -43,11 +45,7 @@ public class SotonCalendarFetcher { // response.getStatusLine()); // EntityUtils.consume(entity); if (entity != null) { - try { - entity.consumeContent(); - } catch (IOException e) { - e.printStackTrace(); - } + entity.consumeContent(); } // System.out.println("Initial set of cookies:"); @@ -60,8 +58,7 @@ public class SotonCalendarFetcher { } } - HttpPost httpost = new HttpPost( - "https://www.adminservices.soton.ac.uk/adminweb/servlet/login"); + 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)); @@ -81,11 +78,16 @@ public class SotonCalendarFetcher { // 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); + BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent())); + StringBuilder responseBuilder = new StringBuilder(); + for (String line; (line = br.readLine()) != null;) { + responseBuilder.append(line); + } + + System.out.println("responseBuilder.length() " + responseBuilder.length()); + + if (responseBuilder.length() != 0) { + throw new LoginException("Login failed"); } // System.out.println("Post logon cookies:"); @@ -117,6 +119,7 @@ public class SotonCalendarFetcher { System.out.println("Second post get: " + response.getStatusLine()); // EntityUtils.consume(entity); br = new BufferedReader(new InputStreamReader(entity.getContent())); + String line; while ((line = br.readLine()) != null) { // System.out.println(line); } @@ -144,8 +147,7 @@ public class SotonCalendarFetcher { // Log.v(TAG, line); } - httpost = new HttpPost( - "https://www.adminservices.soton.ac.uk/adminweb/timetables/ttdownload/.csv"); + httpost = new HttpPost("https://www.adminservices.soton.ac.uk/adminweb/timetables/ttdownload/.csv"); nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("format", "list")); @@ -157,19 +159,20 @@ public class SotonCalendarFetcher { String responseString = IOUtils.toString(entity.getContent()); - if (responseString.contains("Failed Login")) { - throw new LoginException("Login failed"); - } else { - return responseString; - } + return responseString; - } catch (IllegalStateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + exception = e; + } catch (LoginException e) { + exception = e; } finally { + if (exception != null) { + if (exception instanceof IOException) { + throw (IOException) exception; + } else if (exception instanceof IOException) { + throw (LoginException) exception; + } + } // When HttpClient instance is no longer needed, // shut down the connection manager to ensure // immediate deallocation of all system resources diff --git a/src/net/cbaines/suca/SotonCalendarParser.java b/src/net/cbaines/suca/SotonCalendarParser.java index 8feab9a..38b6ac2 100644 --- a/src/net/cbaines/suca/SotonCalendarParser.java +++ b/src/net/cbaines/suca/SotonCalendarParser.java @@ -37,9 +37,9 @@ public class SotonCalendarParser implements CalendarParser { private boolean mergeHeaders = false; - private Calendar startYear = UniTermDates.getStartOf(UniTermDates.SEMESTER_1, - Calendar.getInstance().get(Calendar.YEAR) - 1); - private Calendar endYear = UniTermDates.getEndOf(UniTermDates.SEMESTER_2, UniTermDates.YEAR_BEGINING_2019); + // private Calendar startYear = UniTermDates.getStartOf(UniTermDates.SEMESTER_1, + // Calendar.getInstance().get(Calendar.YEAR) - 1); + // private Calendar endYear = UniTermDates.getEndOf(UniTermDates.SEMESTER_2, UniTermDates.YEAR_BEGINING_2019); // private final static String TAG = "SotonCalendarParser"; @@ -296,7 +296,7 @@ public class SotonCalendarParser implements CalendarParser { 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 @@ -573,19 +573,6 @@ public class SotonCalendarParser implements CalendarParser { + cal.get(Calendar.DAY_OF_MONTH) + "/" + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.YEAR)); } - private static void logDate(String prefix, Date date) { - Map<Integer, String> daysOfTheWeek = new HashMap<Integer, String>(7); - daysOfTheWeek.put(Calendar.MONDAY, "Monday"); - daysOfTheWeek.put(Calendar.TUESDAY, "Tuesday"); - daysOfTheWeek.put(Calendar.WEDNESDAY, "Wednesday"); - daysOfTheWeek.put(Calendar.THURSDAY, "Thursday"); - daysOfTheWeek.put(Calendar.FRIDAY, "Friday"); - daysOfTheWeek.put(Calendar.SATURDAY, "Saturday"); - daysOfTheWeek.put(Calendar.SUNDAY, "Sunday"); - - log(prefix + " " + date.toString()); - } - private static void log(String string) { System.out.println(string); } @@ -674,9 +661,6 @@ public class SotonCalendarParser implements CalendarParser { String location; String weeks; - public Event() { - } - public Event(String[] info) { dayOfWeek = info[0]; startTime = info[1]; diff --git a/web/SouthamptonUniversityCalendarApplet.jar b/web/SouthamptonUniversityCalendarApplet.jar Binary files differnew file mode 100644 index 0000000..8421c99 --- /dev/null +++ b/web/SouthamptonUniversityCalendarApplet.jar diff --git a/web/applet-fu.js b/web/applet-fu.js new file mode 100644 index 0000000..092b7d2 --- /dev/null +++ b/web/applet-fu.js @@ -0,0 +1,95 @@ +/* + * Applet-Fu A Javascript library for cross-browser applet deployment. + + * Copyright (c) 2008, Metamolecular, LLC + * All rights reserved. + * + * http://github.com/rapodaca/applet-fu/tree/master + * info@metamolecular.com + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of Metamolecular, LLC nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var applet_fu = { + run: function(attributes, parameters, minimumVersion, fallbackContent){ + if (applet_fu.isIE()){ + applet_fu.openTagIE(attributes) + } + else{ + applet_fu.openTagStandard(minimumVersion || '1.4.2'); + } + + applet_fu.writeAttributes(attributes); + applet_fu.writeParameters(parameters); + document.write(fallbackContent || 'This content requires Java.'); + document.write('</object>'); + }, + + /* + * Creates the opening object tag for standards-compliant browsers. Requests the minumum JRE version + * specified with minimumVersion. + */ + openTagStandard: function(minimumVersion){ + document.write('<object type="application/x-java-applet;version=' + minimumVersion + '"'); + }, + + /* + * Creates the opening object tag for IE using classid and codebase attributes. + * If these attributes are not set, EasyApplet will request that the applet be run + * with the latest installed JRE, or JDK 1.4, whichever is higher. For more information, see: + * + * http://java.sun.com/javase/6/webnotes/family-clsid.html + * http://java.sun.com/javase/6/docs/technotes/guides/deployment/deployment-guide/autodl-files.html + */ + openTagIE: function(attributes){ + var classid = attributes['classid'] || "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"; //use latest installed JRE; + var codebase = attributes['codebase'] || "http://java.sun.com/products/plugin/autodl/jinstall-1_4-windows-i586.cab#Version=1,4,0,0"; //download JRE 1.4 if suitable JRE not found; + + document.write('<object classid="' + classid + '" codebase=' + codebase + '"'); + }, + + writeAttributes: function(attributes){ + for (attribute in attributes){ + document.write(" "); + document.write(attribute + "='" + attributes[attribute] + "'"); + } + + document.write('>'); + }, + + writeParameters: function(parameters){ + for (parameter in parameters){ + document.write("<param name=" + parameter + " value='" + parameters[parameter] + "'>"); + } + }, + + isIE: function(){ + if (navigator == null) return false; + + return navigator.userAgent.match(/MSIE/) != null; + } +} diff --git a/web/suca.html b/web/suca.html new file mode 100644 index 0000000..ea11a61 --- /dev/null +++ b/web/suca.html @@ -0,0 +1,33 @@ +<html> +<head> + +<title>Southampton University Calendar Applet</title> + +<script type="text/javascript" src="applet-fu.js"></script> + +</head> +<body> + +<div align="center"> + +<script type="text/javascript"> + +applet_fu.run( + {'width':'550','height':'320'}, + { + 'archive':'SouthamptonUniversityCalendarApplet.jar', + 'code':'net/cbaines/suca/CalendarApplet.class', + 'foo':'bar' + }, + '1.4.2', + '<h1>No Java</h1>' +); + +</script> + +</div> + +</body> +</html> + + |