Skip to content

Commit

Permalink
With media client APIs migrated to retrofit (commons-app#2998)
Browse files Browse the repository at this point in the history
* With media client APIs migrated to retrofit

* Add test cases and java docs

* Fix test

* Fix build

* Fix build and other minor issues

* Fix tests
  • Loading branch information
maskaravivek committed Jul 10, 2019
1 parent 828b5a3 commit 78141cb
Show file tree
Hide file tree
Showing 17 changed files with 252 additions and 92 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ dependencies {
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation 'com.drewnoakes:metadata-extractor:2.11.0'
implementation 'com.dmitrybrant:wikimedia-android-data-client:0.0.18'
implementation 'org.apache.commons:commons-lang3:3.8.1'
implementation 'com.dmitrybrant:wikimedia-android-data-client:0.0.23'

// UI
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
Expand Down
21 changes: 11 additions & 10 deletions app/src/main/java/fr/free/nrw/commons/Media.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.apache.commons.lang3.StringUtils;
import org.wikipedia.dataclient.mwapi.MwQueryPage;
import org.wikipedia.gallery.ExtMetadata;
Expand All @@ -20,8 +23,6 @@
import java.util.Locale;
import java.util.Map;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.utils.CommonsDateUtil;
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
Expand Down Expand Up @@ -156,9 +157,9 @@ public static Media from(MwQueryPage page) {
page.title(),
"",
0,
safeParseDate(metadata.dateTimeOriginal().value()),
safeParseDate(metadata.dateTime().value()),
StringUtil.fromHtml(metadata.artist().value()).toString()
safeParseDate(metadata.dateTime()),
safeParseDate(metadata.dateTime()),
StringUtil.fromHtml(metadata.artist()).toString()
);

if (!StringUtils.isBlank(imageInfo.getThumbUrl())) {
Expand All @@ -170,17 +171,17 @@ public static Media from(MwQueryPage page) {
language = "default";
}

media.setDescriptions(Collections.singletonMap(language, metadata.imageDescription().value()));
media.setCategories(MediaDataExtractorUtil.extractCategoriesFromList(metadata.categories().value()));
String latitude = metadata.gpsLatitude().value();
String longitude = metadata.gpsLongitude().value();
media.setDescriptions(Collections.singletonMap(language, metadata.imageDescription()));
media.setCategories(MediaDataExtractorUtil.extractCategoriesFromList(metadata.getCategories()));
String latitude = metadata.getGpsLatitude();
String longitude = metadata.getGpsLongitude();

if (!StringUtils.isBlank(latitude) && !StringUtils.isBlank(longitude)) {
LatLng latLng = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude), 0);
media.setCoordinates(latLng);
}

media.setLicenseInformation(metadata.licenseShortName().value(), metadata.licenseUrl().value());
media.setLicenseInformation(metadata.licenseShortName(), metadata.licenseUrl());
return media;
}

Expand Down
11 changes: 8 additions & 3 deletions app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package fr.free.nrw.commons;

import androidx.core.text.HtmlCompat;

import javax.inject.Inject;
import javax.inject.Singleton;

import androidx.core.text.HtmlCompat;
import fr.free.nrw.commons.media.MediaClient;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import io.reactivex.Single;
Expand All @@ -19,12 +21,15 @@
public class MediaDataExtractor {
private final MediaWikiApi mediaWikiApi;
private final OkHttpJsonApiClient okHttpJsonApiClient;
private final MediaClient mediaClient;

@Inject
public MediaDataExtractor(MediaWikiApi mwApi,
OkHttpJsonApiClient okHttpJsonApiClient) {
OkHttpJsonApiClient okHttpJsonApiClient,
MediaClient mediaClient) {
this.okHttpJsonApiClient = okHttpJsonApiClient;
this.mediaWikiApi = mwApi;
this.mediaClient = mediaClient;
}

/**
Expand All @@ -35,7 +40,7 @@ public MediaDataExtractor(MediaWikiApi mwApi,
*/
public Single<Media> fetchMediaDetails(String filename) {
Single<Media> mediaSingle = getMediaFromFileName(filename);
Single<Boolean> pageExistsSingle = mediaWikiApi.pageExists("Commons:Deletion_requests/" + filename);
Single<Boolean> pageExistsSingle = mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/" + filename);
Single<String> discussionSingle = getDiscussion(filename);
return Single.zip(mediaSingle, pageExistsSingle, discussionSingle, (media, deletionStatus, discussion) -> {
media.setDiscussion(discussion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private static OkHttpClient createClient() {
return new OkHttpClient.Builder()
.cookieJar(SharedPreferenceCookieManager.getInstance())
.cache(NET_CACHE)
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.addInterceptor(new UnsuccessfulResponseInterceptor())
.addInterceptor(new CommonHeaderRequestInterceptor())
.build();
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import dagger.Provides;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.media.MediaInterface;
import fr.free.nrw.commons.mwapi.ApacheHttpClientMediaWikiApi;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
Expand All @@ -39,6 +40,8 @@ public class NetworkingModule {

public static final long OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024;

private static final String NAMED_COMMONS_WIKI_SITE = "commons-wikisite";

@Provides
@Singleton
public OkHttpClient provideOkHttpClient(Context context,
Expand Down Expand Up @@ -120,7 +123,13 @@ public WikiSite provideCommonsWikiSite() {

@Provides
@Singleton
public ReviewInterface provideReviewInterface(@Named("commons-wikisite") WikiSite commonsWikiSite) {
public ReviewInterface provideReviewInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, ReviewInterface.class);
}

@Provides
@Singleton
public MediaInterface provideMediaInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, MediaInterface.class);
}
}
46 changes: 46 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/media/MediaClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package fr.free.nrw.commons.media;


import javax.inject.Inject;
import javax.inject.Singleton;

import io.reactivex.Single;

/**
* Media Client to handle custom calls to Commons MediaWiki APIs
*/
@Singleton
public class MediaClient {

private final MediaInterface mediaInterface;

@Inject
public MediaClient(MediaInterface mediaInterface) {
this.mediaInterface = mediaInterface;
}

/**
* Checks if a page exists on Commons
* The same method can be used to check for file or talk page
*
* @param title File:Test.jpg or Commons:Deletion_requests/File:Test1.jpeg
*/
public Single<Boolean> checkPageExistsUsingTitle(String title) {
return mediaInterface.checkPageExistsUsingTitle(title)
.map(mwQueryResponse -> mwQueryResponse
.query().firstPage().pageId() > 0)
.singleOrError();
}

/**
* Take the fileSha and returns whether a file with a matching SHA exists or not
*
* @param fileSha SHA of the file to be checked
*/
public Single<Boolean> checkFileExistsUsingSha(String fileSha) {
return mediaInterface.checkFileExistsUsingSha(fileSha)
.map(mwQueryResponse -> mwQueryResponse
.query().allImages().size() > 0)
.singleOrError();
}
}
28 changes: 28 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/media/MediaInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package fr.free.nrw.commons.media;

import org.wikipedia.dataclient.mwapi.MwQueryResponse;

import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;

/**
* Interface for interacting with Commons media related APIs
*/
public interface MediaInterface {
/**
* Checks if a page exists or not.
* @param title the title of the page to be checked
* @return
*/
@GET("w/api.php?action=query&format=json&formatversion=2")
Observable<MwQueryResponse> checkPageExistsUsingTitle(@Query("titles") String title);

/**
* Check if file exists
* @param aisha1 the SHA of the media file to be checked
* @return
*/
@GET("w/api.php?action=query&format=json&formatversion=2&list=allimages")
Observable<MwQueryResponse> checkFileExistsUsingSha(@Query("aisha1") String aisha1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import android.net.Uri;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.gson.Gson;

import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -32,8 +35,6 @@
import java.util.Locale;
import java.util.concurrent.Callable;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R;
Expand Down Expand Up @@ -224,23 +225,6 @@ public String getCentralAuthToken() throws IOException {
return centralAuthToken;
}

@Override
public boolean fileExistsWithName(String fileName) throws IOException {
return api.action("query")
.param("prop", "imageinfo")
.param("titles", "File:" + fileName)
.get()
.getNodes("/api/query/pages/page/imageinfo").size() > 0;
}

@Override
public Single<Boolean> pageExists(String pageName) {
return Single.fromCallable(() -> Double.parseDouble(api.action("query")
.param("titles", pageName)
.get()
.getString("/api/query/pages/page/@_idx")) != -1);
}

@Override
public boolean thank(String editToken, long revision) throws IOException {
CustomApiResult res = api.action("thank")
Expand Down Expand Up @@ -749,16 +733,6 @@ private QueryContinue getQueryContinueValues(String keyword) {
return gson.fromJson(queryContinueString, QueryContinue.class);
}

@Override
public boolean existingFile(String fileSha1) throws IOException {
return api.action("query")
.param("format", "xml")
.param("list", "allimages")
.param("aisha1", fileSha1)
.get()
.getNodes("/api/query/allimages/img").size() > 0;
}

@Override
@NonNull
public Single<UploadStash> uploadFile(
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ public interface MediaWikiApi {

String getCentralAuthToken() throws IOException;

boolean fileExistsWithName(String fileName) throws IOException;

Single<Boolean> pageExists(String pageName);

List<String> getSubCategoryList(String categoryName);

List<String> getParentCategoryList(String categoryName);
Expand Down Expand Up @@ -87,8 +83,6 @@ Single<UploadResult> uploadFileFinalize(String filename, String filekey,
@Nullable
String revisionsByFilename(String filename) throws IOException;

boolean existingFile(String fileSha1) throws IOException;

@NonNull
LogEventResult logEvents(String user, String lastModified, String queryContinue, int limit) throws IOException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import javax.inject.Singleton;

import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.media.MediaClient;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import io.reactivex.Observable;
Expand All @@ -26,14 +27,16 @@ public class ReviewHelper {

private final OkHttpJsonApiClient okHttpJsonApiClient;
private final MediaWikiApi mediaWikiApi;
private final MediaClient mediaClient;
private final ReviewInterface reviewInterface;

@Inject
public ReviewHelper(OkHttpJsonApiClient okHttpJsonApiClient,
MediaWikiApi mediaWikiApi,
ReviewInterface reviewInterface) {
MediaClient mediaClient, ReviewInterface reviewInterface) {
this.okHttpJsonApiClient = okHttpJsonApiClient;
this.mediaWikiApi = mediaWikiApi;
this.mediaClient = mediaClient;
this.reviewInterface = reviewInterface;
}

Expand Down Expand Up @@ -86,7 +89,7 @@ public Single<Media> getRandomMedia() {
*/
private Single<Media> getRandomMediaFromRecentChange(RecentChange recentChange) {
return Single.just(recentChange)
.flatMap(change -> mediaWikiApi.pageExists("Commons:Deletion_requests/" + change.getTitle()))
.flatMap(change -> mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/" + change.getTitle()))
.flatMap(isDeleted -> {
if (isDeleted) {
return Single.just(new Media(""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import javax.inject.Inject;
import javax.inject.Singleton;

import fr.free.nrw.commons.media.MediaClient;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.utils.ImageUtils;
Expand All @@ -34,18 +35,20 @@ public class ImageProcessingService {
private final MediaWikiApi mwApi;
private final ReadFBMD readFBMD;
private final EXIFReader EXIFReader;
private final MediaClient mediaClient;
private final Context context;

@Inject
public ImageProcessingService(FileUtilsWrapper fileUtilsWrapper,
ImageUtilsWrapper imageUtilsWrapper,
MediaWikiApi mwApi, ReadFBMD readFBMD, EXIFReader EXIFReader,
Context context) {
MediaClient mediaClient, Context context) {
this.fileUtilsWrapper = fileUtilsWrapper;
this.imageUtilsWrapper = imageUtilsWrapper;
this.mwApi = mwApi;
this.readFBMD = readFBMD;
this.EXIFReader = EXIFReader;
this.mediaClient = mediaClient;
this.context = context;
}

Expand Down Expand Up @@ -128,7 +131,7 @@ private Single<Integer> validateItemTitle(UploadModel.UploadItem uploadItem) {
return Single.just(EMPTY_TITLE);
}

return Single.fromCallable(() -> mwApi.fileExistsWithName(uploadItem.getFileName()))
return mediaClient.checkPageExistsUsingTitle("File:" + uploadItem.getFileName())
.map(doesFileExist -> {
Timber.d("Result for valid title is %s", doesFileExist);
return doesFileExist ? FILE_NAME_EXISTS : IMAGE_OK;
Expand All @@ -146,7 +149,7 @@ private Single<Integer> checkDuplicateImage(String filePath) {
return Single.fromCallable(() ->
fileUtilsWrapper.getFileInputStream(filePath))
.map(fileUtilsWrapper::getSHA1)
.map(mwApi::existingFile)
.flatMap(mediaClient::checkFileExistsUsingSha)
.map(b -> {
Timber.d("Result for duplicate image %s", b);
return b ? ImageUtils.IMAGE_DUPLICATE : ImageUtils.IMAGE_OK;
Expand Down
Loading

0 comments on commit 78141cb

Please sign in to comment.