/**
* 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 org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import android.content.Context;
import android.content.Intent;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import com.dalthed.tucan.R;
import com.dalthed.tucan.TucanMobile;
import com.dalthed.tucan.Connection.AnswerObject;
import com.dalthed.tucan.Connection.BrowserAnswerReciever;
import com.dalthed.tucan.Connection.CookieManager;
import com.dalthed.tucan.Connection.RequestObject;
import com.dalthed.tucan.Connection.SimpleSecureBrowser;
import com.dalthed.tucan.adapters.AppointmentAdapter;
import com.dalthed.tucan.adapters.TwoLinesAdapter;
import com.dalthed.tucan.exceptions.LostSessionException;
import com.dalthed.tucan.exceptions.TucanDownException;
import com.dalthed.tucan.helpers.FastSwitchHelper;
import com.dalthed.tucan.ui.FragmentSingleEvent.PagerAdapter;
import com.dalthed.tucan.ui.Module;
public class SingleEventScraper extends BasicScraper {
/**
* Prepcall wird bei einem Intent aus dem Schedule mitgesendet, und
* bedeutet, dass eine Seite geöffnet wurde, welche nur informationen zum
* einzelnen Termin gibt.
*/
public boolean PREPCall;
public ArrayList<String> materialLink;
private CookieManager localCookieManager;
private FastSwitchHelper fsh;
private PagerAdapter mPageAdapter;
private ViewPager mPager;
public SingleEventScraper(Context context, AnswerObject result, Boolean PREPCall,
FastSwitchHelper fsh, PagerAdapter mPageAdapter, ViewPager mPager) {
super(context, result);
this.PREPCall = PREPCall;
this.localCookieManager = result.getCookieManager();
this.fsh = fsh;
this.mPageAdapter = mPageAdapter;
this.mPager = mPager;
}
private static String[] crop(String startstring) {
int pos = startstring.indexOf("</b>"); //wir suchen nur den ersten close-Tag. Bei Split wuerden wir bei jedem </b> splitten!
if (startstring.length() > 0 && pos != -1 && startstring.length() > pos + 4) {
String first = startstring.substring(0, pos + 4);
String second = startstring.substring(pos + 4).trim();
// if(!first.endsWith(":</b>")) // Doppelpunkte immer in der ersten Zeile
// first.replaceAll("</b>", ":</b>");
// if(second.startsWith(":<br />")) // und nicht manchmal in der zweiten
// second = second.substring(7).trim();
// while(second.startsWith("<br />")) // Schwachsinn entfernen, z.B. " <br /> <br />SomeText"
// second = second.replaceFirst("<br />", "").trim();
// while(second.endsWith("<br />")) // Schwachsinn entfernen, z.B. "SomeText <br /> <br />"
// second = second.substring(0, second.length()-6).trim();
if (!first.endsWith(": </b>") && !first.endsWith(":</b>")) { // Doppelpunkte immer in der ersten Zeile
first = first.replaceAll("</b>", ":</b>");
}
if (second.startsWith(":<br />")) { // und nicht manchmal in der zweiten
second = second.substring(7).trim();
}
if (second.startsWith(":<br>")) { // und nicht manchmal in der zweiten
second = second.substring(5).trim();
}
while (second.startsWith("<br />")) { // Schwachsinn entfernen, z.B. " <br /> <br />SomeText"
second = second.replaceFirst("<br />", "").trim();
}
while (second.endsWith("<br />")) {// Schwachsinn entfernen, z.B. "SomeText <br /> <br />"
second = second.substring(0, second.length() - 6).trim();
}
return new String[]{Jsoup.parse(first).text().trim(),
second.trim()};
} else {
return new String[]{"", ""};
}
}
@Override
public ListAdapter scrapeAdapter(int mode) throws LostSessionException, TucanDownException {
if (checkForLostSeesion()) {
if (PREPCall == false) {
if (checkforModule()) {
return null;
}
String Title = doc.select("h1").text().replace("\n"," ");
if (fsh != null) {
fsh.setSubtitle(Title);
}
Iterator<Element> captionIt = doc.select("caption").iterator();
Iterator<Element> dateTable = null;
Iterator<Element> materialTable = null;
Iterator<Element> informationTable = null;
while (captionIt.hasNext()) {
Element next = captionIt.next();
// if (next.text().equals("Termine")) {
if (next.text().equals("Appointments") || next.text().equals("Termine")) {
dateTable = next.parent().select("tr").iterator();
} else if (next.text().contains("Material")) {
materialTable = next.parent().select("tr").iterator();
// } else if (next.text().contains("Veranstaltungsdetails")) {
} else if (next.text().contains("Course offering details") || next.text().contains("Veranstaltungsdetails")) {
informationTable = next.parent().select("tr").iterator();
}
}
scrapeInformations(informationTable);
scrapeAppointments(dateTable);
scrapeMaterials(materialTable);
if (mPageAdapter != null) {
mPageAdapter.initializeData(mPager);
}
} else {
// Es handelt sich um eine Übersichtsseite zu einem einzelnen
// Termin
callRealEventPage();
}
}
return null;
}
public void configurationChange(FastSwitchHelper fsh, PagerAdapter mPageAdapter,
ViewPager mPager) throws LostSessionException, TucanDownException {
this.fsh = fsh;
this.mPageAdapter = mPageAdapter;
this.mPager = mPager;
scrapeAdapter(0);
}
/**
*
*/
private void callRealEventPage() {
String nextlink = TucanMobile.TUCAN_PROT + TucanMobile.TUCAN_HOST
+ doc.select("div.detailout").select("a").attr("href");
if (context instanceof BrowserAnswerReciever) {
SimpleSecureBrowser callOverviewBrowser = new SimpleSecureBrowser(
(BrowserAnswerReciever) context);
RequestObject thisRequest = new RequestObject(nextlink, localCookieManager,
RequestObject.METHOD_GET, "");
PREPCall = false;
callOverviewBrowser.execute(thisRequest);
}
}
/**
* @param materialTable
*/
private void scrapeMaterials(Iterator<Element> materialTable) {
int ct = 0;
ArrayList<String> materialNumber = new ArrayList<String>();
ArrayList<String> materialName = new ArrayList<String>();
ArrayList<String> materialDesc = new ArrayList<String>();
materialLink = new ArrayList<String>();
ArrayList<String> materialFile = new ArrayList<String>();
int mod = 0;
if (materialTable != null) {
while (materialTable.hasNext()) {
Element next = materialTable.next();
if (next.select("td").size() > 1) {
ct++;
if (next.select("td").get(0).text().matches("[0-9]+")) {
// First line
materialNumber.add(next.select("td").get(0).text());
materialName.add(next.select("td").get(1).text());
if (mod == 1) {
materialDesc.add("");
mod = 2;
}
if (mod == 2) {
materialLink.add("");
materialFile.add("");
}
mod = 1;
} else if (mod == 1) {
materialDesc.add(next.select("td").get(1).text());
mod = 2;
} else if (mod == 2) {
materialLink.add(next.select("td").get(1).select("a").attr("href"));
materialFile.add(next.select("td").get(1).select("a").text());
mod = 0;
}
}
}
}
if (mod == 1) {
materialDesc.add("");
mod = 2;
}
if (mod == 2) {
materialLink.add("");
materialFile.add("");
}
if (ct > 2) {
if (mPageAdapter != null) {
mPageAdapter.setAdapter(new AppointmentAdapter(context, materialNumber,
materialFile, null, materialName, materialDesc));
mPageAdapter.fileList = materialLink;
}
} else if (mPageAdapter != null) {
// mPageAdapter.setAdapter(new ArrayAdapter<String>(context,android.R.layout.simple_list_item_1, new String[] { "Kein Material" }));
mPageAdapter.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, new String[]{context.getResources().getString(R.string.no_material)}));
}
}
/**
* @param DateTable
*/
private void scrapeAppointments(Iterator<Element> DateTable) {
ArrayList<String> eventNumber = new ArrayList<String>();
ArrayList<String> eventDate = new ArrayList<String>();
ArrayList<String> eventTime = new ArrayList<String>();
ArrayList<String> eventRoom = new ArrayList<String>();
ArrayList<String> eventInstructor = new ArrayList<String>();
if (DateTable != null) {
while (DateTable.hasNext()) {
Element next = DateTable.next();
Elements cols = next.select("td");
if (cols.size() > 5) {
eventNumber.add(cols.get(0).text());
eventDate.add(cols.get(1).text());
eventTime.add(cols.get(2).text() + "-" + cols.get(3).text());
eventRoom.add(cols.get(4).text());
eventInstructor.add(cols.get(5).text());
}
}
} else {
eventDate.add("");
eventTime.add("");
eventNumber.add("");
// eventRoom.add("Keine Daten vorhanden");
eventRoom.add(context.getResources().getString(R.string.no_data_available));
eventInstructor.add("");
}
if (mPageAdapter != null) {
mPageAdapter.setAdapter(new AppointmentAdapter(context, eventDate, eventTime,
eventNumber, eventRoom, eventInstructor));
}
}
/**
*
*/
private void scrapeInformations(Iterator<Element> informationIterator) {
while (informationIterator.hasNext()) {
Element nextElement = informationIterator.next();
Elements td = nextElement.select("td");
if(td!=null && td.hasClass("tbdata")){
Elements Paragraphs = nextElement.select("p");
Iterator<Element> PaIt = Paragraphs.iterator();
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> values = new ArrayList<String>();
while (PaIt.hasNext()) {
Element next = PaIt.next();
// String[] information = crop(next.html());
// if(information[1].length() > 0){
// titles.add(information[0]);
// values.add(information[1]);
// }
Element siblingElement = next.nextElementSibling();
String tmp = "";
if (siblingElement != null) {
tmp = siblingElement.toString();
}
String[] information = crop(next.html());
if ((information[1].length() > 0) || (!information[0].equals("") && (information[1].isEmpty() || information[1].length() == 0))) {
titles.add(information[0]);
if (tmp.startsWith("<ul>")) {
values.add(information[1] + " " + tmp);//
} else {
values.add(information[1]);
}
}
}
Log.i(LOG_TAG, "Informationscraper working");
if (mPageAdapter != null) {
Log.i(LOG_TAG, "InformationAdapter set");
mPageAdapter.setAdapter(new TwoLinesAdapter(context, titles, values));
}
}
}
}
/**
*
*/
private Boolean checkforModule() {
if (!doc.select("form[name=moduleform]").isEmpty()) {
// Möglicherweise ist ein Modul angewählt
Intent goToModule = new Intent(context, Module.class);
goToModule.putExtra("Cookie",
localCookieManager.getCookieHTTPString(TucanMobile.TUCAN_HOST));
goToModule.putExtra("URL", "HTML");
goToModule.putExtra("HTML", doc.html());
context.startActivity(goToModule);
return true;
}
return false;
}
}