/**
* Copyright (C) 2013 by Raphael Michel under the MIT license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software
* is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package de.geeksfactory.opacclient.apis;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import de.geeksfactory.opacclient.i18n.StringProvider;
import de.geeksfactory.opacclient.networking.HttpClientFactory;
import de.geeksfactory.opacclient.objects.Account;
import de.geeksfactory.opacclient.objects.AccountData;
import de.geeksfactory.opacclient.objects.Copy;
import de.geeksfactory.opacclient.objects.Detail;
import de.geeksfactory.opacclient.objects.DetailedItem;
import de.geeksfactory.opacclient.objects.Filter;
import de.geeksfactory.opacclient.objects.Filter.Option;
import de.geeksfactory.opacclient.objects.LentItem;
import de.geeksfactory.opacclient.objects.Library;
import de.geeksfactory.opacclient.objects.ReservedItem;
import de.geeksfactory.opacclient.objects.SearchRequestResult;
import de.geeksfactory.opacclient.objects.SearchResult;
import de.geeksfactory.opacclient.objects.SearchResult.MediaType;
import de.geeksfactory.opacclient.objects.SearchResult.Status;
import de.geeksfactory.opacclient.searchfields.DropdownSearchField;
import de.geeksfactory.opacclient.searchfields.SearchField;
import de.geeksfactory.opacclient.searchfields.SearchQuery;
import de.geeksfactory.opacclient.searchfields.TextSearchField;
public class Heidi extends BaseApi implements OpacApi {
protected String opac_url = "";
protected Library library;
protected JSONObject data;
protected String sessid;
protected String ENCODING = "UTF-8";
protected String last_error;
protected int pagesize = 20;
protected List<SearchQuery> last_query;
protected CookieStore cookieStore = new BasicCookieStore();
@Override
public void start() throws IOException {
String html = httpGet(opac_url + "/search.cgi?art=f", ENCODING, false,
cookieStore);
Document doc = Jsoup.parse(html);
doc.setBaseUri(opac_url);
sessid = null;
for (Element link : doc.select("a")) {
String sid = getQueryParamsFirst(link.absUrl("href")).get("sess");
if (sid != null) {
sessid = sid;
break;
}
}
super.start();
}
@Override
protected String getDefaultEncoding() {
return ENCODING;
}
@Override
public void init(Library library, HttpClientFactory httpClientFactory) {
super.init(library, httpClientFactory);
this.library = library;
this.data = library.getData();
this.opac_url = data.optString("baseurl", "");
}
protected int addParameters(String key, String value,
List<NameValuePair> params, int index) {
index++;
if (index != 3) {
params.add(new BasicNameValuePair("op" + index, "AND"));
}
params.add(new BasicNameValuePair("kat" + index, key));
params.add(new BasicNameValuePair("var" + index, value));
return index;
}
@Override
public SearchRequestResult search(List<SearchQuery> queries)
throws IOException, OpacErrorException {
last_query = queries;
List<NameValuePair> params = new ArrayList<>();
if (sessid == null) {
start();
}
int index = 0;
int page = 1;
String homebranch = "";
params.add(new BasicNameValuePair("fsubmit", "1"));
params.add(new BasicNameValuePair("sess", sessid));
params.add(new BasicNameValuePair("art", "f"));
params.add(new BasicNameValuePair("pagesize", String.valueOf(pagesize)));
for (SearchQuery query : queries) {
if (query.getKey().equals("_heidi_page")) {
page = Integer.parseInt(query.getValue());
params.add(new BasicNameValuePair("start", String
.valueOf((page - 1) * pagesize + 1)));
} else if (query.getKey().equals("_heidi_branch")) {
homebranch = query.getValue();
} else if (query.getKey().equals("f[teil2]")) {
params.add(new BasicNameValuePair(query.getKey(), query
.getValue()));
} else {
if (!query.getValue().equals("")) {
index = addParameters(query.getKey(), query.getValue(),
params, index);
}
}
}
params.add(new BasicNameValuePair("vr", "1"));
if (index == 0) {
throw new OpacErrorException(
stringProvider.getString(StringProvider.NO_CRITERIA_INPUT));
}
if (index > 3) {
throw new OpacErrorException(stringProvider.getQuantityString(
StringProvider.LIMITED_NUM_OF_CRITERIA, 3, 3));
}
while (index < 3) {
index++;
if (index != 3) {
params.add(new BasicNameValuePair("op" + index, "AND"));
}
params.add(new BasicNameValuePair("kat" + index, "freitext"));
params.add(new BasicNameValuePair("var" + index, ""));
}
// Homebranch selection
httpGet(opac_url + "/zweigstelle.cgi?sess=" + sessid + "&zweig="
+ homebranch, ENCODING, false, cookieStore);
// The actual search
String html = httpGet(
opac_url + "/search.cgi?"
+ URLEncodedUtils.format(params, "UTF-8"), ENCODING,
false, cookieStore);
return parse_search(html, page);
}
private SearchRequestResult parse_search(String html, int page) {
Document doc = Jsoup.parse(html);
doc.setBaseUri(opac_url);
int results_total = 0;
if (doc.select("#heiditreffer").size() > 0) {
String resstr = doc.select("#heiditreffer").text();
String resnum = resstr.replaceAll("\\(([0-9.]+)([^0-9]*)\\)", "$1")
.replace(".", "");
results_total = Integer.parseInt(resnum);
}
Elements table = doc.select("table.treffer tr");
List<SearchResult> results = new ArrayList<>();
for (int i = 0; i < table.size(); i++) {
Element tr = table.get(i);
SearchResult sr = new SearchResult();
StringBuilder description = null;
String author = "";
for (Element link : tr.select("a")) {
String kk = getQueryParamsFirst(link.absUrl("href")).get(
"katkey");
if (kk != null) {
sr.setId(kk);
break;
}
}
if (tr.select("span.Z3988").size() == 1) {
// Luckily there is a <span class="Z3988"> item which provides
// data in a standardized format.
String zdata = tr.select("span.Z3988").attr("title").replace(";", "%3B").replace(":", "%3A").replace("/", "%2F");
boolean hastitle = false;
description = new StringBuilder();
List<NameValuePair> z3988data = parse_z3988data(zdata);
for (NameValuePair nv : z3988data) {
if (nv.getValue() != null) {
if (!nv.getValue().trim().equals("")) {
if (nv.getName().equals("rft.btitle")
&& !hastitle) {
description.append("<b>").append(nv.getValue()).append("</b>");
hastitle = true;
} else if (nv.getName().equals("rft.atitle")
&& !hastitle) {
description.append("<b>").append(nv.getValue()).append("</b>");
hastitle = true;
} else if (nv.getName().equals("rft.au")) {
author = nv.getValue();
} else if (nv.getName().equals("rft.aufirst")) {
author = author + ", " + nv.getValue();
} else if (nv.getName().equals("rft.aulast")) {
author = nv.getValue();
} else if (nv.getName().equals("rft.date")) {
description.append("<br />").append(nv.getValue());
}
}
}
}
}
if (!"".equals(author)) {
author = author + "<br />";
}
sr.setInnerhtml(author + description.toString());
if (tr.select(".kurzstat").size() > 0) {
String stattext = tr.select(".kurzstat").first().text();
if (stattext.contains("ausleihbar")) {
sr.setStatus(Status.GREEN);
} else if (stattext.contains("online")) {
sr.setStatus(Status.GREEN);
} else if (stattext.contains("entliehen")) {
sr.setStatus(Status.RED);
} else if (stattext.contains("Präsenznutzung")) {
sr.setStatus(Status.YELLOW);
} else if (stattext.contains("bestellen")) {
sr.setStatus(Status.YELLOW);
}
}
if (tr.select(".typbild").size() > 0) {
String typtext = tr.select(".typbild").first().text();
if (typtext.contains("Buch")) {
sr.setType(MediaType.BOOK);
} else if (typtext.contains("DVD-ROM")) {
sr.setType(MediaType.CD_SOFTWARE);
} else if (typtext.contains("Online-Ressource")) {
sr.setType(MediaType.EDOC);
} else if (typtext.contains("DVD")) {
sr.setType(MediaType.DVD);
} else if (typtext.contains("Film")) {
sr.setType(MediaType.MOVIE);
} else if (typtext.contains("Zeitschrift")) {
sr.setType(MediaType.MAGAZINE);
} else if (typtext.contains("Musiknoten")) {
sr.setType(MediaType.SCORE_MUSIC);
} else if (typtext.contains("Bildliche Darstellung")) {
sr.setType(MediaType.ART);
} else if (typtext.contains("Zeitung")) {
sr.setType(MediaType.NEWSPAPER);
} else if (typtext.contains("Karte")) {
sr.setType(MediaType.MAP);
} else if (typtext.contains("Mehrteilig")) {
sr.setType(MediaType.PACKAGE_BOOKS);
}
}
results.add(sr);
}
// TODO
return new SearchRequestResult(results, results_total, page);
}
private List<NameValuePair> parse_z3988data(String zdata) {
List<NameValuePair> nvps = new ArrayList<>();
for (String tuple : zdata.split("&")) {
if (tuple.contains("=")) {
String[] parts = tuple.split("=");
if (parts.length < 2) {
continue;
}
try {
nvps.add(new BasicNameValuePair(parts[0], URLDecoder.decode(parts[1],
"UTF-8")));
} catch (UnsupportedEncodingException e) {
nvps.add(new BasicNameValuePair(parts[0], "?"));
}
} else {
nvps.add(new BasicNameValuePair(tuple, ""));
}
}
return nvps;
}
@Override
public SearchRequestResult filterResults(Filter filter, Option option)
throws IOException {
// Not implemented
return null;
}
@Override
public SearchRequestResult searchGetPage(int page) throws IOException,
OpacErrorException {
TextSearchField pagefield = new TextSearchField();
pagefield.setId("_heidi_page");
pagefield.setVisible(false);
pagefield.setDisplayName("Seite");
pagefield.setHint("");
for (SearchQuery q : last_query) {
if (q.getKey().equals("_heidi_page")) {
last_query.remove(q);
}
}
last_query.add(new SearchQuery(pagefield, String.valueOf(page)));
return search(last_query);
}
@Override
public SearchRequestResult volumeSearch(Map<String, String> query)
throws IOException, OpacErrorException {
String html = httpGet(opac_url + "/search.cgi?sess=" + sessid
+ "&format=html&query=" + query.get("query"), ENCODING, false,
cookieStore);
return parse_search(html, 1);
}
@Override
public DetailedItem getResultById(String id, final String homebranch)
throws IOException {
if (sessid == null) {
start();
}
// Homebranch
if (homebranch != null && !"".equals(homebranch)) {
cookieStore.addCookie(new BasicClientCookie("zweig", homebranch));
}
String html = httpGet(opac_url + "/titel.cgi?katkey=" + id + "&sess="
+ sessid, ENCODING, false, cookieStore);
Document doc = Jsoup.parse(html);
DetailedItem item = new DetailedItem();
item.setId(id);
Elements table = doc.select(".titelsatz tr");
for (Element tr : table) {
if (tr.select("th").size() == 0 || tr.select("td").size() == 0) {
continue;
}
String d = tr.select("th").first().text();
String c = tr.select("td").first().text();
if (d.equals("Titel:")) {
item.setTitle(c);
} else if ((d.contains("URL") || d.contains("Link")) && tr.select("td a").size() > 0) {
item.addDetail(new Detail(d, tr.select("td a").first().attr("href")));
} else {
item.addDetail(new Detail(d, c));
}
}
if (doc.select(".ex table tr").size() > 0) {
table = doc.select(".ex table tr");
DateTimeFormatter
fmt = DateTimeFormat.forPattern("dd.MM.yyyy").withLocale(Locale.GERMAN);
for (Element tr : table) {
if (tr.hasClass("exueber") || tr.select(".exsig").size() == 0
|| tr.select(".exso").size() == 0
|| tr.select(".exstatus").size() == 0) {
continue;
}
Copy copy = new Copy();
copy.setShelfmark(tr.select(".exsig").first().text());
copy.setBranch(tr.select(".exso").first().text());
String status = tr.select(".exstatus").first().text();
if (status.contains("entliehen bis")) {
copy.setReturnDate(fmt.parseLocalDate(
status.replaceAll("entliehen bis ([0-9.]+) .*", "$1")));
copy.setReservations(
status.replaceAll(".*\\(.*Vormerkungen: ([0-9]+)\\)", "$1"));
copy.setStatus("entliehen");
} else {
copy.setStatus(status);
}
item.addCopy(copy);
}
}
for (Element a : doc.select(".status1 a")) {
if (a.attr("href").contains("bestellung.cgi")) {
item.setReservable(true);
item.setReservation_info(id);
break;
}
}
for (Element a : doc.select(".titelsatz a")) {
if (a.text().trim().matches("B.+nde")) {
Map<String, String> volumesearch = new HashMap<>();
volumesearch.put("query", getQueryParamsFirst(a.attr("href"))
.get("query"));
item.setVolumesearch(volumesearch);
}
}
return item;
}
@Override
public DetailedItem getResult(int position) throws IOException {
throw new UnsupportedOperationException("Not implemented.");
}
@Override
public String getShareUrl(String id, String title) {
return opac_url + "/titel.cgi?katkey=" + id;
}
@Override
public int getSupportFlags() {
return SUPPORT_FLAG_ENDLESS_SCROLLING
| SUPPORT_FLAG_ACCOUNT_PROLONG_ALL;
}
@Override
public List<SearchField> parseSearchFields() throws IOException,
OpacErrorException, JSONException {
String html = httpGet(opac_url + "/search.cgi?art=f", ENCODING, false,
cookieStore);
Document doc = Jsoup.parse(html);
doc.setBaseUri(opac_url);
List<SearchField> fields = new ArrayList<>();
Elements options = doc.select("select[name=kat1] option");
for (Element option : options) {
TextSearchField field = new TextSearchField();
field.setDisplayName(option.text());
field.setId(option.attr("value"));
field.setHint("");
fields.add(field);
}
DropdownSearchField field = new DropdownSearchField();
Elements zst_opts = doc.select("#teilk2 option");
for (int i = 0; i < zst_opts.size(); i++) {
Element opt = zst_opts.get(i);
field.addDropdownValue(opt.val(), opt.text());
}
field.setDisplayName("Einrichtung");
field.setId("f[teil2]");
field.setVisible(true);
field.setMeaning(SearchField.Meaning.BRANCH);
fields.add(field);
try {
field = new DropdownSearchField();
Document doc2 = Jsoup.parse(httpGet(opac_url
+ "/zweigstelle.cgi?sess=" + sessid, ENCODING, false,
cookieStore));
Elements home_opts = doc2.select("#zweig option");
for (int i = 0; i < home_opts.size(); i++) {
Element opt = home_opts.get(i);
if (!opt.val().equals("")) {
Map<String, String> option = new HashMap<>();
option.put("key", opt.val());
option.put("value", opt.text());
field.addDropdownValue(opt.val(), opt.text());
}
}
field.setDisplayName("Leihstelle");
field.setId("_heidi_branch");
field.setVisible(true);
field.setMeaning(SearchField.Meaning.HOME_BRANCH);
fields.add(field);
} catch (IOException e) {
e.printStackTrace();
}
TextSearchField pagefield = new TextSearchField();
pagefield.setId("_heidi_page");
pagefield.setVisible(false);
pagefield.setDisplayName("Seite");
pagefield.setHint("");
fields.add(pagefield);
return fields;
}
@Override
public ReservationResult reservation(DetailedItem item, Account account,
int useraction, String selection) throws IOException {
String html = httpGet(opac_url + "/bestellung.cgi?ks=" + item.getId()
+ "&sess=" + sessid, ENCODING, false, cookieStore);
Document doc = Jsoup.parse(html);
if (doc.select("input[name=pw]").size() > 0) {
List<NameValuePair> nameValuePairs = new ArrayList<>(2);
nameValuePairs.add(new BasicNameValuePair("id", account.getName()));
nameValuePairs.add(new BasicNameValuePair("pw", account
.getPassword()));
nameValuePairs.add(new BasicNameValuePair("sess", sessid));
nameValuePairs.add(new BasicNameValuePair("log", "login"));
nameValuePairs.add(new BasicNameValuePair("weiter",
"bestellung.cgi?ks=" + item.getId()));
html = httpPost(opac_url + "/login.cgi", new UrlEncodedFormEntity(
nameValuePairs), ENCODING);
doc = Jsoup.parse(html);
if (doc.select(".loginbox .meld").size() > 0) {
return new ReservationResult(MultiStepResult.Status.ERROR, doc
.select(".loginbox .meld").text());
}
}
if (doc.select("input[name=ort]").size() > 0) {
if (selection != null) {
List<NameValuePair> nameValuePairs = new ArrayList<>(
2);
nameValuePairs.add(new BasicNameValuePair("ks", item.getId()));
nameValuePairs.add(new BasicNameValuePair("ort", selection));
nameValuePairs.add(new BasicNameValuePair("sess", sessid));
nameValuePairs.add(new BasicNameValuePair("funktion",
"Vormerkung"));
html = httpPost(opac_url + "/bestellung.cgi",
new UrlEncodedFormEntity(nameValuePairs), ENCODING);
doc = Jsoup.parse(html);
} else {
List<Map<String, String>> options = new ArrayList<>();
for (Element input : doc.select("input[name=ort]")) {
Element label = doc.select("label[for=" + input.id() + "]")
.first();
Map<String, String> selopt = new HashMap<>();
selopt.put("key", input.attr("value"));
selopt.put("value", label.text());
options.add(selopt);
}
ReservationResult res = new ReservationResult(
MultiStepResult.Status.SELECTION_NEEDED);
res.setSelection(options);
return res;
}
}
if (doc.select(".fehler").size() > 0) {
String text = doc.select(".fehler").text();
return new ReservationResult(MultiStepResult.Status.ERROR, text);
}
String text = doc.select(".meld2").text();
if (text.contains("Das Medium wurde")) {
return new ReservationResult(MultiStepResult.Status.OK, text);
} else {
return new ReservationResult(MultiStepResult.Status.ERROR, text);
}
}
@Override
public ProlongResult prolong(String media, Account account, int useraction,
String selection) throws IOException {
// Internal convention: a is either a § followed by an error message or
// the URI of the page this item was found on and the query string the
// prolonging link links to, seperated by a $.
if (media.startsWith("§")) {
String error = stringProvider.getString(StringProvider.PROLONGING_IMPOSSIBLE);
if (media.substring(1).equals("rot")) {
error = stringProvider.getString(StringProvider.PROLONGING_EXPIRED);
} else if (media.substring(1).equals("gruen")) {
error = stringProvider.getString(StringProvider.PROLONGING_WAITING);
}
return new ProlongResult(MultiStepResult.Status.ERROR, error);
}
List<NameValuePair> nameValuePairs = new ArrayList<>(2);
nameValuePairs
.add(new BasicNameValuePair("everl", "Einzelverlängerung"));
nameValuePairs.add(new BasicNameValuePair("mailversand", "Ok"));
nameValuePairs.add(new BasicNameValuePair("mark", media));
nameValuePairs.add(new BasicNameValuePair("sess", sessid));
String html = httpPost(opac_url + "/konto.cgi",
new UrlEncodedFormEntity(nameValuePairs), ENCODING);
Document doc = Jsoup.parse(html);
if (doc.select("input[name=pw]").size() > 0) {
try {
login(account);
} catch (OpacErrorException e) {
return new ProlongResult(MultiStepResult.Status.ERROR,
e.getMessage());
}
return prolong(media, account, useraction, selection);
}
if (doc.select(".meld2").size() > 0) {
String text = doc.select(".meld2").text();
if (text.matches(".*Neues Leihfristende.*")) {
return new ProlongResult(MultiStepResult.Status.OK, text);
} else {
return new ProlongResult(MultiStepResult.Status.ERROR, text);
}
}
return new ProlongResult(MultiStepResult.Status.OK);
}
@Override
public ProlongAllResult prolongAll(Account account, int useraction,
String selection) throws IOException {
String html = httpGet(opac_url + "/konto.cgi?sess=" + sessid
+ "&email=&verl=Gesamtkontoverlängerung", ENCODING);
Document doc = Jsoup.parse(html);
if (doc.select("input[name=pw]").size() > 0) {
try {
login(account);
} catch (OpacErrorException e) {
return new ProlongAllResult(MultiStepResult.Status.ERROR,
e.getMessage());
}
return prolongAll(account, useraction, selection);
}
List<Map<String, String>> result = new ArrayList<>();
Map<String, String> line = new HashMap<>();
for (Element tr : doc.select(".kontobox table tbody tr")) {
if (tr.children().size() < 2) {
if (line.size() > 0) {
line.put(ProlongAllResult.KEY_LINE_MESSAGE, tr.child(0)
.text().trim());
result.add(line);
line = new HashMap<>();
}
continue;
}
String label = tr.child(0).text();
String text = tr.child(1).text().trim();
if (label.contains("Verfasser")) {
line.put(ProlongAllResult.KEY_LINE_AUTHOR, text);
} else if (label.contains("Titel")) {
line.put(ProlongAllResult.KEY_LINE_TITLE, text);
} else if (label.contains("Altes Leihfristende")) {
line.put(ProlongAllResult.KEY_LINE_OLD_RETURNDATE, text);
} else if (label.contains("Neues")) {
line.put(ProlongAllResult.KEY_LINE_NEW_RETURNDATE, text);
}
}
return new ProlongAllResult(MultiStepResult.Status.OK, result);
}
@Override
public CancelResult cancel(String media, Account account, int useraction,
String selection) throws IOException, OpacErrorException {
List<NameValuePair> nameValuePairs = new ArrayList<>(2);
nameValuePairs.add(new BasicNameValuePair("storno",
"Vormerkung stornieren"));
nameValuePairs.add(new BasicNameValuePair("mark", media));
nameValuePairs.add(new BasicNameValuePair("sess", sessid));
String html = httpPost(opac_url + "/konto.cgi",
new UrlEncodedFormEntity(nameValuePairs), ENCODING);
Document doc = Jsoup.parse(html);
if (doc.select("input[name=pw]").size() > 0) {
login(account);
return cancel(media, account, useraction, selection);
}
if (doc.select(".meld2").size() > 0) {
String text = doc.select(".meld2").text();
if (text.matches(".*durchgef.+hrt.*")) {
return new CancelResult(MultiStepResult.Status.OK, text);
} else {
return new CancelResult(MultiStepResult.Status.ERROR, text);
}
}
return new CancelResult(MultiStepResult.Status.OK);
}
@Override
public AccountData account(Account account) throws IOException,
JSONException, OpacErrorException {
login(account);
String html;
Document doc;
AccountData adata = new AccountData(account.getId());
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd.MM.yyyy").withLocale(Locale.GERMAN);
html = httpGet(opac_url + "/konto.cgi?sess=" + sessid,
getDefaultEncoding());
doc = Jsoup.parse(html);
doc.setBaseUri(opac_url + "/");
for (Element td : doc.select("table.konto td")) {
if (td.text().contains("Offene")) {
String text = td
.text()
.trim()
.replaceAll(
"Offene[^0-9]+Geb.+hren:[^0-9]+([0-9.," +
"]+)[^0-9€A-Z]*(€|EUR|CHF|Fr.)",
"$1 $2");
adata.setPendingFees(text);
}
}
List<LentItem> lent = new ArrayList<>();
for (Element tr : doc.select("table.kontopos tr")) {
LentItem item = new LentItem();
Element desc = tr.child(1).select("label").first();
String dates = tr.child(2).text().trim();
if (tr.child(1).select("a").size() > 0) {
String kk = getQueryParamsFirst(
tr.child(1).select("a").first().absUrl("href")).get(
"katkey");
item.setId(kk);
}
int i = 0;
for (Node node : desc.childNodes()) {
if (node instanceof TextNode) {
String text = ((TextNode) node).text().trim();
if (i == 0) {
item.setAuthor(text);
} else if (i == 1) {
item.setTitle(text);
} else if (text.contains("Mediennummer")) {
item.setBarcode(text.replace("Mediennummer: ", ""));
}
i++;
}
}
if (tr.child(0).select("input").size() == 1) {
item.setProlongData(tr.child(0).select("input").first().val());
item.setRenewable(true);
} else {
item.setProlongData("§" + tr.child(0).select("span").first().attr("class"));
item.setRenewable(false);
}
String todate = dates;
if (todate.contains("-")) {
String[] datesplit = todate.split("-");
todate = datesplit[1].trim();
}
try {
item.setDeadline(fmt.parseLocalDate(todate.substring(0, 10)));
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
lent.add(item);
}
adata.setLent(lent);
List<ReservedItem> reservations = new ArrayList<>();
html = httpGet(opac_url + "/konto.cgi?konto=v&sess=" + sessid,
getDefaultEncoding());
reservations.addAll(parse_reservations(html));
html = httpGet(opac_url + "/konto.cgi?konto=b&sess=" + sessid,
getDefaultEncoding());
reservations.addAll(parse_reservations(html));
adata.setReservations(reservations);
return adata;
}
protected List<ReservedItem> parse_reservations(String html) {
Document doc = Jsoup.parse(html);
List<ReservedItem> reservations = new ArrayList<>();
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd.MM.yyyy").withLocale(Locale.GERMAN);
for (Element tr : doc.select("table.kontopos tr")) {
ReservedItem item = new ReservedItem();
Element desc = tr.child(1).select("label").first();
Element pos = tr.child(3);
if (tr.child(1).select("a").size() > 0) {
String kk = getQueryParamsFirst(
tr.child(1).select("a").first().absUrl("href")).get("katkey");
item.setId(kk);
}
if (tr.child(0).select("input").size() > 0) {
item.setCancelData(tr.child(0).select("input").first().val());
}
int i = 0;
for (Node node : desc.childNodes()) {
if (node instanceof TextNode) {
String text = ((TextNode) node).text().trim();
if (i == 0) {
item.setAuthor(text);
} else if (i == 1) {
item.setTitle(text);
}
i++;
}
}
i = 0;
for (Node node : pos.childNodes()) {
if (node instanceof TextNode) {
String text = ((TextNode) node).text().trim();
if (i == 0 && text.contains("")) {
try {
item.setReadyDate(fmt.parseLocalDate(text));
} catch (IllegalArgumentException e) {
item.setStatus(text);
}
} else if (i == 1) {
item.setBranch(text);
}
i++;
}
}
reservations.add(item);
}
return reservations;
}
protected void login(Account account) throws IOException,
OpacErrorException {
start();
List<NameValuePair> nameValuePairs = new ArrayList<>(2);
nameValuePairs.add(new BasicNameValuePair("id", account.getName()));
nameValuePairs.add(new BasicNameValuePair("pw", account.getPassword()));
nameValuePairs.add(new BasicNameValuePair("sess", sessid));
nameValuePairs.add(new BasicNameValuePair("log", "login"));
nameValuePairs.add(new BasicNameValuePair("weiter", "konto.cgi"));
String html = httpPost(opac_url + "/login.cgi",
new UrlEncodedFormEntity(nameValuePairs), ENCODING);
Document doc = Jsoup.parse(html);
if (doc.select(".loginbox .meld").size() > 0) {
throw new OpacErrorException(doc.select(".loginbox .meld").text());
}
}
@Override
public void checkAccountData(Account account) throws IOException,
JSONException, OpacErrorException {
login(account);
}
@Override
public void setLanguage(String language) {
// TODO Auto-generated method stub
}
@Override
public Set<String> getSupportedLanguages() throws IOException {
// TODO Auto-generated method stub
return null;
}
}