Brion VIBBER has submitted this change and it was merged.

Change subject: Search thumbnails for Android
......................................................................


Search thumbnails for Android

* PageQueryTask abstract query class to fetch per-title data
* PageImagesTask to fetch page images specifically
* fetching images with Picasso, mostly works?
** sometimes seems to update the wrong image view?

Change-Id: I4b1432cab6762fb052b2c5e2c10c1a91226b9085
---
M wikipedia-it/pom.xml
A wikipedia/res/drawable-mdpi/ic_pageimage_placeholder.png
A wikipedia/res/drawable-xhdpi/ic_pageimage_placeholder.png
M wikipedia/res/layout/item_search_result.xml
A wikipedia/src/main/java/org/wikimedia/wikipedia/PageImagesTask.java
A wikipedia/src/main/java/org/wikimedia/wikipedia/PageQueryTask.java
M wikipedia/src/main/java/org/wikimedia/wikipedia/SearchArticlesFragment.java
7 files changed, 173 insertions(+), 9 deletions(-)

Approvals:
  Brion VIBBER: Verified; Looks good to me, approved



diff --git a/wikipedia-it/pom.xml b/wikipedia-it/pom.xml
index 8876928..324834c 100644
--- a/wikipedia-it/pom.xml
+++ b/wikipedia-it/pom.xml
@@ -35,7 +35,12 @@
                        <version>1.0-SNAPSHOT</version>
                        <scope>provided</scope>
                </dependency>
-       </dependencies>
+        <dependency>
+            <groupId>com.squareup.picasso</groupId>
+            <artifactId>picasso</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+    </dependencies>
 
        <build>
                <finalName>${project.artifactId}</finalName>
diff --git a/wikipedia/res/drawable-mdpi/ic_pageimage_placeholder.png 
b/wikipedia/res/drawable-mdpi/ic_pageimage_placeholder.png
new file mode 100644
index 0000000..6af4d15
--- /dev/null
+++ b/wikipedia/res/drawable-mdpi/ic_pageimage_placeholder.png
Binary files differ
diff --git a/wikipedia/res/drawable-xhdpi/ic_pageimage_placeholder.png 
b/wikipedia/res/drawable-xhdpi/ic_pageimage_placeholder.png
new file mode 100644
index 0000000..593085d
--- /dev/null
+++ b/wikipedia/res/drawable-xhdpi/ic_pageimage_placeholder.png
Binary files differ
diff --git a/wikipedia/res/layout/item_search_result.xml 
b/wikipedia/res/layout/item_search_result.xml
index c657b99..5d7b2db 100644
--- a/wikipedia/res/layout/item_search_result.xml
+++ b/wikipedia/res/layout/item_search_result.xml
@@ -6,12 +6,11 @@
               android:layout_height="wrap_content">
     <ImageView
         android:id="@+id/result_image"
-        android:layout_width="32dp"
-        android:layout_margin="8dp"
+        android:layout_width="48dp"
+        android:layout_margin="0dp"
         android:layout_marginRight="0dp"
-        android:layout_height="32dp"
-        android:background="@android:color/darker_gray"
-        />
+        android:layout_height="48dp"
+        android:scaleType="centerCrop"/>
     <TextView android:id="@+id/result_text"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
diff --git 
a/wikipedia/src/main/java/org/wikimedia/wikipedia/PageImagesTask.java 
b/wikipedia/src/main/java/org/wikimedia/wikipedia/PageImagesTask.java
new file mode 100644
index 0000000..d4e6caa
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikimedia/wikipedia/PageImagesTask.java
@@ -0,0 +1,36 @@
+package org.wikimedia.wikipedia;
+
+import android.content.Context;
+import org.json.JSONObject;
+import org.mediawiki.api.json.RequestBuilder;
+
+import java.util.List;
+
+public class PageImagesTask extends PageQueryTask<String> {
+    private int thumbSize;
+    private int maxThumbs;
+
+    public PageImagesTask(Context context, Site site, List<PageTitle> titles, 
int thumbSize) {
+        super(context, site, titles);
+        this.thumbSize = thumbSize;
+        maxThumbs = titles.size();
+    }
+
+    @Override
+    public void buildQueryParams(RequestBuilder builder) {
+        builder.param("prop", "pageimages")
+               .param("piprop", "thumbnail")
+               .param("pithumbsize", Integer.toString(thumbSize))
+               .param("pilimit", Integer.toString(maxThumbs));
+    }
+
+    @Override
+    public String processPage(int pageId, PageTitle pageTitle, JSONObject 
pageData) throws Throwable {
+        JSONObject thumbnail = pageData.optJSONObject("thumbnail");
+        if (thumbnail == null) {
+            return null;
+        } else {
+            return thumbnail.getString("source");
+        }
+    }
+}
diff --git a/wikipedia/src/main/java/org/wikimedia/wikipedia/PageQueryTask.java 
b/wikipedia/src/main/java/org/wikimedia/wikipedia/PageQueryTask.java
new file mode 100644
index 0000000..c0f35e6
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikimedia/wikipedia/PageQueryTask.java
@@ -0,0 +1,72 @@
+package org.wikimedia.wikipedia;
+
+import android.content.Context;
+import android.util.Log;
+import org.json.JSONObject;
+import org.mediawiki.api.json.Api;
+import org.mediawiki.api.json.ApiResult;
+import org.mediawiki.api.json.RequestBuilder;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public abstract class PageQueryTask<T> extends ApiTask<Map<PageTitle,T>> {
+    private List<PageTitle> titles;
+
+    public PageQueryTask(Context context, Site site, List<PageTitle> titles) {
+        super(context, site);
+        this.titles = titles;
+    }
+
+    @Override
+    public ApiResult buildRequest(Api api) {
+        RequestBuilder builder = api.action("query").param("titles", 
joinTitles());
+        buildQueryParams(builder);
+        return builder.get();
+    }
+
+    public String joinTitles() {
+        StringBuilder str = new StringBuilder();
+        boolean first = true;
+        for (PageTitle title : titles) {
+            str.append(title.getPrefixedText());
+            if (first) {
+                first = false;
+            } else {
+                str.append('|');
+            }
+        }
+        return str.toString();
+    }
+
+    @Override
+    public Map<PageTitle,T> processResult(ApiResult result) throws Throwable {
+        Map<PageTitle,T> map = new HashMap<PageTitle,T>();
+        JSONObject data = result.asObject();
+        JSONObject query = data.getJSONObject("query");
+        JSONObject pages = query.getJSONObject("pages");
+
+        // You would think you could use foreach on an Iterator, but you can't.
+        Iterator<String> keys = pages.keys();
+        for (String key = keys.next(); keys.hasNext(); key = keys.next()) {
+            int pageId = Integer.parseInt(key);
+            JSONObject pageData = pages.getJSONObject(key);
+            PageTitle pageTitle = processPageTitle(pageData);
+            T pageResult = processPage(pageId, pageTitle, pageData);
+            map.put(pageTitle, pageResult);
+        }
+
+        return map;
+    }
+
+    public PageTitle processPageTitle(JSONObject pageData) throws Throwable {
+        String title = pageData.getString("title");
+        return new PageTitle(null, title, getSite());
+    }
+
+    abstract public void buildQueryParams(RequestBuilder buildQueryParams);
+
+    abstract public T processPage(int pageId, PageTitle pageTitle, JSONObject 
page) throws Throwable;
+}
diff --git 
a/wikipedia/src/main/java/org/wikimedia/wikipedia/SearchArticlesFragment.java 
b/wikipedia/src/main/java/org/wikimedia/wikipedia/SearchArticlesFragment.java
index 70d2cf4..8ff53a7 100644
--- 
a/wikipedia/src/main/java/org/wikimedia/wikipedia/SearchArticlesFragment.java
+++ 
b/wikipedia/src/main/java/org/wikimedia/wikipedia/SearchArticlesFragment.java
@@ -1,6 +1,7 @@
 package org.wikimedia.wikipedia;
 
 import android.content.Context;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -11,9 +12,14 @@
 import android.view.*;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.*;
+import com.squareup.picasso.Picasso;
 import org.wikimedia.wikipedia.events.NewWikiPageNavigationEvent;
 
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 public class SearchArticlesFragment extends Fragment {
     private static final int DELAY_MILLIS = 300;
@@ -33,6 +39,8 @@
     private String lastSearchedText;
 
     private Handler searchHandler;
+    private Map<String,String> pageThumbnails = new HashMap<String,String>();
+    private PageImagesTask currentThumbnailTask;
 
     /**
      * Displays results passed to it as search suggestions.
@@ -54,6 +62,33 @@
         } else {
             searchResultsList.setVisibility(View.VISIBLE);
         }
+    }
+
+    /**
+     * @fixme show the list before we finish, then update the images
+     * @param results
+     */
+    private void fetchThumbnails(final List<PageTitle> results) {
+        Log.d("Wikipedia", "QQQ start");
+        PageImagesTask thumbnailTask = new PageImagesTask(getActivity(), 
app.getPrimarySite(), results, 48) {
+            @Override
+            public void onFinish(Map<PageTitle,String> thumbs) {
+                Log.d("Wikipedia", "QQQ finish");
+                for (PageTitle title : thumbs.keySet()) {
+                    String thumbUrl = thumbs.get(title);
+                    Log.d("Wikipedia", "QQQ " + title.getPrefixedText() + ": " 
+ thumbUrl);
+                    if (thumbUrl != null) {
+                        pageThumbnails.put(title.getPrefixedText(), thumbUrl);
+                    }
+                }
+                displayResults(results);
+            }
+        };
+        if (currentThumbnailTask != null) {
+            currentThumbnailTask.cancel();
+        }
+        thumbnailTask.execute();
+        currentThumbnailTask = thumbnailTask;
     }
 
     @Override
@@ -79,7 +114,7 @@
                 SearchArticlesTask searchTask = new 
SearchArticlesTask(getActivity(), app.getPrimarySite(), searchTerm) {
                     @Override
                     public void onFinish(List<PageTitle> result) {
-                        displayResults(result);
+                        fetchThumbnails(result);
                         searchProgress.setVisibility(View.GONE);
                         searchResultsCache.put(searchTerm, result);
                         lastSearchedText = searchTerm;
@@ -121,10 +156,13 @@
                 if (Utils.compareStrings(s.toString(), lastSearchedText) && 
!isSearchActive) {
                     return; // Nothing has changed!
                 }
+                if (s.toString().equals("")) {
+                       return; // nothing!
+                }
 
                 List<PageTitle> cacheResult = 
searchResultsCache.get(s.toString());
                 if (cacheResult != null) {
-                    displayResults(cacheResult);
+                    fetchThumbnails(cacheResult);
                     return;
                 }
                 searchHandler.removeMessages(MESSAGE_SEARCH);
@@ -150,7 +188,7 @@
         outState.putBoolean("isSearchActive", isSearchActive);
     }
 
-    private static class SearchResultAdapter extends BaseAdapter {
+    private class SearchResultAdapter extends BaseAdapter {
         private List<PageTitle> results;
         private final LayoutInflater inflater;
 
@@ -189,6 +227,20 @@
             TextView pageTitleText = (TextView) 
convertView.findViewById(R.id.result_text);
             PageTitle title = (PageTitle) getItem(position);
             pageTitleText.setText(title.getText());
+            ImageView imageView = (ImageView) 
convertView.findViewById(R.id.result_image);
+
+            String thumbnail = pageThumbnails.get(title.getPrefixedText());
+            if (thumbnail == null) {
+                Log.d("Wikipedia", "QQQ thumb is empty for " + 
title.getPrefixedText());
+                
imageView.setImageResource(R.drawable.ic_pageimage_placeholder);
+            } else {
+                Log.d("Wikipedia", "QQQ thumb is " + thumbnail + " for " + 
title.getPrefixedText());
+                Picasso.with(getActivity())
+                          .load(thumbnail)
+                          .placeholder(R.drawable.ic_pageimage_placeholder)
+                                          
.error(R.drawable.ic_pageimage_placeholder)
+                          .into(imageView);
+            }
 
             return convertView;
         }

-- 
To view, visit https://gerrit.wikimedia.org/r/95722
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I4b1432cab6762fb052b2c5e2c10c1a91226b9085
Gerrit-PatchSet: 6
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Yuvipanda <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to