Search in sources :

Example 16 with SearchResult

use of de.geeksfactory.opacclient.objects.SearchResult in project opacclient by opacapp.

the class TouchPoint method parse_search.

protected SearchRequestResult parse_search(String html, int page) throws OpacErrorException, IOException, IOException, SingleResultFound {
    Document doc = Jsoup.parse(html);
    if (doc.select("#RefineHitListForm").size() > 0) {
        // the results are located on a different page loaded via AJAX
        html = httpGet(opac_url + "/speedHitList.do?_=" + String.valueOf(System.currentTimeMillis() / 1000) + "&hitlistindex=0&exclusionList=", ENCODING);
        doc = Jsoup.parse(html);
    }
    if (doc.select(".nodata").size() > 0) {
        return new SearchRequestResult(new ArrayList<SearchResult>(), 0, 1, 1);
    }
    doc.setBaseUri(opac_url + "/searchfoo");
    int results_total = -1;
    String resultnumstr = doc.select(".box-header h2, .box-header h1").first().text();
    if (resultnumstr.contains("(1/1)") || resultnumstr.contains(" 1/1")) {
        throw new SingleResultFound();
    } else if (resultnumstr.contains("(")) {
        results_total = Integer.parseInt(resultnumstr.replaceAll(".*\\(([0-9]+)\\).*", "$1"));
    } else if (resultnumstr.contains(": ")) {
        results_total = Integer.parseInt(resultnumstr.replaceAll(".*: ([0-9]+)$", "$1"));
    } else if (resultnumstr.contains("Treffer")) {
        try {
            results_total = Integer.parseInt(resultnumstr.replaceAll(".* ([0-9]+)$", "$1"));
        } catch (NumberFormatException e) {
        // pass
        }
    }
    Elements table = doc.select("table.data > tbody > tr");
    identifier = null;
    Elements links = doc.select("table.data a");
    boolean haslink = false;
    for (Element node : links) {
        if (node.hasAttr("href") & node.attr("href").contains("singleHit.do") && !haslink) {
            haslink = true;
            try {
                List<NameValuePair> anyurl = URLEncodedUtils.parse(new URI(node.attr("href").replace(" ", "%20").replace("&amp;", "&")), ENCODING);
                for (NameValuePair nv : anyurl) {
                    if (nv.getName().equals("identifier")) {
                        identifier = nv.getValue();
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    List<SearchResult> results = new ArrayList<>();
    for (int i = 0; i < table.size(); i++) {
        Element tr = table.get(i);
        SearchResult sr = new SearchResult();
        if (tr.select(".icn, img[width=32]").size() > 0) {
            String[] fparts = tr.select(".icn, img[width=32]").first().attr("src").split("/");
            String fname = fparts[fparts.length - 1];
            String changedFname = fname.toLowerCase(Locale.GERMAN).replace(".jpg", "").replace(".gif", "").replace(".png", "");
            // File names can look like this: "20_DVD_Video.gif"
            Pattern pattern = Pattern.compile("(\\d+)_.*");
            Matcher matcher = pattern.matcher(changedFname);
            if (matcher.find()) {
                changedFname = matcher.group(1);
            }
            MediaType defaulttype = defaulttypes.get(changedFname);
            if (data.has("mediatypes")) {
                try {
                    sr.setType(MediaType.valueOf(data.getJSONObject("mediatypes").getString(fname)));
                } catch (JSONException | IllegalArgumentException e) {
                    sr.setType(defaulttype);
                }
            } else {
                sr.setType(defaulttype);
            }
        }
        String title;
        String text;
        if (tr.select(".results table").size() > 0) {
            // e.g. RWTH Aachen
            title = tr.select(".title a").text();
            text = tr.select(".title div").text();
        } else {
            // e.g. Schaffhausen, BSB München
            title = tr.select(".title, .hitlistTitle").text();
            text = tr.select(".results, .hitlistMetadata").first().ownText();
        }
        // we need to do some evil javascript parsing here to get the cover
        // and loan status of the item
        // get cover
        sr.setCover(findCoverUrl(tr, true));
        // get loan status and media ID
        if (tr.select("div[id^=loanstatus] + script").size() > 0) {
            String js = tr.select("div[id^=loanstatus] + script").first().html();
            String[] variables = new String[] { "loanstateDBId", "itemIdentifier", "hitlistIdentifier", "hitlistPosition", "duplicateHitlistIdentifier", "itemType", "titleStatus", "typeofHit", "context" };
            String ajaxUrl = matchJSVariable(js, "ajaxUrl");
            if (!"".equals(ajaxUrl)) {
                JSONObject id = new JSONObject();
                List<NameValuePair> map = new ArrayList<>();
                for (String variable : variables) {
                    String value = matchJSVariable(js, variable);
                    if (!"".equals(value)) {
                        map.add(new BasicNameValuePair(variable, value));
                    }
                    try {
                        if (variable.equals("itemIdentifier")) {
                            id.put("id", value);
                        } else if (variable.equals("loanstateDBId")) {
                            id.put("db", value);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                sr.setId(id.toString());
                String url = new URL(new URL(opac_url + "/"), ajaxUrl).toString();
                String loanStatusHtml = httpGet(url + "?" + URLEncodedUtils.format(map, "UTF-8"), ENCODING).replace("\r\n", "").trim();
                Document loanStatusDoc = Jsoup.parse(loanStatusHtml);
                String loanstatus = loanStatusDoc.text().replace("\u00bb", "").trim();
                if ((loanstatus.startsWith("entliehen") && loanstatus.contains("keine Vormerkung möglich") || loanstatus.contains("Keine Exemplare verfügbar"))) {
                    sr.setStatus(SearchResult.Status.RED);
                } else if (loanstatus.startsWith("entliehen") || loanstatus.contains("andere Zweigstelle")) {
                    sr.setStatus(SearchResult.Status.YELLOW);
                } else if ((loanstatus.startsWith("bestellbar") && !loanstatus.contains("nicht bestellbar")) || (loanstatus.startsWith("vorbestellbar") && !loanstatus.contains("nicht vorbestellbar")) || (loanstatus.startsWith("vorbestellbar") && !loanstatus.contains("nicht vorbestellbar")) || (loanstatus.startsWith("vormerkbar") && !loanstatus.contains("nicht vormerkbar")) || (loanstatus.contains("heute zurückgebucht")) || (loanstatus.contains("ausleihbar") && !loanstatus.contains("nicht ausleihbar"))) {
                    sr.setStatus(SearchResult.Status.GREEN);
                } else if (loanstatus.equals("")) {
                    // In special databases (like "Handschriften" in Winterthur) ID lookup is
                    // not possible, which we try to detect this way. We therefore also cannot
                    // use getResultById when accessing the results.
                    sr.setId(null);
                }
                if (sr.getType() != null) {
                    if (sr.getType().equals(MediaType.EBOOK) || sr.getType().equals(MediaType.EVIDEO) || sr.getType().equals(MediaType.MP3)) // Especially Onleihe.de ebooks are often marked
                    // green though they are not available.
                    {
                        sr.setStatus(SearchResult.Status.UNKNOWN);
                    }
                }
            }
        }
        sr.setInnerhtml(("<b>" + title + "</b><br/>") + text);
        sr.setNr(10 * (page - 1) + i + 1);
        results.add(sr);
    }
    resultcount = results.size();
    return new SearchRequestResult(results, results_total, page);
}
Also used : Matcher(java.util.regex.Matcher) Element(org.jsoup.nodes.Element) ArrayList(java.util.ArrayList) Document(org.jsoup.nodes.Document) Elements(org.jsoup.select.Elements) URI(java.net.URI) URL(java.net.URL) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) MediaType(de.geeksfactory.opacclient.objects.SearchResult.MediaType) NameValuePair(org.apache.http.NameValuePair) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) Pattern(java.util.regex.Pattern) JSONException(org.json.JSONException) SearchResult(de.geeksfactory.opacclient.objects.SearchResult) URISyntaxException(java.net.URISyntaxException) JSONException(org.json.JSONException) NotReachableException(de.geeksfactory.opacclient.networking.NotReachableException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) SearchRequestResult(de.geeksfactory.opacclient.objects.SearchRequestResult) JSONObject(org.json.JSONObject)

Example 17 with SearchResult

use of de.geeksfactory.opacclient.objects.SearchResult in project opacclient by opacapp.

the class ResultsAdapter method getView.

@Override
public View getView(int position, View contentView, ViewGroup viewGroup) {
    View view;
    // position always 0-7
    if (objects.get(position) == null) {
        LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(R.layout.listitem_searchresult, viewGroup, false);
        return view;
    }
    SearchResult item = objects.get(position);
    if (contentView == null) {
        LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = layoutInflater.inflate(R.layout.listitem_searchresult, viewGroup, false);
    } else {
        view = contentView;
    }
    TextView tv = (TextView) view.findViewById(R.id.tvResult);
    tv.setText(Html.fromHtml(item.getInnerhtml()));
    ImageView ivType = (ImageView) view.findViewById(R.id.ivType);
    PreferenceDataSource pds = new PreferenceDataSource(getContext());
    ConnectivityManager connMgr = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    if (item.getCoverBitmap() != null) {
        ivType.setImageBitmap(BitmapUtils.bitmapFromBytes(item.getCoverBitmap()));
        ivType.setVisibility(View.VISIBLE);
    } else if ((pds.isLoadCoversOnDataPreferenceSet() || !ConnectivityManagerCompat.isActiveNetworkMetered(connMgr)) && item.getCover() != null) {
        LoadCoverTask lct = new LoadCoverTask(ivType, item);
        lct.execute();
        ivType.setImageResource(R.drawable.ic_loading);
        ivType.setVisibility(View.VISIBLE);
    } else if (item.getType() != null && item.getType() != MediaType.NONE) {
        ivType.setImageResource(getResourceByMediaType(item.getType()));
        ivType.setVisibility(View.VISIBLE);
    } else {
        ivType.setVisibility(View.INVISIBLE);
    }
    ImageView ivStatus = (ImageView) view.findViewById(R.id.ivStatus);
    if (item.getStatus() != null) {
        ivStatus.setVisibility(View.VISIBLE);
        switch(item.getStatus()) {
            case GREEN:
                ivStatus.setImageResource(R.drawable.status_light_green);
                break;
            case RED:
                ivStatus.setImageResource(R.drawable.status_light_red);
                break;
            case YELLOW:
                ivStatus.setImageResource(R.drawable.status_light_yellow);
                break;
            case UNKNOWN:
                ivStatus.setVisibility(View.INVISIBLE);
                break;
        }
    } else {
        ivStatus.setVisibility(View.GONE);
    }
    return view;
}
Also used : PreferenceDataSource(de.geeksfactory.opacclient.storage.PreferenceDataSource) ConnectivityManager(android.net.ConnectivityManager) LayoutInflater(android.view.LayoutInflater) SearchResult(de.geeksfactory.opacclient.objects.SearchResult) TextView(android.widget.TextView) ImageView(android.widget.ImageView) ImageView(android.widget.ImageView) TextView(android.widget.TextView) View(android.view.View)

Example 18 with SearchResult

use of de.geeksfactory.opacclient.objects.SearchResult in project opacclient by opacapp.

the class ResultsAdapterEndless method cacheInBackground.

@Override
protected boolean cacheInBackground() throws Exception {
    if (page < maxPage || getWrappedAdapter().getCount() < resultCount || (resultCount == -1 && objects.size() > 0 && !endReached)) {
        page++;
        SearchRequestResult result = listener.onLoadMore(page);
        itemsToAppend = result.getResults();
        /* When IOpac finds more than 200 results, the real result count is
            not known until the second page is loaded */
        maxPage = result.getPage_count();
        resultCount = result.getTotal_result_count();
        for (SearchResult item : itemsToAppend) {
            item.setPage(page);
        }
        return itemsToAppend != null;
    } else {
        endReached = true;
        return false;
    }
}
Also used : SearchRequestResult(de.geeksfactory.opacclient.objects.SearchRequestResult) SearchResult(de.geeksfactory.opacclient.objects.SearchResult)

Example 19 with SearchResult

use of de.geeksfactory.opacclient.objects.SearchResult in project opacclient by opacapp.

the class WebOpacNet method parse_search.

private SearchRequestResult parse_search(String text, int page) throws OpacErrorException {
    if (!text.equals("")) {
        try {
            List<SearchResult> results = new ArrayList<>();
            JSONObject json = new JSONObject(text);
            int total_result_count = Integer.parseInt(json.getString("totalcount"));
            JSONArray resultList = json.getJSONArray("mobmeds");
            for (int i = 0; i < resultList.length(); i++) {
                JSONObject resultJson = resultList.getJSONObject(i);
                SearchResult result = new SearchResult();
                result.setId(resultJson.getString("medid"));
                String title = resultJson.getString("titel");
                String publisher = resultJson.getString("verlag");
                String series = resultJson.getString("reihe");
                String html = "<b>" + title + "</b><br />" + publisher + ", " + series;
                String type = resultJson.getString("iconurl").substring(12, 13);
                result.setType(defaulttypes.get(type));
                result.setInnerhtml(html);
                if (resultJson.getString("imageurl").length() > 0) {
                    result.setCover(resultJson.getString("imageurl"));
                }
                results.add(result);
            }
            return new SearchRequestResult(results, total_result_count, page);
        } catch (JSONException e) {
            e.printStackTrace();
            throw new OpacErrorException(stringProvider.getFormattedString(StringProvider.INTERNAL_ERROR_WITH_DESCRIPTION, e.getMessage()));
        }
    } else {
        return new SearchRequestResult(new ArrayList<SearchResult>(), 0, page);
    }
}
Also used : JSONObject(org.json.JSONObject) SearchRequestResult(de.geeksfactory.opacclient.objects.SearchRequestResult) ArrayList(java.util.ArrayList) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) SearchResult(de.geeksfactory.opacclient.objects.SearchResult)

Example 20 with SearchResult

use of de.geeksfactory.opacclient.objects.SearchResult in project opacclient by opacapp.

the class WinBiap method parse_search.

private SearchRequestResult parse_search(String html, int page) throws OpacErrorException, IOException {
    Document doc = Jsoup.parse(html);
    if (doc.select(".alert h4").text().contains("Keine Treffer gefunden")) {
        // no media found
        return new SearchRequestResult(new ArrayList<SearchResult>(), 0, page);
    }
    if (doc.select("errortype").size() > 0) {
        // Error (e.g. 404)
        throw new OpacErrorException(doc.select("errortype").text());
    }
    // Total count
    String header = doc.select(".ResultHeader").text();
    Pattern pattern = Pattern.compile("Die Suche ergab (\\d*) Treffer");
    Matcher matcher = pattern.matcher(header);
    int results_total;
    if (matcher.find()) {
        results_total = Integer.parseInt(matcher.group(1));
    } else {
        throw new OpacErrorException(stringProvider.getString(StringProvider.INTERNAL_ERROR));
    }
    // Results
    Elements trs = doc.select("#listview .ResultItem");
    List<SearchResult> results = new ArrayList<>();
    for (Element tr : trs) {
        SearchResult sr = new SearchResult();
        String author = tr.select(".autor").text();
        String title = tr.select(".title").text();
        String titleAddition = tr.select(".titleZusatz").text();
        String desc = tr.select(".smallDescription").text();
        sr.setInnerhtml("<b>" + (author.equals("") ? "" : author + "<br />") + title + (titleAddition.equals("") ? "" : " - <i>" + titleAddition + "</i>") + "</b><br /><small>" + desc + "</small>");
        if (tr.select(".coverWrapper input, .coverWrapper img").size() > 0) {
            Element cover = tr.select(".coverWrapper input, .coverWrapper img").first();
            if (cover.hasAttr("data-src")) {
                sr.setCover(cover.attr("data-src"));
            } else if (cover.hasAttr("src") && !cover.attr("src").contains("empty.gif") && !cover.attr("src").contains("leer.gif")) {
                sr.setCover(cover.attr("src"));
            }
            sr.setType(getMediaType(cover, data));
        }
        String link = tr.select("a[href*=detail.aspx]").attr("href");
        String base64 = getQueryParamsFirst(link).get("data");
        if (// Most of the time, the base64 string is
        base64.contains("-")) // followed by a hyphen and some
        // mysterious
        // letters that we don't want
        {
            base64 = base64.substring(0, base64.indexOf("-") - 1);
        }
        String decoded = new String(Base64.decode(base64), "UTF-8");
        pattern = Pattern.compile("CatalogueId=(\\d*)");
        matcher = pattern.matcher(decoded);
        if (matcher.find()) {
            sr.setId(matcher.group(1));
        } else {
            throw new OpacErrorException(stringProvider.getString(StringProvider.INTERNAL_ERROR));
        }
        if (tr.select(".mediaStatus").size() > 0) {
            Element status = tr.select(".mediaStatus").first();
            if (status.hasClass("StatusNotAvailable")) {
                sr.setStatus(Status.RED);
            } else if (status.hasClass("StatusAvailable")) {
                sr.setStatus(Status.GREEN);
            } else {
                sr.setStatus(Status.YELLOW);
            }
        } else if (tr.select(".showCopies").size() > 0) {
            // Multiple copies
            if (tr.nextElementSibling().select(".StatusNotAvailable").size() == 0) {
                sr.setStatus(Status.GREEN);
            } else if (tr.nextElementSibling().select(".StatusAvailable").size() == 0) {
                sr.setStatus(Status.RED);
            } else {
                sr.setStatus(Status.YELLOW);
            }
        }
        results.add(sr);
    }
    return new SearchRequestResult(results, results_total, page);
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) Element(org.jsoup.nodes.Element) FormElement(org.jsoup.nodes.FormElement) ArrayList(java.util.ArrayList) SearchResult(de.geeksfactory.opacclient.objects.SearchResult) Document(org.jsoup.nodes.Document) Elements(org.jsoup.select.Elements) SearchRequestResult(de.geeksfactory.opacclient.objects.SearchRequestResult)

Aggregations

SearchResult (de.geeksfactory.opacclient.objects.SearchResult)23 SearchRequestResult (de.geeksfactory.opacclient.objects.SearchRequestResult)21 ArrayList (java.util.ArrayList)17 Element (org.jsoup.nodes.Element)16 Document (org.jsoup.nodes.Document)12 Elements (org.jsoup.select.Elements)12 JSONException (org.json.JSONException)11 Matcher (java.util.regex.Matcher)9 NotReachableException (de.geeksfactory.opacclient.networking.NotReachableException)8 IOException (java.io.IOException)8 Pattern (java.util.regex.Pattern)8 URISyntaxException (java.net.URISyntaxException)5 DetailedItem (de.geeksfactory.opacclient.objects.DetailedItem)4 MalformedURLException (java.net.MalformedURLException)4 URI (java.net.URI)4 HashMap (java.util.HashMap)4 NameValuePair (org.apache.http.NameValuePair)4 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)4 SearchQuery (de.geeksfactory.opacclient.searchfields.SearchQuery)3 TextSearchField (de.geeksfactory.opacclient.searchfields.TextSearchField)3