Skip to content

Commit bb8f62e

Browse files
committed
Use data client for peer review calls
1 parent 230b952 commit bb8f62e

File tree

7 files changed

+153
-157
lines changed

7 files changed

+153
-157
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
import android.app.Activity;
44
import android.content.ContentProviderClient;
55
import android.content.Context;
6-
import androidx.collection.LruCache;
76
import android.view.inputmethod.InputMethodManager;
87

98
import com.google.gson.Gson;
109

10+
import org.wikipedia.dataclient.WikiSite;
11+
1112
import java.util.ArrayList;
1213
import java.util.HashMap;
1314
import java.util.List;
@@ -16,6 +17,7 @@
1617
import javax.inject.Named;
1718
import javax.inject.Singleton;
1819

20+
import androidx.collection.LruCache;
1921
import dagger.Module;
2022
import dagger.Provides;
2123
import fr.free.nrw.commons.BuildConfig;
@@ -24,7 +26,6 @@
2426
import fr.free.nrw.commons.auth.SessionManager;
2527
import fr.free.nrw.commons.data.DBOpenHelper;
2628
import fr.free.nrw.commons.kvstore.JsonKvStore;
27-
import fr.free.nrw.commons.kvstore.JsonKvStore;
2829
import fr.free.nrw.commons.location.LocationServiceManager;
2930
import fr.free.nrw.commons.settings.Prefs;
3031
import fr.free.nrw.commons.upload.UploadController;

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import com.google.gson.Gson;
66

7+
import org.wikipedia.dataclient.ServiceFactory;
8+
import org.wikipedia.dataclient.WikiSite;
79
import org.wikipedia.json.GsonUtil;
810

911
import java.io.File;
@@ -20,6 +22,7 @@
2022
import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi;
2123
import fr.free.nrw.commons.mwapi.MediaWikiApi;
2224
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
25+
import fr.free.nrw.commons.review.ReviewInterface;
2326
import okhttp3.Cache;
2427
import okhttp3.HttpUrl;
2528
import okhttp3.OkHttpClient;
@@ -108,4 +111,16 @@ public Gson provideGson() {
108111
return GsonUtil.getDefaultGson();
109112
}
110113

114+
@Provides
115+
@Singleton
116+
@Named("commons-wikisite")
117+
public WikiSite provideCommonsWikiSite() {
118+
return new WikiSite(BuildConfig.COMMONS_URL);
119+
}
120+
121+
@Provides
122+
@Singleton
123+
public ReviewInterface provideReviewInterface(@Named("commons-wikisite") WikiSite commonsWikiSite) {
124+
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, ReviewInterface.class);
125+
}
111126
}

app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import org.apache.commons.lang3.StringUtils;
1111
import org.wikipedia.dataclient.mwapi.MwQueryPage;
1212
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
13-
import org.wikipedia.dataclient.mwapi.RecentChange;
14-
import org.wikipedia.util.DateUtil;
1513

1614
import java.io.IOException;
1715
import java.lang.reflect.Type;
@@ -20,7 +18,6 @@
2018
import java.util.List;
2119
import java.util.Locale;
2220
import java.util.Map;
23-
import java.util.Random;
2421

2522
import javax.inject.Inject;
2623
import javax.inject.Singleton;
@@ -421,80 +418,4 @@ private void putContinueValues(String keyword, Map<String, String> values) {
421418
private Map<String, String> getContinueValues(String keyword) {
422419
return defaultKvStore.getJson("query_continue_" + keyword, mapType);
423420
}
424-
425-
/**
426-
* Returns recent changes on commons
427-
*
428-
* @return list of recent changes made
429-
*/
430-
@Nullable
431-
public Single<List<RecentChange>> getRecentFileChanges() {
432-
final int RANDOM_SECONDS = 60 * 60 * 24 * 30;
433-
final String FILE_NAMESPACE = "6";
434-
Random r = new Random();
435-
Date now = new Date();
436-
Date startDate = new Date(now.getTime() - r.nextInt(RANDOM_SECONDS) * 1000L);
437-
438-
String rcStart = DateUtil.iso8601DateFormat(startDate);
439-
HttpUrl.Builder urlBuilder = HttpUrl
440-
.parse(commonsBaseUrl)
441-
.newBuilder()
442-
.addQueryParameter("action", "query")
443-
.addQueryParameter("format", "json")
444-
.addQueryParameter("formatversion", "2")
445-
.addQueryParameter("list", "recentchanges")
446-
.addQueryParameter("rcstart", rcStart)
447-
.addQueryParameter("rcnamespace", FILE_NAMESPACE)
448-
.addQueryParameter("rcprop", "title|ids")
449-
.addQueryParameter("rctype", "new|log")
450-
.addQueryParameter("rctoponly", "1");
451-
452-
Request request = new Request.Builder()
453-
.url(urlBuilder.build())
454-
.build();
455-
456-
return Single.fromCallable(() -> {
457-
Response response = okHttpClient.newCall(request).execute();
458-
if (response.body() != null && response.isSuccessful()) {
459-
String json = response.body().string();
460-
MwQueryResponse mwQueryPage = gson.fromJson(json, MwQueryResponse.class);
461-
return mwQueryPage.query().getRecentChanges();
462-
}
463-
return new ArrayList<>();
464-
});
465-
}
466-
467-
/**
468-
* Returns the first revision of the file
469-
*
470-
* @return Revision object
471-
*/
472-
@Nullable
473-
public Single<MwQueryPage.Revision> getFirstRevisionOfFile(String filename) {
474-
HttpUrl.Builder urlBuilder = HttpUrl
475-
.parse(commonsBaseUrl)
476-
.newBuilder()
477-
.addQueryParameter("action", "query")
478-
.addQueryParameter("format", "json")
479-
.addQueryParameter("formatversion", "2")
480-
.addQueryParameter("prop", "revisions")
481-
.addQueryParameter("rvprop", "timestamp|ids|user")
482-
.addQueryParameter("titles", filename)
483-
.addQueryParameter("rvdir", "newer")
484-
.addQueryParameter("rvlimit", "1");
485-
486-
Request request = new Request.Builder()
487-
.url(urlBuilder.build())
488-
.build();
489-
490-
return Single.fromCallable(() -> {
491-
Response response = okHttpClient.newCall(request).execute();
492-
if (response.body() != null && response.isSuccessful()) {
493-
String json = response.body().string();
494-
MwQueryResponse mwQueryPage = gson.fromJson(json, MwQueryResponse.class);
495-
return mwQueryPage.query().firstPage().revisions().get(0);
496-
}
497-
return null;
498-
});
499-
}
500421
}

app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@
1212
import android.widget.Button;
1313
import android.widget.ProgressBar;
1414
import android.widget.TextView;
15+
16+
import com.facebook.drawee.view.SimpleDraweeView;
17+
import com.google.android.material.navigation.NavigationView;
18+
import com.viewpagerindicator.CirclePageIndicator;
19+
20+
import java.util.ArrayList;
21+
22+
import javax.inject.Inject;
23+
1524
import androidx.appcompat.widget.Toolbar;
1625
import androidx.drawerlayout.widget.DrawerLayout;
1726
import butterknife.BindView;
1827
import butterknife.ButterKnife;
19-
import com.facebook.drawee.view.SimpleDraweeView;
20-
import com.google.android.material.navigation.NavigationView;
21-
import com.viewpagerindicator.CirclePageIndicator;
2228
import fr.free.nrw.commons.Media;
2329
import fr.free.nrw.commons.R;
2430
import fr.free.nrw.commons.auth.AuthenticatedActivity;
@@ -29,8 +35,6 @@
2935
import io.reactivex.android.schedulers.AndroidSchedulers;
3036
import io.reactivex.disposables.CompositeDisposable;
3137
import io.reactivex.schedulers.Schedulers;
32-
import java.util.ArrayList;
33-
import javax.inject.Inject;
3438

3539
public class ReviewActivity extends AuthenticatedActivity {
3640

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
package fr.free.nrw.commons.review;
22

3+
34
import org.wikipedia.dataclient.mwapi.MwQueryPage;
45
import org.wikipedia.dataclient.mwapi.RecentChange;
6+
import org.wikipedia.util.DateUtil;
57

8+
import java.util.Collections;
9+
import java.util.Date;
610
import java.util.List;
711
import java.util.Random;
812

913
import javax.inject.Inject;
1014
import javax.inject.Singleton;
1115

12-
import androidx.annotation.Nullable;
13-
import androidx.core.util.Pair;
1416
import fr.free.nrw.commons.Media;
1517
import fr.free.nrw.commons.mwapi.MediaWikiApi;
1618
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
19+
import io.reactivex.Observable;
1720
import io.reactivex.Single;
1821

1922
@Singleton
@@ -24,16 +27,29 @@ public class ReviewHelper {
2427

2528
private final OkHttpJsonApiClient okHttpJsonApiClient;
2629
private final MediaWikiApi mediaWikiApi;
30+
private final ReviewInterface reviewInterface;
2731

2832
@Inject
29-
public ReviewHelper(OkHttpJsonApiClient okHttpJsonApiClient, MediaWikiApi mediaWikiApi) {
33+
public ReviewHelper(OkHttpJsonApiClient okHttpJsonApiClient,
34+
MediaWikiApi mediaWikiApi,
35+
ReviewInterface reviewInterface) {
3036
this.okHttpJsonApiClient = okHttpJsonApiClient;
3137
this.mediaWikiApi = mediaWikiApi;
38+
this.reviewInterface = reviewInterface;
3239
}
3340

34-
Single<Media> getRandomMedia() {
35-
return getRandomFileChange()
36-
.flatMap(fileName -> okHttpJsonApiClient.getMedia(fileName, false));
41+
private Observable<List<RecentChange>> getRecentChanges() {
42+
final int RANDOM_SECONDS = 60 * 60 * 24 * 30;
43+
Random r = new Random();
44+
Date now = new Date();
45+
Date startDate = new Date(now.getTime() - r.nextInt(RANDOM_SECONDS) * 1000L);
46+
47+
String rcStart = DateUtil.iso8601DateFormat(startDate);
48+
return reviewInterface.getRecentChanges(rcStart).map(mwQueryResponse -> mwQueryResponse.query().getRecentChanges())
49+
.map(recentChanges -> {
50+
Collections.shuffle(recentChanges);
51+
return recentChanges;
52+
});
3753
}
3854

3955
/**
@@ -43,57 +59,46 @@ Single<Media> getRandomMedia() {
4359
* - Checks if the file is nominated for deletion
4460
* - Retries upto 5 times for getting a file which is not nominated for deletion
4561
*
46-
* @return
62+
* @return Random file change
4763
*/
48-
private Single<String> getRandomFileChange() {
49-
return okHttpJsonApiClient.getRecentFileChanges()
50-
.map(this::findImageInRecentChanges)
51-
.flatMap(title -> mediaWikiApi.pageExists("Commons:Deletion_requests/" + title)
52-
.map(pageExists -> new Pair<>(title, pageExists)))
53-
.map((Pair<String, Boolean> pair) -> {
54-
if (!pair.second) {
55-
return pair.first;
56-
}
57-
throw new Exception("Already nominated for deletion");
58-
}).retry(MAX_RANDOM_TRIES);
64+
public Single<Media> getRandomMedia() {
65+
return getRecentChanges()
66+
.flatMapIterable(changes -> changes)
67+
.filter(this::isChangeReviewable)
68+
.flatMapSingle(change -> mediaWikiApi.pageExists("Commons:Deletion_requests/" + change.getTitle())
69+
.map(exists -> {
70+
if (exists) {
71+
throw new RuntimeException("Already nominated for deletion");
72+
}
73+
return change.getTitle();
74+
}))
75+
.flatMapSingle(fileName -> okHttpJsonApiClient.getMedia(fileName, false)
76+
.map(media -> {
77+
if (media == null) {
78+
throw new NullPointerException("Media is null");
79+
}
80+
return media;
81+
}))
82+
.retry(MAX_RANDOM_TRIES)
83+
.firstOrError();
5984
}
6085

61-
Single<MwQueryPage.Revision> getFirstRevisionOfFile(String fileName) {
62-
return okHttpJsonApiClient.getFirstRevisionOfFile(fileName);
86+
Observable<MwQueryPage.Revision> getFirstRevisionOfFile(String filename) {
87+
return reviewInterface.getFirstRevisionOfFile(filename)
88+
.map(response -> response.query().firstPage().revisions().get(0));
6389
}
6490

65-
@Nullable
66-
private String findImageInRecentChanges(List<RecentChange> recentChanges) {
67-
String imageTitle;
68-
Random r = new Random();
69-
int count = recentChanges.size();
70-
// Build a range array
71-
int[] randomIndexes = new int[count];
72-
for (int i = 0; i < count; i++) {
73-
randomIndexes[i] = i;
91+
private boolean isChangeReviewable(RecentChange recentChange) {
92+
if (recentChange.getType().equals("log") && !(recentChange.getOldRevisionId() == 0)) {
93+
return false;
7494
}
75-
// Then shuffle it
76-
for (int i = 0; i < count; i++) {
77-
int swapIndex = r.nextInt(count);
78-
int temp = randomIndexes[i];
79-
randomIndexes[i] = randomIndexes[swapIndex];
80-
randomIndexes[swapIndex] = temp;
81-
}
82-
for (int i = 0; i < count; i++) {
83-
int randomIndex = randomIndexes[i];
84-
RecentChange recentChange = recentChanges.get(randomIndex);
85-
if (recentChange.getType().equals("log") && !(recentChange.getOldRevisionId() == 0)) {
86-
// For log entries, we only want ones where old_revid is zero, indicating a new file
87-
continue;
88-
}
89-
imageTitle = recentChange.getTitle();
9095

91-
for (String imageExtension : imageExtensions) {
92-
if (imageTitle.toLowerCase().endsWith(imageExtension)) {
93-
return imageTitle;
94-
}
96+
for (String extension : imageExtensions) {
97+
if (recentChange.getTitle().endsWith(extension)) {
98+
return true;
9599
}
96100
}
97-
return null;
101+
102+
return false;
98103
}
99104
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package fr.free.nrw.commons.review;
2+
3+
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
4+
5+
import io.reactivex.Observable;
6+
import retrofit2.http.GET;
7+
import retrofit2.http.Query;
8+
9+
public interface ReviewInterface {
10+
@GET("w/api.php?action=query&format=json&formatversion=2&list=recentchanges&rcprop=title|ids&rctype=new|log&rctoponly=1&rcnamespace=6")
11+
Observable<MwQueryResponse> getRecentChanges(@Query("rcstart") String rcStart);
12+
13+
@GET("w/api.php?action=query&format=json&formatversion=2&prop=revisions&rvprop=timestamp|ids|user&rvdir=newer&rvlimit=1")
14+
Observable<MwQueryResponse> getFirstRevisionOfFile(@Query("titles") String titles);
15+
}

0 commit comments

Comments
 (0)