From dd59fa0fa9902f216b027a4954252e10ed84ec88 Mon Sep 17 00:00:00 2001 From: thesebas Date: Thu, 2 Jun 2016 02:22:57 +0200 Subject: [PATCH 1/9] initial opac4 --- .../opacclient/OpacApiFactory.java | 2 + .../geeksfactory/opacclient/apis/Opac4.java | 99 +++++++++++++++++++ .../bibs/PL_BielskoBiala_Ksiaznica.json | 17 ++++ .../src/main/assets/meanings/opac4.json | 1 + 4 files changed, 119 insertions(+) create mode 100644 opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Opac4.java create mode 100644 opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json create mode 100644 opacclient/opacapp/src/main/assets/meanings/opac4.json diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java index 68e9c9a5f..0c67d4e73 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java @@ -127,6 +127,8 @@ public static OpacApi create(Library lib, StringProvider sp, HttpClientFactory h newApiInstance = new TouchPoint(); } else if (lib.getApi().equals("open")) { newApiInstance = new Open(); + } else if (lib.getApi().equals("opac4")) { + newApiInstance = new Opac4(); } else if (lib.getApi().equals("test")) { newApiInstance = new TestApi(); } else { diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Opac4.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Opac4.java new file mode 100644 index 000000000..2d84aa3e1 --- /dev/null +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Opac4.java @@ -0,0 +1,99 @@ +package de.geeksfactory.opacclient.apis; + +import de.geeksfactory.opacclient.networking.HttpClientFactory; +import de.geeksfactory.opacclient.objects.*; +import de.geeksfactory.opacclient.searchfields.SearchField; +import de.geeksfactory.opacclient.searchfields.SearchQuery; +import org.json.JSONException; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +public class Opac4 extends BaseApi{ + @Override + public void init(Library lib, HttpClientFactory httpClientFactory) { + + + } + + @Override + public SearchRequestResult search(List query) throws IOException, OpacErrorException, JSONException { + return null; + } + + @Override + public SearchRequestResult filterResults(Filter filter, Filter.Option option) throws IOException, OpacErrorException { + return null; + } + + @Override + public SearchRequestResult searchGetPage(int page) throws IOException, OpacErrorException, JSONException { + return null; + } + + @Override + public DetailledItem getResultById(String id, String homebranch) throws IOException, OpacErrorException { + return null; + } + + @Override + public DetailledItem getResult(int position) throws IOException, OpacErrorException { + return null; + } + + @Override + public ReservationResult reservation(DetailledItem item, Account account, int useraction, String selection) throws IOException { + return null; + } + + @Override + public ProlongResult prolong(String media, Account account, int useraction, String selection) throws IOException { + return null; + } + + @Override + public ProlongAllResult prolongAll(Account account, int useraction, String selection) throws IOException { + return null; + } + + @Override + public CancelResult cancel(String media, Account account, int useraction, String selection) throws IOException, OpacErrorException { + return null; + } + + @Override + public AccountData account(Account account) throws IOException, JSONException, OpacErrorException { + return null; + } + + @Override + public void checkAccountData(Account account) throws IOException, JSONException, OpacErrorException { + + } + + @Override + public List getSearchFields() throws IOException, OpacErrorException, JSONException { + return null; + } + + @Override + public String getShareUrl(String id, String title) { + return null; + } + + @Override + public int getSupportFlags() { + return 0; + } + + @Override + public Set getSupportedLanguages() throws IOException { + return null; + } + + @Override + public void setLanguage(String language) { + + } +} \ No newline at end of file diff --git a/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json b/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json new file mode 100644 index 000000000..e06bbb073 --- /dev/null +++ b/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json @@ -0,0 +1,17 @@ +{ + "account_supported": false, + "api": "opac4", + "city": "Bielsko-Biała", + "country": "Polska", + "data": { + "baseurl": "http://185.43.138.133:8080/Opac4/" + }, + "geo": [ + 49.8240171, + 19.0405984 + ], + "information": "http://ksiaznica.bielsko.pl/", + "state": "śląskie", + "title": "Książnica Beskidzka", + "wiki": "https://pl.wikipedia.org/wiki/Ksi%C4%85%C5%BCnica_Beskidzka" +} diff --git a/opacclient/opacapp/src/main/assets/meanings/opac4.json b/opacclient/opacapp/src/main/assets/meanings/opac4.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/opacclient/opacapp/src/main/assets/meanings/opac4.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 2af58c7b3e5f3da61a655e02fe45ec1409c45f73 Mon Sep 17 00:00:00 2001 From: thesebas Date: Thu, 2 Jun 2016 02:26:24 +0200 Subject: [PATCH 2/9] un-auto-optimize imports --- .../src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java index 0c67d4e73..e82160c30 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java @@ -26,6 +26,7 @@ import de.geeksfactory.opacclient.apis.Littera; import de.geeksfactory.opacclient.apis.OpacApi; import de.geeksfactory.opacclient.apis.Open; +import de.geeksfactory.opacclient.apis.Opac4; import de.geeksfactory.opacclient.apis.PicaLBS; import de.geeksfactory.opacclient.apis.PicaOld; import de.geeksfactory.opacclient.apis.Primo; From 95582cff576cc4dd943cbb79a6508d402c57cf46 Mon Sep 17 00:00:00 2001 From: thesebas Date: Thu, 2 Jun 2016 13:09:07 +0200 Subject: [PATCH 3/9] rename Opac4 to Patron --- .../java/de/geeksfactory/opacclient/OpacApiFactory.java | 6 +++--- .../opacclient/apis/{Opac4.java => Patron.java} | 2 +- .../src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/{Opac4.java => Patron.java} (98%) diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java index e82160c30..07e481137 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/OpacApiFactory.java @@ -26,7 +26,7 @@ import de.geeksfactory.opacclient.apis.Littera; import de.geeksfactory.opacclient.apis.OpacApi; import de.geeksfactory.opacclient.apis.Open; -import de.geeksfactory.opacclient.apis.Opac4; +import de.geeksfactory.opacclient.apis.Patron; import de.geeksfactory.opacclient.apis.PicaLBS; import de.geeksfactory.opacclient.apis.PicaOld; import de.geeksfactory.opacclient.apis.Primo; @@ -128,8 +128,8 @@ public static OpacApi create(Library lib, StringProvider sp, HttpClientFactory h newApiInstance = new TouchPoint(); } else if (lib.getApi().equals("open")) { newApiInstance = new Open(); - } else if (lib.getApi().equals("opac4")) { - newApiInstance = new Opac4(); + } else if (lib.getApi().equals("patron")) { + newApiInstance = new Patron(); } else if (lib.getApi().equals("test")) { newApiInstance = new TestApi(); } else { diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Opac4.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java similarity index 98% rename from opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Opac4.java rename to opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java index 2d84aa3e1..436e059da 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Opac4.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java @@ -10,7 +10,7 @@ import java.util.List; import java.util.Set; -public class Opac4 extends BaseApi{ +public class Patron extends BaseApi{ @Override public void init(Library lib, HttpClientFactory httpClientFactory) { diff --git a/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json b/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json index e06bbb073..4b00d20b2 100644 --- a/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json +++ b/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json @@ -1,6 +1,6 @@ { "account_supported": false, - "api": "opac4", + "api": "patron", "city": "Bielsko-Biała", "country": "Polska", "data": { From d5ff64d8fd5353d38602a51141f97679e43dfa29 Mon Sep 17 00:00:00 2001 From: thesebas Date: Thu, 9 Jun 2016 00:08:09 +0200 Subject: [PATCH 4/9] search form parsing and 2 more libraries --- opacclient/.idea/vcs.xml | 4 +- .../geeksfactory/opacclient/apis/Patron.java | 143 ++++++++++++++++-- .../bibs/PL_BielskoBiala_Ksiaznica.json | 6 +- .../src/main/assets/bibs/PL_Tczew.json | 15 ++ .../src/main/assets/bibs/PL_Wejherowo.json | 15 ++ .../src/main/assets/meanings/opac4.json | 1 - .../src/main/assets/meanings/patron.json | 5 + 7 files changed, 169 insertions(+), 20 deletions(-) create mode 100644 opacclient/opacapp/src/main/assets/bibs/PL_Tczew.json create mode 100644 opacclient/opacapp/src/main/assets/bibs/PL_Wejherowo.json delete mode 100644 opacclient/opacapp/src/main/assets/meanings/opac4.json create mode 100644 opacclient/opacapp/src/main/assets/meanings/patron.json diff --git a/opacclient/.idea/vcs.xml b/opacclient/.idea/vcs.xml index 21cbaa607..0e6ace726 100644 --- a/opacclient/.idea/vcs.xml +++ b/opacclient/.idea/vcs.xml @@ -2,6 +2,6 @@ + - - + \ No newline at end of file diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java index 436e059da..3f90afd4a 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java @@ -2,38 +2,65 @@ import de.geeksfactory.opacclient.networking.HttpClientFactory; import de.geeksfactory.opacclient.objects.*; +import de.geeksfactory.opacclient.searchfields.DropdownSearchField; import de.geeksfactory.opacclient.searchfields.SearchField; import de.geeksfactory.opacclient.searchfields.SearchQuery; +import de.geeksfactory.opacclient.searchfields.TextSearchField; + +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.message.BasicNameValuePair; 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.select.Elements; import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.Set; -public class Patron extends BaseApi{ +public class Patron extends BaseApi { + + private String base_url; + @Override public void init(Library lib, HttpClientFactory httpClientFactory) { - + super.init(lib, httpClientFactory); + try { + base_url = lib.getData().getString("baseurl"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + System.err.print("starting Patron"); } @Override - public SearchRequestResult search(List query) throws IOException, OpacErrorException, JSONException { + public SearchRequestResult search(List query) + throws IOException, OpacErrorException, JSONException { return null; } @Override - public SearchRequestResult filterResults(Filter filter, Filter.Option option) throws IOException, OpacErrorException { + public SearchRequestResult filterResults(Filter filter, Filter.Option option) + throws IOException, OpacErrorException { return null; } @Override - public SearchRequestResult searchGetPage(int page) throws IOException, OpacErrorException, JSONException { + public SearchRequestResult searchGetPage(int page) + throws IOException, OpacErrorException, JSONException { return null; } @Override - public DetailledItem getResultById(String id, String homebranch) throws IOException, OpacErrorException { + public DetailledItem getResultById(String id, String homebranch) + throws IOException, OpacErrorException { return null; } @@ -43,38 +70,126 @@ public DetailledItem getResult(int position) throws IOException, OpacErrorExcept } @Override - public ReservationResult reservation(DetailledItem item, Account account, int useraction, String selection) throws IOException { + public ReservationResult reservation(DetailledItem item, Account account, int useraction, + String selection) throws IOException { return null; } @Override - public ProlongResult prolong(String media, Account account, int useraction, String selection) throws IOException { + public ProlongResult prolong(String media, Account account, int useraction, String selection) + throws IOException { return null; } @Override - public ProlongAllResult prolongAll(Account account, int useraction, String selection) throws IOException { + public ProlongAllResult prolongAll(Account account, int useraction, String selection) + throws IOException { return null; } @Override - public CancelResult cancel(String media, Account account, int useraction, String selection) throws IOException, OpacErrorException { + public CancelResult cancel(String media, Account account, int useraction, String selection) + throws IOException, OpacErrorException { return null; } @Override - public AccountData account(Account account) throws IOException, JSONException, OpacErrorException { + public AccountData account(Account account) + throws IOException, JSONException, OpacErrorException { return null; } @Override - public void checkAccountData(Account account) throws IOException, JSONException, OpacErrorException { + public void checkAccountData(Account account) + throws IOException, JSONException, OpacErrorException { } + protected HttpEntity preGetSearchFields(String url) throws IOException { + String html = httpGet(url, getDefaultEncoding(), true); + Document doc = Jsoup.parse(html); + + List params = new ArrayList<>(); + for (Element e : doc.select("#form1").select("input")) { + params.add(new BasicNameValuePair(e.attr("name"), e.attr("value"))); + } + return new UrlEncodedFormEntity(params); + } + @Override - public List getSearchFields() throws IOException, OpacErrorException, JSONException { - return null; + public List getSearchFields() + throws IOException, OpacErrorException, JSONException { + + String url = base_url + "faces/Szukaj.jsp"; + String html = httpPost(url, preGetSearchFields(base_url), getDefaultEncoding()); + Document doc = Jsoup.parse(html); + List fields = new LinkedList<>(); + + try { + Elements options = doc.select("[id=\"form1:dropdown1\"]").first().select("option"); + + for (Element option : options) { + + TextSearchField field = new TextSearchField(); + field.setDisplayName(option.text()); + field.setId("@term" + option.val()); + + field.setData(new JSONObject()); + field.getData().put("meaning", field.getId()); + field.setHint(""); + fields.add(field); + } + + + Elements txtFields = doc.select("[id=\"form1:textField4\"],[id=\"form1:textField5\"]"); + for (Element txtField : txtFields) { + TextSearchField field = new TextSearchField(); + String displayName = doc + .select(String.format("label[for=\"%s\"", txtField.id())) + .first() + .text() + .replaceAll(":$", ""); + field.setDisplayName(displayName); + field.setId("#" + txtField.id()); + + field.setData(new JSONObject()); + field.getData().put("meaning", field.getId()); + field.setHint(""); + fields.add(field); + } + + Elements selects = doc.select("[id=\"form1:dropdown4\"]," + + "[id=\"form1:dropdown5\"]," + + "[id=\"form1:dropdown6\"]," + + "[id=\"form1:dropdown7\"]" + ); + + for (Element select : selects) { + options = select.select("option"); + DropdownSearchField field = new DropdownSearchField(); + for (Element option : options) { + field.addDropdownValue(option.val(), option.text()); + } + field.setId("#" + select.id()); + field.setData(new JSONObject()); + field.getData().put("meaning", field.getId()); + + String displayName = doc + .select(String.format("label[for=\"%s\"", select.id())) + .first() + .text() + .replaceAll(":$", ""); + + field.setDisplayName(displayName); + fields.add(field); + } + throw new Exception("thesebas some err"); + + } catch (Exception e) { + System.err.print(e.getMessage()); + } + + return fields; } @Override diff --git a/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json b/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json index 4b00d20b2..ac0f34995 100644 --- a/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json +++ b/opacclient/opacapp/src/main/assets/bibs/PL_BielskoBiala_Ksiaznica.json @@ -4,7 +4,8 @@ "city": "Bielsko-Biała", "country": "Polska", "data": { - "baseurl": "http://185.43.138.133:8080/Opac4/" + "baseurl": "http://185.43.138.133:8080/Opac4/", + "wiki": "https://pl.wikipedia.org/wiki/Ksi%C4%85%C5%BCnica_Beskidzka" }, "geo": [ 49.8240171, @@ -12,6 +13,5 @@ ], "information": "http://ksiaznica.bielsko.pl/", "state": "śląskie", - "title": "Książnica Beskidzka", - "wiki": "https://pl.wikipedia.org/wiki/Ksi%C4%85%C5%BCnica_Beskidzka" + "title": "Książnica Beskidzka" } diff --git a/opacclient/opacapp/src/main/assets/bibs/PL_Tczew.json b/opacclient/opacapp/src/main/assets/bibs/PL_Tczew.json new file mode 100644 index 000000000..0375a8671 --- /dev/null +++ b/opacclient/opacapp/src/main/assets/bibs/PL_Tczew.json @@ -0,0 +1,15 @@ +{ + "account_supported": false, + "api": "patron", + "city": "Tczew", + "country": "Polska", + "data": { + "baseurl": "http://mbp.tczew.pl:8080/Opac4/" + }, + "geo": [ + 54.092192, 18.777331 + ], + "information": "http://mbp.tczew.pl", + "state": "pomorskie", + "title": "Miejska Biblioteka Publiczna w Tczewie" +} diff --git a/opacclient/opacapp/src/main/assets/bibs/PL_Wejherowo.json b/opacclient/opacapp/src/main/assets/bibs/PL_Wejherowo.json new file mode 100644 index 000000000..35312a31b --- /dev/null +++ b/opacclient/opacapp/src/main/assets/bibs/PL_Wejherowo.json @@ -0,0 +1,15 @@ +{ + "account_supported": false, + "api": "patron", + "city": "Wejherowo", + "country": "Polska", + "data": { + "baseurl": "http://biblioteka.wejherowo.pl:81/Opac4/" + }, + "geo": [ + 54.604167, 18.248889 + ], + "information": "http://biblioteka.wejherowo.pl/", + "state": "pomorskie", + "title": "Miejska Biblioteka Publiczna im. Aleksandra Majkowskiego w Wejherowie" +} diff --git a/opacclient/opacapp/src/main/assets/meanings/opac4.json b/opacclient/opacapp/src/main/assets/meanings/opac4.json deleted file mode 100644 index 9e26dfeeb..000000000 --- a/opacclient/opacapp/src/main/assets/meanings/opac4.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/opacclient/opacapp/src/main/assets/meanings/patron.json b/opacclient/opacapp/src/main/assets/meanings/patron.json new file mode 100644 index 000000000..ce9f05eb4 --- /dev/null +++ b/opacclient/opacapp/src/main/assets/meanings/patron.json @@ -0,0 +1,5 @@ +{ + "@term1": "AUTHOR", + "@term2": "TITLE", + "@term7": "FREE" +} \ No newline at end of file From 5bfebd3191069491d063cf0370ffd3a8ce195f3b Mon Sep 17 00:00:00 2001 From: thesebas Date: Thu, 20 Oct 2016 18:38:16 +0200 Subject: [PATCH 5/9] search form parsing fixes, results parsing --- opacclient/libopac/build.gradle | 3 + .../geeksfactory/opacclient/apis/Patron.java | 135 ++++++++++++++++-- .../opacclient/objects/SearchResult.java | 2 +- .../src/main/assets/meanings/patron.json | 4 +- .../opacclient/frontend/ResultsAdapter.java | 2 + 5 files changed, 135 insertions(+), 11 deletions(-) diff --git a/opacclient/libopac/build.gradle b/opacclient/libopac/build.gradle index 94e7f24fc..5287d9b67 100644 --- a/opacclient/libopac/build.gradle +++ b/opacclient/libopac/build.gradle @@ -58,3 +58,6 @@ ext { } apply from: '../bintray.gradle' +dependencies { + compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1' +} \ No newline at end of file diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java index 3f90afd4a..10abc7e05 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java @@ -1,5 +1,6 @@ package de.geeksfactory.opacclient.apis; +import de.geeksfactory.opacclient.i18n.StringProvider; import de.geeksfactory.opacclient.networking.HttpClientFactory; import de.geeksfactory.opacclient.objects.*; import de.geeksfactory.opacclient.searchfields.DropdownSearchField; @@ -7,9 +8,14 @@ import de.geeksfactory.opacclient.searchfields.SearchQuery; import de.geeksfactory.opacclient.searchfields.TextSearchField; +import org.apache.commons.codec.binary.Base64OutputStream; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; +import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.message.BasicNameValuePair; import org.json.JSONException; import org.json.JSONObject; @@ -18,7 +24,11 @@ import org.jsoup.nodes.Element; import org.jsoup.select.Elements; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -27,23 +37,87 @@ public class Patron extends BaseApi { private String base_url; + protected CookieStore cookieStore; + protected static String QUERY_URL = "faces/Szukaj.jsp"; + + protected List lastFormState; @Override public void init(Library lib, HttpClientFactory httpClientFactory) { super.init(lib, httpClientFactory); + cookieStore = new BasicCookieStore(); try { base_url = lib.getData().getString("baseurl"); } catch (JSONException e) { throw new RuntimeException(e); } - System.err.print("starting Patron"); + } + @Override + protected String getDefaultEncoding() { + return "UTF-8"; } @Override public SearchRequestResult search(List query) throws IOException, OpacErrorException, JSONException { - return null; + + List sp = buildSearchParams(query); + sp.add(new BasicNameValuePair("form1:btnSzukajIndeks", "Szukaj")); + HttpEntity ent = buildHttpEntity(sp); + String html = httpPost(base_url + QUERY_URL, ent, getDefaultEncoding(), false, cookieStore); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + Document doc = Jsoup.parse(html); + + return parseResults(doc, 1); + } + + private SearchRequestResult parseResults(Document doc, int i) { + List results = new ArrayList<>(); + int total_result_count = 0; + int page_count = 0; + int page_index = i; + + SearchRequestResult result = + new SearchRequestResult(results, total_result_count, page_count, page_index); + + return result; + } + + private HttpEntity buildHttpEntity(List nameValuePairs) throws IOException { + return new UrlEncodedFormEntity(nameValuePairs); + } + + protected List buildSearchParams(List query) + throws OpacErrorException { + List params = lastFormState; + + int n = 0; + for (SearchQuery term : query) { + if (term.getValue().isEmpty()) continue; + if (term.getKey().startsWith("@")) { + n++; + + if (n > 3) { + throw new OpacErrorException(stringProvider.getQuantityString( + StringProvider.LIMITED_NUM_OF_CRITERIA, 3, 3)); + } + + params.add(new BasicNameValuePair("form1:textField" + n, term.getValue())); + if (n > 1) { + params.add(new BasicNameValuePair("rbOper" + (n - 1), "a")); + } + continue; + } + if (term.getSearchField().getId().startsWith("#")) { + + params.add(new BasicNameValuePair(term.getKey().substring(1), term.getValue())); + } + } + params.add(new BasicNameValuePair("rbOperStem", "a")); + + return params; } @Override @@ -105,15 +179,32 @@ public void checkAccountData(Account account) } - protected HttpEntity preGetSearchFields(String url) throws IOException { - String html = httpGet(url, getDefaultEncoding(), true); - Document doc = Jsoup.parse(html); + protected FormParseResult parseForm(String html) { + return parseForm(Jsoup.parse(html)); + } + protected FormParseResult parseForm(Document doc) { List params = new ArrayList<>(); - for (Element e : doc.select("#form1").select("input")) { + Element form = doc.select("#form1").first(); + for (Element e : form.select("input[type=\"text\"],input[type=\"hidden\"]," + + "input[type=\"radio\"][checked=\"checked\"],input[type=\"submit\"]" + )) { params.add(new BasicNameValuePair(e.attr("name"), e.attr("value"))); } - return new UrlEncodedFormEntity(params); + + for (Element select : form.select("select")) { + Elements selectedOptions = select.select("option[selected=\"selected\"]"); + if (!selectedOptions.isEmpty()) { + params.add(new BasicNameValuePair(select.attr("name"), + selectedOptions.first().attr("value"))); + } else { + Element firstOptions = select.select("option").first(); + params.add(new BasicNameValuePair(select.attr("name"), firstOptions.attr("value"))); + } + + } + + return new FormParseResult(form, params); } @Override @@ -121,8 +212,24 @@ public List getSearchFields() throws IOException, OpacErrorException, JSONException { String url = base_url + "faces/Szukaj.jsp"; - String html = httpPost(url, preGetSearchFields(base_url), getDefaultEncoding()); - Document doc = Jsoup.parse(html); + String html = httpGet(url, getDefaultEncoding(), false, cookieStore); + FormParseResult res = parseForm(html); + res.params.add(new BasicNameValuePair("form1:lnkZaaw", "form1:lnkZaaw")); + + url = res.form.attr("action"); + try { + URIBuilder ub = new URIBuilder(base_url); + ub.setPath(url); + url = ub.build().toString(); + } catch (URISyntaxException e) { + url = base_url + "faces/Szukaj.jsp"; + } + html = httpPost(url, new UrlEncodedFormEntity(res.params), + getDefaultEncoding(), false, cookieStore); + + res = parseForm(html); + lastFormState = res.params; + Element doc = res.form; List fields = new LinkedList<>(); try { @@ -211,4 +318,14 @@ public Set getSupportedLanguages() throws IOException { public void setLanguage(String language) { } + + private class FormParseResult { + public Element form; + public List params; + + public FormParseResult(Element form, List params) { + this.form = form; + this.params = params; + } + } } \ No newline at end of file diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/SearchResult.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/SearchResult.java index 37a072f02..73b8e148a 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/SearchResult.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/SearchResult.java @@ -233,7 +233,7 @@ public enum MediaType { GAME_CONSOLE, EBOOK, SCORE_MUSIC, PACKAGE_BOOKS, UNKNOWN, NEWSPAPER, BOARDGAME, SCHOOL_VERSION, MAP, BLURAY, AUDIO_CASSETTE, ART, MAGAZINE, GAME_CONSOLE_WII, GAME_CONSOLE_NINTENDO, GAME_CONSOLE_PLAYSTATION, - GAME_CONSOLE_XBOX, LP_RECORD, MP3, URL, EVIDEO, EDOC, EAUDIO + GAME_CONSOLE_XBOX, LP_RECORD, MP3, URL, EVIDEO, EDOC, EAUDIO, OLD_PRINT } /** diff --git a/opacclient/opacapp/src/main/assets/meanings/patron.json b/opacclient/opacapp/src/main/assets/meanings/patron.json index ce9f05eb4..38931b8dd 100644 --- a/opacclient/opacapp/src/main/assets/meanings/patron.json +++ b/opacclient/opacapp/src/main/assets/meanings/patron.json @@ -1,5 +1,7 @@ { "@term1": "AUTHOR", "@term2": "TITLE", - "@term7": "FREE" + "@term7": "FREE", + "#form1:textField4": "YEAR", + "#form1:textField5": "YEAR" } \ No newline at end of file diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/ResultsAdapter.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/ResultsAdapter.java index b65d1514c..fedbb91ca 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/ResultsAdapter.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/ResultsAdapter.java @@ -109,6 +109,8 @@ public static int getResourceByMediaType(MediaType type) { return R.drawable.type_map; case LP_RECORD: return R.drawable.type_lp_record; + case OLD_PRINT: + return R.drawable.type_unknown; } return R.drawable.type_unknown; From 79a16e1c3d0822c8bb22503373c10c1ea989e5b5 Mon Sep 17 00:00:00 2001 From: thesebas Date: Fri, 21 Oct 2016 01:33:40 +0200 Subject: [PATCH 6/9] rename function because of new interface/abstract base class --- .../src/main/java/de/geeksfactory/opacclient/apis/Patron.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java index 10abc7e05..9696ebd62 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java @@ -208,7 +208,7 @@ protected FormParseResult parseForm(Document doc) { } @Override - public List getSearchFields() + public List parseSearchFields() throws IOException, OpacErrorException, JSONException { String url = base_url + "faces/Szukaj.jsp"; From 83b3a7718c999415569bc957063789d5b9a3aaa9 Mon Sep 17 00:00:00 2001 From: thesebas Date: Fri, 21 Oct 2016 08:41:48 +0200 Subject: [PATCH 7/9] remove uneccessary dep --- opacclient/libopac/build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/opacclient/libopac/build.gradle b/opacclient/libopac/build.gradle index 5287d9b67..94e7f24fc 100644 --- a/opacclient/libopac/build.gradle +++ b/opacclient/libopac/build.gradle @@ -58,6 +58,3 @@ ext { } apply from: '../bintray.gradle' -dependencies { - compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1' -} \ No newline at end of file From 353595f878b6ac97c5e502ed0cd663d079fc64b9 Mon Sep 17 00:00:00 2001 From: thesebas Date: Fri, 21 Oct 2016 08:44:05 +0200 Subject: [PATCH 8/9] undo .idea project file --- opacclient/.idea/vcs.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opacclient/.idea/vcs.xml b/opacclient/.idea/vcs.xml index 0e6ace726..21cbaa607 100644 --- a/opacclient/.idea/vcs.xml +++ b/opacclient/.idea/vcs.xml @@ -2,6 +2,6 @@ - - \ No newline at end of file + + From 6d2d9875cb4b1d911543734b6cca7949671ff0b4 Mon Sep 17 00:00:00 2001 From: thesebas Date: Tue, 25 Oct 2016 08:35:14 +0200 Subject: [PATCH 9/9] results parsing improvements --- .../geeksfactory/opacclient/apis/Patron.java | 68 +++++++++++++++---- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java index 9696ebd62..925edce6a 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/apis/Patron.java @@ -8,13 +8,11 @@ import de.geeksfactory.opacclient.searchfields.SearchQuery; import de.geeksfactory.opacclient.searchfields.TextSearchField; -import org.apache.commons.codec.binary.Base64OutputStream; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.utils.URIBuilder; -import org.apache.http.entity.BasicHttpEntity; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.message.BasicNameValuePair; import org.json.JSONException; @@ -28,11 +26,12 @@ import java.io.IOException; import java.io.OutputStream; import java.net.URISyntaxException; -import java.net.URL; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Patron extends BaseApi { @@ -66,19 +65,52 @@ public SearchRequestResult search(List query) sp.add(new BasicNameValuePair("form1:btnSzukajIndeks", "Szukaj")); HttpEntity ent = buildHttpEntity(sp); String html = httpPost(base_url + QUERY_URL, ent, getDefaultEncoding(), false, cookieStore); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); +// ent.writeTo(baos); +// String s = new String(baos.toByteArray(), "utf-8"); Document doc = Jsoup.parse(html); return parseResults(doc, 1); } + private SearchResult parseListItem(Element item) { + SearchResult result = new SearchResult(); + + Element info = item.select(".info").first(); + info.select("script").remove(); + result.setInnerhtml(info.html()); + result.setId(item.id()); + + return result; + } + + + private int parseTotalResultCount(Element doc){ + Pattern p = Pattern.compile("Liczba rekordów:\\s*(\\d+)"); + + Matcher m = p.matcher(doc.select("#opisy").text()); + if(!m.find()){ + return 0; + } + return Integer.parseInt(m.group(1)); + } + private int parsePageCount(Element doc){ + return 1; + } + private int parsePageIndex(Element doc){ + return Integer.parseInt( doc.select("#opisy .linki").eq(1).select(".sel").first().text()); + } + private SearchRequestResult parseResults(Document doc, int i) { List results = new ArrayList<>(); - int total_result_count = 0; - int page_count = 0; - int page_index = i; - + int total_result_count = parseTotalResultCount(doc); + int page_count = parsePageCount(doc); + int page_index = parsePageIndex(doc); + for (Element e : doc.select("#opisy .opis")) { + results.add(parseListItem(e)); + } SearchRequestResult result = new SearchRequestResult(results, total_result_count, page_count, page_index); @@ -91,6 +123,15 @@ private HttpEntity buildHttpEntity(List nameValuePairs) throws IO protected List buildSearchParams(List query) throws OpacErrorException { + if (lastFormState == null) { + try { + parseSearchFields(); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } List params = lastFormState; int n = 0; @@ -186,9 +227,13 @@ protected FormParseResult parseForm(String html) { protected FormParseResult parseForm(Document doc) { List params = new ArrayList<>(); Element form = doc.select("#form1").first(); - for (Element e : form.select("input[type=\"text\"],input[type=\"hidden\"]," + - "input[type=\"radio\"][checked=\"checked\"],input[type=\"submit\"]" - )) { + + Elements elements = form.select( + "input[type=\"text\"],input[type=\"hidden\"]," + + "input[type=\"radio\"][checked=\"checked\"],input[type=\"submit\"]" + ).not("[id=\"form1:btnCzyscForme\"]"); + + for (Element e : elements) { params.add(new BasicNameValuePair(e.attr("name"), e.attr("value"))); } @@ -290,7 +335,6 @@ public List parseSearchFields() field.setDisplayName(displayName); fields.add(field); } - throw new Exception("thesebas some err"); } catch (Exception e) { System.err.print(e.getMessage());