mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Set Media legend for wikidata entity (#3838)
* Set media legends and P18 * Minor * Make media legends work * Add test cases * Use statement partial * With minor refactoring * Fix build
This commit is contained in:
parent
7caf73fb4b
commit
f26784e9c3
12 changed files with 195 additions and 199 deletions
|
|
@ -76,7 +76,7 @@ dependencies {
|
||||||
testImplementation "org.powermock:powermock-api-mockito2:2.0.0-beta.5"
|
testImplementation "org.powermock:powermock-api-mockito2:2.0.0-beta.5"
|
||||||
|
|
||||||
// Unit testing
|
// Unit testing
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.13'
|
||||||
testImplementation 'org.robolectric:robolectric:4.3'
|
testImplementation 'org.robolectric:robolectric:4.3'
|
||||||
testImplementation 'androidx.test:core:1.2.0'
|
testImplementation 'androidx.test:core:1.2.0'
|
||||||
testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.1'
|
testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.1'
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import fr.free.nrw.commons.Utils;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.media.MediaClient;
|
import fr.free.nrw.commons.media.MediaClient;
|
||||||
import fr.free.nrw.commons.utils.DialogUtil;
|
import fr.free.nrw.commons.utils.DialogUtil;
|
||||||
|
import fr.free.nrw.commons.wikidata.WikidataEditService;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
@ -41,7 +42,8 @@ import org.wikipedia.dataclient.WikiSite;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ContributionsListFragment extends CommonsDaggerSupportFragment implements
|
public class ContributionsListFragment extends CommonsDaggerSupportFragment implements
|
||||||
ContributionsListContract.View, ContributionsListAdapter.Callback, WikipediaInstructionsDialogFragment.Callback {
|
ContributionsListContract.View, ContributionsListAdapter.Callback,
|
||||||
|
WikipediaInstructionsDialogFragment.Callback {
|
||||||
|
|
||||||
private static final String RV_STATE = "rv_scroll_state";
|
private static final String RV_STATE = "rv_scroll_state";
|
||||||
|
|
||||||
|
|
@ -275,7 +277,6 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Media getMediaAtPosition(final int i) {
|
public Media getMediaAtPosition(final int i) {
|
||||||
return adapter.getContributionForPosition(i);
|
return adapter.getContributionForPosition(i);
|
||||||
}
|
}
|
||||||
|
|
@ -296,7 +297,8 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
Utils.copy("wikicode", wikicode, getContext());
|
Utils.copy("wikicode", wikicode, getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
final String url = languageWikipediaSite.mobileUrl() + "/wiki/" + contribution.getWikidataPlace()
|
final String url =
|
||||||
|
languageWikipediaSite.mobileUrl() + "/wiki/" + contribution.getWikidataPlace()
|
||||||
.getWikipediaPageTitle();
|
.getWikipediaPageTitle();
|
||||||
Utils.handleWebUrl(getContext(), Uri.parse(url));
|
Utils.handleWebUrl(getContext(), Uri.parse(url));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,24 +21,16 @@ import fr.free.nrw.commons.contributions.MainActivity;
|
||||||
import fr.free.nrw.commons.di.CommonsApplicationModule;
|
import fr.free.nrw.commons.di.CommonsApplicationModule;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerService;
|
import fr.free.nrw.commons.di.CommonsDaggerService;
|
||||||
import fr.free.nrw.commons.media.MediaClient;
|
import fr.free.nrw.commons.media.MediaClient;
|
||||||
import fr.free.nrw.commons.utils.CommonsDateUtil;
|
|
||||||
import fr.free.nrw.commons.wikidata.WikidataEditService;
|
import fr.free.nrw.commons.wikidata.WikidataEditService;
|
||||||
import io.reactivex.Completable;
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Scheduler;
|
import io.reactivex.Scheduler;
|
||||||
import io.reactivex.Single;
|
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
import io.reactivex.functions.Action;
|
|
||||||
import io.reactivex.functions.Consumer;
|
|
||||||
import io.reactivex.processors.PublishProcessor;
|
import io.reactivex.processors.PublishProcessor;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
@ -313,7 +305,7 @@ public class UploadService extends CommonsDaggerService {
|
||||||
.add(wikidataEditService.addDepictionsAndCaptions(uploadResult, contribution));
|
.add(wikidataEditService.addDepictionsAndCaptions(uploadResult, contribution));
|
||||||
WikidataPlace wikidataPlace = contribution.getWikidataPlace();
|
WikidataPlace wikidataPlace = contribution.getWikidataPlace();
|
||||||
if (wikidataPlace != null && wikidataPlace.getImageValue() == null) {
|
if (wikidataPlace != null && wikidataPlace.getImageValue() == null) {
|
||||||
wikidataEditService.createImageClaim(wikidataPlace, uploadResult);
|
wikidataEditService.createClaim(wikidataPlace, uploadResult.getFilename(), contribution.getCaptions());
|
||||||
}
|
}
|
||||||
saveCompletedContribution(contribution, uploadResult);
|
saveCompletedContribution(contribution, uploadResult);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package fr.free.nrw.commons.wikidata;
|
package fr.free.nrw.commons.wikidata;
|
||||||
|
|
||||||
import fr.free.nrw.commons.upload.WikidataItem;
|
import com.google.gson.Gson;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
@ -9,64 +9,38 @@ import javax.inject.Singleton;
|
||||||
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse;
|
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.ObservableSource;
|
import io.reactivex.ObservableSource;
|
||||||
import okhttp3.MediaType;
|
import org.wikipedia.wikidata.Statement_partial;
|
||||||
import okhttp3.RequestBody;
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class WikidataClient {
|
public class WikidataClient {
|
||||||
|
|
||||||
|
|
||||||
private final WikidataInterface wikidataInterface;
|
private final WikidataInterface wikidataInterface;
|
||||||
|
private final Gson gson;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public WikidataClient(WikidataInterface wikidataInterface) {
|
public WikidataClient(WikidataInterface wikidataInterface, final Gson gson) {
|
||||||
this.wikidataInterface = wikidataInterface;
|
this.wikidataInterface = wikidataInterface;
|
||||||
|
this.gson = gson;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create wikidata claim to add P18 value
|
* Create wikidata claim to add P18 value
|
||||||
* @param entity wikidata entity ID
|
*
|
||||||
* @param value value of the P18 edit
|
|
||||||
* @return revisionID of the edit
|
* @return revisionID of the edit
|
||||||
*/
|
*/
|
||||||
Observable<Long> createImageClaim(WikidataItem entity, String value) {
|
Observable<Long> setClaim(Statement_partial claim, String tags) {
|
||||||
return getCsrfToken()
|
return getCsrfToken()
|
||||||
.flatMap(csrfToken -> wikidataInterface.postCreateClaim(
|
.flatMap(csrfToken -> wikidataInterface.postSetClaim(gson.toJson(claim), tags, csrfToken))
|
||||||
toRequestBody(entity.getId()),
|
|
||||||
toRequestBody("value"),
|
|
||||||
toRequestBody(WikidataProperties.IMAGE.getPropertyName()),
|
|
||||||
toRequestBody(value),
|
|
||||||
toRequestBody("en"),
|
|
||||||
toRequestBody(csrfToken)))
|
|
||||||
.map(mwPostResponse -> mwPostResponse.getPageinfo().getLastrevid());
|
.map(mwPostResponse -> mwPostResponse.getPageinfo().getLastrevid());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts string value to RequestBody for multipart request
|
|
||||||
*/
|
|
||||||
private RequestBody toRequestBody(String value) {
|
|
||||||
return RequestBody.create(MediaType.parse("text/plain"), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get csrf token for wikidata edit
|
* Get csrf token for wikidata edit
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
private Observable<String> getCsrfToken() {
|
private Observable<String> getCsrfToken() {
|
||||||
return wikidataInterface.getCsrfToken().map(mwQueryResponse -> mwQueryResponse.query().csrfToken());
|
return wikidataInterface.getCsrfToken()
|
||||||
}
|
.map(mwQueryResponse -> mwQueryResponse.query().csrfToken());
|
||||||
|
|
||||||
/**
|
|
||||||
* Add edit tag for a given revision ID. The app currently uses this to tag P18 edits
|
|
||||||
* @param revisionId revision ID of the page edited
|
|
||||||
* @param tag to be added
|
|
||||||
* @param reason to be mentioned
|
|
||||||
*/
|
|
||||||
ObservableSource<AddEditTagResponse> addEditTag(Long revisionId, String tag, String reason) {
|
|
||||||
return getCsrfToken()
|
|
||||||
.flatMap(csrfToken -> wikidataInterface.addEditTag(String.valueOf(revisionId),
|
|
||||||
tag,
|
|
||||||
reason,
|
|
||||||
csrfToken));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,24 +20,33 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.Disposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import org.wikipedia.dataclient.mwapi.MwPostResponse;
|
import org.wikipedia.dataclient.mwapi.MwPostResponse;
|
||||||
|
import org.wikipedia.wikidata.DataValue;
|
||||||
|
import org.wikipedia.wikidata.DataValue.ValueString;
|
||||||
import org.wikipedia.wikidata.EditClaim;
|
import org.wikipedia.wikidata.EditClaim;
|
||||||
|
import org.wikipedia.wikidata.Snak_partial;
|
||||||
|
import org.wikipedia.wikidata.Statement_partial;
|
||||||
|
import org.wikipedia.wikidata.WikiBaseMonolingualTextValue;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is meant to handle the Wikidata edits made through the app
|
* This class is meant to handle the Wikidata edits made through the app It will talk with MediaWiki
|
||||||
* It will talk with MediaWiki Apis to make the necessary calls, log the edits and fire listeners
|
* Apis to make the necessary calls, log the edits and fire listeners on successful edits
|
||||||
* on successful edits
|
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class WikidataEditService {
|
public class WikidataEditService {
|
||||||
|
|
||||||
private static final String COMMONS_APP_TAG = "wikimedia-commons-app";
|
public static final String COMMONS_APP_TAG = "wikimedia-commons-app";
|
||||||
private static final String COMMONS_APP_EDIT_REASON = "Add tag for edits made using Android Commons app";
|
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final WikidataEditListener wikidataEditListener;
|
private final WikidataEditListener wikidataEditListener;
|
||||||
|
|
@ -61,8 +70,8 @@ public class WikidataEditService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits the wikibase entity by adding DEPICTS property.
|
* Edits the wikibase entity by adding DEPICTS property. Adding DEPICTS property requires call to
|
||||||
* Adding DEPICTS property requires call to the wikibase API to set tag against the entity.
|
* the wikibase API to set tag against the entity.
|
||||||
*/
|
*/
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
private Observable<Boolean> addDepictsProperty(final String fileEntityId,
|
private Observable<Boolean> addDepictsProperty(final String fileEntityId,
|
||||||
|
|
@ -97,12 +106,14 @@ public class WikidataEditService {
|
||||||
*/
|
*/
|
||||||
private void showSuccessToast(final String wikiItemName) {
|
private void showSuccessToast(final String wikiItemName) {
|
||||||
final String successStringTemplate = context.getString(R.string.successful_wikidata_edit);
|
final String successStringTemplate = context.getString(R.string.successful_wikidata_edit);
|
||||||
final String successMessage = String.format(Locale.getDefault(), successStringTemplate, wikiItemName);
|
final String successMessage = String
|
||||||
|
.format(Locale.getDefault(), successStringTemplate, wikiItemName);
|
||||||
ViewUtil.showLongToast(context, successMessage);
|
ViewUtil.showLongToast(context, successMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds label to Wikidata using the fileEntityId and the edit token, obtained from csrfTokenClient
|
* Adds label to Wikidata using the fileEntityId and the edit token, obtained from
|
||||||
|
* csrfTokenClient
|
||||||
*
|
*
|
||||||
* @param fileEntityId
|
* @param fileEntityId
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -128,29 +139,41 @@ public class WikidataEditService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createImageClaim(@Nullable final WikidataPlace wikidataPlace, final UploadResult imageUpload) {
|
public void createClaim(@Nullable final WikidataPlace wikidataPlace, final String fileName, final
|
||||||
|
Map<String, String> captions) {
|
||||||
if (!(directKvStore.getBoolean("Picture_Has_Correct_Location", true))) {
|
if (!(directKvStore.getBoolean("Picture_Has_Correct_Location", true))) {
|
||||||
Timber.d("Image location and nearby place location mismatched, so Wikidata item won't be edited");
|
Timber
|
||||||
|
.d("Image location and nearby place location mismatched, so Wikidata item won't be edited");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
editWikidataImageProperty(wikidataPlace, imageUpload);
|
addImageAndMediaLegends(wikidataPlace, fileName, captions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
public void addImageAndMediaLegends(final WikidataItem wikidataItem, final String fileName,
|
||||||
private void editWikidataImageProperty(final WikidataItem wikidataItem, final UploadResult imageUpload) {
|
final Map<String, String> captions) {
|
||||||
wikidataClient.createImageClaim(wikidataItem, String.format("\"%s\"", imageUpload.getFilename()))
|
final Snak_partial p18 = new Snak_partial("value", WikidataProperties.IMAGE.getPropertyName(),
|
||||||
.flatMap(revisionId -> {
|
new ValueString(fileName.replace("File:", "")));
|
||||||
if (revisionId != -1) {
|
|
||||||
return wikidataClient.addEditTag(revisionId, COMMONS_APP_TAG, COMMONS_APP_EDIT_REASON);
|
final List<Snak_partial> snaks = new ArrayList<>();
|
||||||
|
for (final Map.Entry<String, String> entry : captions.entrySet()) {
|
||||||
|
snaks.add(new Snak_partial("value",
|
||||||
|
WikidataProperties.MEDIA_LEGENDS.getPropertyName(), new DataValue.MonoLingualText(
|
||||||
|
new WikiBaseMonolingualTextValue(entry.getValue(), entry.getKey()))));
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Unable to edit wikidata item");
|
|
||||||
})
|
final String id = wikidataItem.getId() + "$" + UUID.randomUUID().toString();
|
||||||
.subscribeOn(Schedulers.io())
|
final Statement_partial claim = new Statement_partial(p18, "statement", "normal", id,
|
||||||
|
Collections.singletonMap(WikidataProperties.MEDIA_LEGENDS.getPropertyName(), snaks),
|
||||||
|
Arrays.asList(WikidataProperties.MEDIA_LEGENDS.getPropertyName()));
|
||||||
|
|
||||||
|
wikidataClient.setClaim(claim, COMMONS_APP_TAG).subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(revisionId -> handleImageClaimResult(wikidataItem, String.valueOf(revisionId)), throwable -> {
|
.subscribe(revisionId -> handleImageClaimResult(wikidataItem, String.valueOf(revisionId)),
|
||||||
|
throwable -> {
|
||||||
Timber.e(throwable, "Error occurred while making claim");
|
Timber.e(throwable, "Error occurred while making claim");
|
||||||
ViewUtil.showLongToast(context, context.getString(R.string.wikidata_edit_failure));
|
ViewUtil.showLongToast(context, context.getString(R.string.wikidata_edit_failure));
|
||||||
});
|
});
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleImageClaimResult(final WikidataItem wikidataItem, final String revisionId) {
|
private void handleImageClaimResult(final WikidataItem wikidataItem, final String revisionId) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.wikidata;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
|
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
|
||||||
|
|
||||||
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse;
|
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse;
|
||||||
|
|
@ -20,30 +21,6 @@ import static org.wikipedia.dataclient.Service.MW_API_PREFIX;
|
||||||
|
|
||||||
public interface WikidataInterface {
|
public interface WikidataInterface {
|
||||||
|
|
||||||
/**
|
|
||||||
* Wikidata create claim API. Posts a new claim for the given entity ID
|
|
||||||
*/
|
|
||||||
@Headers("Cache-Control: no-cache")
|
|
||||||
@POST("w/api.php?format=json&errorformat=plaintext&action=wbcreateclaim&errorlang=uselang")
|
|
||||||
@Multipart
|
|
||||||
Observable<WbCreateClaimResponse> postCreateClaim(@NonNull @Part("entity") RequestBody entity,
|
|
||||||
@NonNull @Part("snaktype") RequestBody snakType,
|
|
||||||
@NonNull @Part("property") RequestBody property,
|
|
||||||
@NonNull @Part("value") RequestBody value,
|
|
||||||
@NonNull @Part("uselang") RequestBody useLang,
|
|
||||||
@NonNull @Part("token") RequestBody token);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add edit tag and reason for any revision
|
|
||||||
*/
|
|
||||||
@Headers("Cache-Control: no-cache")
|
|
||||||
@POST(MW_API_PREFIX + "action=tag")
|
|
||||||
@FormUrlEncoded
|
|
||||||
Observable<AddEditTagResponse> addEditTag(@NonNull @Field("revid") String revId,
|
|
||||||
@NonNull @Field("add") String tagName,
|
|
||||||
@NonNull @Field("reason") String reason,
|
|
||||||
@NonNull @Field("token") String token);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get edit token for wikidata wiki site
|
* Get edit token for wikidata wiki site
|
||||||
*/
|
*/
|
||||||
|
|
@ -51,4 +28,14 @@ public interface WikidataInterface {
|
||||||
@GET(MW_API_PREFIX + "action=query&meta=tokens&type=csrf")
|
@GET(MW_API_PREFIX + "action=query&meta=tokens&type=csrf")
|
||||||
@NonNull
|
@NonNull
|
||||||
Observable<MwQueryResponse> getCsrfToken();
|
Observable<MwQueryResponse> getCsrfToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wikidata create claim API. Posts a new claim for the given entity ID
|
||||||
|
*/
|
||||||
|
@Headers("Cache-Control: no-cache")
|
||||||
|
@POST("w/api.php?format=json&action=wbsetclaim")
|
||||||
|
@FormUrlEncoded
|
||||||
|
Observable<WbCreateClaimResponse> postSetClaim(@NonNull @Field("claim") String request,
|
||||||
|
@NonNull @Field("tags") String tags,
|
||||||
|
@NonNull @Field("token") String token);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,6 @@ enum class WikidataProperties(val propertyName: String) {
|
||||||
IMAGE("P18"),
|
IMAGE("P18"),
|
||||||
DEPICTS(BuildConfig.DEPICTS_PROPERTY),
|
DEPICTS(BuildConfig.DEPICTS_PROPERTY),
|
||||||
COMMONS_CATEGORY("P373"),
|
COMMONS_CATEGORY("P373"),
|
||||||
INSTANCE_OF("P31");
|
INSTANCE_OF("P31"),
|
||||||
|
MEDIA_LEGENDS("P2096");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package fr.free.nrw.commons.wikidata
|
package fr.free.nrw.commons.wikidata
|
||||||
|
|
||||||
import com.nhaarman.mockitokotlin2.mock
|
import com.google.gson.Gson
|
||||||
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
|
import fr.free.nrw.commons.wikidata.model.PageInfo
|
||||||
|
import fr.free.nrw.commons.wikidata.model.WbCreateClaimResponse
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -14,12 +16,16 @@ import org.mockito.Mockito.mock
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
import org.wikipedia.dataclient.mwapi.MwQueryResponse
|
import org.wikipedia.dataclient.mwapi.MwQueryResponse
|
||||||
import org.wikipedia.dataclient.mwapi.MwQueryResult
|
import org.wikipedia.dataclient.mwapi.MwQueryResult
|
||||||
|
import org.wikipedia.wikidata.Statement_partial
|
||||||
|
|
||||||
class WikidataClientTest {
|
class WikidataClientTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
internal var wikidataInterface: WikidataInterface? = null
|
internal var wikidataInterface: WikidataInterface? = null
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
internal var gson: Gson? = null
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
var wikidataClient: WikidataClient? = null
|
var wikidataClient: WikidataClient? = null
|
||||||
|
|
||||||
|
|
@ -35,26 +41,18 @@ class WikidataClientTest {
|
||||||
.thenReturn(Observable.just(mwQueryResponse))
|
.thenReturn(Observable.just(mwQueryResponse))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun createClaim() {
|
|
||||||
`when`(
|
|
||||||
wikidataInterface!!.postCreateClaim(
|
|
||||||
any(),
|
|
||||||
any(),
|
|
||||||
any(),
|
|
||||||
any(),
|
|
||||||
any(),
|
|
||||||
any()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.thenReturn(Observable.just(mock()))
|
|
||||||
wikidataClient!!.createImageClaim(mock(), "test.jpg")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun addEditTag() {
|
fun addEditTag() {
|
||||||
`when`(wikidataInterface!!.addEditTag(anyString(), anyString(), anyString(), anyString()))
|
val response = mock(WbCreateClaimResponse::class.java)
|
||||||
.thenReturn(Observable.just(mock(AddEditTagResponse::class.java)))
|
val pageInfo = mock(PageInfo::class.java)
|
||||||
wikidataClient!!.addEditTag(1L, "test", "test")
|
whenever(pageInfo.lastrevid).thenReturn(1)
|
||||||
|
whenever(response.pageinfo).thenReturn(pageInfo)
|
||||||
|
`when`(wikidataInterface!!.postSetClaim(anyString(), anyString(), anyString()))
|
||||||
|
.thenReturn(Observable.just(response))
|
||||||
|
whenever(gson!!.toJson(any(Statement_partial::class.java))).thenReturn("claim")
|
||||||
|
val request = mock(Statement_partial::class.java)
|
||||||
|
|
||||||
|
val claim = wikidataClient!!.setClaim(request, "test").test()
|
||||||
|
.assertValue(1L)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
package fr.free.nrw.commons.wikidata
|
package fr.free.nrw.commons.wikidata
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.nhaarman.mockitokotlin2.mock
|
import com.nhaarman.mockitokotlin2.mock
|
||||||
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
|
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
|
||||||
import com.nhaarman.mockitokotlin2.whenever
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore
|
import fr.free.nrw.commons.kvstore.JsonKvStore
|
||||||
import fr.free.nrw.commons.upload.UploadResult
|
import fr.free.nrw.commons.upload.UploadResult
|
||||||
import fr.free.nrw.commons.upload.WikidataPlace
|
import fr.free.nrw.commons.upload.WikidataPlace
|
||||||
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -15,7 +15,6 @@ import org.mockito.ArgumentMatchers.any
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
import org.mockito.ArgumentMatchers.anyString
|
||||||
import org.mockito.InjectMocks
|
import org.mockito.InjectMocks
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.*
|
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
class WikidataEditServiceTest {
|
class WikidataEditServiceTest {
|
||||||
|
|
@ -31,6 +30,9 @@ class WikidataEditServiceTest {
|
||||||
@Mock
|
@Mock
|
||||||
internal lateinit var wikibaseClient: WikiBaseClient
|
internal lateinit var wikibaseClient: WikiBaseClient
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
internal lateinit var gson: Gson
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
lateinit var wikidataEditService: WikidataEditService
|
lateinit var wikidataEditService: WikidataEditService
|
||||||
|
|
||||||
|
|
@ -44,7 +46,7 @@ class WikidataEditServiceTest {
|
||||||
fun noClaimsWhenLocationIsNotCorrect() {
|
fun noClaimsWhenLocationIsNotCorrect() {
|
||||||
whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
|
whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
|
||||||
.thenReturn(false)
|
.thenReturn(false)
|
||||||
wikidataEditService.createImageClaim(mock(), mock())
|
wikidataEditService.createClaim(mock(), "Test.jpg", hashMapOf())
|
||||||
verifyZeroInteractions(wikidataClient)
|
verifyZeroInteractions(wikidataClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,15 +54,16 @@ class WikidataEditServiceTest {
|
||||||
fun createImageClaim() {
|
fun createImageClaim() {
|
||||||
whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
|
whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
|
||||||
.thenReturn(true)
|
.thenReturn(true)
|
||||||
whenever(wikidataClient.createImageClaim(any(), any()))
|
|
||||||
.thenReturn(Observable.just(1L))
|
|
||||||
whenever(wikidataClient.addEditTag(anyLong(), anyString(), anyString()))
|
|
||||||
.thenReturn(Observable.just(mock(AddEditTagResponse::class.java)))
|
|
||||||
whenever(wikibaseClient.getFileEntityId(any())).thenReturn(Observable.just(1L))
|
whenever(wikibaseClient.getFileEntityId(any())).thenReturn(Observable.just(1L))
|
||||||
|
whenever(wikidataClient.setClaim(any(), anyString()))
|
||||||
|
.thenReturn(Observable.just(1L))
|
||||||
val wikidataPlace: WikidataPlace = mock()
|
val wikidataPlace: WikidataPlace = mock()
|
||||||
val uploadResult = mock<UploadResult>()
|
val uploadResult = mock<UploadResult>()
|
||||||
whenever(uploadResult.filename).thenReturn("file")
|
whenever(uploadResult.filename).thenReturn("file")
|
||||||
wikidataEditService.createImageClaim(wikidataPlace, uploadResult)
|
wikidataEditService.createClaim(
|
||||||
verify(wikidataClient, times(1)).createImageClaim(wikidataPlace, """"file"""")
|
wikidataPlace,
|
||||||
|
uploadResult.filename,
|
||||||
|
hashMapOf<String, String>()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ sealed class DataValue(val type: String) {
|
||||||
.registerSubtype(GlobeCoordinate_partial::class.java, GlobeCoordinate_partial.TYPE)
|
.registerSubtype(GlobeCoordinate_partial::class.java, GlobeCoordinate_partial.TYPE)
|
||||||
.registerSubtype(Time_partial::class.java, Time_partial.TYPE)
|
.registerSubtype(Time_partial::class.java, Time_partial.TYPE)
|
||||||
.registerSubtype(Quantity_partial::class.java, Quantity_partial.TYPE)
|
.registerSubtype(Quantity_partial::class.java, Quantity_partial.TYPE)
|
||||||
.registerSubtype(MonoLingualText_partial::class.java, MonoLingualText_partial.TYPE)
|
.registerSubtype(MonoLingualText::class.java, MonoLingualText.TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// "value": {
|
// "value": {
|
||||||
|
|
@ -87,7 +87,7 @@ sealed class DataValue(val type: String) {
|
||||||
// "language": "ko"
|
// "language": "ko"
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
class MonoLingualText_partial() : DataValue(TYPE) {
|
class MonoLingualText(val value: WikiBaseMonolingualTextValue) : DataValue(TYPE) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TYPE = "monolingualtext"
|
const val TYPE = "monolingualtext"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,8 @@ import com.google.gson.annotations.SerializedName
|
||||||
data class Statement_partial(
|
data class Statement_partial(
|
||||||
@SerializedName("mainsnak") val mainSnak: Snak_partial,
|
@SerializedName("mainsnak") val mainSnak: Snak_partial,
|
||||||
val type: String,
|
val type: String,
|
||||||
val rank: String
|
val rank: String,
|
||||||
|
val id: String? = null,
|
||||||
|
val qualifiers: Map<String, List<Snak_partial>> = mapOf(),
|
||||||
|
@SerializedName("qualifiers-order") val qualifiersOrder: List<String> = listOf()
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.wikipedia.wikidata
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
/*"value": {
|
||||||
|
"type": "monolingualtext",
|
||||||
|
"value": {
|
||||||
|
"text": "some value",
|
||||||
|
"language": "en"
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
data class WikiBaseMonolingualTextValue(val text: String, val language: String)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue