/**
* This file is part of TuCan Mobile.
*
* TuCan Mobile is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TuCan Mobile is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with TuCan Mobile. If not, see <http://www.gnu.org/licenses/>.
*/
package com.dalthed.tucan.scraper;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;
import android.content.Context;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;
import com.dalthed.tucan.R;
import com.dalthed.tucan.TucanMobile;
import com.dalthed.tucan.Connection.AnswerObject;
import com.dalthed.tucan.adapters.HighlightedThreeLinesAdapter;
import com.dalthed.tucan.adapters.MergedAdapter;
import com.dalthed.tucan.adapters.ThreeLinesAdapter;
import com.dalthed.tucan.exceptions.LostSessionException;
import com.dalthed.tucan.exceptions.TucanDownException;
import com.dalthed.tucan.ui.SimpleWebListActivity;
public class EventsScraper extends BasicScraper {
/**
* Links zu den einzelnen Untermodulen
*/
public ArrayList<String> eventLinks;
/**
* Namen deer einzelnen Events
*/
public ArrayList<String> eventNames;
/**
* Links zur Anmeldung zu Events
*/
public ArrayList<String> applyLink;
/**
* Links zu den einzelnen Events
*/
public ArrayList<String> eventLink;
/**
* Option zum Einstellen des Semesters - Name
*/
public ArrayList<String> SemesterOptionName;
/**
* Option zum einstellen des Semesters - Link
*/
public ArrayList<String> SemesterOptionValue;
/**
* id des gewählten Semesters
*/
public int SemesterOptionSelected;
private int mode;
private ArrayAdapter<String> ListAdapter;
public EventsScraper(Context context, AnswerObject result) {
super(context, result);
}
public ListAdapter scrapeAdapter(int modus) throws LostSessionException,
TucanDownException {
this.mode = modus;
if (checkForLostSeesion()) {
// When bug exists: send HTML to resolve Bug
SimpleWebListActivity.sendHTMLatBug(doc.html());
switch (mode) {
case 0:
// LinkGruppe Veranstaltungen finden und durchlaufen
return getMenuAdapter();
case 2:
// Modus Anmeldung
return getApplicationAdapter();
case 10:
eventLink = new ArrayList<String>();
// Modus Module
return getModules();
case 1:
eventLink = new ArrayList<String>();
// Modus Veranstaltungen
return getEvents();
}
}
return null;
}
/**
* Gibt den Adapter für den Spinner zurück
*
* @return Spinneradapter mit den Semestern
* @author Daniel Thiem
*/
public SpinnerAdapter spinnerAdapter() {
if (doc == null) {
return null;
}
SemesterOptionName = new ArrayList<String>();
SemesterOptionValue = new ArrayList<String>();
doc.select("select#semester");
Iterator<Element> SemesterOptionIterator = doc.select("option")
.iterator();
int i = 0;
while (SemesterOptionIterator.hasNext()) {
Element next = SemesterOptionIterator.next();
SemesterOptionName.add(next.text());
SemesterOptionValue.add(next.attr("value"));
if (next.hasAttr("selected")) {
Log.i(LOG_TAG, next.text() + " is selected, has val " + i);
SemesterOptionSelected = i;
}
i++;
}
ArrayAdapter<String> SpinnerAdapter = new ArrayAdapter<String>(context,
android.R.layout.simple_spinner_item, SemesterOptionName);
return SpinnerAdapter;
}
/**
* Gibt einen ListAdapter mit allen Events zurück
*
* @return ListAdapter mit Events zu Semester
* @author Daniel Thiem
*/
private ListAdapter getEvents() {
ArrayList<String> eventName = new ArrayList<String>();
ArrayList<String> eventHead = new ArrayList<String>();
ArrayList<String> eventTime = new ArrayList<String>();
Element ModuleOverviewTable = doc.select("table.tb").first();
if (ModuleOverviewTable != null) {
final Element tableBody = ModuleOverviewTable.select("tbody")
.first();
if (tableBody != null) {
final Elements tableRow = tableBody.select("tr");
if (tableRow != null) {
Iterator<Element> ExamRowIterator = tableRow.iterator();
while (ExamRowIterator.hasNext()) {
Element next = ExamRowIterator.next();
Elements ExamCols = next.select("td");
if (ExamCols.size() > 0) {
eventName.add(ExamCols.get(2).text());
eventLink.add(ExamCols.get(2).select("a")
.attr("href"));
Log.i(LOG_TAG, "Link"
+ ExamCols.get(2).select("a").attr("href"));
eventHead.add(ExamCols.get(3).text());
eventTime.add(ExamCols.get(4).text());
}
}
if (ListAdapter != null) {
ListAdapter.clear();
}
ListAdapter = new ThreeLinesAdapter(context, eventName,
eventTime, eventHead);
return ListAdapter;
}
}
}
return new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, android.R.id.text1,
new String[] { context.getResources().getString(
R.string.events_none_found) });
}
/**
* Gibt einen ListAdapter mit den Modulen zurück
*
* @return ListAdapter mit dem zum Semester passenden Modulen
* @author Daniel Thiem
*/
private ListAdapter getModules() {
ArrayList<String> eventName = new ArrayList<String>();
ArrayList<String> eventHead = new ArrayList<String>();
ArrayList<String> eventCredits = new ArrayList<String>();
Element ModuleOverviewTable = doc.select("div.tb").first();
Iterator<Element> ExamRowIterator = ModuleOverviewTable.select("tbody")
.first().select("tr").iterator();
while (ExamRowIterator.hasNext()) {
Element next = ExamRowIterator.next();
Elements ExamCols = next.select("td");
if (ExamCols.size() > 4) {
eventName.add(ExamCols.get(2).text());
eventHead.add(ExamCols.get(3).text());
eventCredits.add(ExamCols.get(4).text());
eventLink.add(ExamCols.get(2).select("a").attr("href"));
Log.i(LOG_TAG, "Link"
+ ExamCols.get(2).select("a").attr("href"));
}
}
if (ListAdapter != null) {
ListAdapter.clear();
}
ListAdapter = new ThreeLinesAdapter(context, eventName, eventCredits,
eventHead);
return ListAdapter;
}
/**
* Gibt einen ListAdapter zurück der durch die Anmeldungsdaten anzeigt
*
* @return ListAdapter mit anmeldungsdaten
* @author Daniel Thiem
*/
private ListAdapter getApplicationAdapter() {
Element content = doc.select("div#contentSpacer_IE").first();
if (content != null) {
// Informationen über tiefere Kategorien
ListAdapter deepLinkAdapter = getApplicationDeepLinkAdapter(content);
// Informationen über einzelne Events
ListAdapter singleItemAdapter = getApplicationSingleItems(content);
// Adapter ggf. zusammenfügen
if (deepLinkAdapter != null && singleItemAdapter != null) {
return new MergedAdapter(deepLinkAdapter, singleItemAdapter);
} else if (deepLinkAdapter != null && singleItemAdapter == null) {
return deepLinkAdapter;
} else if (deepLinkAdapter == null && singleItemAdapter != null) {
return singleItemAdapter;
} else {
return null;
}
} else {
return null;
}
}
/**
* Gibt einzelne Events in einem ListAdapter zurück.
*
* @param content
* Content div Element
* @return ListAdapter
* @author Daniel Thiem
*/
private ListAdapter getApplicationSingleItems(Element content) {
final Element coursestatusTable = content
.select("table.tbcoursestatus").first();
if (coursestatusTable != null) {
Elements moduleTable = coursestatusTable.select("tr");
ListAdapter singleEventAdapter = null;
if (moduleTable.size() > 0) {
// Einzelne Veranstaltungen werden angeboten
ArrayList<String> itemName = new ArrayList<String>();
ArrayList<String> itemInstructor = new ArrayList<String>();
ArrayList<String> itemDate = new ArrayList<String>();
ArrayList<Boolean> isModule = new ArrayList<Boolean>();
for (Element next : moduleTable) {
final Elements cols = next.select("td");
Element firstCol = cols.first();
if (firstCol != null && cols.size() == 4) {
final Element secondCol = cols.get(1);
List<Node> innerChilds = secondCol.childNodes();
if (firstCol.hasClass("tbsubhead")) {
// Es handelt sich um ein Modul
if (innerChilds.size() == 4) {
final Node instructorNode = innerChilds.get(3);
if (instructorNode instanceof TextNode) {
String moduleInstructor = ((TextNode) instructorNode)
.text();
String moduleName = secondCol.select(
"span.eventTitle").text();
String moduleDeadline = cols.get(2).text();
itemName.add(moduleName);
itemInstructor.add(moduleInstructor);
itemDate.add(moduleDeadline);
isModule.add(true);
}
}
} else if (firstCol.hasClass("tbdata")) {
// Es handelt sich um ein Event
String eventName = null, eventInstructor = null, eventDates = null;
if (innerChilds.size() == 1) {
// Event nur mit Namen
final String evNmHtml = secondCol.html();
eventName = TucanMobile
.getEventNameByString(evNmHtml);
eventInstructor = "";
eventDates = "";
} else if (innerChilds.size() == 7) {
// Event mit Vollinformationen
final Node instructorNode = innerChilds.get(4);
final Node dateNode = innerChilds.get(6);
if (instructorNode instanceof TextNode
&& dateNode instanceof TextNode) {
eventName = secondCol.select(
"span.eventTitle").text();
eventInstructor = ((TextNode) instructorNode)
.text().trim();
eventDates = ((TextNode) dateNode).text()
.trim();
}
} else if (innerChilds.size() == 5) {
// Event ohne Datum
final Node instructorNode = innerChilds.get(4);
if (instructorNode instanceof TextNode) {
eventName = secondCol.select(
"span.eventTitle").text();
eventInstructor = ((TextNode) instructorNode)
.text().trim();
eventDates = "";
}
}
itemName.add(eventName);
itemInstructor.add(eventInstructor);
itemDate.add(eventDates);
isModule.add(false);
}
}
}
// Adapter zum zurückgeben erstellen
singleEventAdapter = new HighlightedThreeLinesAdapter(context,
itemName, itemInstructor, itemDate, isModule);
}
return singleEventAdapter;
}
return null;
}
/**
* Gibt einen Adapter zurück welcher die Kategorien enthalten um tiefer zu
* gehen. Speichert ausserdem den Link zu diesen Kategorien in applyLink ab
*
* @param content
* Das Seitenelement, welches diese informationen enthält
* @return Adapter mit Kategorien
* @author Daniel Thiem
* @since 2012-11-26
*/
private ListAdapter getApplicationDeepLinkAdapter(Element content) {
final Elements deepLinkListElement = content
.select("div#contentSpacer_IE > ul");
if (deepLinkListElement.size() > 0) {
Elements deepLinkList = deepLinkListElement.first().select("li");
if (deepLinkList.size() > 0) {
// Tiefergehende Links verfügbar
applyLink = new ArrayList<String>();
ArrayList<String> applyName = new ArrayList<String>();
for (Element next : deepLinkList) {
// Listenelemente durchgehen
final Elements linkElement = next.select("a");
if (linkElement.size() == 1) {
applyLink.add(linkElement.attr("href"));
applyName.add(next.text());
}
}
if (TucanMobile.TESTING) {
System.out.println(applyName.toString());
}
ListAdapter deepListAdapter = new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, applyName);
return deepListAdapter;
}
}
return null;
}
/**
* Gibt einen Adapter zurück, welcher auf der Hauptseite angezeigt wird.
* Ausserdem speichert er die Links für die Einzelnen Seiten in den
* eventLinks ab
*
* @return ListAdapter mit der MenüNavigation
* @author Daniel Thiem
*
*/
private ListAdapter getMenuAdapter() {
// Commented old code and added new code below that.
// Elements links = doc.select("li#link000273").select("li");
// ArrayList<String> linkids = new ArrayList<String>();
// linkids.add("link000275");
// linkids.add("link000274");
// if (TucanMobile.DEBUG) {
// linkids.add("link000311");
// }
Elements links;
ArrayList<String> linkids;
if (!MainMenuScraper.isEnglish) { //if language is not english
links = doc.select("li#link000273").select("li");
linkids = new ArrayList<String>();
linkids.add("link000275");
linkids.add("link000274");
if (TucanMobile.DEBUG) {
linkids.add("link000311");
}
} else {
links = doc.select("li#link000176").select("li");
linkids = new ArrayList<String>();
linkids.add("link000177");
linkids.add("link000356");
if (TucanMobile.DEBUG) {
linkids.add("link000358");
}
}
Iterator<Element> linkIt = links.iterator();
eventLinks = new ArrayList<String>();
eventNames = new ArrayList<String>();
while (linkIt.hasNext()) {
Element next = linkIt.next();
String id = next.id();
// Links Veranstaltugen und Module finden und aufnehmen
if (linkids.contains(id)) {
eventLinks.add(next.select("a").attr("href"));
eventNames.add(next.select("a").text());
}
}
// ArrayList kopieren um Links nicht neu laden zu müssen
@SuppressWarnings("unchecked")
ArrayList<String> eventNameBuffer = (ArrayList<String>) eventNames
.clone();
// Adapter erstellen und einsetzen
ListAdapter = new ArrayAdapter<String>(context, R.layout.menu_row,
R.id.main_menu_row_textField, eventNameBuffer);
return ListAdapter;
}
}