mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-28 13:23:58 +01:00
Use JSON APIs for peer review (#2714)
This commit is contained in:
parent
ce3349385f
commit
7cb1f56165
14 changed files with 203 additions and 138 deletions
|
|
@ -32,7 +32,6 @@ import java.util.Collections;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
|
|
@ -45,7 +44,6 @@ import fr.free.nrw.commons.auth.AccountUtil;
|
|||
import fr.free.nrw.commons.category.CategoryImageUtils;
|
||||
import fr.free.nrw.commons.category.QueryContinue;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.media.RecentChangesImageUtils;
|
||||
import fr.free.nrw.commons.notification.Notification;
|
||||
import fr.free.nrw.commons.notification.NotificationUtils;
|
||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||
|
|
@ -63,14 +61,6 @@ import static fr.free.nrw.commons.utils.ContinueUtils.getQueryContinue;
|
|||
*/
|
||||
public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
||||
private static final String THUMB_SIZE = "640";
|
||||
// Give up if no random recent image found after 5 tries
|
||||
private static final int MAX_RANDOM_TRIES = 5;
|
||||
// Random image request is for some time in the past 30 days
|
||||
private static final int RANDOM_SECONDS = 60 * 60 * 24 * 30;
|
||||
// Assuming MW always gives me UTC
|
||||
private static final SimpleDateFormat isoFormat =
|
||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
|
||||
private static final String FILE_NAMESPACE = "6";
|
||||
private AbstractHttpClient httpClient;
|
||||
private CustomMwApi api;
|
||||
private CustomMwApi wikidataApi;
|
||||
|
|
@ -586,24 +576,6 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
|||
.getString("/api/query/pages/page/revisions/rev");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Single<Revision> firstRevisionOfFile(String filename) {
|
||||
return Single.fromCallable(() -> {
|
||||
CustomApiResult res = api.action("query")
|
||||
.param("prop", "revisions")
|
||||
.param("rvprop", "timestamp|ids|user")
|
||||
.param("titles", filename)
|
||||
.param("rvdir", "newer")
|
||||
.param("rvlimit", "1")
|
||||
.get();
|
||||
return new Revision(
|
||||
res.getString("/api/query/pages/page/revisions/rev/@revid"),
|
||||
res.getString("/api/query/pages/page/revisions/rev/@user"),
|
||||
filename);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public List<Notification> getNotifications(boolean archived) {
|
||||
|
|
@ -1053,52 +1025,4 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
|||
}
|
||||
}
|
||||
|
||||
private String formatMWDate(Date date) {
|
||||
return isoFormat.format(date);
|
||||
}
|
||||
|
||||
public Media getRecentRandomImage() throws IOException {
|
||||
Media media = null;
|
||||
int tries = 0;
|
||||
Random r = new Random();
|
||||
|
||||
while (media == null && tries < MAX_RANDOM_TRIES) {
|
||||
Date now = new Date();
|
||||
Date startDate = new Date(now.getTime() - r.nextInt(RANDOM_SECONDS) * 1000L);
|
||||
CustomApiResult apiResult = null;
|
||||
try {
|
||||
CustomMwApi.RequestBuilder requestBuilder = api.action("query")
|
||||
.param("list", "recentchanges")
|
||||
.param("rcstart", formatMWDate(startDate))
|
||||
.param("rcnamespace", FILE_NAMESPACE)
|
||||
.param("rcprop", "title|ids")
|
||||
.param("rctype", "new|log")
|
||||
.param("rctoponly", "1");
|
||||
|
||||
apiResult = requestBuilder.get();
|
||||
} catch (IOException e) {
|
||||
Timber.e(e, "Failed to obtain recent random");
|
||||
}
|
||||
if (apiResult != null) {
|
||||
CustomApiResult recentChangesNode = apiResult.getNode("/api/query/recentchanges");
|
||||
if (recentChangesNode != null
|
||||
&& recentChangesNode.getDocument() != null
|
||||
&& recentChangesNode.getDocument().getChildNodes() != null
|
||||
&& recentChangesNode.getDocument().getChildNodes().getLength() > 0) {
|
||||
NodeList childNodes = recentChangesNode.getDocument().getChildNodes();
|
||||
String imageTitle = RecentChangesImageUtils.findImageInRecentChanges(childNodes);
|
||||
if (imageTitle != null) {
|
||||
boolean deletionStatus = pageExists("Commons:Deletion_requests/" + imageTitle);
|
||||
if (!deletionStatus) {
|
||||
// strip File: prefix
|
||||
imageTitle = imageTitle.replace("File:", "");
|
||||
media = new Media(imageTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tries++;
|
||||
}
|
||||
return media;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package fr.free.nrw.commons.mwapi;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.notification.Notification;
|
||||
import io.reactivex.Observable;
|
||||
|
|
@ -108,12 +108,7 @@ public interface MediaWikiApi {
|
|||
|
||||
boolean thank(String editToken, String revision) throws IOException;
|
||||
|
||||
Single<Revision> firstRevisionOfFile(String filename);
|
||||
|
||||
interface ProgressListener {
|
||||
void onProgress(long transferred, long total);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Media getRecentRandomImage() throws IOException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
package fr.free.nrw.commons.mwapi;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.PageTitle;
|
||||
import fr.free.nrw.commons.achievements.FeaturedImages;
|
||||
|
|
@ -21,6 +22,7 @@ import fr.free.nrw.commons.campaigns.CampaignResponseDTO;
|
|||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.media.model.MwQueryPage;
|
||||
import fr.free.nrw.commons.mwapi.model.MwQueryResponse;
|
||||
import fr.free.nrw.commons.mwapi.model.RecentChange;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.nearby.model.NearbyResponse;
|
||||
import fr.free.nrw.commons.nearby.model.NearbyResultItem;
|
||||
|
|
@ -277,4 +279,76 @@ public class OkHttpJsonApiClient {
|
|||
return mediaList;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns recent changes on commons
|
||||
* @return list of recent changes made
|
||||
*/
|
||||
@Nullable
|
||||
public Single<List<RecentChange>> getRecentFileChanges() {
|
||||
final int RANDOM_SECONDS = 60 * 60 * 24 * 30;
|
||||
final String FILE_NAMESPACE = "6";
|
||||
Random r = new Random();
|
||||
Date now = new Date();
|
||||
Date startDate = new Date(now.getTime() - r.nextInt(RANDOM_SECONDS) * 1000L);
|
||||
|
||||
HttpUrl.Builder urlBuilder = HttpUrl
|
||||
.parse(commonsBaseUrl)
|
||||
.newBuilder()
|
||||
.addQueryParameter("action", "query")
|
||||
.addQueryParameter("format", "json")
|
||||
.addQueryParameter("list", "recentchanges")
|
||||
.addQueryParameter("rcstart", DateUtils.formatMWDate(startDate))
|
||||
.addQueryParameter("rcnamespace", FILE_NAMESPACE)
|
||||
.addQueryParameter("rcprop", "title|ids")
|
||||
.addQueryParameter("rctype", "new|log")
|
||||
.addQueryParameter("rctoponly", "1");
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(urlBuilder.build())
|
||||
.build();
|
||||
|
||||
return Single.fromCallable(() -> {
|
||||
Response response = okHttpClient.newCall(request).execute();
|
||||
if (response.body() != null && response.isSuccessful()) {
|
||||
String json = response.body().string();
|
||||
MwQueryResponse mwQueryPage = gson.fromJson(json, MwQueryResponse.class);
|
||||
return mwQueryPage.query().getRecentchanges();
|
||||
}
|
||||
return new ArrayList<>();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first revision of the file
|
||||
*
|
||||
* @return Revision object
|
||||
*/
|
||||
@Nullable
|
||||
public Single<MwQueryPage.Revision> getFirstRevisionOfFile(String filename) {
|
||||
HttpUrl.Builder urlBuilder = HttpUrl
|
||||
.parse(commonsBaseUrl)
|
||||
.newBuilder()
|
||||
.addQueryParameter("action", "query")
|
||||
.addQueryParameter("format", "json")
|
||||
.addQueryParameter("prop", "revisions")
|
||||
.addQueryParameter("rvprop", "timestamp|ids|user")
|
||||
.addQueryParameter("titles", filename)
|
||||
.addQueryParameter("rvdir", "newer")
|
||||
.addQueryParameter("rvlimit", "1");
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(urlBuilder.build())
|
||||
.build();
|
||||
|
||||
return Single.fromCallable(() -> {
|
||||
Response response = okHttpClient.newCall(request).execute();
|
||||
if (response.body() != null && response.isSuccessful()) {
|
||||
String json = response.body().string();
|
||||
MwQueryResponse mwQueryPage = gson.fromJson(json, MwQueryResponse.class);
|
||||
return mwQueryPage.query().firstPage().revisions().get(0);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
package fr.free.nrw.commons.mwapi;
|
||||
|
||||
import fr.free.nrw.commons.PageTitle;
|
||||
|
||||
public class Revision {
|
||||
public final String revisionId;
|
||||
public final String username;
|
||||
public final PageTitle pageTitle;
|
||||
|
||||
public Revision(String revisionId, String username, String pageTitle) {
|
||||
this.revisionId = revisionId;
|
||||
this.username = username;
|
||||
this.pageTitle = new PageTitle(pageTitle);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
package fr.free.nrw.commons.mwapi.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import fr.free.nrw.commons.media.model.ImageInfo;
|
||||
import fr.free.nrw.commons.media.model.MwQueryPage;
|
||||
|
||||
|
|
@ -15,6 +14,7 @@ public class MwQueryResult {
|
|||
@SuppressWarnings("unused")
|
||||
@Nullable
|
||||
private HashMap<String, MwQueryPage> pages;
|
||||
private List<RecentChange> recentchanges;
|
||||
|
||||
@NonNull
|
||||
public List<MwQueryPage> pages() {
|
||||
|
|
@ -24,6 +24,10 @@ public class MwQueryResult {
|
|||
return new ArrayList<>(pages.values());
|
||||
}
|
||||
|
||||
public List<RecentChange> getRecentchanges() {
|
||||
return recentchanges;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MwQueryPage firstPage() {
|
||||
return pages().get(0);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package fr.free.nrw.commons.mwapi.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class RecentChange {
|
||||
private final String type;
|
||||
private final String title;
|
||||
@SerializedName("old_revid")
|
||||
private final String oldRevisionId;
|
||||
|
||||
public RecentChange(String type, String title, String oldRevisionId) {
|
||||
this.type = type;
|
||||
this.title = title;
|
||||
this.oldRevisionId = oldRevisionId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getOldRevisionId() {
|
||||
return oldRevisionId;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue