Skip to content

Commit 91cfc7b

Browse files
ilgazermaskaravivek
authored andcommitted
OkHttpJsonApi#getMediaList migrated to retrofit (#3054)
* Migrated OkHttpJsonApi#getMediaList partially to MediaClient#getCategoryImages * Migrated rest of OkHttpJsonApi#getMediaList functionality to MediaClient#getCategoryImages * Removed unused code and tests * Fixed small bug * Added tests * Removed unused CategoryImageController
1 parent 52284b8 commit 91cfc7b

File tree

9 files changed

+153
-332
lines changed

9 files changed

+153
-332
lines changed

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

-30
This file was deleted.

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import fr.free.nrw.commons.R;
2828
import fr.free.nrw.commons.explore.categories.ExploreActivity;
2929
import fr.free.nrw.commons.kvstore.JsonKvStore;
30+
import fr.free.nrw.commons.media.MediaClient;
3031
import fr.free.nrw.commons.utils.NetworkUtils;
3132
import fr.free.nrw.commons.utils.ViewUtil;
3233
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -56,7 +57,7 @@ public class CategoryImagesListFragment extends DaggerFragment {
5657
private boolean isLoading = true;
5758
private String categoryName = null;
5859

59-
@Inject CategoryImageController controller;
60+
@Inject MediaClient mediaClient;
6061
@Inject
6162
@Named("default_preferences")
6263
JsonKvStore categoryKvStore;
@@ -116,7 +117,7 @@ private void initList() {
116117

117118
isLoading = true;
118119
progressBar.setVisibility(VISIBLE);
119-
compositeDisposable.add(controller.getCategoryImages(categoryName)
120+
compositeDisposable.add(mediaClient.getMediaListFromCategory(categoryName)
120121
.subscribeOn(Schedulers.io())
121122
.observeOn(AndroidSchedulers.mainThread())
122123
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
@@ -222,7 +223,7 @@ private void fetchMoreImages() {
222223
}
223224

224225
progressBar.setVisibility(VISIBLE);
225-
compositeDisposable.add(controller.getCategoryImages(categoryName)
226+
compositeDisposable.add(mediaClient.getMediaListFromCategory(categoryName)
226227
.subscribeOn(Schedulers.io())
227228
.observeOn(AndroidSchedulers.mainThread())
228229
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)

app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java

-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ public OkHttpJsonApiClient provideOkHttpJsonApiClient(OkHttpClient okHttpClient,
8585
WIKIDATA_SPARQL_QUERY_URL,
8686
BuildConfig.WIKIMEDIA_CAMPAIGNS_URL,
8787
BuildConfig.WIKIMEDIA_API_HOST,
88-
defaultKvStore,
8988
gson);
9089
}
9190

app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java

+5-13
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,18 @@
2424
import androidx.recyclerview.widget.RecyclerView;
2525
import butterknife.BindView;
2626
import butterknife.ButterKnife;
27-
import com.pedrogomez.renderers.RVRendererAdapter;
2827
import fr.free.nrw.commons.Media;
2928
import fr.free.nrw.commons.R;
3029
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
3130
import fr.free.nrw.commons.explore.SearchActivity;
3231
import fr.free.nrw.commons.explore.recentsearches.RecentSearch;
3332
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao;
3433
import fr.free.nrw.commons.kvstore.JsonKvStore;
35-
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
34+
import fr.free.nrw.commons.media.MediaClient;
3635
import fr.free.nrw.commons.utils.NetworkUtils;
3736
import fr.free.nrw.commons.utils.ViewUtil;
3837
import io.reactivex.android.schedulers.AndroidSchedulers;
39-
import io.reactivex.disposables.Disposable;
4038
import io.reactivex.schedulers.Schedulers;
41-
import java.util.ArrayList;
42-
import java.util.Date;
43-
import java.util.List;
44-
import java.util.concurrent.TimeUnit;
45-
import javax.inject.Inject;
46-
import javax.inject.Named;
4739
import timber.log.Timber;
4840

4941
import static android.view.View.GONE;
@@ -69,7 +61,7 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
6961

7062
@Inject RecentSearchesDao recentSearchesDao;
7163
@Inject
72-
OkHttpJsonApiClient okHttpJsonApiClient;
64+
MediaClient mediaClient;
7365
@Inject
7466
@Named("default_preferences")
7567
JsonKvStore defaultKvStore;
@@ -148,7 +140,7 @@ public void updateImageList(String query) {
148140
bottomProgressBar.setVisibility(GONE);
149141
queryList.clear();
150142
imagesAdapter.clear();
151-
compositeDisposable.add(okHttpJsonApiClient.getMediaList("search", query)
143+
compositeDisposable.add(mediaClient.getMediaListFromSearch(query)
152144
.subscribeOn(Schedulers.io())
153145
.observeOn(AndroidSchedulers.mainThread())
154146
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
@@ -165,7 +157,7 @@ public void addImagesToList(String query) {
165157
this.query = query;
166158
bottomProgressBar.setVisibility(View.VISIBLE);
167159
progressBar.setVisibility(GONE);
168-
compositeDisposable.add(okHttpJsonApiClient.getMediaList("search", query)
160+
compositeDisposable.add(mediaClient.getMediaListFromSearch(query)
169161
.subscribeOn(Schedulers.io())
170162
.observeOn(AndroidSchedulers.mainThread())
171163
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
@@ -228,7 +220,7 @@ private void handleError(Throwable throwable) {
228220
private void initErrorView() {
229221
progressBar.setVisibility(GONE);
230222
imagesNotFoundView.setVisibility(VISIBLE);
231-
imagesNotFoundView.setText(getString(R.string.images_not_found, query));
223+
imagesNotFoundView.setText(getString(R.string.images_not_found));
232224
}
233225

234226
/**

app/src/main/java/fr/free/nrw/commons/media/MediaClient.java

+61
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
package fr.free.nrw.commons.media;
22

33

4+
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
5+
6+
import java.util.ArrayList;
7+
import java.util.Collections;
8+
import java.util.HashMap;
9+
import java.util.List;
10+
import java.util.Map;
11+
412
import javax.inject.Inject;
513
import javax.inject.Singleton;
614

15+
import fr.free.nrw.commons.Media;
16+
import io.reactivex.Observable;
717
import io.reactivex.Single;
818

919
/**
@@ -14,9 +24,13 @@ public class MediaClient {
1424

1525
private final MediaInterface mediaInterface;
1626

27+
//OkHttpJsonApiClient used JsonKvStore for this. I don't know why.
28+
private Map<String, Map<String, String>> continuationStore;
29+
1730
@Inject
1831
public MediaClient(MediaInterface mediaInterface) {
1932
this.mediaInterface = mediaInterface;
33+
this.continuationStore = new HashMap<>();
2034
}
2135

2236
/**
@@ -43,4 +57,51 @@ public Single<Boolean> checkFileExistsUsingSha(String fileSha) {
4357
.query().allImages().size() > 0)
4458
.singleOrError();
4559
}
60+
61+
/**
62+
* This method takes the category as input and returns a list of Media objects filtered using image generator query
63+
* It uses the generator query API to get the images searched using a query, 10 at a time.
64+
*
65+
* @param category the search category. Must start with "Category:"
66+
* @return
67+
*/
68+
public Single<List<Media>> getMediaListFromCategory(String category) {
69+
return responseToMediaList(
70+
continuationStore.containsKey("category_" + category) ?
71+
mediaInterface.getMediaListFromCategory(category, 10, continuationStore.get("category_" + category)) : //if true
72+
mediaInterface.getMediaListFromCategory(category, 10, Collections.emptyMap()),
73+
"category_" + category); //if false
74+
75+
}
76+
77+
/**
78+
* This method takes a keyword as input and returns a list of Media objects filtered using image generator query
79+
* It uses the generator query API to get the images searched using a query, 10 at a time.
80+
*
81+
* @param keyword the search keyword
82+
* @return
83+
*/
84+
public Single<List<Media>> getMediaListFromSearch(String keyword) {
85+
return responseToMediaList(
86+
continuationStore.containsKey("search_" + keyword) ?
87+
mediaInterface.getMediaListFromSearch(keyword, 10, continuationStore.get("search_" + keyword)) : //if true
88+
mediaInterface.getMediaListFromSearch(keyword, 10, Collections.emptyMap()), //if false
89+
"search_" + keyword);
90+
91+
}
92+
93+
private Single<List<Media>> responseToMediaList(Observable<MwQueryResponse> response, String key) {
94+
return response.flatMap(mwQueryResponse -> {
95+
if (null == mwQueryResponse
96+
|| null == mwQueryResponse.query()
97+
|| null == mwQueryResponse.query().pages()) {
98+
return Observable.empty();
99+
}
100+
continuationStore.put(key, mwQueryResponse.continuation());
101+
return Observable.fromIterable(mwQueryResponse.query().pages());
102+
})
103+
.map(Media::from)
104+
.collect(ArrayList<Media>::new, List::add);
105+
}
106+
46107
}

app/src/main/java/fr/free/nrw/commons/media/MediaInterface.java

+38
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package fr.free.nrw.commons.media;
22

3+
import org.jetbrains.annotations.NotNull;
34
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
45

6+
import java.util.Map;
7+
58
import io.reactivex.Observable;
69
import retrofit2.http.GET;
710
import retrofit2.http.Query;
11+
import retrofit2.http.QueryMap;
812

913
/**
1014
* Interface for interacting with Commons media related APIs
1115
*/
1216
public interface MediaInterface {
1317
/**
1418
* Checks if a page exists or not.
19+
*
1520
* @param title the title of the page to be checked
1621
* @return
1722
*/
@@ -20,9 +25,42 @@ public interface MediaInterface {
2025

2126
/**
2227
* Check if file exists
28+
*
2329
* @param aisha1 the SHA of the media file to be checked
2430
* @return
2531
*/
2632
@GET("w/api.php?action=query&format=json&formatversion=2&list=allimages")
2733
Observable<MwQueryResponse> checkFileExistsUsingSha(@Query("aisha1") String aisha1);
34+
35+
36+
/**
37+
* This method retrieves a list of Media objects filtered using image generator query
38+
*
39+
* @param category the category name. Must start with "Category:"
40+
* @param itemLimit how many images are returned
41+
* @param continuation the continuation string from the previous query or empty map
42+
* @return
43+
*/
44+
@GET("w/api.php?action=query&format=json&formatversion=2" + //Basic parameters
45+
"&generator=categorymembers&gcmtype=file&gcmsort=timestamp&gcmdir=desc" + //Category parameters
46+
"&prop=imageinfo&iiprop=url|extmetadata&iiurlwidth=640" + //Media property parameters
47+
"&iiextmetadatafilter=DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal" +
48+
"|Artist|LicenseShortName|LicenseUrl")
49+
Observable<MwQueryResponse> getMediaListFromCategory(@Query("gcmtitle") String category, @Query("gcmlimit") int itemLimit, @QueryMap Map<String, String> continuation);
50+
51+
/**
52+
* This method retrieves a list of Media objects filtered using image generator query
53+
*
54+
* @param keyword the searched keyword
55+
* @param itemLimit how many images are returned
56+
* @param continuation the continuation string from the previous query
57+
* @return
58+
*/
59+
@GET("w/api.php?action=query&format=json&formatversion=2" + //Basic parameters
60+
"&generator=search&gsrwhat=text&gsrnamespace=6" + //Search parameters
61+
"&prop=imageinfo&iiprop=url|extmetadata&iiurlwidth=640" + //Media property parameters
62+
"&iiextmetadatafilter=DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal" +
63+
"|Artist|LicenseShortName|LicenseUrl")
64+
Observable<MwQueryResponse> getMediaListFromSearch(@Query("gsrsearch") String keyword, @Query("gsrlimit") int itemLimit, @QueryMap Map<String, String> continuation);
65+
2866
}

0 commit comments

Comments
 (0)