--- /dev/null
+/*
+ * Copyright (C) 2014 Naofumi Fukue
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.geeksfactory.opacclient.apis;
+
+import java.io.IOException;
+import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+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.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 de.geeksfactory.opacclient.ISBNTools;
+import de.geeksfactory.opacclient.NotReachableException;
+import de.geeksfactory.opacclient.objects.Account;
+import de.geeksfactory.opacclient.objects.AccountData;
+import de.geeksfactory.opacclient.objects.Detail;
+import de.geeksfactory.opacclient.objects.DetailledItem;
+import de.geeksfactory.opacclient.objects.Filter;
+import de.geeksfactory.opacclient.objects.Filter.Option;
+import de.geeksfactory.opacclient.objects.Library;
+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.storage.MetaDataSource;
+
+public class JapanLicsre extends BaseApi implements OpacApi {
+
+ protected String opac_url = "";
+ protected String https_url = "";
+ protected JSONObject data;
+ protected MetaDataSource metadata;
+ protected boolean initialised = false;
+ protected Library library;
+ protected int resultcount = 10;
+ protected String reusehtml;
+ protected Integer searchSet;
+ protected String db;
+ protected String unEncoded;
+ protected String pwEncoded;
+ CookieStore cookieStore = new BasicCookieStore();
+
+ protected List<NameValuePair> sellist_params;
+
+ protected Document res_doc;
+ protected String contact;
+ // protected String num;
+ // protected String ctg;
+ protected String dtype;
+ protected String type;
+ protected String sid;
+ // protected String tm;
+ // protected String aut;
+
+ protected String lor_reservations;
+
+ protected static HashMap<String, MediaType> defaulttypes = new HashMap<String, MediaType>();
+
+ static {
+ defaulttypes.put("一般", MediaType.BOOK);
+ defaulttypes.put("新書", MediaType.BOOK);
+ defaulttypes.put("本", MediaType.BOOK);
+ defaulttypes.put("図書", MediaType.BOOK);
+ defaulttypes.put("図書資料", MediaType.BOOK);
+ defaulttypes.put("図書その他", MediaType.BOOK);
+ defaulttypes.put("文庫", MediaType.BOOK);
+ defaulttypes.put("文庫本", MediaType.BOOK);
+ defaulttypes.put("旅行案内", MediaType.BOOK);
+ defaulttypes.put("参考資料", MediaType.BOOK);
+ defaulttypes.put("例規集", MediaType.BOOK);
+ defaulttypes.put("和綴資料", MediaType.BOOK);
+ defaulttypes.put("大活字", MediaType.BOOK);
+ defaulttypes.put("大活字本", MediaType.BOOK);
+ defaulttypes.put("拡大写本", MediaType.BOOK);
+ defaulttypes.put("外国語", MediaType.BOOK);
+ defaulttypes.put("まんが", MediaType.BOOK);
+ defaulttypes.put("点字資料", MediaType.BOOK);
+ defaulttypes.put("点字付資料", MediaType.BOOK);
+ defaulttypes.put("新聞", MediaType.NEWSPAPER);
+ defaulttypes.put("新聞縮刷版", MediaType.NEWSPAPER);
+ defaulttypes.put("雑誌", MediaType.MAGAZINE);
+ defaulttypes.put("雑誌(点字)", MediaType.MAGAZINE);
+ defaulttypes.put("絵本", MediaType.ART);
+ defaulttypes.put("特大絵本", MediaType.ART);
+ defaulttypes.put("しかけ絵本", MediaType.ART);
+ defaulttypes.put("布の絵本", MediaType.ART);
+ defaulttypes.put("紙芝居", MediaType.ART);
+ defaulttypes.put("ポスター", MediaType.ART);
+ defaulttypes.put("絵画", MediaType.ART);
+ defaulttypes.put("写真", MediaType.ART);
+ defaulttypes.put("パンフレット", MediaType.ART);
+ defaulttypes.put("図譜・図案等", MediaType.ART);
+ defaulttypes.put("地図", MediaType.MAP);
+ defaulttypes.put("地図(1枚もの)", MediaType.MAP);
+ defaulttypes.put("楽譜", MediaType.SCORE_MUSIC);
+ defaulttypes.put("CD-ROM", MediaType.CD_SOFTWARE);
+ defaulttypes.put("マイクロフィルム", MediaType.UNKNOWN);
+ defaulttypes.put("区分なし", MediaType.UNKNOWN);
+ defaulttypes.put("その他作成物", MediaType.UNKNOWN);
+ defaulttypes.put("CD", MediaType.CD);
+ defaulttypes.put("朗読CD", MediaType.CD);
+ defaulttypes.put("コンパクトディスク", MediaType.CD);
+ defaulttypes.put("DVD", MediaType.DVD);
+ defaulttypes.put("映像", MediaType.MOVIE);
+ defaulttypes.put("ビデオテープ", MediaType.MOVIE);
+ defaulttypes.put("ビデオテープ(VHS)", MediaType.MOVIE);
+ defaulttypes.put("カセットテープ", MediaType.AUDIO_CASSETTE);
+ defaulttypes.put("カセット", MediaType.AUDIO_CASSETTE);
+ defaulttypes.put("音響", MediaType.CD);
+ }
+
+ @Override
+ public void start() throws IOException, NotReachableException {
+ // String html = httpGet(opac_url
+ // + "/DB=" + db + "/SET=1/TTL=1/ADVANCED_SEARCHFILTER",
+ // getDefaultEncoding(), false, cookieStore);
+
+ // Document doc = Jsoup.parse(html);
+
+ // updateSearchSetValue(doc);
+
+ try {
+ metadata.open();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ if (!metadata.hasMeta(library.getIdent())) {
+ metadata.close();
+ // extract_meta(doc);
+ } else {
+ metadata.close();
+ }
+ }
+
+ @Override
+ public void init(MetaDataSource metadata, Library lib) {
+ super.init(metadata, lib);
+
+ this.metadata = metadata;
+ this.library = lib;
+ this.data = lib.getData();
+
+ try {
+ this.opac_url = data.getString("baseurl");
+ this.db = data.getString("db");
+ if (!library.getData().isNull("accountSupported")) {
+ if (data.has("httpsbaseurl")) {
+ this.https_url = data.getString("httpsbaseurl");
+ } else {
+ this.https_url = this.opac_url;
+ }
+ }
+ } catch (JSONException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected int addParameters(Map<String, String> query, String key,
+ String searchkey, List<NameValuePair> params, int index) {
+ if (!query.containsKey(key) || query.get(key).equals(""))
+ return index;
+ try {
+ if (data.has("searchindex")
+ && data.getJSONObject("searchindex").has(key)) {
+ searchkey = data.getJSONObject("searchindex").getString(key);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+
+ params.add(new BasicNameValuePair("KEY" + index, query.get(key)));
+ params.add(new BasicNameValuePair("ITEM" + index, searchkey));
+ params.add(new BasicNameValuePair("COMP" + index, "3"));
+ return index + 1;
+
+ }
+
+ @Override
+ public SearchRequestResult search(Map<String, String> query)
+ throws IOException, NotReachableException, OpacErrorException {
+ List<NameValuePair> params = new ArrayList<NameValuePair>();
+
+ // int index = 0;
+ start();
+
+ params.add(new BasicNameValuePair("type", "0"));
+ params.add(new BasicNameValuePair("allc", ""));
+ params.add(new BasicNameValuePair("page", "1"));
+
+ // if (query.containsKey(KEY_SEARCH_QUERY_FREE)
+ // && !query.get(KEY_SEARCH_QUERY_FREE).equals("")) {
+ params.add(new BasicNameValuePair("keyword", query
+ .get(KEY_SEARCH_QUERY_FREE)));
+ // }
+ params.add(new BasicNameValuePair("sentaku", "and"));
+ // if (query.containsKey(KEY_SEARCH_QUERY_TITLE)
+ // && !query.get(KEY_SEARCH_QUERY_TITLE).equals("")) {
+ params.add(new BasicNameValuePair("title", query
+ .get(KEY_SEARCH_QUERY_TITLE)));
+ // }
+ params.add(new BasicNameValuePair("sentaku", "and"));
+ // if (query.containsKey(KEY_SEARCH_QUERY_AUTHOR)
+ // && !query.get(KEY_SEARCH_QUERY_AUTHOR).equals("")) {
+ params.add(new BasicNameValuePair("author", query
+ .get(KEY_SEARCH_QUERY_AUTHOR)));
+ // }
+ params.add(new BasicNameValuePair("sentaku", "or"));
+ if (query.containsKey(KEY_SEARCH_QUERY_PUBLISHER)
+ && !query.get(KEY_SEARCH_QUERY_PUBLISHER).equals("")) {
+ params.add(new BasicNameValuePair("publish", query
+ .get(KEY_SEARCH_QUERY_PUBLISHER)));
+ } else {
+ params.add(new BasicNameValuePair("publish", ""));
+ }
+ params.add(new BasicNameValuePair("sentaku", "or"));
+ // if (query.containsKey(KEY_SEARCH_QUERY_ISBN)
+ // && !query.get(KEY_SEARCH_QUERY_ISBN).equals("")) {
+ params.add(new BasicNameValuePair("isbn", query
+ .get(KEY_SEARCH_QUERY_ISBN)));
+ // }
+ // if (query.containsKey(KEY_SEARCH_QUERY_YEAR)
+ // && !query.get(KEY_SEARCH_QUERY_YEAR).equals("")) {
+ params.add(new BasicNameValuePair("pubydate1", query
+ .get(KEY_SEARCH_QUERY_YEAR)));
+ // }
+ params.add(new BasicNameValuePair("pubydate3", ""));
+ params.add(new BasicNameValuePair("bunrui", ""));
+ params.add(new BasicNameValuePair("syubetu", "all"));
+ params.add(new BasicNameValuePair("kan", "all"));
+ params.add(new BasicNameValuePair("media", "all"));
+ params.add(new BasicNameValuePair("count", "10"));
+ params.add(new BasicNameValuePair("order", "publish"));
+
+ params.add(new BasicNameValuePair("before", "select"));
+ params.add(new BasicNameValuePair("authorid", ""));
+ params.add(new BasicNameValuePair("opacfile", ""));
+ params.add(new BasicNameValuePair("titleid", ""));
+ params.add(new BasicNameValuePair("tophp", "select"));
+ params.add(new BasicNameValuePair("sid", ""));
+ sellist_params = params;
+
+ String html = httpGet(
+ opac_url + "/sellist?"
+ + URLEncodedUtils.format(params, getDefaultEncoding()),
+ getDefaultEncoding(), false, cookieStore);
+
+ return parse_search(html, 1);
+ }
+
+ protected SearchRequestResult parse_search(String html, int page)
+ throws OpacErrorException {
+ Document doc = Jsoup.parse(html);
+
+ // updateSearchSetValue(doc);
+
+ if (doc.select("div.page_content center").size() > 0) {
+ if (doc.select("div.page_content center").text().trim()
+ .contains("検索結果はありません")) {
+ // nothing found
+ return new SearchRequestResult(new ArrayList<SearchResult>(),
+ 0, 1, 1);
+ } else {
+ // error
+ throw new OpacErrorException(doc
+ .select("div.page_content center").first().text()
+ .trim());
+ }
+ }
+
+ reusehtml = html;
+
+ int results_total = -1;
+
+ String resultnumstr = "";
+ if (doc.select("div.search_report input[name=allc]").size() > 0) {
+ resultnumstr = doc.select("div.search_report input[name=allc]")
+ .val();
+ results_total = Integer.valueOf(resultnumstr);
+ }
+
+ List<NameValuePair> params = new ArrayList<NameValuePair>();
+ params.add(new BasicNameValuePair("type", "0"));
+ params.add(new BasicNameValuePair("allc", String.valueOf(results_total)));
+ for (int i = 2; i < sellist_params.size(); i++) {
+ params.add(sellist_params.get(i));
+ }
+ sellist_params = params;
+
+ // end of page
+ if ((results_total - 1) / 10 + 1 < page) {
+ return new SearchRequestResult(new ArrayList<SearchResult>(), 0, 1,
+ 1);
+ }
+ List<SearchResult> results = new ArrayList<SearchResult>();
+
+ Elements table = doc.select("table.list tr");
+ // identifier = null;
+
+ Elements links = doc.select("table.list a");
+ boolean haslink = false;
+ for (int i = 0; i < links.size(); i++) {
+ Element node = links.get(i);
+ if (node.hasAttr("href") & node.attr("href").contains("detail?")
+ && !haslink) {
+ haslink = true;
+ try {
+ List<NameValuePair> anyurl = URLEncodedUtils.parse(new URI(
+ node.attr("href")), getDefaultEncoding());
+ for (NameValuePair nv : anyurl) {
+ if (nv.getName().equals("identifier")) {
+ // identifier = nv.getValue();
+ break;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ for (int i = 1; i < table.size(); i++) {
+ Element tr = table.get(i);
+ SearchResult sr = new SearchResult();
+ if (tr.select("td").size() > 6) {
+ String fname = tr.select("td").get(6).text();
+ if (data.has("mediatypes")) {
+ try {
+ sr.setType(MediaType.valueOf(data.getJSONObject(
+ "mediatypes").getString(fname)));
+ } catch (JSONException e) {
+ sr.setType(defaulttypes.get(fname));
+ } catch (IllegalArgumentException e) {
+ sr.setType(defaulttypes.get(fname));
+ }
+ } else {
+ sr.setType(defaulttypes.get(fname));
+ }
+ }
+ // Element middlething = tr.child(2);
+
+ // List<Node> children = middlething.childNodes();
+ // int childrennum = children.size();
+
+ StringBuilder description = new StringBuilder();
+
+ if (tr.select("td").size() > 4) {
+ description.append("<b>" + tr.select("td").get(1).text()
+ + "</b>");
+ description.append("<br />" + tr.select("td").get(2).text());
+ description.append(" - " + tr.select("td").get(3).text());
+ description.append(" - " + tr.select("td").get(4).text());
+ sr.setInnerhtml(description.toString());
+ }
+
+ sr.setNr(10 * (page - 1) + i);
+ sr.setId(null);
+ if (tr.select("a").size() > 0) {
+ sr.setId(tr.select("a").first().attr("href"));
+ }
+ if (tr.select("td").size() > 5) {
+ if (tr.select("td").get(5).text().contains("貸出中")) {
+ sr.setStatus(Status.RED);
+ }
+ }
+ results.add(sr);
+ }
+ resultcount = results.size();
+ return new SearchRequestResult(results, results_total, page);
+ }
+
+ @Override
+ public SearchRequestResult searchGetPage(int page) throws IOException,
+ NotReachableException, OpacErrorException {
+ if (!initialised)
+ start();
+
+ List<NameValuePair> params = new ArrayList<NameValuePair>();
+ for (int i = 0; i < sellist_params.size(); i++) {
+ if (i == 2) {
+ params.add(new BasicNameValuePair("page", String.valueOf(page)));
+ } else {
+ params.add(sellist_params.get(i));
+ }
+ }
+
+ String html = httpGet(
+ opac_url + "/sellist?"
+ + URLEncodedUtils.format(params, getDefaultEncoding()),
+ getDefaultEncoding(), false, cookieStore);
+ return parse_search(html, page);
+ }
+
+ @Override
+ public SearchRequestResult filterResults(Filter filter, Option option)
+ throws IOException, NotReachableException {
+ return null;
+ }
+
+ @Override
+ public DetailledItem getResultById(String id, String homebranch)
+ throws IOException, NotReachableException {
+
+ String html = httpGet(opac_url + "/" + id, getDefaultEncoding(), false);
+
+ return parse_result(html);
+ }
+
+ @Override
+ public DetailledItem getResult(int position) throws IOException {
+ // Should not be called because every media has an ID
+
+ return null;
+ }
+
+ protected DetailledItem parse_result(String html) throws IOException {
+ Document doc = Jsoup.parse(html);
+ doc.setBaseUri(opac_url);
+
+ DetailledItem result = new DetailledItem();
+
+ // GET TITLE AND SUBTITLE
+ Element part = doc.select("table.list").first();
+ for (Element element : part.select("tr")) {
+ String title = element.select("th").text().trim();
+ String detail = element.select("td").text().trim();
+
+ if (title.contains("書名") || title.contains("タイトル")) {
+ result.setTitle(detail);
+ // result.addDetail(new Detail("Titelzusatz", subtitle));
+ } else if (title.contains("ISBN")) {
+ // GET COVER
+ if (detail.replaceAll("[^\\dX]", "").length() == 13) {
+ result.setCover(ISBNTools.getAmazonCoverURL(detail, true));
+ } else {
+ result.setCover(ISBNTools.getAmazonCoverURL("000" + detail,
+ true));
+ }
+ result.addDetail(new Detail(title, detail));
+ } else if (title.contains("外部サイトで調べる")) {
+ // skip
+ } else {
+ result.addDetail(new Detail(title, detail));
+ }
+ }
+
+ Element form;
+ if (doc.select("form[name=PutFORM]").size() > 0) {
+ form = doc.select("form[name=PutFORM]").get(1);
+ result.setId(doc.select("input[name=bid]").first().val());
+ Elements inputs = form.parent().select("input");
+ StringBuilder str = new StringBuilder();
+ for (Element input : inputs) {
+ if (str.length() > 0) {
+ str.append("&");
+ }
+ str.append(input.attr("name") + "=" + input.val());
+ }
+ result.setReservation_info(form.attr("action") + "?"
+ + str.toString());
+ }
+
+ // GET OTHER INFORMATION
+ Map<String, String> e = new HashMap<String, String>();
+
+ if (!library.getData().isNull("accountSupported")) {
+ try {
+ result.setReservable(library.getData().getBoolean(
+ "accountSupported"));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ if (doc.select("table.list").size() > 1) {
+ part = doc.select("table.list").get(1);
+ } else {
+ part = doc.select("table.list").get(0);
+ }
+ for (Element element : part.select("tr")) {
+ if (element.select("td").size() > 5) {
+ e.put(DetailledItem.KEY_COPY_BRANCH, element.select("td")
+ .get(1).text().trim());
+ e.put(DetailledItem.KEY_COPY_STATUS, element.select("td")
+ .get(4).text().trim());
+ result.addCopy(e);
+ e = new HashMap<String, String>();
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public ReservationResult reservation(DetailledItem item, Account account,
+ int useraction, String selection) throws IOException {
+ String reservation_info = item.getReservation_info();
+
+ // Document doc = null;
+
+ if (useraction == MultiStepResult.ACTION_CONFIRMATION) {
+ Elements inputs = res_doc.select("form[name=PutFORM]").parents()
+ .select("input");
+ List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
+ if (inputs.size() > 0) {
+ for (int i = 0; i < inputs.size(); i++) {
+ nameValuePairs.add(new BasicNameValuePair(inputs.get(i)
+ .attr("name"), inputs.get(i).val()));
+ }
+ }
+ httpPost(opac_url + "/rsvend", new UrlEncodedFormEntity(
+ nameValuePairs), getDefaultEncoding());
+ return new ReservationResult(MultiStepResult.Status.OK);
+ } else if (selection == null || useraction == 0) {
+ // login
+ String html = httpGet(opac_url + "/" + reservation_info,
+ getDefaultEncoding());
+ res_doc = Jsoup.parse(html);
+
+ if (res_doc.select("form[name=theFORM]").size() > 0) {
+ Elements inputs = res_doc.select("form[name=theFORM]")
+ .parents().select("input");
+ List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
+ for (int i = 0; i < inputs.size(); i++) {
+ if (i == 0) {
+ nameValuePairs.add(new BasicNameValuePair("type", "0"));
+ } else if (i == 2) {
+ nameValuePairs.add(new BasicNameValuePair("n1", account
+ .getName()));
+ } else if (i == 3) {
+ nameValuePairs.add(new BasicNameValuePair("n2", account
+ .getPassword()));
+ } else {
+ nameValuePairs.add(new BasicNameValuePair(inputs.get(i)
+ .attr("name"), inputs.get(i).val()));
+ }
+ }
+ html = httpPost(opac_url + "/rsvinput",
+ new UrlEncodedFormEntity(nameValuePairs),
+ getDefaultEncoding());
+ res_doc = Jsoup.parse(html);
+ }
+
+ // select contact method
+ if (res_doc.select("select[name=selectsyudan]").size() > 0) {
+ Map<String, String> branches = new HashMap<String, String>();
+ for (Element option : res_doc
+ .select("select[name=selectsyudan]").first().children()) {
+ String value = option.text().trim();
+ String key;
+ if (option.hasAttr("value")) {
+ key = option.attr("value");
+ } else {
+ key = value;
+ }
+ branches.put(key, value);
+ }
+ ReservationResult result = new ReservationResult(
+ MultiStepResult.Status.SELECTION_NEEDED);
+ result.setActionIdentifier(ReservationResult.ACTION_USER);
+ result.setSelection(branches);
+ return result;
+ } else if (res_doc.select("select[name=selectplace]").size() > 0) {
+ // select branch
+ Map<String, String> branches = new HashMap<String, String>();
+ for (Element option : res_doc
+ .select("select[name=selectplace]").first().children()) {
+ String value = option.text().trim();
+ String key;
+ if (option.hasAttr("value")) {
+ key = option.attr("value");
+ } else {
+ key = value;
+ }
+ branches.put(key, value);
+ }
+ ReservationResult result = new ReservationResult(
+ MultiStepResult.Status.SELECTION_NEEDED);
+ result.setActionIdentifier(ReservationResult.ACTION_BRANCH);
+ result.setSelection(branches);
+ return result;
+ }
+ } else if (useraction == ReservationResult.ACTION_USER) {
+ // select branch
+ contact = selection;
+ // String html = httpGet(reservation_info, getDefaultEncoding());
+ // doc = Jsoup.parse(html);
+
+ if (res_doc.select("select[name=selectplace]").size() > 0) {
+ Map<String, String> branches = new HashMap<String, String>();
+ for (Element option : res_doc
+ .select("select[name=selectplace]").first().children()) {
+ String value = option.text().trim();
+ String key;
+ if (option.hasAttr("value")) {
+ key = option.attr("value");
+ } else {
+ key = value;
+ }
+ branches.put(key, value);
+ }
+ ReservationResult result = new ReservationResult(
+ MultiStepResult.Status.SELECTION_NEEDED);
+ result.setActionIdentifier(ReservationResult.ACTION_BRANCH);
+ result.setSelection(branches);
+ return result;
+ }
+ } else if (useraction == ReservationResult.ACTION_BRANCH) {
+ // String html = httpGet(reservation_info, getDefaultEncoding());
+ // doc = Jsoup.parse(html);
+
+ Elements inputs = res_doc.select("form[name=PutFORM]").parents()
+ .select("input");
+ List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
+ if (inputs.size() > 5) {
+ for (int i = 0; i < 6; i++) {
+ nameValuePairs.add(new BasicNameValuePair(inputs.get(i)
+ .attr("name"), inputs.get(i).val()));
+ }
+ }
+ nameValuePairs
+ .add(new BasicNameValuePair("selectplace", selection));
+ if (contact != null) {
+ nameValuePairs.add(new BasicNameValuePair("selectsyudan",
+ contact));
+ }
+ if (inputs.size() > 6) {
+ for (int i = 6; i < inputs.size(); i++) {
+ nameValuePairs.add(new BasicNameValuePair(inputs.get(i)
+ .attr("name"), inputs.get(i).val()));
+ }
+ }
+ String html = httpPost(opac_url + "/rsvinfo",
+ new UrlEncodedFormEntity(nameValuePairs),
+ getDefaultEncoding());
+ res_doc = Jsoup.parse(html);
+ }
+
+ if (res_doc == null)
+ return new ReservationResult(MultiStepResult.Status.ERROR);
+
+ if (res_doc.select("table.ulist").size() > 1) {
+ List<String[]> details = new ArrayList<String[]>();
+
+ for (Element row : res_doc.select("table.ulist").get(1)
+ .select("tr")) {
+ if (row.select("th").size() == 1
+ && row.select("td").size() == 1) {
+ details.add(new String[] { row.select("th").text().trim(),
+ row.select("td").text().trim() });
+ }
+ }
+ ReservationResult result = new ReservationResult(
+ MultiStepResult.Status.CONFIRMATION_NEEDED);
+ result.setDetails(details);
+ return result;
+ }
+
+ if (res_doc.getElementsByClass("MSGBOLDL").size() == 1) {
+ return new ReservationResult(MultiStepResult.Status.ERROR, res_doc
+ .getElementsByClass("MSGBOLDL").get(0).text());
+ }
+
+ return new ReservationResult(MultiStepResult.Status.ERROR,
+ "Unbekannter Fehler");
+ }
+
+ @Override
+ public ProlongResult prolong(String media, Account account, int useraction,
+ String Selection) throws IOException {
+ if (pwEncoded == null)
+ try {
+ account(account);
+ } catch (JSONException e1) {
+ return new ProlongResult(MultiStepResult.Status.ERROR);
+ } catch (OpacErrorException e1) {
+ return new ProlongResult(MultiStepResult.Status.ERROR,
+ e1.getMessage());
+ }
+
+ String html = httpGet(opac_url + "/" + media, getDefaultEncoding());
+ Document doc = Jsoup.parse(html);
+
+ if (doc.select("div.page_content_frame").text().contains("完了しました")) {
+ return new ProlongResult(MultiStepResult.Status.OK);
+ } else if (doc.select("div.page_content_frame").text()
+ .contains("ログインしてください")
+ || doc.select("div.page_content_frame").text()
+ .contains("有効時間が経過しています")) {
+ try {
+ account(account);
+ return prolong(media, account, useraction, Selection);
+ } catch (JSONException e) {
+ return new ProlongResult(MultiStepResult.Status.ERROR);
+ } catch (OpacErrorException e) {
+ return new ProlongResult(MultiStepResult.Status.ERROR,
+ e.getMessage());
+ }
+ } else {
+ ProlongResult res = new ProlongResult(MultiStepResult.Status.ERROR);
+ res.setMessage(doc.select("div.page_content_frame").text());
+ return res;
+ }
+ }
+
+ @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 {
+ String html = httpGet(opac_url + "/" + media, getDefaultEncoding());
+ Document doc = Jsoup.parse(html);
+
+ if (doc.select("div.page_content_frame").text().contains("完了しました")) {
+ return new CancelResult(MultiStepResult.Status.OK);
+ } else if (doc.select("div.page_content_frame").text()
+ .contains("ログインしてください")
+ || doc.select("div.page_content_frame").text()
+ .contains("有効時間が経過しています")) {
+ try {
+ account(account);
+ return cancel(media, account, useraction, selection);
+ } catch (JSONException e) {
+ throw new OpacErrorException("内部エラー");
+ }
+ } else {
+ CancelResult res = new CancelResult(MultiStepResult.Status.ERROR);
+ res.setMessage(doc.select("div.page_content_frame").text());
+ return res;
+ }
+ }
+
+ @Override
+ public AccountData account(Account account) throws IOException,
+ JSONException, OpacErrorException {
+ List<NameValuePair> params = new ArrayList<NameValuePair>();
+ params.add(new BasicNameValuePair("type", "0"));
+ params.add(new BasicNameValuePair("n1", account.getName()));
+ params.add(new BasicNameValuePair("n2", account.getPassword()));
+ params.add(new BasicNameValuePair("ptype", ""));
+ params.add(new BasicNameValuePair("befHP", "userlogin"));
+
+ String html = httpPost(opac_url + "/userinfo",
+ new UrlEncodedFormEntity(params, getDefaultEncoding()),
+ getDefaultEncoding());
+ Document doc = Jsoup.parse(html);
+
+ // if (doc.select("div.MSGBOLDL").size() > 0) {
+ // throw new OpacErrorException(doc.select("div.MSGBOLDL").text());
+ // }
+ unEncoded = doc.select("input[name=.u1]").val();
+ pwEncoded = doc.select("input[name=.u2]").val();
+ dtype = doc.select("input[name=dtype]").val();
+ type = doc.select("input[name=type]").val();
+ sid = doc.select("input[name=sid]").val();
+
+ params = new ArrayList<NameValuePair>();
+ params.add(new BasicNameValuePair("dtype", "0"));
+ params.add(new BasicNameValuePair(".u1", unEncoded));
+ params.add(new BasicNameValuePair(".u2", pwEncoded));
+ params.add(new BasicNameValuePair("type", "2"));
+ params.add(new BasicNameValuePair(sid, sid));
+
+ html = httpPost(opac_url + "/userlendlist", new UrlEncodedFormEntity(
+ params, getDefaultEncoding()), getDefaultEncoding());
+ doc = Jsoup.parse(html);
+
+ params = new ArrayList<NameValuePair>();
+ params.add(new BasicNameValuePair("dtype", "0"));
+ params.add(new BasicNameValuePair(".u1", unEncoded));
+ params.add(new BasicNameValuePair(".u2", pwEncoded));
+ params.add(new BasicNameValuePair("type", "3"));
+ params.add(new BasicNameValuePair(sid, sid));
+
+ html = httpPost(opac_url + "/userlendlist", new UrlEncodedFormEntity(
+ params, getDefaultEncoding()), getDefaultEncoding());
+ Document doc2 = Jsoup.parse(html);
+
+ AccountData res = new AccountData(account.getId());
+
+ List<Map<String, String>> medien = new ArrayList<Map<String, String>>();
+ List<Map<String, String>> reserved = new ArrayList<Map<String, String>>();
+ if (doc.select("div.page_content_frame table tr").size() > 0) {
+ parse_medialist(medien, doc, 1, account.getName());
+ }
+ if (doc2.select("div.page_content_frame table tr").size() > 0) {
+ parse_reslist(reserved, doc2, 1);
+ }
+
+ res.setLent(medien);
+ res.setReservations(reserved);
+
+ if (medien == null || reserved == null) {
+ throw new OpacErrorException("不明なエラー. アカウントが正しいことを確認してください.");
+ // Log.d("OPACCLIENT", html);
+ }
+ return res;
+
+ }
+
+ protected void parse_medialist(List<Map<String, String>> medien,
+ Document doc, int offset, String accountName)
+ throws ClientProtocolException, IOException {
+
+ Elements copytrs = doc.select("div.page_content_frame table tr");
+ Elements table = doc.select("div.page_content_frame table tr th");
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd", Locale.JAPAN);
+
+ int trs = copytrs.size();
+ if (trs < 1) {
+ medien = null;
+ return;
+ }
+ assert (trs > 1);
+ for (int i = 1; i < trs; i++) {
+ // Document doc1 = null;
+ // try {
+ // String html = httpGet(copytrs.get(i).select("a").attr("href"),
+ // getDefaultEncoding());
+ // doc1 = Jsoup.parse(html);
+ // } catch (IOException e) {
+ //
+ // }
+ Element tr = copytrs.get(i);
+ Map<String, String> e = new HashMap<String, String>();
+ for (int j = 0; j < table.size(); j++) {
+ if (table.get(j).text().trim().equals("書名")
+ || table.get(j).text().trim().equals("タイトル")) {
+ e.put(AccountData.KEY_LENT_TITLE, tr.select("td").get(j)
+ .text().trim());
+ } else if (table.get(j).text().trim().equals("返却期限")
+ || table.get(j).text().trim().equals("返却日")) {
+ e.put(AccountData.KEY_LENT_DEADLINE, tr.select("td").get(j)
+ .text().trim());
+ }
+ }
+ // e.put(AccountData.KEY_LENT_STATUS, status);
+ try {
+ e.put(AccountData.KEY_LENT_DEADLINE_TIMESTAMP, String
+ .valueOf(sdf
+ .parse(e.get(AccountData.KEY_LENT_DEADLINE))
+ .getTime()));
+ } catch (ParseException e1) {
+ e1.printStackTrace();
+ }
+ if (tr.select("form[name=PutFORM]").size() > 0) {
+ Elements inputs = doc.select("form[name=PutFORM]")
+ .parents().select("input");
+ List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
+ if (inputs.size() > 0) {
+ for (int j = 0; j < inputs.size(); j++) {
+ nameValuePairs.add(new BasicNameValuePair(inputs.get(j)
+ .attr("name"), inputs.get(j).val()));
+ }
+ }
+ e.put(AccountData.KEY_LENT_LINK, "userencho?" + URLEncodedUtils.format(nameValuePairs, getDefaultEncoding()));
+ } else {
+ e.put(AccountData.KEY_LENT_RENEWABLE, "N");
+ }
+
+ medien.add(e);
+ }
+ assert (medien.size() == trs - 1);
+ }
+
+ protected void parse_reslist(List<Map<String, String>> medien,
+ Document doc, int offset) throws ClientProtocolException,
+ IOException {
+
+ // if(doc.select("input[name=LOR_RESERVATIONS]").size()>0) {
+ // lor_reservations =
+ // doc.select("input[name=LOR_RESERVATIONS]").attr("value");
+ // }
+
+ Elements copytrs = doc.select("div.page_content_frame table tr");
+ Elements table = doc.select("div.page_content_frame table tr th");
+ if (doc.select("div.page_content_frame").size() > 0) {
+ copytrs = doc.select("div.page_content_frame").get(0).select("table tr");
+ table = doc.select("div.page_content_frame").get(0).select("table tr th");
+ }
+
+ int trs1 = copytrs.size();
+ if (trs1 >= 1) {
+ for (int i = 1; i < trs1; i++) {
+ Element tr = copytrs.get(i);
+ Map<String, String> e = new HashMap<String, String>();
+
+ for (int j = 0; j < table.size(); j++) {
+ if (table.get(j).text().trim().equals("書名")
+ || table.get(j).text().trim().equals("タイトル")) {
+ e.put(AccountData.KEY_RESERVATION_TITLE, tr.select("td")
+ .get(j).text().trim());
+ e.put(AccountData.KEY_RESERVATION_READY, "ご用意できました");
+ } else if (table.get(j).text().trim().equals("受取館")) {
+ e.put(AccountData.KEY_RESERVATION_BRANCH, tr.select("td")
+ .get(j).text().trim());
+ } else if (table.get(j).text().trim().equals("引取期限日")) {
+ e.put(AccountData.KEY_RESERVATION_EXPIRE, tr.select("td")
+ .get(j).text().trim());
+ }
+ }
+
+ medien.add(e);
+ }
+ }
+// assert (medien.size() == trs1 - 1);
+
+ if (doc.select("div.page_content_frame").size() > 1) {
+ copytrs = doc.select("div.page_content_frame").get(1).select("table tr");
+ table = doc.select("div.page_content_frame").get(1).select("table tr th");
+ }
+
+ int trs = copytrs.size();
+ if (trs >= 1) {
+ for (int i = 1; i < trs; i++) {
+ Element tr = copytrs.get(i);
+ Map<String, String> e = new HashMap<String, String>();
+
+ for (int j = 0; j < table.size(); j++) {
+ if (table.get(j).text().trim().equals("書名")
+ || table.get(j).text().trim().equals("タイトル")) {
+ e.put(AccountData.KEY_RESERVATION_TITLE, tr.select("td")
+ .get(j).text().trim());
+ } else if (table.get(j).text().trim().equals("予約状況")
+ || table.get(j).text().trim().equals("予約順位")) {
+ e.put(AccountData.KEY_RESERVATION_READY, tr.select("td")
+ .get(j).text().trim());
+ } else if (table.get(j).text().trim().equals("受取館")) {
+ e.put(AccountData.KEY_RESERVATION_BRANCH, tr.select("td")
+ .get(j).text().trim());
+ }
+ }
+ // e.put(AccountData.KEY_RESERVATION_TITLE,
+ // tr.select("td").get(1).text().trim());
+ // e.put(AccountData.KEY_RESERVATION_READY,
+ // tr.select("td").get(4).text().trim());
+ if (tr.select("form[name=PutFORM]").size() > 0) {
+ Elements inputs = doc.select("form[name=PutFORM]")
+ .parents().select("input");
+ List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
+ if (inputs.size() > 0) {
+ for (int j = 0; j < inputs.size(); j++) {
+ nameValuePairs.add(new BasicNameValuePair(inputs.get(j)
+ .attr("name"), inputs.get(j).val()));
+ }
+ }
+ e.put(AccountData.KEY_RESERVATION_CANCEL, "userrsvdel?" +
+ URLEncodedUtils.format(nameValuePairs, getDefaultEncoding()));
+ }
+
+ medien.add(e);
+ }
+ }
+// assert (medien.size() == trs - 1 + trs1 - 1);
+ }
+
+ @Override
+ public String[] getSearchFields() {
+ return new String[] { KEY_SEARCH_QUERY_FREE, KEY_SEARCH_QUERY_AUTHOR,
+ KEY_SEARCH_QUERY_KEYWORDA, KEY_SEARCH_QUERY_YEAR,
+ KEY_SEARCH_QUERY_SYSTEM, KEY_SEARCH_QUERY_PUBLISHER,
+ KEY_SEARCH_QUERY_ISBN };
+ }
+
+ @Override
+ public boolean isAccountSupported(Library library) {
+ if (!library.getData().isNull("accountSupported")) {
+ try {
+ return library.getData().getBoolean("accountSupported");
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isAccountExtendable() {
+ return false;
+ }
+
+ @Override
+ public String getAccountExtendableInfo(Account account) throws IOException,
+ NotReachableException {
+ return null;
+ }
+
+ @Override
+ public String getShareUrl(String id, String title) {
+ return id;
+ }
+
+ @Override
+ public int getSupportFlags() {
+ return SUPPORT_FLAG_ENDLESS_SCROLLING | SUPPORT_FLAG_CHANGE_ACCOUNT;
+ }
+
+ @Override
+ protected String getDefaultEncoding() {
+ try {
+ if (data.has("charset"))
+ return data.getString("charset");
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return "UTF-8";
+ }
+
+}
\ No newline at end of file