mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 12:53:55 +01:00
commit
5657a7194d
6 changed files with 166 additions and 78 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,16 @@ public class FilePathConverter {
|
||||||
* May return null
|
* May return null
|
||||||
*/
|
*/
|
||||||
public String getFilePath(){
|
public String getFilePath(){
|
||||||
|
|
||||||
String filePath ="";
|
String filePath ="";
|
||||||
|
|
||||||
|
try {
|
||||||
// Will return "image:x*"
|
// Will return "image:x*"
|
||||||
String wholeID = DocumentsContract.getDocumentId(uri);
|
String wholeID = DocumentsContract.getDocumentId(uri);
|
||||||
|
|
||||||
// Split at colon, use second item in the array
|
// Split at colon, use second item in the array
|
||||||
String id = wholeID.split(":")[1];
|
String id = wholeID.split(":")[1];
|
||||||
String[] column = { MediaStore.Images.Media.DATA };
|
String[] column = {MediaStore.Images.Media.DATA};
|
||||||
|
|
||||||
// where id is equal to
|
// where id is equal to
|
||||||
String sel = MediaStore.Images.Media._ID + "=?";
|
String sel = MediaStore.Images.Media._ID + "=?";
|
||||||
|
|
@ -45,5 +48,9 @@ public class FilePathConverter {
|
||||||
|
|
||||||
Log.d("Image", "File path: " + filePath);
|
Log.d("Image", "File path: " + filePath);
|
||||||
return filePath;
|
return filePath;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.w("Image", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,12 +45,9 @@ 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);
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w("Image", e);
|
|
||||||
}
|
|
||||||
return decimalCoords;
|
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
|
||||||
private String getDecimalCoords(String latitude, String latitude_ref, String longitude, String longitude_ref) {
|
private String getDecimalCoords(String latitude, String latitude_ref, String longitude, String longitude_ref) {
|
||||||
|
|
|
||||||
|
|
@ -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,15 +211,18 @@ 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(), "");
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
|
if (filePath != null) {
|
||||||
//extract the coordinates of image in decimal degrees
|
//extract the coordinates of image in decimal degrees
|
||||||
|
Log.d("Image", "Calling GPSExtractor");
|
||||||
GPSExtractor imageObj = new GPSExtractor(filePath);
|
GPSExtractor imageObj = new GPSExtractor(filePath);
|
||||||
String coords = imageObj.getCoords();
|
String coords = imageObj.getCoords();
|
||||||
|
|
||||||
|
if (coords != null) {
|
||||||
Log.d("Image", "Coords of image: " + coords);
|
Log.d("Image", "Coords of image: " + coords);
|
||||||
|
MwVolleyApi apiCall = new MwVolleyApi(this);
|
||||||
//build URL with image coords for MediaWiki API calls
|
|
||||||
String apiUrl = UrlBuilder.buildUrl(coords);
|
|
||||||
Log.d("Image", "URL: " + apiUrl);
|
|
||||||
|
|
||||||
|
|
||||||
//asynchronous calls to MediaWiki Commons API to match image coords with nearby Commons categories
|
//asynchronous calls to MediaWiki Commons API to match image coords with nearby Commons categories
|
||||||
MwVolleyApi apiCall = new MwVolleyApi(this);
|
apiCall.request(coords);
|
||||||
apiCall.request(apiUrl);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue