mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 21:03:54 +01:00
Convert wikidata/mwapi to kotlin (part 4) (#6010)
* Convert ImageDetails to kotlin * Convert MwException/MwServiceError to kotlin * Convert ListUserResponse to kotlin * Convert MwPostResponse to kotlin * Convert MwQueryResponse to kotlin * Convert MwQueryResult to kotlin * Convert MwQueryPage to kotlin --------- Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com>
This commit is contained in:
parent
56ada36b83
commit
73311970c5
28 changed files with 474 additions and 615 deletions
|
|
@ -237,7 +237,7 @@ class LoginClient(
|
||||||
.subscribe({ response: MwQueryResponse? ->
|
.subscribe({ response: MwQueryResponse? ->
|
||||||
loginResult.userId = response?.query()?.userInfo()?.id() ?: 0
|
loginResult.userId = response?.query()?.userInfo()?.id() ?: 0
|
||||||
loginResult.groups =
|
loginResult.groups =
|
||||||
response?.query()?.getUserResponse(userName)?.groups ?: emptySet()
|
response?.query()?.getUserResponse(userName)?.getGroups() ?: emptySet()
|
||||||
cb.success(loginResult)
|
cb.success(loginResult)
|
||||||
}, { caught: Throwable ->
|
}, { caught: Throwable ->
|
||||||
Timber.e(caught, "Login succeeded but getting group information failed. ")
|
Timber.e(caught, "Login succeeded but getting group information failed. ")
|
||||||
|
|
|
||||||
|
|
@ -938,7 +938,7 @@ class MediaDetailFragment : CommonsDaggerSupportFragment(), CategoryEditHelper.C
|
||||||
|
|
||||||
Observable.defer {
|
Observable.defer {
|
||||||
thanksClient.thank(
|
thanksClient.thank(
|
||||||
firstRevision.revisionId
|
firstRevision.revisionId()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ class ReviewActivity : BaseActivity() {
|
||||||
val caption = getString(
|
val caption = getString(
|
||||||
R.string.review_is_uploaded_by,
|
R.string.review_is_uploaded_by,
|
||||||
fileName,
|
fileName,
|
||||||
revision.user
|
revision.user()
|
||||||
)
|
)
|
||||||
binding.tvImageCaption.text = caption
|
binding.tvImageCaption.text = caption
|
||||||
binding.pbReviewImage.visibility = View.GONE
|
binding.pbReviewImage.visibility = View.GONE
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException
|
||||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
|
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
|
||||||
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.concurrent.Callable
|
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Named
|
import javax.inject.Named
|
||||||
|
|
@ -27,7 +26,6 @@ import fr.free.nrw.commons.delete.DeleteHelper
|
||||||
import fr.free.nrw.commons.di.ApplicationlessInjection
|
import fr.free.nrw.commons.di.ApplicationlessInjection
|
||||||
import fr.free.nrw.commons.utils.ViewUtil
|
import fr.free.nrw.commons.utils.ViewUtil
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.ObservableSource
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
@ -175,7 +173,7 @@ class ReviewController @Inject constructor(
|
||||||
if (firstRevision == null) return
|
if (firstRevision == null) return
|
||||||
|
|
||||||
Observable.defer {
|
Observable.defer {
|
||||||
thanksClient.thank(firstRevision!!.revisionId)
|
thanksClient.thank(firstRevision!!.revisionId())
|
||||||
}
|
}
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class ReviewHelper
|
||||||
reviewInterface
|
reviewInterface
|
||||||
.getRecentChanges()
|
.getRecentChanges()
|
||||||
.map { it.query()?.pages() }
|
.map { it.query()?.pages() }
|
||||||
.map(MutableList<MwQueryPage>::shuffled)
|
.map { it.shuffled() }
|
||||||
.flatMapIterable { changes: List<MwQueryPage>? -> changes }
|
.flatMapIterable { changes: List<MwQueryPage>? -> changes }
|
||||||
.filter { isChangeReviewable(it) }
|
.filter { isChangeReviewable(it) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,15 @@ package fr.free.nrw.commons.review
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.text.TextUtils
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import fr.free.nrw.commons.CommonsApplication
|
import fr.free.nrw.commons.CommonsApplication
|
||||||
import fr.free.nrw.commons.Media
|
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.auth.SessionManager
|
import fr.free.nrw.commons.auth.SessionManager
|
||||||
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException
|
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException
|
||||||
import fr.free.nrw.commons.databinding.FragmentReviewImageBinding
|
import fr.free.nrw.commons.databinding.FragmentReviewImageBinding
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
||||||
import java.util.ArrayList
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -126,7 +123,7 @@ class ReviewImageFragment : CommonsDaggerSupportFragment() {
|
||||||
enableButtons()
|
enableButtons()
|
||||||
question = getString(R.string.review_thanks)
|
question = getString(R.string.review_thanks)
|
||||||
|
|
||||||
user = reviewActivity.reviewController.firstRevision?.user
|
user = reviewActivity.reviewController.firstRevision?.user()
|
||||||
?: savedInstanceState?.getString(SAVED_USER)
|
?: savedInstanceState?.getString(SAVED_USER)
|
||||||
|
|
||||||
//if the user is null because of whatsoever reason, review will not be sent anyways
|
//if the user is null because of whatsoever reason, review will not be sent anyways
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ class UploadClient
|
||||||
if (uploadResult.upload == null) {
|
if (uploadResult.upload == null) {
|
||||||
val exception = gson.fromJson(uploadResponse, MwException::class.java)
|
val exception = gson.fromJson(uploadResponse, MwException::class.java)
|
||||||
Timber.e(exception, "Error in uploading file from stash")
|
Timber.e(exception, "Error in uploading file from stash")
|
||||||
throw Exception(exception.getErrorCode())
|
throw Exception(exception.errorCode)
|
||||||
}
|
}
|
||||||
uploadResult.upload
|
uploadResult.upload
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
public class ImageDetails {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
@NonNull public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
class ImageDetails {
|
||||||
|
val name: String? = null
|
||||||
|
val title: String? = null
|
||||||
|
}
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.collection.ArraySet;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
|
||||||
public class ListUserResponse {
|
|
||||||
@SerializedName("name") @Nullable private String name;
|
|
||||||
private long userid;
|
|
||||||
@Nullable private List<String> groups;
|
|
||||||
|
|
||||||
@Nullable public String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public Set<String> getGroups() {
|
|
||||||
return groups != null ? new ArraySet<>(groups) : Collections.emptySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
class ListUserResponse {
|
||||||
|
private val name: String? = null
|
||||||
|
private val userid: Long = 0
|
||||||
|
private val groups: List<String>? = null
|
||||||
|
|
||||||
|
fun name(): String? = name
|
||||||
|
|
||||||
|
fun getGroups(): Set<String> =
|
||||||
|
groups?.toSet() ?: emptySet()
|
||||||
|
}
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MwException extends RuntimeException {
|
|
||||||
@Nullable private final MwServiceError error;
|
|
||||||
|
|
||||||
@Nullable private final List<MwServiceError> errors;
|
|
||||||
|
|
||||||
public MwException(@Nullable MwServiceError error,
|
|
||||||
@Nullable final List<MwServiceError> errors) {
|
|
||||||
this.error = error;
|
|
||||||
this.errors = errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrorCode() {
|
|
||||||
if(error!=null) {
|
|
||||||
return error.getCode();
|
|
||||||
}
|
|
||||||
return errors != null ? errors.get(0).getCode() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public MwServiceError getError() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getTitle() {
|
|
||||||
if (error != null) {
|
|
||||||
return error.getTitle();
|
|
||||||
}
|
|
||||||
return errors != null ? errors.get(0).getTitle() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public String getMessage() {
|
|
||||||
if (error != null) {
|
|
||||||
return error.getDetails();
|
|
||||||
}
|
|
||||||
return errors != null ? errors.get(0).getDetails() : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
class MwException(
|
||||||
|
val error: MwServiceError?,
|
||||||
|
private val errors: List<MwServiceError>?
|
||||||
|
) : RuntimeException() {
|
||||||
|
val errorCode: String?
|
||||||
|
get() = error?.code ?: errors?.get(0)?.code
|
||||||
|
|
||||||
|
val title: String?
|
||||||
|
get() = error?.title ?: errors?.get(0)?.title
|
||||||
|
|
||||||
|
override val message: String?
|
||||||
|
get() = error?.details ?: errors?.get(0)?.details
|
||||||
|
}
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
public class MwPostResponse extends MwResponse {
|
|
||||||
private int success;
|
|
||||||
|
|
||||||
public boolean success(@Nullable String result) {
|
|
||||||
return "success".equals(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSuccessVal() {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
open class MwPostResponse : MwResponse() {
|
||||||
|
val successVal: Int = 0
|
||||||
|
|
||||||
|
fun success(result: String?): Boolean =
|
||||||
|
"success" == result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,229 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import fr.free.nrw.commons.wikidata.model.gallery.ImageInfo;
|
|
||||||
import fr.free.nrw.commons.wikidata.model.BaseModel;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class representing a standard page object as returned by the MediaWiki API.
|
|
||||||
*/
|
|
||||||
public class MwQueryPage extends BaseModel {
|
|
||||||
private int pageid;
|
|
||||||
private int index;
|
|
||||||
@NonNull private String title;
|
|
||||||
@NonNull private CategoryInfo categoryinfo;
|
|
||||||
@Nullable private List<Revision> revisions;
|
|
||||||
@SerializedName("fileusage") @Nullable private List<FileUsage> fileUsages;
|
|
||||||
@SerializedName("globalusage") @Nullable private List<GlobalUsage> globalUsages;
|
|
||||||
@Nullable private List<Coordinates> coordinates;
|
|
||||||
@Nullable private List<Category> categories;
|
|
||||||
@Nullable private Thumbnail thumbnail;
|
|
||||||
@Nullable private String description;
|
|
||||||
@SerializedName("imageinfo") @Nullable private List<ImageInfo> imageInfo;
|
|
||||||
@Nullable private String redirectFrom;
|
|
||||||
@Nullable private String convertedFrom;
|
|
||||||
@Nullable private String convertedTo;
|
|
||||||
|
|
||||||
@NonNull public String title() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public CategoryInfo categoryInfo() {
|
|
||||||
return categoryinfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int index() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public List<Revision> revisions() {
|
|
||||||
return revisions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public List<Category> categories() {
|
|
||||||
return categories;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public List<Coordinates> coordinates() {
|
|
||||||
// TODO: Handle null values in lists during deserialization, perhaps with a new
|
|
||||||
// @RequiredElements annotation and corresponding TypeAdapter
|
|
||||||
if (coordinates != null) {
|
|
||||||
coordinates.removeAll(Collections.singleton(null));
|
|
||||||
}
|
|
||||||
return coordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int pageId() {
|
|
||||||
return pageid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String thumbUrl() {
|
|
||||||
return thumbnail != null ? thumbnail.source() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String description() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public ImageInfo imageInfo() {
|
|
||||||
return imageInfo != null ? imageInfo.get(0) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void redirectFrom(@Nullable String from) {
|
|
||||||
redirectFrom = from;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void convertedFrom(@Nullable String from) {
|
|
||||||
convertedFrom = from;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void convertedTo(@Nullable String to) {
|
|
||||||
convertedTo = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void appendTitleFragment(@Nullable String fragment) {
|
|
||||||
title += "#" + fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean checkWhetherFileIsUsedInWikis() {
|
|
||||||
if (globalUsages != null && globalUsages.size() > 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileUsages == null || fileUsages.size() == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int totalCount = fileUsages.size();
|
|
||||||
|
|
||||||
/* Ignore usage under https://commons.wikimedia.org/wiki/User:Didym/Mobile_upload/
|
|
||||||
which has been a gallery of all of our uploads since 2014 */
|
|
||||||
for (final FileUsage fileUsage : fileUsages) {
|
|
||||||
if ( ! fileUsage.title().contains("User:Didym/Mobile upload")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Revision {
|
|
||||||
@SerializedName("revid") private long revisionId;
|
|
||||||
private String user;
|
|
||||||
@SerializedName("contentformat") @NonNull private String contentFormat;
|
|
||||||
@SerializedName("contentmodel") @NonNull private String contentModel;
|
|
||||||
@SerializedName("timestamp") @NonNull private String timeStamp;
|
|
||||||
@NonNull private String content;
|
|
||||||
|
|
||||||
@NonNull public String content() {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public String timeStamp() {
|
|
||||||
return StringUtils.defaultString(timeStamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getRevisionId() {
|
|
||||||
return revisionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public String getUser() {
|
|
||||||
return StringUtils.defaultString(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Coordinates {
|
|
||||||
@Nullable private Double lat;
|
|
||||||
@Nullable private Double lon;
|
|
||||||
|
|
||||||
@Nullable public Double lat() {
|
|
||||||
return lat;
|
|
||||||
}
|
|
||||||
@Nullable public Double lon() {
|
|
||||||
return lon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CategoryInfo {
|
|
||||||
private boolean hidden;
|
|
||||||
private int size;
|
|
||||||
private int pages;
|
|
||||||
private int files;
|
|
||||||
private int subcats;
|
|
||||||
public boolean isHidden() {
|
|
||||||
return hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Thumbnail {
|
|
||||||
private String source;
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
String source() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class GlobalUsage {
|
|
||||||
@SerializedName("title") private String title;
|
|
||||||
@SerializedName("wiki")private String wiki;
|
|
||||||
@SerializedName("url") private String url;
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWiki() {
|
|
||||||
return wiki;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FileUsage {
|
|
||||||
@SerializedName("pageid") private int pageid;
|
|
||||||
@SerializedName("ns") private int ns;
|
|
||||||
@SerializedName("title") private String title;
|
|
||||||
|
|
||||||
public int pageId() {
|
|
||||||
return pageid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int ns() {
|
|
||||||
return ns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String title() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Category {
|
|
||||||
private int ns;
|
|
||||||
@SuppressWarnings("unused,NullableProblems") @Nullable private String title;
|
|
||||||
private boolean hidden;
|
|
||||||
|
|
||||||
public int ns() {
|
|
||||||
return ns;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public String title() {
|
|
||||||
return StringUtils.defaultString(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hidden() {
|
|
||||||
return hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import fr.free.nrw.commons.wikidata.model.BaseModel
|
||||||
|
import fr.free.nrw.commons.wikidata.model.gallery.ImageInfo
|
||||||
|
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage.GlobalUsage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class representing a standard page object as returned by the MediaWiki API.
|
||||||
|
*/
|
||||||
|
class MwQueryPage : BaseModel() {
|
||||||
|
private val pageid = 0
|
||||||
|
private val index = 0
|
||||||
|
private var title: String? = null
|
||||||
|
private val categoryinfo: CategoryInfo? = null
|
||||||
|
private val revisions: List<Revision>? = null
|
||||||
|
|
||||||
|
@SerializedName("fileusage")
|
||||||
|
private val fileUsages: List<FileUsage>? = null
|
||||||
|
|
||||||
|
@SerializedName("globalusage")
|
||||||
|
private val globalUsages: List<GlobalUsage>? = null
|
||||||
|
private val coordinates: MutableList<Coordinates?>? = null
|
||||||
|
private val categories: List<Category>? = null
|
||||||
|
private val thumbnail: Thumbnail? = null
|
||||||
|
private val description: String? = null
|
||||||
|
|
||||||
|
@SerializedName("imageinfo")
|
||||||
|
private val imageInfo: List<ImageInfo>? = null
|
||||||
|
private var redirectFrom: String? = null
|
||||||
|
private var convertedFrom: String? = null
|
||||||
|
private var convertedTo: String? = null
|
||||||
|
|
||||||
|
fun title(): String = title!!
|
||||||
|
|
||||||
|
fun categoryInfo(): CategoryInfo = categoryinfo!!
|
||||||
|
|
||||||
|
fun index(): Int = index
|
||||||
|
|
||||||
|
fun revisions(): List<Revision>? = revisions
|
||||||
|
|
||||||
|
fun categories(): List<Category>? = categories
|
||||||
|
|
||||||
|
// TODO: Handle null values in lists during deserialization, perhaps with a new
|
||||||
|
// @RequiredElements annotation and corresponding TypeAdapter
|
||||||
|
fun coordinates(): List<Coordinates?>? = coordinates?.filterNotNull()
|
||||||
|
|
||||||
|
fun pageId(): Int = pageid
|
||||||
|
|
||||||
|
fun thumbUrl(): String? = thumbnail?.source()
|
||||||
|
|
||||||
|
fun description(): String? = description
|
||||||
|
|
||||||
|
fun imageInfo(): ImageInfo? = imageInfo?.get(0)
|
||||||
|
|
||||||
|
fun redirectFrom(from: String?) {
|
||||||
|
redirectFrom = from
|
||||||
|
}
|
||||||
|
|
||||||
|
fun convertedFrom(from: String?) {
|
||||||
|
convertedFrom = from
|
||||||
|
}
|
||||||
|
|
||||||
|
fun convertedTo(to: String?) {
|
||||||
|
convertedTo = to
|
||||||
|
}
|
||||||
|
|
||||||
|
fun appendTitleFragment(fragment: String?) {
|
||||||
|
title += "#$fragment"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkWhetherFileIsUsedInWikis(): Boolean {
|
||||||
|
return checkWhetherFileIsUsedInWikis(globalUsages, fileUsages)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Revision {
|
||||||
|
@SerializedName("revid")
|
||||||
|
private val revisionId: Long = 0
|
||||||
|
private val user: String? = null
|
||||||
|
@SerializedName("contentformat")
|
||||||
|
private val contentFormat: String? = null
|
||||||
|
@SerializedName("contentmodel")
|
||||||
|
private val contentModel: String? = null
|
||||||
|
@SerializedName("timestamp")
|
||||||
|
private val timeStamp: String? = null
|
||||||
|
private val content: String? = null
|
||||||
|
|
||||||
|
fun revisionId(): Long = revisionId
|
||||||
|
|
||||||
|
fun user(): String = user ?: ""
|
||||||
|
|
||||||
|
fun content(): String = content!!
|
||||||
|
|
||||||
|
fun timeStamp(): String = timeStamp ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
class Coordinates {
|
||||||
|
private val lat: Double? = null
|
||||||
|
private val lon: Double? = null
|
||||||
|
|
||||||
|
fun lat(): Double? = lat
|
||||||
|
|
||||||
|
fun lon(): Double? = lon
|
||||||
|
}
|
||||||
|
|
||||||
|
class CategoryInfo {
|
||||||
|
val isHidden: Boolean = false
|
||||||
|
private val size = 0
|
||||||
|
private val pages = 0
|
||||||
|
private val files = 0
|
||||||
|
private val subcats = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Thumbnail {
|
||||||
|
private val source: String? = null
|
||||||
|
private val width = 0
|
||||||
|
private val height = 0
|
||||||
|
|
||||||
|
fun source(): String? = source
|
||||||
|
}
|
||||||
|
|
||||||
|
class GlobalUsage {
|
||||||
|
@SerializedName("title")
|
||||||
|
val title: String? = null
|
||||||
|
|
||||||
|
@SerializedName("wiki")
|
||||||
|
val wiki: String? = null
|
||||||
|
|
||||||
|
@SerializedName("url")
|
||||||
|
val url: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileUsage {
|
||||||
|
@SerializedName("pageid")
|
||||||
|
private val pageid = 0
|
||||||
|
|
||||||
|
@SerializedName("ns")
|
||||||
|
private val ns = 0
|
||||||
|
|
||||||
|
@SerializedName("title")
|
||||||
|
private var title: String? = null
|
||||||
|
|
||||||
|
fun pageId(): Int = pageid
|
||||||
|
|
||||||
|
fun ns(): Int = ns
|
||||||
|
|
||||||
|
fun title(): String = title ?: ""
|
||||||
|
|
||||||
|
fun setTitle(value: String) {
|
||||||
|
title = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Category {
|
||||||
|
private val ns = 0
|
||||||
|
private val title: String? = null
|
||||||
|
private val hidden = false
|
||||||
|
|
||||||
|
fun ns(): Int = ns
|
||||||
|
|
||||||
|
fun title(): String = title ?: ""
|
||||||
|
|
||||||
|
fun hidden(): Boolean = hidden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
fun checkWhetherFileIsUsedInWikis(
|
||||||
|
globalUsages: List<GlobalUsage>?,
|
||||||
|
fileUsages: List<MwQueryPage.FileUsage>?
|
||||||
|
): Boolean {
|
||||||
|
if (!globalUsages.isNullOrEmpty()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileUsages.isNullOrEmpty()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore usage under https://commons.wikimedia.org/wiki/User:Didym/Mobile_upload/
|
||||||
|
which has been a gallery of all of our uploads since 2014 */
|
||||||
|
return fileUsages.filterNot {
|
||||||
|
it.title().contains("User:Didym/Mobile upload")
|
||||||
|
}.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class MwQueryResponse extends MwResponse {
|
|
||||||
|
|
||||||
@SerializedName("continue") @Nullable private Map<String, String> continuation;
|
|
||||||
|
|
||||||
@SerializedName("query") @Nullable private MwQueryResult query;
|
|
||||||
|
|
||||||
@Nullable public Map<String, String> continuation() {
|
|
||||||
return continuation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public MwQueryResult query() {
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean success() {
|
|
||||||
return query != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
class MwQueryResponse : MwResponse() {
|
||||||
|
@SerializedName("continue")
|
||||||
|
private val continuation: Map<String, String>? = null
|
||||||
|
private val query: MwQueryResult? = null
|
||||||
|
|
||||||
|
fun continuation(): Map<String, String>? = continuation
|
||||||
|
|
||||||
|
fun query(): MwQueryResult? = query
|
||||||
|
|
||||||
|
fun success(): Boolean = query != null
|
||||||
|
}
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.wikidata.json.PostProcessingTypeAdapter;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import fr.free.nrw.commons.wikidata.model.gallery.ImageInfo;
|
|
||||||
import fr.free.nrw.commons.wikidata.model.BaseModel;
|
|
||||||
import fr.free.nrw.commons.wikidata.model.notifications.Notification;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
public class MwQueryResult extends BaseModel implements PostProcessingTypeAdapter.PostProcessable {
|
|
||||||
@SerializedName("pages") @Nullable private List<MwQueryPage> pages;
|
|
||||||
@Nullable private List<Redirect> redirects;
|
|
||||||
@Nullable private List<ConvertedTitle> converted;
|
|
||||||
@SerializedName("userinfo") private UserInfo userInfo;
|
|
||||||
@Nullable private List<ListUserResponse> users;
|
|
||||||
@Nullable private Tokens tokens;
|
|
||||||
@Nullable private NotificationList notifications;
|
|
||||||
@SerializedName("allimages") @Nullable private List<ImageDetails> allImages;
|
|
||||||
|
|
||||||
@Nullable public List<MwQueryPage> pages() {
|
|
||||||
return pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public MwQueryPage firstPage() {
|
|
||||||
if (pages != null && pages.size() > 0) {
|
|
||||||
return pages.get(0);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public List<ImageDetails> allImages() {
|
|
||||||
return allImages == null ? Collections.emptyList() : allImages;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public UserInfo userInfo() {
|
|
||||||
return userInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String csrfToken() {
|
|
||||||
return tokens != null ? tokens.csrf() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String loginToken() {
|
|
||||||
return tokens != null ? tokens.login() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public NotificationList notifications() {
|
|
||||||
return notifications;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public ListUserResponse getUserResponse(@NonNull String userName) {
|
|
||||||
if (users != null) {
|
|
||||||
for (ListUserResponse user : users) {
|
|
||||||
// MediaWiki user names are case sensitive, but the first letter is always capitalized.
|
|
||||||
if (StringUtils.capitalize(userName).equals(user.name())) {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public Map<String, ImageInfo> images() {
|
|
||||||
Map<String, ImageInfo> result = new HashMap<>();
|
|
||||||
if (pages != null) {
|
|
||||||
for (MwQueryPage page : pages) {
|
|
||||||
if (page.imageInfo() != null) {
|
|
||||||
result.put(page.title(), page.imageInfo());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postProcess() {
|
|
||||||
resolveConvertedTitles();
|
|
||||||
resolveRedirectedTitles();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resolveRedirectedTitles() {
|
|
||||||
if (redirects == null || pages == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (MwQueryPage page : pages) {
|
|
||||||
for (MwQueryResult.Redirect redirect : redirects) {
|
|
||||||
// TODO: Looks like result pages and redirects can also be matched on the "index"
|
|
||||||
// property. Confirm in the API docs and consider updating.
|
|
||||||
if (page.title().equals(redirect.to())) {
|
|
||||||
page.redirectFrom(redirect.from());
|
|
||||||
if (redirect.toFragment() != null) {
|
|
||||||
page.appendTitleFragment(redirect.toFragment());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resolveConvertedTitles() {
|
|
||||||
if (converted == null || pages == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// noinspection ConstantConditions
|
|
||||||
for (MwQueryResult.ConvertedTitle convertedTitle : converted) {
|
|
||||||
// noinspection ConstantConditions
|
|
||||||
for (MwQueryPage page : pages) {
|
|
||||||
if (page.title().equals(convertedTitle.to())) {
|
|
||||||
page.convertedFrom(convertedTitle.from());
|
|
||||||
page.convertedTo(convertedTitle.to());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Redirect {
|
|
||||||
private int index;
|
|
||||||
@Nullable private String from;
|
|
||||||
@Nullable private String to;
|
|
||||||
@SerializedName("tofragment") @Nullable private String toFragment;
|
|
||||||
|
|
||||||
@Nullable public String to() {
|
|
||||||
return to;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String from() {
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String toFragment() {
|
|
||||||
return toFragment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ConvertedTitle {
|
|
||||||
@Nullable private String from;
|
|
||||||
@Nullable private String to;
|
|
||||||
|
|
||||||
@Nullable public String to() {
|
|
||||||
return to;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public String from() {
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Tokens {
|
|
||||||
@SuppressWarnings("unused,NullableProblems") @SerializedName("csrftoken")
|
|
||||||
@Nullable private String csrf;
|
|
||||||
@SuppressWarnings("unused,NullableProblems") @SerializedName("createaccounttoken")
|
|
||||||
@Nullable private String createAccount;
|
|
||||||
@SuppressWarnings("unused,NullableProblems") @SerializedName("logintoken")
|
|
||||||
@Nullable private String login;
|
|
||||||
|
|
||||||
@Nullable private String csrf() {
|
|
||||||
return csrf;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable private String createAccount() {
|
|
||||||
return createAccount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable private String login() {
|
|
||||||
return login;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NotificationList {
|
|
||||||
@Nullable
|
|
||||||
private List<Notification> list;
|
|
||||||
@Nullable
|
|
||||||
public List<Notification> list() {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import fr.free.nrw.commons.wikidata.json.PostProcessingTypeAdapter.PostProcessable
|
||||||
|
import fr.free.nrw.commons.wikidata.model.BaseModel
|
||||||
|
import fr.free.nrw.commons.wikidata.model.gallery.ImageInfo
|
||||||
|
import fr.free.nrw.commons.wikidata.model.notifications.Notification
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
|
||||||
|
class MwQueryResult : BaseModel(), PostProcessable {
|
||||||
|
private val pages: List<MwQueryPage>? = null
|
||||||
|
private val redirects: List<Redirect>? = null
|
||||||
|
private val converted: List<ConvertedTitle>? = null
|
||||||
|
|
||||||
|
@SerializedName("userinfo")
|
||||||
|
private val userInfo: UserInfo? = null
|
||||||
|
private val users: List<ListUserResponse>? = null
|
||||||
|
private val tokens: Tokens? = null
|
||||||
|
private val notifications: NotificationList? = null
|
||||||
|
|
||||||
|
@SerializedName("allimages")
|
||||||
|
private val allImages: List<ImageDetails>? = null
|
||||||
|
|
||||||
|
fun pages(): List<MwQueryPage>? = pages
|
||||||
|
|
||||||
|
fun firstPage(): MwQueryPage? = pages?.firstOrNull()
|
||||||
|
|
||||||
|
fun allImages(): List<ImageDetails> = allImages ?: emptyList()
|
||||||
|
|
||||||
|
fun userInfo(): UserInfo? = userInfo
|
||||||
|
|
||||||
|
fun csrfToken(): String? = tokens?.csrf()
|
||||||
|
|
||||||
|
fun loginToken(): String? = tokens?.login()
|
||||||
|
|
||||||
|
fun notifications(): NotificationList? = notifications
|
||||||
|
|
||||||
|
fun getUserResponse(userName: String): ListUserResponse? =
|
||||||
|
users?.find { StringUtils.capitalize(userName) == it.name() }
|
||||||
|
|
||||||
|
fun images() = buildMap {
|
||||||
|
pages?.forEach { page ->
|
||||||
|
page.imageInfo()?.let {
|
||||||
|
put(page.title(), it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postProcess() {
|
||||||
|
resolveConvertedTitles()
|
||||||
|
resolveRedirectedTitles()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveRedirectedTitles() {
|
||||||
|
if (redirects == null || pages == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pages.forEach { page ->
|
||||||
|
redirects.forEach { redirect ->
|
||||||
|
// TODO: Looks like result pages and redirects can also be matched on the "index"
|
||||||
|
// property. Confirm in the API docs and consider updating.
|
||||||
|
if (page.title() == redirect.to()) {
|
||||||
|
page.redirectFrom(redirect.from())
|
||||||
|
if (redirect.toFragment() != null) {
|
||||||
|
page.appendTitleFragment(redirect.toFragment())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveConvertedTitles() {
|
||||||
|
if (converted == null || pages == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
converted.forEach { convertedTitle ->
|
||||||
|
pages.forEach { page ->
|
||||||
|
if (page.title() == convertedTitle.to()) {
|
||||||
|
page.convertedFrom(convertedTitle.from())
|
||||||
|
page.convertedTo(convertedTitle.to())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Redirect {
|
||||||
|
private val index = 0
|
||||||
|
private val from: String? = null
|
||||||
|
private val to: String? = null
|
||||||
|
|
||||||
|
@SerializedName("tofragment")
|
||||||
|
private val toFragment: String? = null
|
||||||
|
|
||||||
|
fun to(): String? = to
|
||||||
|
|
||||||
|
fun from(): String? = from
|
||||||
|
|
||||||
|
fun toFragment(): String? = toFragment
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConvertedTitle {
|
||||||
|
private val from: String? = null
|
||||||
|
private val to: String? = null
|
||||||
|
|
||||||
|
fun to(): String? = to
|
||||||
|
|
||||||
|
fun from(): String? = from
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Tokens {
|
||||||
|
@SerializedName("csrftoken")
|
||||||
|
private val csrf: String? = null
|
||||||
|
|
||||||
|
@SerializedName("createaccounttoken")
|
||||||
|
private val createAccount: String? = null
|
||||||
|
|
||||||
|
@SerializedName("logintoken")
|
||||||
|
private val login: String? = null
|
||||||
|
|
||||||
|
fun csrf(): String? = csrf
|
||||||
|
|
||||||
|
fun createAccount(): String? = createAccount
|
||||||
|
|
||||||
|
fun login(): String? = login
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotificationList {
|
||||||
|
private val list: List<Notification>? = null
|
||||||
|
|
||||||
|
fun list(): List<Notification>? = list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.wikidata.json.PostProcessingTypeAdapter;
|
|
||||||
import fr.free.nrw.commons.wikidata.model.BaseModel;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class MwResponse extends BaseModel implements PostProcessingTypeAdapter.PostProcessable {
|
|
||||||
@SuppressWarnings({"unused"}) @Nullable private List<MwServiceError> errors;
|
|
||||||
@SuppressWarnings("unused,NullableProblems") @SerializedName("servedby") @NonNull private String servedBy;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postProcess() {
|
|
||||||
if (errors != null && !errors.isEmpty()) {
|
|
||||||
throw new MwException(errors.get(0), errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import fr.free.nrw.commons.wikidata.json.PostProcessingTypeAdapter.PostProcessable
|
||||||
|
import fr.free.nrw.commons.wikidata.model.BaseModel
|
||||||
|
|
||||||
|
abstract class MwResponse : BaseModel(), PostProcessable {
|
||||||
|
private val errors: List<MwServiceError>? = null
|
||||||
|
|
||||||
|
@SerializedName("servedby")
|
||||||
|
private val servedBy: String? = null
|
||||||
|
|
||||||
|
override fun postProcess() {
|
||||||
|
if (!errors.isNullOrEmpty()) {
|
||||||
|
throw MwException(errors[0], errors)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.mwapi;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import fr.free.nrw.commons.wikidata.model.BaseModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gson POJO for a MediaWiki API error.
|
|
||||||
*/
|
|
||||||
public class MwServiceError extends BaseModel {
|
|
||||||
|
|
||||||
@Nullable private String code;
|
|
||||||
@Nullable private String text;
|
|
||||||
|
|
||||||
@NonNull public String getTitle() {
|
|
||||||
return StringUtils.defaultString(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public String getDetails() {
|
|
||||||
return StringUtils.defaultString(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.wikidata.model.BaseModel
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gson POJO for a MediaWiki API error.
|
||||||
|
*/
|
||||||
|
class MwServiceError : BaseModel() {
|
||||||
|
val code: String? = null
|
||||||
|
private val text: String? = null
|
||||||
|
|
||||||
|
val title: String
|
||||||
|
get() = code ?: ""
|
||||||
|
|
||||||
|
val details: String
|
||||||
|
get() = text ?: ""
|
||||||
|
}
|
||||||
|
|
@ -139,7 +139,7 @@ class ReviewControllerTest {
|
||||||
@Test
|
@Test
|
||||||
fun testSendThanks() {
|
fun testSendThanks() {
|
||||||
shadowOf(Looper.getMainLooper()).idle()
|
shadowOf(Looper.getMainLooper()).idle()
|
||||||
whenever(firstRevision.revisionId).thenReturn(1)
|
whenever(firstRevision.revisionId()).thenReturn(1)
|
||||||
Whitebox.setInternalState(controller, "firstRevision", firstRevision)
|
Whitebox.setInternalState(controller, "firstRevision", firstRevision)
|
||||||
controller.sendThanks(activity)
|
controller.sendThanks(activity)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
|
|
|
||||||
|
|
@ -95,11 +95,11 @@ class ReviewHelperTest {
|
||||||
@Test
|
@Test
|
||||||
fun getFirstRevisionOfFile() {
|
fun getFirstRevisionOfFile() {
|
||||||
val rev1 = mock<MwQueryPage.Revision>()
|
val rev1 = mock<MwQueryPage.Revision>()
|
||||||
whenever(rev1.user).thenReturn("TestUser")
|
whenever(rev1.user()).thenReturn("TestUser")
|
||||||
whenever(rev1.revisionId).thenReturn(1L)
|
whenever(rev1.revisionId()).thenReturn(1L)
|
||||||
val rev2 = mock<MwQueryPage.Revision>()
|
val rev2 = mock<MwQueryPage.Revision>()
|
||||||
whenever(rev2.user).thenReturn("TestUser")
|
whenever(rev2.user()).thenReturn("TestUser")
|
||||||
whenever(rev2.revisionId).thenReturn(2L)
|
whenever(rev2.revisionId()).thenReturn(2L)
|
||||||
|
|
||||||
val page = setupMedia("Test.jpg", rev1, rev2)
|
val page = setupMedia("Test.jpg", rev1, rev2)
|
||||||
whenever(mwQueryResult.firstPage()).thenReturn(page)
|
whenever(mwQueryResult.firstPage()).thenReturn(page)
|
||||||
|
|
@ -107,7 +107,7 @@ class ReviewHelperTest {
|
||||||
|
|
||||||
val firstRevisionOfFile = reviewHelper.getFirstRevisionOfFile("Test.jpg").blockingFirst()
|
val firstRevisionOfFile = reviewHelper.getFirstRevisionOfFile("Test.jpg").blockingFirst()
|
||||||
|
|
||||||
assertEquals(1, firstRevisionOfFile.revisionId)
|
assertEquals(1, firstRevisionOfFile.revisionId())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.mwapi
|
||||||
|
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class MwQueryPageTest {
|
||||||
|
private val didymUsage = MwQueryPage.FileUsage().apply {
|
||||||
|
setTitle("User:Didym/Mobile upload")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun checkWhetherFileIsUsedInWikis_nullGlobalUsages() {
|
||||||
|
assertFalse(checkWhetherFileIsUsedInWikis(null, null))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun checkWhetherFileIsUsedInWikis_emptyGlobalUsages() {
|
||||||
|
assertFalse(checkWhetherFileIsUsedInWikis(emptyList(), null))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun checkWhetherFileIsUsedInWikis_emptyFileUsage() {
|
||||||
|
assertFalse(checkWhetherFileIsUsedInWikis(emptyList(), emptyList()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun checkWhetherFileIsUsedInWikis_singleGlobalUsages() {
|
||||||
|
assertTrue(checkWhetherFileIsUsedInWikis(listOf(MwQueryPage.GlobalUsage()), null))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun checkWhetherFileIsUsedInWikis_singleFileUsageContainsDidym() {
|
||||||
|
assertFalse(checkWhetherFileIsUsedInWikis(null, listOf(didymUsage)))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun checkWhetherFileIsUsedInWikis_didymIgnoredInList() {
|
||||||
|
assertTrue(
|
||||||
|
checkWhetherFileIsUsedInWikis(
|
||||||
|
null, listOf(
|
||||||
|
didymUsage, MwQueryPage.FileUsage().apply { setTitle("somewhere else") }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue