mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Convert wikidata/mwapi to kotlin (part 2) (#5999)
* Convert DepictSearchResponse to kotlin * Convert Entities to kotlin * Convert WikiSite to kotlin --------- Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com>
This commit is contained in:
parent
f8d519e8eb
commit
ae52267a27
8 changed files with 348 additions and 427 deletions
|
|
@ -105,7 +105,7 @@ class AboutActivityTest {
|
||||||
fun testLaunchTranslate() {
|
fun testLaunchTranslate() {
|
||||||
Espresso.onView(ViewMatchers.withId(R.id.about_translate)).perform(ViewActions.click())
|
Espresso.onView(ViewMatchers.withId(R.id.about_translate)).perform(ViewActions.click())
|
||||||
Espresso.onView(ViewMatchers.withId(android.R.id.button1)).perform(ViewActions.click())
|
Espresso.onView(ViewMatchers.withId(android.R.id.button1)).perform(ViewActions.click())
|
||||||
val langCode = CommonsApplication.instance.languageLookUpTable!!.codes[0]
|
val langCode = CommonsApplication.instance.languageLookUpTable!!.getCodes()[0]
|
||||||
Intents.intended(
|
Intents.intended(
|
||||||
CoreMatchers.allOf(
|
CoreMatchers.allOf(
|
||||||
IntentMatchers.hasAction(Intent.ACTION_VIEW),
|
IntentMatchers.hasAction(Intent.ACTION_VIEW),
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ import okhttp3.logging.HttpLoggingInterceptor
|
||||||
import okhttp3.logging.HttpLoggingInterceptor.Level
|
import okhttp3.logging.HttpLoggingInterceptor.Level
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Locale
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Named
|
import javax.inject.Named
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
@ -293,9 +292,8 @@ class NetworkingModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE)
|
@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE)
|
||||||
fun provideLanguageWikipediaSite(): WikiSite {
|
fun provideLanguageWikipediaSite(): WikiSite =
|
||||||
return WikiSite.forLanguageCode(Locale.getDefault().language)
|
WikiSite.forDefaultLocaleLanguageCode()
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val WIKIDATA_SPARQL_QUERY_URL = "https://query.wikidata.org/sparql"
|
private const val WIKIDATA_SPARQL_QUERY_URL = "https://query.wikidata.org/sparql"
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.model;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Model class for API response obtained from search for depictions
|
|
||||||
*/
|
|
||||||
public class DepictSearchResponse {
|
|
||||||
private final List<DepictSearchItem> search;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor to initialise value of the search object
|
|
||||||
*/
|
|
||||||
public DepictSearchResponse(List<DepictSearchItem> search) {
|
|
||||||
this.search = search;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return List<DepictSearchItem> for the DepictSearchResponse
|
|
||||||
*/
|
|
||||||
public List<DepictSearchItem> getSearch() {
|
|
||||||
return search;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.model
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model class for API response obtained from search for depictions
|
||||||
|
*/
|
||||||
|
class DepictSearchResponse(
|
||||||
|
/**
|
||||||
|
* @return List<DepictSearchItem> for the DepictSearchResponse
|
||||||
|
</DepictSearchItem>
|
||||||
|
*/
|
||||||
|
val search: List<DepictSearchItem>
|
||||||
|
)
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.model;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import fr.free.nrw.commons.wikidata.mwapi.MwResponse;
|
|
||||||
|
|
||||||
|
|
||||||
public class Entities extends MwResponse {
|
|
||||||
@Nullable private Map<String, Entity> entities;
|
|
||||||
private int success;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Map<String, Entity> entities() {
|
|
||||||
return entities != null ? entities : Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSuccess() {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable public Entity getFirst() {
|
|
||||||
if (entities == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return entities.values().iterator().next();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postProcess() {
|
|
||||||
if (getFirst() != null && getFirst().isMissing()) {
|
|
||||||
throw new RuntimeException("The requested entity was not found.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Entity {
|
|
||||||
@Nullable private String type;
|
|
||||||
@Nullable private String id;
|
|
||||||
@Nullable private Map<String, Label> labels;
|
|
||||||
@Nullable private Map<String, Label> descriptions;
|
|
||||||
@Nullable private Map<String, SiteLink> sitelinks;
|
|
||||||
@Nullable @SerializedName(value = "statements", alternate = "claims") private Map<String, List<StatementPartial>> statements;
|
|
||||||
@Nullable private String missing;
|
|
||||||
|
|
||||||
@NonNull public String id() {
|
|
||||||
return StringUtils.defaultString(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public Map<String, Label> labels() {
|
|
||||||
return labels != null ? labels : Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public Map<String, Label> descriptions() {
|
|
||||||
return descriptions != null ? descriptions : Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public Map<String, SiteLink> sitelinks() {
|
|
||||||
return sitelinks != null ? sitelinks : Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Map<String, List<StatementPartial>> getStatements() {
|
|
||||||
return statements;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isMissing() {
|
|
||||||
return "-1".equals(id) && missing != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Label {
|
|
||||||
@Nullable private String language;
|
|
||||||
@Nullable private String value;
|
|
||||||
|
|
||||||
public Label(@Nullable final String language, @Nullable final String value) {
|
|
||||||
this.language = language;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public String language() {
|
|
||||||
return StringUtils.defaultString(language);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public String value() {
|
|
||||||
return StringUtils.defaultString(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SiteLink {
|
|
||||||
@Nullable private String site;
|
|
||||||
@Nullable private String title;
|
|
||||||
|
|
||||||
@NonNull public String getSite() {
|
|
||||||
return StringUtils.defaultString(site);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull public String getTitle() {
|
|
||||||
return StringUtils.defaultString(title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.model
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import fr.free.nrw.commons.wikidata.mwapi.MwResponse
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
|
||||||
|
class Entities : MwResponse() {
|
||||||
|
private val entities: Map<String, Entity>? = null
|
||||||
|
val success: Int = 0
|
||||||
|
|
||||||
|
fun entities(): Map<String, Entity> = entities ?: emptyMap()
|
||||||
|
|
||||||
|
private val first : Entity?
|
||||||
|
get() = entities?.values?.iterator()?.next()
|
||||||
|
|
||||||
|
override fun postProcess() {
|
||||||
|
first?.let {
|
||||||
|
if (it.isMissing()) throw RuntimeException("The requested entity was not found.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Entity {
|
||||||
|
private val type: String? = null
|
||||||
|
private val id: String? = null
|
||||||
|
private val labels: Map<String, Label>? = null
|
||||||
|
private val descriptions: Map<String, Label>? = null
|
||||||
|
private val sitelinks: Map<String, SiteLink>? = null
|
||||||
|
|
||||||
|
@SerializedName(value = "statements", alternate = ["claims"])
|
||||||
|
val statements: Map<String, List<StatementPartial>>? = null
|
||||||
|
private val missing: String? = null
|
||||||
|
|
||||||
|
fun id(): String =
|
||||||
|
StringUtils.defaultString(id)
|
||||||
|
|
||||||
|
fun labels(): Map<String, Label> =
|
||||||
|
labels ?: emptyMap()
|
||||||
|
|
||||||
|
fun descriptions(): Map<String, Label> =
|
||||||
|
descriptions ?: emptyMap()
|
||||||
|
|
||||||
|
fun sitelinks(): Map<String, SiteLink> =
|
||||||
|
sitelinks ?: emptyMap()
|
||||||
|
|
||||||
|
fun isMissing(): Boolean =
|
||||||
|
"-1" == id && missing != null
|
||||||
|
}
|
||||||
|
|
||||||
|
class Label(private val language: String?, private val value: String?) {
|
||||||
|
fun language(): String =
|
||||||
|
StringUtils.defaultString(language)
|
||||||
|
|
||||||
|
fun value(): String =
|
||||||
|
StringUtils.defaultString(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
class SiteLink {
|
||||||
|
val site: String? = null
|
||||||
|
get() = StringUtils.defaultString(field)
|
||||||
|
|
||||||
|
private val title: String? = null
|
||||||
|
get() = StringUtils.defaultString(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,292 +0,0 @@
|
||||||
package fr.free.nrw.commons.wikidata.model;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Parcel;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import fr.free.nrw.commons.language.AppLanguageLookUpTable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base URL and Wikipedia language code for a MediaWiki site. Examples:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <lh>Name: scheme / authority / language code</lh>
|
|
||||||
* <li>English Wikipedia: HTTPS / en.wikipedia.org / en</li>
|
|
||||||
* <li>Chinese Wikipedia: HTTPS / zh.wikipedia.org / zh-hans or zh-hant</li>
|
|
||||||
* <li>Meta-Wiki: HTTPS / meta.wikimedia.org / (none)</li>
|
|
||||||
* <li>Test Wikipedia: HTTPS / test.wikipedia.org / test</li>
|
|
||||||
* <li>Võro Wikipedia: HTTPS / fiu-vro.wikipedia.org / fiu-vro</li>
|
|
||||||
* <li>Simple English Wikipedia: HTTPS / simple.wikipedia.org / simple</li>
|
|
||||||
* <li>Simple English Wikipedia (beta cluster mirror): HTTP / simple.wikipedia.beta.wmflabs.org / simple</li>
|
|
||||||
* <li>Development: HTTP / 192.168.1.11:8080 / (none)</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <strong>As shown above, the language code or mapping is part of the authority:</strong>
|
|
||||||
* <ul>
|
|
||||||
* <lh>Validity: authority / language code</lh>
|
|
||||||
* <li>Correct: "test.wikipedia.org" / "test"</li>
|
|
||||||
* <li>Correct: "wikipedia.org", ""</li>
|
|
||||||
* <li>Correct: "no.wikipedia.org", "nb"</li>
|
|
||||||
* <li>Incorrect: "wikipedia.org", "test"</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public class WikiSite implements Parcelable {
|
|
||||||
private static String WIKIPEDIA_URL = "https://wikipedia.org/";
|
|
||||||
|
|
||||||
public static final String DEFAULT_SCHEME = "https";
|
|
||||||
private static String DEFAULT_BASE_URL = WIKIPEDIA_URL;
|
|
||||||
|
|
||||||
public static final Parcelable.Creator<WikiSite> CREATOR = new Parcelable.Creator<WikiSite>() {
|
|
||||||
@Override
|
|
||||||
public WikiSite createFromParcel(Parcel in) {
|
|
||||||
return new WikiSite(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WikiSite[] newArray(int size) {
|
|
||||||
return new WikiSite[size];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// todo: remove @SerializedName. this is now in the TypeAdapter and a "uri" case may be added
|
|
||||||
@SerializedName("domain") @NonNull private final Uri uri;
|
|
||||||
@NonNull private String languageCode;
|
|
||||||
|
|
||||||
public static WikiSite forLanguageCode(@NonNull String languageCode) {
|
|
||||||
Uri uri = ensureScheme(Uri.parse(DEFAULT_BASE_URL));
|
|
||||||
return new WikiSite((languageCode.isEmpty()
|
|
||||||
? "" : (languageCodeToSubdomain(languageCode) + ".")) + uri.getAuthority(),
|
|
||||||
languageCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WikiSite(@NonNull Uri uri) {
|
|
||||||
Uri tempUri = ensureScheme(uri);
|
|
||||||
String authority = tempUri.getAuthority();
|
|
||||||
if (("wikipedia.org".equals(authority) || "www.wikipedia.org".equals(authority))
|
|
||||||
&& tempUri.getPath() != null && tempUri.getPath().startsWith("/wiki")) {
|
|
||||||
// Special case for Wikipedia only: assume English subdomain when none given.
|
|
||||||
authority = "en.wikipedia.org";
|
|
||||||
}
|
|
||||||
String langVariant = getLanguageVariantFromUri(tempUri);
|
|
||||||
if (!TextUtils.isEmpty(langVariant)) {
|
|
||||||
languageCode = langVariant;
|
|
||||||
} else {
|
|
||||||
languageCode = authorityToLanguageCode(authority);
|
|
||||||
}
|
|
||||||
this.uri = new Uri.Builder()
|
|
||||||
.scheme(tempUri.getScheme())
|
|
||||||
.encodedAuthority(authority)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get language variant code from a Uri, e.g. "zh-*", otherwise returns empty string. */
|
|
||||||
@NonNull
|
|
||||||
private String getLanguageVariantFromUri(@NonNull Uri uri) {
|
|
||||||
if (TextUtils.isEmpty(uri.getPath())) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
String[] parts = StringUtils.split(StringUtils.defaultString(uri.getPath()), '/');
|
|
||||||
return parts.length > 1 && !parts[0].equals("wiki") ? parts[0] : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public WikiSite(@NonNull String url) {
|
|
||||||
this(url.startsWith("http") ? Uri.parse(url) : url.startsWith("//")
|
|
||||||
? Uri.parse(DEFAULT_SCHEME + ":" + url) : Uri.parse(DEFAULT_SCHEME + "://" + url));
|
|
||||||
}
|
|
||||||
|
|
||||||
public WikiSite(@NonNull String authority, @NonNull String languageCode) {
|
|
||||||
this(authority);
|
|
||||||
this.languageCode = languageCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public String scheme() {
|
|
||||||
return TextUtils.isEmpty(uri.getScheme()) ? DEFAULT_SCHEME : uri.getScheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The complete wiki authority including language subdomain but not including scheme,
|
|
||||||
* authentication, port, nor trailing slash.
|
|
||||||
*
|
|
||||||
* @see <a href='https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax'>URL syntax</a>
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public String authority() {
|
|
||||||
return uri.getAuthority();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like {@link #authority()} but with a "m." between the language subdomain and the rest of the host.
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>English Wikipedia: en.m.wikipedia.org</li>
|
|
||||||
* <li>Chinese Wikipedia: zh.m.wikipedia.org</li>
|
|
||||||
* <li>Meta-Wiki: meta.m.wikimedia.org</li>
|
|
||||||
* <li>Test Wikipedia: test.m.wikipedia.org</li>
|
|
||||||
* <li>Võro Wikipedia: fiu-vro.m.wikipedia.org</li>
|
|
||||||
* <li>Simple English Wikipedia: simple.m.wikipedia.org</li>
|
|
||||||
* <li>Simple English Wikipedia (beta cluster mirror): simple.m.wikipedia.beta.wmflabs.org</li>
|
|
||||||
* <li>Development: m.192.168.1.11</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public String mobileAuthority() {
|
|
||||||
return authorityToMobile(authority());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get wiki's mobile URL
|
|
||||||
* Eg. https://en.m.wikipedia.org
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String mobileUrl() {
|
|
||||||
return String.format("%1$s://%2$s", scheme(), mobileAuthority());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public String subdomain() {
|
|
||||||
return languageCodeToSubdomain(languageCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A path without an authority for the segment including a leading "/".
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public String path(@NonNull String segment) {
|
|
||||||
return "/w/" + segment;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull public Uri uri() {
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The canonical URL. e.g., https://en.wikipedia.org.
|
|
||||||
*/
|
|
||||||
@NonNull public String url() {
|
|
||||||
return uri.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The canonical URL for segment. e.g., https://en.wikipedia.org/w/foo.
|
|
||||||
*/
|
|
||||||
@NonNull public String url(@NonNull String segment) {
|
|
||||||
return url() + path(segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The wiki language code which may differ from the language subdomain. Empty if
|
|
||||||
* language code is unknown. Ex: "en", "zh-hans", ""
|
|
||||||
*
|
|
||||||
* @see AppLanguageLookUpTable
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public String languageCode() {
|
|
||||||
return languageCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-generated
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WikiSite wiki = (WikiSite) o;
|
|
||||||
|
|
||||||
if (!uri.equals(wiki.uri)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return languageCode.equals(wiki.languageCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-generated
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = uri.hashCode();
|
|
||||||
result = 31 * result + languageCode.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-generated
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "WikiSite{"
|
|
||||||
+ "uri=" + uri
|
|
||||||
+ ", languageCode='" + languageCode + '\''
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int describeContents() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
||||||
dest.writeParcelable(uri, 0);
|
|
||||||
dest.writeString(languageCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected WikiSite(@NonNull Parcel in) {
|
|
||||||
this.uri = in.readParcelable(Uri.class.getClassLoader());
|
|
||||||
this.languageCode = in.readString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private static String languageCodeToSubdomain(@NonNull String languageCode) {
|
|
||||||
switch (languageCode) {
|
|
||||||
case AppLanguageLookUpTable.SIMPLIFIED_CHINESE_LANGUAGE_CODE:
|
|
||||||
case AppLanguageLookUpTable.TRADITIONAL_CHINESE_LANGUAGE_CODE:
|
|
||||||
case AppLanguageLookUpTable.CHINESE_CN_LANGUAGE_CODE:
|
|
||||||
case AppLanguageLookUpTable.CHINESE_HK_LANGUAGE_CODE:
|
|
||||||
case AppLanguageLookUpTable.CHINESE_MO_LANGUAGE_CODE:
|
|
||||||
case AppLanguageLookUpTable.CHINESE_SG_LANGUAGE_CODE:
|
|
||||||
case AppLanguageLookUpTable.CHINESE_TW_LANGUAGE_CODE:
|
|
||||||
return AppLanguageLookUpTable.CHINESE_LANGUAGE_CODE;
|
|
||||||
case AppLanguageLookUpTable.NORWEGIAN_BOKMAL_LANGUAGE_CODE:
|
|
||||||
return AppLanguageLookUpTable.NORWEGIAN_LEGACY_LANGUAGE_CODE; // T114042
|
|
||||||
default:
|
|
||||||
return languageCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull private static String authorityToLanguageCode(@NonNull String authority) {
|
|
||||||
String[] parts = authority.split("\\.");
|
|
||||||
final int minLengthForSubdomain = 3;
|
|
||||||
if (parts.length < minLengthForSubdomain
|
|
||||||
|| parts.length == minLengthForSubdomain && parts[0].equals("m")) {
|
|
||||||
// ""
|
|
||||||
// wikipedia.org
|
|
||||||
// m.wikipedia.org
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return parts[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull private static Uri ensureScheme(@NonNull Uri uri) {
|
|
||||||
if (TextUtils.isEmpty(uri.getScheme())) {
|
|
||||||
return uri.buildUpon().scheme(DEFAULT_SCHEME).build();
|
|
||||||
}
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param authority Host and optional port. */
|
|
||||||
@NonNull private String authorityToMobile(@NonNull String authority) {
|
|
||||||
if (authority.startsWith("m.") || authority.contains(".m.")) {
|
|
||||||
return authority;
|
|
||||||
}
|
|
||||||
return authority.replaceFirst("^" + subdomain() + "\\.?", "$0m.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
269
app/src/main/java/fr/free/nrw/commons/wikidata/model/WikiSite.kt
Normal file
269
app/src/main/java/fr/free/nrw/commons/wikidata/model/WikiSite.kt
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
package fr.free.nrw.commons.wikidata.model
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
|
import android.text.TextUtils
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.CHINESE_CN_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.CHINESE_HK_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.CHINESE_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.CHINESE_MO_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.CHINESE_SG_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.CHINESE_TW_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.NORWEGIAN_BOKMAL_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.NORWEGIAN_LEGACY_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.SIMPLIFIED_CHINESE_LANGUAGE_CODE
|
||||||
|
import fr.free.nrw.commons.language.AppLanguageLookUpTable.Companion.TRADITIONAL_CHINESE_LANGUAGE_CODE
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base URL and Wikipedia language code for a MediaWiki site. Examples:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <lh>Name: scheme / authority / language code</lh>
|
||||||
|
* * English Wikipedia: HTTPS / en.wikipedia.org / en
|
||||||
|
* * Chinese Wikipedia: HTTPS / zh.wikipedia.org / zh-hans or zh-hant
|
||||||
|
* * Meta-Wiki: HTTPS / meta.wikimedia.org / (none)
|
||||||
|
* * Test Wikipedia: HTTPS / test.wikipedia.org / test
|
||||||
|
* * Võro Wikipedia: HTTPS / fiu-vro.wikipedia.org / fiu-vro
|
||||||
|
* * Simple English Wikipedia: HTTPS / simple.wikipedia.org / simple
|
||||||
|
* * Simple English Wikipedia (beta cluster mirror): HTTP / simple.wikipedia.beta.wmflabs.org / simple
|
||||||
|
* * Development: HTTP / 192.168.1.11:8080 / (none)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* **As shown above, the language code or mapping is part of the authority:**
|
||||||
|
*
|
||||||
|
* <lh>Validity: authority / language code</lh>
|
||||||
|
* * Correct: "test.wikipedia.org" / "test"
|
||||||
|
* * Correct: "wikipedia.org", ""
|
||||||
|
* * Correct: "no.wikipedia.org", "nb"
|
||||||
|
* * Incorrect: "wikipedia.org", "test"
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class WikiSite : Parcelable {
|
||||||
|
//TODO: remove @SerializedName. this is now in the TypeAdapter and a "uri" case may be added
|
||||||
|
@SerializedName("domain")
|
||||||
|
private val uri: Uri
|
||||||
|
|
||||||
|
private var languageCode: String? = null
|
||||||
|
|
||||||
|
constructor(uri: Uri) {
|
||||||
|
val tempUri = ensureScheme(uri)
|
||||||
|
var authority = tempUri.authority
|
||||||
|
|
||||||
|
if (authority.isWikipedia && tempUri.path?.startsWith("/wiki") == true) {
|
||||||
|
// Special case for Wikipedia only: assume English subdomain when none given.
|
||||||
|
authority = "en.wikipedia.org"
|
||||||
|
}
|
||||||
|
|
||||||
|
val langVariant = getLanguageVariantFromUri(tempUri)
|
||||||
|
languageCode = if (!TextUtils.isEmpty(langVariant)) {
|
||||||
|
langVariant
|
||||||
|
} else {
|
||||||
|
authorityToLanguageCode(authority!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.uri = Uri.Builder()
|
||||||
|
.scheme(tempUri.scheme)
|
||||||
|
.encodedAuthority(authority)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val String?.isWikipedia: Boolean get() =
|
||||||
|
(this == "wikipedia.org" || this == "www.wikipedia.org")
|
||||||
|
|
||||||
|
/** Get language variant code from a Uri, e.g. "zh-*", otherwise returns empty string. */
|
||||||
|
private fun getLanguageVariantFromUri(uri: Uri): String {
|
||||||
|
if (TextUtils.isEmpty(uri.path)) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
val parts = StringUtils.split(StringUtils.defaultString(uri.path), '/')
|
||||||
|
return if (parts.size > 1 && parts[0] != "wiki") parts[0] else ""
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(url: String) : this(
|
||||||
|
if (url.startsWith("http")) Uri.parse(url) else if (url.startsWith("//"))
|
||||||
|
Uri.parse("$DEFAULT_SCHEME:$url")
|
||||||
|
else
|
||||||
|
Uri.parse("$DEFAULT_SCHEME://$url")
|
||||||
|
)
|
||||||
|
|
||||||
|
constructor(authority: String, languageCode: String) : this(authority) {
|
||||||
|
this.languageCode = languageCode
|
||||||
|
}
|
||||||
|
|
||||||
|
fun scheme(): String =
|
||||||
|
if (TextUtils.isEmpty(uri.scheme)) DEFAULT_SCHEME else uri.scheme!!
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The complete wiki authority including language subdomain but not including scheme,
|
||||||
|
* authentication, port, nor trailing slash.
|
||||||
|
*
|
||||||
|
* @see [URL syntax](https://en.wikipedia.org/wiki/Uniform_Resource_Locator.Syntax)
|
||||||
|
*/
|
||||||
|
fun authority(): String = uri.authority!!
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like [.authority] but with a "m." between the language subdomain and the rest of the host.
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* * English Wikipedia: en.m.wikipedia.org
|
||||||
|
* * Chinese Wikipedia: zh.m.wikipedia.org
|
||||||
|
* * Meta-Wiki: meta.m.wikimedia.org
|
||||||
|
* * Test Wikipedia: test.m.wikipedia.org
|
||||||
|
* * Võro Wikipedia: fiu-vro.m.wikipedia.org
|
||||||
|
* * Simple English Wikipedia: simple.m.wikipedia.org
|
||||||
|
* * Simple English Wikipedia (beta cluster mirror): simple.m.wikipedia.beta.wmflabs.org
|
||||||
|
* * Development: m.192.168.1.11
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
fun mobileAuthority(): String = authorityToMobile(authority())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get wiki's mobile URL
|
||||||
|
* Eg. https://en.m.wikipedia.org
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
fun mobileUrl(): String = String.format("%1\$s://%2\$s", scheme(), mobileAuthority())
|
||||||
|
|
||||||
|
fun subdomain(): String = languageCodeToSubdomain(languageCode!!)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A path without an authority for the segment including a leading "/".
|
||||||
|
*/
|
||||||
|
fun path(segment: String): String = "/w/$segment"
|
||||||
|
|
||||||
|
|
||||||
|
fun uri(): Uri = uri
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The canonical URL. e.g., https://en.wikipedia.org.
|
||||||
|
*/
|
||||||
|
fun url(): String = uri.toString()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The canonical URL for segment. e.g., https://en.wikipedia.org/w/foo.
|
||||||
|
*/
|
||||||
|
fun url(segment: String): String = url() + path(segment)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The wiki language code which may differ from the language subdomain. Empty if
|
||||||
|
* language code is unknown. Ex: "en", "zh-hans", ""
|
||||||
|
*
|
||||||
|
* @see AppLanguageLookUpTable
|
||||||
|
*/
|
||||||
|
fun languageCode(): String = languageCode!!
|
||||||
|
|
||||||
|
// Auto-generated
|
||||||
|
override fun equals(o: Any?): Boolean {
|
||||||
|
if (this === o) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (o == null || javaClass != o.javaClass) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val wiki = o as WikiSite
|
||||||
|
|
||||||
|
if (uri != wiki.uri) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return languageCode == wiki.languageCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-generated
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = uri.hashCode()
|
||||||
|
result = 31 * result + languageCode.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-generated
|
||||||
|
override fun toString(): String {
|
||||||
|
return ("WikiSite{"
|
||||||
|
+ "uri=" + uri
|
||||||
|
+ ", languageCode='" + languageCode + '\''
|
||||||
|
+ '}')
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun describeContents(): Int = 0
|
||||||
|
|
||||||
|
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||||
|
dest.writeParcelable(uri, 0)
|
||||||
|
dest.writeString(languageCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected constructor(`in`: Parcel) {
|
||||||
|
uri = `in`.readParcelable(Uri::class.java.classLoader)!!
|
||||||
|
languageCode = `in`.readString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param authority Host and optional port.
|
||||||
|
*/
|
||||||
|
private fun authorityToMobile(authority: String): String {
|
||||||
|
if (authority.startsWith("m.") || authority.contains(".m.")) {
|
||||||
|
return authority
|
||||||
|
}
|
||||||
|
return authority.replaceFirst(("^" + subdomain() + "\\.?").toRegex(), "$0m.")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val WIKIPEDIA_URL = "https://wikipedia.org/"
|
||||||
|
const val DEFAULT_SCHEME: String = "https"
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val CREATOR: Parcelable.Creator<WikiSite> = object : Parcelable.Creator<WikiSite> {
|
||||||
|
override fun createFromParcel(parcel: Parcel): WikiSite {
|
||||||
|
return WikiSite(parcel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newArray(size: Int): Array<WikiSite?> {
|
||||||
|
return arrayOfNulls(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun forDefaultLocaleLanguageCode(): WikiSite {
|
||||||
|
val languageCode: String = Locale.getDefault().language
|
||||||
|
val subdomain = if (languageCode.isEmpty()) "" else languageCodeToSubdomain(languageCode) + "."
|
||||||
|
val uri = ensureScheme(Uri.parse(WIKIPEDIA_URL))
|
||||||
|
return WikiSite(subdomain + uri.authority, languageCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun languageCodeToSubdomain(languageCode: String): String = when (languageCode) {
|
||||||
|
SIMPLIFIED_CHINESE_LANGUAGE_CODE,
|
||||||
|
TRADITIONAL_CHINESE_LANGUAGE_CODE,
|
||||||
|
CHINESE_CN_LANGUAGE_CODE,
|
||||||
|
CHINESE_HK_LANGUAGE_CODE,
|
||||||
|
CHINESE_MO_LANGUAGE_CODE,
|
||||||
|
CHINESE_SG_LANGUAGE_CODE,
|
||||||
|
CHINESE_TW_LANGUAGE_CODE -> CHINESE_LANGUAGE_CODE
|
||||||
|
|
||||||
|
NORWEGIAN_BOKMAL_LANGUAGE_CODE -> NORWEGIAN_LEGACY_LANGUAGE_CODE // T114042
|
||||||
|
|
||||||
|
else -> languageCode
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun authorityToLanguageCode(authority: String): String {
|
||||||
|
val parts = authority.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||||
|
val minLengthForSubdomain = 3
|
||||||
|
if (parts.size < minLengthForSubdomain || parts.size == minLengthForSubdomain && parts[0] == "m") {
|
||||||
|
// ""
|
||||||
|
// wikipedia.org
|
||||||
|
// m.wikipedia.org
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return parts[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ensureScheme(uri: Uri): Uri {
|
||||||
|
if (TextUtils.isEmpty(uri.scheme)) {
|
||||||
|
return uri.buildUpon().scheme(DEFAULT_SCHEME).build()
|
||||||
|
}
|
||||||
|
return uri
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue