Use JSON SPARQL query for fetching nearby places (#2398)

* Use JSON response for nearby places

* Move okhttp calls to a different class

* wip

* Fetch picture of the day using JSON API

* Search images using JSON APIs

* tests

* Fix injection based on code review comments
This commit is contained in:
Vivek Maskara 2019-02-06 10:40:30 +05:30 committed by Ashish Kumar
parent 323527b3be
commit f12837650a
44 changed files with 1472 additions and 418 deletions

View file

@ -1,9 +1,9 @@
package fr.free.nrw.commons.media;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObserver;
import android.net.Uri;
@ -12,7 +12,6 @@ import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.Html;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
@ -27,7 +26,6 @@ import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
@ -54,8 +52,11 @@ import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.ui.widget.CompatTextView;
import timber.log.Timber;
import fr.free.nrw.commons.utils.DateUtils;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
import static android.content.Context.CLIPBOARD_SERVICE;
import static android.view.View.GONE;
@ -93,6 +94,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
MediaWikiApi mwApi;
@Inject
SessionManager sessionManager;
@Inject
ReasonBuilder reasonBuilder;
private int initialListTop = 0;
@ -404,19 +407,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(spinner);
builder.setTitle(R.string.nominate_delete)
.setPositiveButton(R.string.about_translate_proceed, (dialog, which) -> {
String reason = spinner.getSelectedItem().toString();
ReasonBuilder reasonBuilder = new ReasonBuilder(reason,
getActivity(),
media,
sessionManager,
mwApi);
reason = reasonBuilder.getReason();
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
isDeleted = true;
enableDeleteButton(false);
});
.setPositiveButton(R.string.about_translate_proceed, (dialog, which) -> onDeleteClicked(spinner));
builder.setNegativeButton(R.string.about_translate_cancel, (dialog, which) -> dialog.dismiss());
AlertDialog dialog = builder.create();
dialog.show();
@ -425,6 +416,21 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
}
}
@SuppressLint("CheckResult")
private void onDeleteClicked(Spinner spinner) {
String reason = spinner.getSelectedItem().toString();
Single<String> deletionReason = reasonBuilder.getReason(media, reason);
deletionReason
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
isDeleted = true;
enableDeleteButton(false);
});
}
@OnClick(R.id.seeMore)
public void onSeeMoreClicked(){
if (nominatedForDeletion.getVisibility()== VISIBLE) {

View file

@ -0,0 +1,161 @@
package fr.free.nrw.commons.media.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.gson.annotations.SerializedName;
public class ExtMetadata {
@SuppressWarnings("unused") @SerializedName("DateTime") @Nullable
private Values dateTime;
@SuppressWarnings("unused") @SerializedName("ObjectName") @Nullable private Values objectName;
@SuppressWarnings("unused") @SerializedName("CommonsMetadataExtension") @Nullable private Values commonsMetadataExtension;
@SuppressWarnings("unused") @SerializedName("Categories") @Nullable private Values categories;
@SuppressWarnings("unused") @SerializedName("Assessments") @Nullable private Values assessments;
@SuppressWarnings("unused") @SerializedName("ImageDescription") @Nullable private Values imageDescription;
@SuppressWarnings("unused") @SerializedName("DateTimeOriginal") @Nullable private Values dateTimeOriginal;
@SuppressWarnings("unused") @SerializedName("Artist") @Nullable private Values artist;
@SuppressWarnings("unused") @SerializedName("Credit") @Nullable private Values credit;
@SuppressWarnings("unused") @SerializedName("Permission") @Nullable private Values permission;
@SuppressWarnings("unused") @SerializedName("AuthorCount") @Nullable private Values authorCount;
@SuppressWarnings("unused") @SerializedName("LicenseShortName") @Nullable private Values licenseShortName;
@SuppressWarnings("unused") @SerializedName("UsageTerms") @Nullable private Values usageTerms;
@SuppressWarnings("unused") @SerializedName("LicenseUrl") @Nullable private Values licenseUrl;
@SuppressWarnings("unused") @SerializedName("AttributionRequired") @Nullable private Values attributionRequired;
@SuppressWarnings("unused") @SerializedName("Copyrighted") @Nullable private Values copyrighted;
@SuppressWarnings("unused") @SerializedName("Restrictions") @Nullable private Values restrictions;
@SuppressWarnings("unused") @SerializedName("License") @Nullable private Values license;
@Nullable public Values licenseShortName() {
return licenseShortName;
}
@Nullable public Values licenseUrl() {
return licenseUrl;
}
@Nullable public Values license() {
return license;
}
@Nullable public Values imageDescription() {
return imageDescription;
}
@Nullable
public Values getDateTime() {
return dateTime;
}
@Nullable
public Values getObjectName() {
return objectName;
}
@Nullable
public Values getCommonsMetadataExtension() {
return commonsMetadataExtension;
}
@Nullable
public Values getCategories() {
return categories;
}
@Nullable
public Values getAssessments() {
return assessments;
}
@Nullable
public Values getImageDescription() {
return imageDescription;
}
@Nullable
public Values getDateTimeOriginal() {
return dateTimeOriginal;
}
@Nullable
public Values getArtist() {
return artist;
}
@Nullable
public Values getCredit() {
return credit;
}
@Nullable
public Values getPermission() {
return permission;
}
@Nullable
public Values getAuthorCount() {
return authorCount;
}
@Nullable
public Values getLicenseShortName() {
return licenseShortName;
}
@Nullable
public Values getUsageTerms() {
return usageTerms;
}
@Nullable
public Values getLicenseUrl() {
return licenseUrl;
}
@Nullable
public Values getAttributionRequired() {
return attributionRequired;
}
@Nullable
public Values getCopyrighted() {
return copyrighted;
}
@Nullable
public Values getRestrictions() {
return restrictions;
}
@Nullable
public Values getLicense() {
return license;
}
@Nullable public Values objectName() {
return objectName;
}
@Nullable public Values usageTerms() {
return usageTerms;
}
@Nullable public Values artist() {
return artist;
}
public class Values {
@SuppressWarnings("unused,NullableProblems") @NonNull
private String value;
@SuppressWarnings("unused,NullableProblems") @NonNull private String source;
@SuppressWarnings("unused,NullableProblems") @NonNull private String hidden;
@NonNull public String value() {
return value;
}
@NonNull public String source() {
return source;
}
}
}

View file

@ -0,0 +1,63 @@
package fr.free.nrw.commons.media.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.gson.annotations.SerializedName;
import java.io.Serializable;
import fr.free.nrw.commons.utils.StringUtils;
/**
* Gson POJO for a standard image info object as returned by the API ImageInfo module
*/
public class ImageInfo implements Serializable {
@SuppressWarnings("unused") private int size;
@SuppressWarnings("unused") private int width;
@SuppressWarnings("unused") private int height;
@SuppressWarnings("unused,NullableProblems") @Nullable
private String source;
@SuppressWarnings("unused") @SerializedName("thumburl") @Nullable private String thumbUrl;
@SuppressWarnings("unused") @SerializedName("thumbwidth") private int thumbWidth;
@SuppressWarnings("unused") @SerializedName("thumbheight") private int thumbHeight;
@SuppressWarnings("unused") @SerializedName("url") @Nullable private String originalUrl;
@SuppressWarnings("unused") @SerializedName("descriptionurl") @Nullable private String descriptionUrl;
@SuppressWarnings("unused") @SerializedName("descriptionshorturl") @Nullable private String descriptionShortUrl;
@SuppressWarnings("unused,NullableProblems") @SerializedName("mime") @NonNull
private String mimeType = "*/*";
@SuppressWarnings("unused") @SerializedName("extmetadata")@Nullable private ExtMetadata metadata;
@NonNull
public String getSource() {
return StringUtils.defaultString(source);
}
public void setSource(@Nullable String source) {
this.source = source;
}
public int getSize() {
return size;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
@NonNull public String getThumbUrl() {
return StringUtils.defaultString(thumbUrl);
}
@NonNull public String getOriginalUrl() {
return StringUtils.defaultString(originalUrl);
}
@Nullable public ExtMetadata getMetadata() {
return metadata;
}
}

View file

@ -0,0 +1,292 @@
package fr.free.nrw.commons.media.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.gson.annotations.SerializedName;
import java.util.Collections;
import java.util.List;
import fr.free.nrw.commons.utils.StringUtils;
/**
* A class representing a standard page object as returned by the MediaWiki API.
*/
public class MwQueryPage {
@SuppressWarnings("unused")
private int pageid;
@SuppressWarnings("unused")
private int ns;
@SuppressWarnings("unused")
private int index;
@SuppressWarnings("unused,NullableProblems")
@NonNull
private String title;
@SuppressWarnings("unused")
@Nullable
private List<LangLink> langlinks;
@SuppressWarnings("unused")
@Nullable
private List<Revision> revisions;
@SuppressWarnings("unused")
@Nullable
private List<Coordinates> coordinates;
@SuppressWarnings("unused")
@Nullable
private List<Category> categories;
@SuppressWarnings("unused")
@Nullable
private PageProps pageprops;
@SuppressWarnings("unused")
@Nullable
private String extract;
@SuppressWarnings("unused")
@Nullable
private Thumbnail thumbnail;
@SuppressWarnings("unused")
@Nullable
private String description;
@SuppressWarnings("unused")
@SerializedName("descriptionsource")
@Nullable
private String descriptionSource;
@SuppressWarnings("unused")
@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;
}
public int index() {
return index;
}
@Nullable
public List<LangLink> langLinks() {
return langlinks;
}
@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 PageProps pageProps() {
return pageprops;
}
@Nullable
public String extract() {
return extract;
}
@Nullable
public String thumbUrl() {
return thumbnail != null ? thumbnail.source() : null;
}
@Nullable
public String description() {
return description;
}
@Nullable
public String descriptionSource() {
return descriptionSource;
}
@Nullable
public ImageInfo imageInfo() {
return imageInfo != null ? imageInfo.get(0) : null;
}
@Nullable
public String redirectFrom() {
return redirectFrom;
}
public void redirectFrom(@Nullable String from) {
redirectFrom = from;
}
@Nullable
public String convertedFrom() {
return convertedFrom;
}
public void convertedFrom(@Nullable String from) {
convertedFrom = from;
}
@Nullable
public String convertedTo() {
return convertedTo;
}
public void convertedTo(@Nullable String to) {
convertedTo = to;
}
public void appendTitleFragment(@Nullable String fragment) {
title += "#" + fragment;
}
public static class Revision {
@SuppressWarnings("unused,NullableProblems")
@SerializedName("contentformat")
@NonNull
private String contentFormat;
@SuppressWarnings("unused,NullableProblems")
@SerializedName("contentmodel")
@NonNull
private String contentModel;
@SuppressWarnings("unused,NullableProblems")
@SerializedName("timestamp")
@NonNull
private String timeStamp;
@SuppressWarnings("unused,NullableProblems")
@NonNull
private String content;
@NonNull
public String content() {
return content;
}
@NonNull
public String timeStamp() {
return StringUtils.defaultString(timeStamp);
}
}
public static class LangLink {
@SuppressWarnings("unused,NullableProblems")
@NonNull
private String lang;
@SuppressWarnings("unused,NullableProblems")
@NonNull
private String title;
@NonNull
public String lang() {
return lang;
}
@NonNull
public String title() {
return title;
}
}
public static class Coordinates {
@SuppressWarnings("unused")
@Nullable
private Double lat;
@SuppressWarnings("unused")
@Nullable
private Double lon;
@Nullable
public Double lat() {
return lat;
}
@Nullable
public Double lon() {
return lon;
}
}
static class Thumbnail {
@SuppressWarnings("unused")
private String source;
@SuppressWarnings("unused")
private int width;
@SuppressWarnings("unused")
private int height;
String source() {
return source;
}
}
public static class PageProps {
@SuppressWarnings("unused")
@SerializedName("wikibase_item")
@Nullable
private String wikiBaseItem;
@SuppressWarnings("unused")
@Nullable
private String displaytitle;
@SuppressWarnings("unused")
@Nullable
private String disambiguation;
@Nullable
public String getDisplayTitle() {
return displaytitle;
}
@NonNull
public String getWikiBaseItem() {
return StringUtils.defaultString(wikiBaseItem);
}
public boolean isDisambiguation() {
return disambiguation != null;
}
}
public static class Category {
@SuppressWarnings("unused")
private int ns;
@SuppressWarnings("unused,NullableProblems")
@Nullable
private String title;
@SuppressWarnings("unused")
private boolean hidden;
public int ns() {
return ns;
}
@NonNull
public String title() {
return StringUtils.defaultString(title);
}
public boolean hidden() {
return hidden;
}
}
}