Skip to content

Commit 9d1ed8b

Browse files
authored
Merge pull request commons-app#303 from misaochan/suggest-cats-from-title
Suggest categories from entered filename
2 parents 7f56a7a + 2496e37 commit 9d1ed8b

File tree

5 files changed

+160
-15
lines changed

5 files changed

+160
-15
lines changed

app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java

+83-12
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
import android.widget.TextView;
3434
import android.widget.Toast;
3535

36+
import org.mediawiki.api.ApiResult;
37+
import org.mediawiki.api.MWApi;
38+
39+
import java.io.IOException;
3640
import java.util.ArrayList;
3741
import java.util.Date;
3842
import java.util.HashMap;
@@ -41,8 +45,10 @@
4145
import java.util.List;
4246
import java.util.Set;
4347
import java.util.concurrent.CountDownLatch;
48+
import java.util.concurrent.ExecutionException;
4449
import java.util.concurrent.ScheduledThreadPoolExecutor;
4550

51+
import fr.free.nrw.commons.CommonsApplication;
4652
import fr.free.nrw.commons.R;
4753
import fr.free.nrw.commons.Utils;
4854
import fr.free.nrw.commons.upload.MwVolleyApi;
@@ -73,6 +79,9 @@ public static interface OnCategoriesSaveHandler {
7379
PrefixUpdater prefixUpdaterSub;
7480
MethodAUpdater methodAUpdaterSub;
7581

82+
private final ArrayList<String> titleCatItems = new ArrayList<String>();
83+
final CountDownLatch mergeLatch = new CountDownLatch(1);
84+
7685
private ContentProviderClient client;
7786

7887
protected final static int SEARCH_CATS_LIMIT = 25;
@@ -113,12 +122,48 @@ public void writeToParcel(Parcel parcel, int flags) {
113122
}
114123

115124
/**
116-
* Retrieves recently-used categories and nearby categories, and merges them without duplicates.
117-
* @return a list containing these categories
125+
* Retrieves category suggestions from title input
126+
* @return a list containing title-related categories
127+
*/
128+
protected ArrayList<String> titleCatQuery() {
129+
130+
TitleCategories titleCategoriesSub;
131+
132+
//Retrieve the title that was saved when user tapped submit icon
133+
SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity());
134+
String title = titleDesc.getString("Title", "");
135+
Log.d(TAG, "Title: " + title);
136+
137+
//Override onPostExecute to access the results of async API call
138+
titleCategoriesSub = new TitleCategories(title) {
139+
@Override
140+
protected void onPostExecute(ArrayList<String> result) {
141+
super.onPostExecute(result);
142+
Log.d(TAG, "Results in onPostExecute: " + result);
143+
titleCatItems.addAll(result);
144+
Log.d(TAG, "TitleCatItems in onPostExecute: " + titleCatItems);
145+
mergeLatch.countDown();
146+
}
147+
};
148+
149+
Utils.executeAsyncTask(titleCategoriesSub);
150+
Log.d(TAG, "TitleCatItems in titleCatQuery: " + titleCatItems);
151+
152+
//Only return titleCatItems after API call has finished
153+
try {
154+
mergeLatch.await();
155+
} catch (InterruptedException e) {
156+
Log.e(TAG, "Interrupted exception: ", e);
157+
}
158+
return titleCatItems;
159+
}
160+
161+
/**
162+
* Retrieves recently-used categories
163+
* @return a list containing recent categories
118164
*/
119165
protected ArrayList<String> recentCatQuery() {
120166
ArrayList<String> items = new ArrayList<String>();
121-
Set<String> mergedItems = new LinkedHashSet<String>();
122167

123168
try {
124169
Cursor cursor = client.query(
@@ -133,23 +178,49 @@ protected ArrayList<String> recentCatQuery() {
133178
items.add(cat.getName());
134179
}
135180
cursor.close();
181+
}
182+
catch (RemoteException e) {
183+
throw new RuntimeException(e);
184+
}
185+
return items;
186+
}
136187

137-
if (MwVolleyApi.GpsCatExists.getGpsCatExists() == true) {
138-
//Log.d(TAG, "GPS cats found in CategorizationFragment.java" + MwVolleyApi.getGpsCat().toString());
139-
List<String> gpsItems = new ArrayList<String>(MwVolleyApi.getGpsCat());
140-
//Log.d(TAG, "GPS items: " + gpsItems.toString());
188+
/**
189+
* Merges nearby categories, categories suggested based on title, and recent categories... without duplicates.
190+
* @return a list containing merged categories
191+
*/
192+
protected ArrayList<String> mergeItems() {
141193

142-
mergedItems.addAll(gpsItems);
143-
}
194+
Set<String> mergedItems = new LinkedHashSet<String>();
195+
196+
Log.d(TAG, "Calling APIs for GPS cats, title cats and recent cats...");
144197

145-
mergedItems.addAll(items);
198+
List<String> gpsItems = new ArrayList<String>();
199+
if (MwVolleyApi.GpsCatExists.getGpsCatExists()) {
200+
gpsItems.addAll(MwVolleyApi.getGpsCat());
146201
}
147-
catch (RemoteException e) {
148-
throw new RuntimeException(e);
202+
List<String> titleItems = new ArrayList<String>(titleCatQuery());
203+
List<String> recentItems = new ArrayList<String>(recentCatQuery());
204+
205+
//Await results of titleItems, which is likely to come in last
206+
try {
207+
mergeLatch.await();
208+
Log.d(TAG, "Waited for merge");
209+
} catch (InterruptedException e) {
210+
Log.e(TAG, "Interrupted Exception: ", e);
149211
}
150212

213+
mergedItems.addAll(gpsItems);
214+
Log.d(TAG, "Adding GPS items: " + gpsItems);
215+
mergedItems.addAll(titleItems);
216+
Log.d(TAG, "Adding title items: " + titleItems);
217+
mergedItems.addAll(recentItems);
218+
Log.d(TAG, "Adding recent items: " + recentItems);
219+
151220
//Needs to be an ArrayList and not a List unless we want to modify a big portion of preexisting code
152221
ArrayList<String> mergedItemsList = new ArrayList<String>(mergedItems);
222+
Log.d(TAG, "Merged item list: " + mergedItemsList);
223+
153224
return mergedItemsList;
154225
}
155226

app/src/main/java/fr/free/nrw/commons/category/MethodAUpdater.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ protected void onPreExecute() {
4242
protected ArrayList<String> doInBackground(Void... voids) {
4343
//If user hasn't typed anything in yet, get GPS and recent items
4444
if(TextUtils.isEmpty(filter)) {
45-
return catFragment.recentCatQuery();
45+
return catFragment.mergeItems();
4646
}
4747

4848
//if user types in something that is in cache, return cached category

app/src/main/java/fr/free/nrw/commons/category/PrefixUpdater.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected void onPreExecute() {
4545
protected ArrayList<String> doInBackground(Void... voids) {
4646
//If user hasn't typed anything in yet, get GPS and recent items
4747
if(TextUtils.isEmpty(filter)) {
48-
return catFragment.recentCatQuery();
48+
return catFragment.mergeItems();
4949
}
5050

5151
//if user types in something that is in cache, return cached category
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package fr.free.nrw.commons.category;
2+
3+
import android.os.AsyncTask;
4+
import android.text.TextUtils;
5+
import android.util.Log;
6+
import android.view.View;
7+
8+
import org.mediawiki.api.ApiResult;
9+
import org.mediawiki.api.MWApi;
10+
11+
import java.io.IOException;
12+
import java.util.ArrayList;
13+
14+
import fr.free.nrw.commons.CommonsApplication;
15+
16+
/**
17+
* Sends asynchronous queries to the Commons MediaWiki API to retrieve categories that are related to
18+
* the title entered in previous screen. The 'srsearch' action-specific parameter is used for this
19+
* purpose. This class should be subclassed in CategorizationFragment.java to add the results to recent and GPS cats.
20+
*/
21+
public class TitleCategories extends AsyncTask<Void, Void, ArrayList<String>> {
22+
23+
private final static int SEARCH_CATS_LIMIT = 25;
24+
private static final String TAG = TitleCategories.class.getName();
25+
private String title;
26+
27+
public TitleCategories(String title) {
28+
super();
29+
this.title = title;
30+
}
31+
32+
@Override
33+
protected void onPreExecute() {
34+
super.onPreExecute();
35+
}
36+
37+
@Override
38+
protected ArrayList<String> doInBackground(Void... voids) {
39+
40+
MWApi api = CommonsApplication.createMWApi();
41+
ApiResult result;
42+
ArrayList<String> items = new ArrayList<>();
43+
44+
//URL https://commons.wikimedia.org/w/api.php?action=query&format=xml&list=search&srwhat=text&srenablerewrites=1&srnamespace=14&srlimit=10&srsearch=
45+
try {
46+
result = api.action("query")
47+
.param("format", "xml")
48+
.param("list", "search")
49+
.param("srwhat", "text")
50+
.param("srnamespace", "14")
51+
.param("srlimit", SEARCH_CATS_LIMIT)
52+
.param("srsearch", title)
53+
.get();
54+
Log.d(TAG, "Searching for cats for title: " + result.toString());
55+
} catch (IOException e) {
56+
Log.e(TAG, "IO Exception: ", e);
57+
//Return empty arraylist
58+
return items;
59+
}
60+
61+
ArrayList<ApiResult> categoryNodes = result.getNodes("/api/query/search/p/@title");
62+
for(ApiResult categoryNode: categoryNodes) {
63+
String cat = categoryNode.getDocument().getTextContent();
64+
String catString = cat.replace("Category:", "");
65+
items.add(catString);
66+
}
67+
68+
Log.d(TAG, "Title cat query results: " + items);
69+
70+
return items;
71+
}
72+
73+
}

app/src/main/java/fr/free/nrw/commons/upload/SingleUploadFragment.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,13 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
5252
@Override
5353
public boolean onOptionsItemSelected(MenuItem item) {
5454
switch (item.getItemId()) {
55+
//What happens when the 'submit' icon is tapped
5556
case R.id.menu_upload_single:
5657

5758
String title = titleEdit.getText().toString();
5859
String desc = descEdit.getText().toString();
5960

60-
//Save the values of these fields in short-lived cache so next time this fragment is loaded, we can access these
61+
//Save the title/desc in short-lived cache so next time this fragment is loaded, we can access these
6162
SharedPreferences titleDesc = PreferenceManager.getDefaultSharedPreferences(getActivity());
6263
SharedPreferences.Editor editor = titleDesc.edit();
6364
editor.putString("Title", title);

0 commit comments

Comments
 (0)