Merge pull request #34 from misaochan/api-calls

Displays categories
This commit is contained in:
Stephen Niedzielski 2016-01-02 01:32:05 -06:00
commit 5657a7194d
6 changed files with 166 additions and 78 deletions

View file

@ -1,5 +1,8 @@
# Wikimedia Commons for Android # Wikimedia Commons for Android
## v1.5
- New feature: Suggests nearby Commons categories
## v1.3 ## v1.3
- Removed 'send usage reports' setting - Removed 'send usage reports' setting
- Fixed package naming issue - Fixed package naming issue

View file

@ -8,6 +8,7 @@ import android.os.*;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.app.SherlockFragment;
@ -18,12 +19,14 @@ import org.mediawiki.api.ApiResult;
import org.mediawiki.api.MWApi; import org.mediawiki.api.MWApi;
import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.upload.MwVolleyApi;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
public class CategorizationFragment extends SherlockFragment{ public class CategorizationFragment extends SherlockFragment{
@ -112,6 +115,7 @@ public class CategorizationFragment extends SherlockFragment{
items.add(new CategoryItem(category, false)); items.add(new CategoryItem(category, false));
} }
} }
categoriesAdapter.setItems(items); categoriesAdapter.setItems(items);
categoriesAdapter.notifyDataSetInvalidated(); categoriesAdapter.notifyDataSetInvalidated();
categoriesSearchInProgress.setVisibility(View.GONE); categoriesSearchInProgress.setVisibility(View.GONE);
@ -132,6 +136,8 @@ public class CategorizationFragment extends SherlockFragment{
protected ArrayList<String> doInBackground(Void... voids) { protected ArrayList<String> doInBackground(Void... voids) {
if(TextUtils.isEmpty(filter)) { if(TextUtils.isEmpty(filter)) {
ArrayList<String> items = new ArrayList<String>(); ArrayList<String> items = new ArrayList<String>();
ArrayList<String> mergedItems= new ArrayList<String>();
try { try {
Cursor cursor = client.query( Cursor cursor = client.query(
CategoryContentProvider.BASE_URI, CategoryContentProvider.BASE_URI,
@ -144,12 +150,25 @@ public class CategorizationFragment extends SherlockFragment{
Category cat = Category.fromCursor(cursor); Category cat = Category.fromCursor(cursor);
items.add(cat.getName()); items.add(cat.getName());
} }
} catch (RemoteException e) {
if (MwVolleyApi.GpsCatExists.getGpsCatExists() == true){
Log.d("Cat", "GPS cats found in CategorizationFragment.java" + MwVolleyApi.getGpsCat().toString());
List<String> gpsItems = new ArrayList<String>(MwVolleyApi.getGpsCat());
Log.d("Cat", "GPS items: " + gpsItems.toString());
mergedItems.addAll(gpsItems);
}
mergedItems.addAll(items);
}
catch (RemoteException e) {
// faaaail // faaaail
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return items; Log.d("Cat", "Merged items: " + mergedItems.toString());
return mergedItems;
} }
if(categoriesCache.containsKey(filter)) { if(categoriesCache.containsKey(filter)) {
return categoriesCache.get(filter); return categoriesCache.get(filter);
} }

View file

@ -23,27 +23,34 @@ public class FilePathConverter {
* May return null * May return null
*/ */
public String getFilePath(){ public String getFilePath(){
String filePath =""; String filePath ="";
// Will return "image:x*"
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array try {
String id = wholeID.split(":")[1]; // Will return "image:x*"
String[] column = { MediaStore.Images.Media.DATA }; String wholeID = DocumentsContract.getDocumentId(uri);
// where id is equal to // Split at colon, use second item in the array
String sel = MediaStore.Images.Media._ID + "=?"; String id = wholeID.split(":")[1];
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String[] column = {MediaStore.Images.Media.DATA};
column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]); // where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
if (cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndex(column[0]);
filePath = cursor.getString(columnIndex);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
Log.d("Image", "File path: " + filePath);
return filePath;
} catch (IllegalArgumentException e) {
Log.w("Image", e);
return null;
} }
cursor.close();
Log.d("Image", "File path: " + filePath);
return filePath;
} }
} }

View file

@ -26,6 +26,16 @@ public class GPSExtractor {
try { try {
exif = new ExifInterface(filePath); exif = new ExifInterface(filePath);
} catch (IOException e) {
Log.w("Image", e);
return null;
}
if (exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) == null) {
Log.d("Image", "Picture has no GPS info");
return null;
}
else {
latitude = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE); latitude = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
latitude_ref = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF); latitude_ref = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
longitude = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE); longitude = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
@ -35,11 +45,8 @@ public class GPSExtractor {
Log.d("Image", "Longitude: " + longitude + " " + longitude_ref); Log.d("Image", "Longitude: " + longitude + " " + longitude_ref);
decimalCoords = getDecimalCoords(latitude, latitude_ref, longitude, longitude_ref); decimalCoords = getDecimalCoords(latitude, latitude_ref, longitude, longitude_ref);
return decimalCoords;
} catch (IOException e) {
Log.w("Image", e);
} }
return decimalCoords;
} }
//Converts format of coords into decimal coords as required by API for next step //Converts format of coords into decimal coords as required by API for next step

View file

@ -1,6 +1,7 @@
package fr.free.nrw.commons.upload; package fr.free.nrw.commons.upload;
import android.content.Context; import android.content.Context;
import android.net.Uri;
import android.util.Log; import android.util.Log;
import com.android.volley.Cache; import com.android.volley.Cache;
@ -18,23 +19,75 @@ import com.google.gson.GsonBuilder;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MwVolleyApi { public class MwVolleyApi {
private static RequestQueue REQUEST_QUEUE; private static RequestQueue REQUEST_QUEUE;
private static final Gson GSON = new GsonBuilder().create(); private static final Gson GSON = new GsonBuilder().create();
private Context context; private Context context;
private String coordsLog;
protected static Set<String> categorySet;
private static final String MWURL = "https://commons.wikimedia.org/";
public MwVolleyApi(Context context) { public MwVolleyApi(Context context) {
this.context = context; this.context = context;
categorySet = new HashSet<String>();
} }
public void request(String apiUrl) {
//To get the list of categories for display
public static List<String> getGpsCat() {
List<String> list = new ArrayList<String>(categorySet);
return list;
}
public void request(String coords) {
coordsLog = coords;
String apiUrl = buildUrl(coords);
Log.d("Image", "URL: " + apiUrl);
JsonRequest<QueryResponse> request = new QueryRequest(apiUrl, JsonRequest<QueryResponse> request = new QueryRequest(apiUrl,
new LogResponseListener<QueryResponse>(), new LogResponseErrorListener()); new LogResponseListener<QueryResponse>(), new LogResponseErrorListener());
getQueue().add(request); getQueue().add(request);
} }
private RequestQueue getQueue() { /**
* Builds URL with image coords for MediaWiki API calls
* Example URL: https://commons.wikimedia.org/w/api.php?action=query&prop=categories|coordinates|pageprops&format=json&clshow=!hidden&coprop=type|name|dim|country|region|globe&codistancefrompoint=38.11386944444445|13.356263888888888&
* generator=geosearch&redirects=&ggscoord=38.11386944444445|13.356263888888888&ggsradius=100&ggslimit=10&ggsnamespace=6&ggsprop=type|name|dim|country|region|globe&ggsprimary=all&formatversion=2
*/
private String buildUrl (String coords){
Uri.Builder builder = Uri.parse(MWURL).buildUpon();
builder.appendPath("w")
.appendPath("api.php")
.appendQueryParameter("action", "query")
.appendQueryParameter("prop", "categories|coordinates|pageprops")
.appendQueryParameter("format", "json")
.appendQueryParameter("clshow", "!hidden")
.appendQueryParameter("coprop", "type|name|dim|country|region|globe")
.appendQueryParameter("codistancefrompoint", coords)
.appendQueryParameter("generator", "geosearch")
.appendQueryParameter("ggscoord", coords)
.appendQueryParameter("ggsradius", "100")
.appendQueryParameter("ggslimit", "10")
.appendQueryParameter("ggsnamespace", "6")
.appendQueryParameter("ggsprop", "type|name|dim|country|region|globe")
.appendQueryParameter("ggsprimary", "all")
.appendQueryParameter("formatversion", "2");
return builder.toString();
}
private synchronized RequestQueue getQueue() {
return getQueue(context); return getQueue(context);
} }
@ -80,12 +133,10 @@ public class MwVolleyApi {
return Response.success(queryResponse, cacheEntry(response)); return Response.success(queryResponse, cacheEntry(response));
} }
private Cache.Entry cacheEntry(NetworkResponse response) { private Cache.Entry cacheEntry(NetworkResponse response) {
return HttpHeaderParser.parseCacheHeaders(response); return HttpHeaderParser.parseCacheHeaders(response);
} }
private String parseString(NetworkResponse response) { private String parseString(NetworkResponse response) {
try { try {
return new String(response.data, HttpHeaderParser.parseCharset(response.headers)); return new String(response.data, HttpHeaderParser.parseCharset(response.headers));
@ -95,12 +146,40 @@ public class MwVolleyApi {
} }
} }
public static class GpsCatExists {
private static boolean gpsCatExists;
public static void setGpsCatExists(boolean gpsCat) {
gpsCatExists = gpsCat;
}
public static boolean getGpsCatExists() {
return gpsCatExists;
}
}
private static class QueryResponse { private static class QueryResponse {
private Query query; private Query query = new Query();
private String printSet() {
if (categorySet == null || categorySet.isEmpty()) {
GpsCatExists.setGpsCatExists(false);
Log.d("Cat", "gpsCatExists=" + GpsCatExists.getGpsCatExists());
return "No collection of categories";
} else {
GpsCatExists.setGpsCatExists(true);
Log.d("Cat", "gpsCatExists=" + GpsCatExists.getGpsCatExists());
return "CATEGORIES FOUND" + categorySet.toString();
}
}
@Override @Override
public String toString() { public String toString() {
return "query=" + query.toString(); if (query != null) {
return "query=" + query.toString() + "\n" + printSet();
} else {
return "No pages found";
}
} }
} }
@ -115,7 +194,9 @@ public class MwVolleyApi {
builder.append("\n"); builder.append("\n");
} }
builder.replace(builder.length() - 1, builder.length(), ""); builder.replace(builder.length() - 1, builder.length(), "");
return builder.toString(); return builder.toString();
} }
} }
@ -130,16 +211,19 @@ public class MwVolleyApi {
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder("PAGEID=" + pageid + " ns=" + ns + " title=" + title + "\n" + " CATEGORIES= "); StringBuilder builder = new StringBuilder("PAGEID=" + pageid + " ns=" + ns + " title=" + title + "\n" + " CATEGORIES= ");
if (categories != null) {
if (categories == null || categories.length == 0) {
builder.append("no categories exist\n");
} else {
for (Category category : categories) { for (Category category : categories) {
builder.append(category.toString()); builder.append(category.toString());
builder.append("\n"); builder.append("\n");
if (category != null) {
String categoryString = category.toString().replace("Category:", "");
categorySet.add(categoryString);
}
} }
} }
else {
builder.append("no categories exist");
builder.append("\n");
}
builder.replace(builder.length() - 1, builder.length(), ""); builder.replace(builder.length() - 1, builder.length(), "");
return builder.toString(); return builder.toString();
@ -147,12 +231,11 @@ public class MwVolleyApi {
} }
private static class Category { private static class Category {
private int ns;
private String title; private String title;
@Override @Override
public String toString() { public String toString() {
return " ns=" + ns + " title=" + title; return title;
} }
} }
} }

View file

@ -179,20 +179,20 @@ public class ShareActivity
FilePathConverter uriObj = new FilePathConverter(this, mediaUri); FilePathConverter uriObj = new FilePathConverter(this, mediaUri);
String filePath = uriObj.getFilePath(); String filePath = uriObj.getFilePath();
//extract the coordinates of image in decimal degrees if (filePath != null) {
GPSExtractor imageObj = new GPSExtractor(filePath); //extract the coordinates of image in decimal degrees
String coords = imageObj.getCoords(); Log.d("Image", "Calling GPSExtractor");
Log.d("Image", "Coords of image: " + coords); GPSExtractor imageObj = new GPSExtractor(filePath);
String coords = imageObj.getCoords();
//build URL with image coords for MediaWiki API calls if (coords != null) {
String apiUrl = UrlBuilder.buildUrl(coords); Log.d("Image", "Coords of image: " + coords);
Log.d("Image", "URL: " + apiUrl); MwVolleyApi apiCall = new MwVolleyApi(this);
//asynchronous calls to MediaWiki Commons API to match image coords with nearby Commons categories
MwVolleyApi apiCall = new MwVolleyApi(this);
apiCall.request(apiUrl);
//asynchronous calls to MediaWiki Commons API to match image coords with nearby Commons categories
apiCall.request(coords);
}
}
ImageLoader.getInstance().displayImage(mediaUriString, backgroundImageView); ImageLoader.getInstance().displayImage(mediaUriString, backgroundImageView);
@ -220,35 +220,4 @@ public class ShareActivity
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
/**
* Builds URL with image coords for MediaWiki API calls
* Example URL: https://commons.wikimedia.org/w/api.php?action=query&prop=categories|coordinates|pageprops&format=json&clshow=!hidden&coprop=type|name|dim|country|region|globe&codistancefrompoint=38.11386944444445|13.356263888888888&
* generator=geosearch&redirects=&ggscoord=38.11386944444445|13.356263888888888&ggsradius=100&ggslimit=10&ggsnamespace=6&ggsprop=type|name|dim|country|region|globe&ggsprimary=all&formatversion=2
*/
public static class UrlBuilder {
private static String buildUrl (String coords){
Uri.Builder builder = Uri.parse("https://commons.wikimedia.org/").buildUpon();
builder.appendPath("w")
.appendPath("api.php")
.appendQueryParameter("action", "query")
.appendQueryParameter("prop", "categories|coordinates|pageprops")
.appendQueryParameter("format", "json")
.appendQueryParameter("clshow", "!hidden")
.appendQueryParameter("coprop", "type|name|dim|country|region|globe")
.appendQueryParameter("codistancefrompoint", coords)
.appendQueryParameter("generator", "geosearch")
.appendQueryParameter("ggscoord", coords)
.appendQueryParameter("ggsradius", "100")
.appendQueryParameter("ggslimit", "10")
.appendQueryParameter("ggsnamespace", "6")
.appendQueryParameter("ggsprop", "type|name|dim|country|region|globe")
.appendQueryParameter("ggsprimary", "all")
.appendQueryParameter("formatversion", "2");
return builder.toString();
}
}
} }