diff --git a/app/src/main/java/fr/free/nrw/commons/Media.java b/app/src/main/java/fr/free/nrw/commons/Media.java
index 773e9d615..a989d782e 100644
--- a/app/src/main/java/fr/free/nrw/commons/Media.java
+++ b/app/src/main/java/fr/free/nrw/commons/Media.java
@@ -3,18 +3,12 @@ package fr.free.nrw.commons;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.room.Entity;
-import androidx.room.PrimaryKey;
-
-import org.apache.commons.lang3.StringUtils;
-import org.wikipedia.dataclient.mwapi.MwQueryPage;
-import org.wikipedia.gallery.ExtMetadata;
-import org.wikipedia.gallery.ImageInfo;
-import org.wikipedia.page.PageTitle;
-
+import fr.free.nrw.commons.location.LatLng;
+import fr.free.nrw.commons.utils.CommonsDateUtil;
+import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
@@ -23,10 +17,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-
-import fr.free.nrw.commons.location.LatLng;
-import fr.free.nrw.commons.utils.CommonsDateUtil;
-import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.wikipedia.dataclient.mwapi.MwQueryPage;
+import org.wikipedia.gallery.ExtMetadata;
+import org.wikipedia.gallery.ImageInfo;
+import org.wikipedia.page.PageTitle;
@Entity
public class Media implements Parcelable {
@@ -90,7 +85,7 @@ public class Media implements Parcelable {
* Ex: key = "en", value: "
"
* key = "de" , value: ""
*/
- public HashMap captions;
+ public Map captions;
public HashMap tags = new HashMap<>();
@Nullable public LatLng coordinates;
@@ -126,7 +121,7 @@ public class Media implements Parcelable {
* @param dateUploaded Media date uploaded
* @param creator Media creator
*/
- public Media(Uri localUri, String imageUrl, String filename, HashMap captions, String description,
+ public Media(Uri localUri, String imageUrl, String filename, Map captions, String description,
long dataLength, Date dateCreated, Date dateUploaded, String creator) {
this();
this.localUri = localUri;
@@ -395,7 +390,7 @@ public class Media implements Parcelable {
*
* returns list of captions stored in hashmap
*/
- public HashMap getCaptions() {
+ public Map getCaptions() {
return captions;
}
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java
index 3b720344b..d9fb42856 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java
@@ -1,29 +1,25 @@
package fr.free.nrw.commons.contributions;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
-
import androidx.annotation.NonNull;
import androidx.annotation.StringDef;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.lang.annotation.Retention;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.filepicker.UploadableFile;
import fr.free.nrw.commons.settings.Prefs;
import fr.free.nrw.commons.utils.ConfigUtils;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
@Entity(tableName = "contribution")
public class Contribution extends Media {
@@ -83,7 +79,7 @@ public class Contribution extends Media {
public Contribution(Uri contentUri, String filename, Uri localUri, String imageUrl, Date dateCreated,
int state, long dataLength, Date dateUploaded, long transferred,
- String source, HashMap captions, String description, String creator, boolean isMultiple,
+ String source, Map captions, String description, String creator, boolean isMultiple,
int width, int height, String license) {
super(localUri, imageUrl, filename, captions, description, dataLength, dateCreated, dateUploaded, creator);
this.contentUri = contentUri;
@@ -97,7 +93,7 @@ public class Contribution extends Media {
this.dateCreatedSource = "";
}
- public Contribution(Uri localUri, String imageUrl, String filename, HashMap captions, String description, long dataLength,
+ public Contribution(Uri localUri, String imageUrl, String filename, Map captions, String description, long dataLength,
Date dateCreated, Date dateUploaded, String creator, String editSummary, ArrayList depictionsEntityIds, String decimalCoords) {
super(localUri, imageUrl, filename, captions, description, dataLength, dateCreated, dateUploaded, creator);
this.decimalCoords = decimalCoords;
@@ -106,7 +102,7 @@ public class Contribution extends Media {
this.depictionsEntityIds = depictionsEntityIds;
}
- public Contribution(Uri localUri, String imageUrl, String filename, HashMap captions, String description, long dataLength,
+ public Contribution(Uri localUri, String imageUrl, String filename, Map captions, String description, long dataLength,
Date dateCreated, Date dateUploaded, String creator, String editSummary, String decimalCoords, int state) {
super(localUri, imageUrl, filename, captions, description, dataLength, dateCreated, dateUploaded, creator);
this.decimalCoords = decimalCoords;
diff --git a/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java b/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java
index f85c69c36..af9111dc5 100644
--- a/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java
+++ b/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.java
@@ -1,24 +1,8 @@
package fr.free.nrw.commons.di;
import android.content.Context;
-
import androidx.annotation.NonNull;
-
import com.google.gson.Gson;
-
-import org.wikipedia.csrf.CsrfTokenClient;
-import org.wikipedia.dataclient.Service;
-import org.wikipedia.dataclient.ServiceFactory;
-import org.wikipedia.dataclient.WikiSite;
-import org.wikipedia.json.GsonUtil;
-import org.wikipedia.login.LoginClient;
-
-import java.io.File;
-import java.util.concurrent.TimeUnit;
-
-import javax.inject.Named;
-import javax.inject.Singleton;
-
import dagger.Module;
import dagger.Provides;
import fr.free.nrw.commons.BuildConfig;
@@ -32,14 +16,25 @@ import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import fr.free.nrw.commons.mwapi.UserInterface;
import fr.free.nrw.commons.review.ReviewInterface;
import fr.free.nrw.commons.upload.UploadInterface;
-import fr.free.nrw.commons.wikidata.WikidataInterface;
import fr.free.nrw.commons.upload.WikiBaseInterface;
import fr.free.nrw.commons.upload.depicts.DepictsInterface;
import fr.free.nrw.commons.upload.mediaDetails.CaptionInterface;
+import fr.free.nrw.commons.wikidata.WikidataInterface;
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+import javax.inject.Named;
+import javax.inject.Singleton;
import okhttp3.Cache;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
+import okhttp3.logging.HttpLoggingInterceptor.Level;
+import org.wikipedia.csrf.CsrfTokenClient;
+import org.wikipedia.dataclient.Service;
+import org.wikipedia.dataclient.ServiceFactory;
+import org.wikipedia.dataclient.WikiSite;
+import org.wikipedia.json.GsonUtil;
+import org.wikipedia.login.LoginClient;
import timber.log.Timber;
@Module
@@ -76,7 +71,7 @@ public class NetworkingModule {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(message -> {
Timber.tag("OkHttp").v(message);
});
- httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
+ httpLoggingInterceptor.level(BuildConfig.DEBUG ? Level.BODY: HttpLoggingInterceptor.Level.BASIC);
return httpLoggingInterceptor;
}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java
index cb72c80a9..1a5f5ae81 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java
@@ -13,17 +13,8 @@ import android.net.Uri;
import android.os.IBinder;
import android.provider.MediaStore;
import android.text.TextUtils;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
import fr.free.nrw.commons.HandlerService;
+import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.contributions.Contribution;
@@ -34,23 +25,26 @@ import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import timber.log.Timber;
@Singleton
public class UploadController {
private UploadService uploadService;
- private SessionManager sessionManager;
- private Context context;
- private JsonKvStore store;
-
- public interface ContributionUploadProgress {
- void onUploadStarted(Contribution contribution);
- }
+ private final SessionManager sessionManager;
+ private final Context context;
+ private final JsonKvStore store;
@Inject
- public UploadController(SessionManager sessionManager,
- Context context,
- JsonKvStore store) {
+ public UploadController(final SessionManager sessionManager,
+ final Context context,
+ final JsonKvStore store) {
this.sessionManager = sessionManager;
this.context = context;
this.store = store;
@@ -59,13 +53,13 @@ public class UploadController {
private boolean isUploadServiceConnected;
public ServiceConnection uploadServiceConnection = new ServiceConnection() {
@Override
- public void onServiceConnected(ComponentName componentName, IBinder binder) {
+ public void onServiceConnected(final ComponentName componentName, final IBinder binder) {
uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder) binder).getService();
isUploadServiceConnected = true;
}
@Override
- public void onServiceDisconnected(ComponentName componentName) {
+ public void onServiceDisconnected(final ComponentName componentName) {
// this should never happen
isUploadServiceConnected = false;
Timber.e(new RuntimeException("UploadService died but the rest of the process did not!"));
@@ -76,7 +70,7 @@ public class UploadController {
* Prepares the upload service.
*/
public void prepareService() {
- Intent uploadServiceIntent = new Intent(context, UploadService.class);
+ final Intent uploadServiceIntent = new Intent(context, UploadService.class);
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
context.startService(uploadServiceIntent);
context.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE);
@@ -96,28 +90,18 @@ public class UploadController {
*
* @param contribution the contribution object
*/
- public void startUpload(Contribution contribution) {
- startUpload(contribution, c -> {});
- }
-
- /**
- * Starts a new upload task.
- *
- * @param contribution the contribution object
- * @param onComplete the progress tracker
- */
@SuppressLint("StaticFieldLeak")
- private void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) {
+ public void startUpload(final Contribution contribution) {
//Set creator, desc, and license
// If author name is enabled and set, use it
if (store.getBoolean("useAuthorName", false)) {
- String authorName = store.getString("authorName", "");
+ final String authorName = store.getString("authorName", "");
contribution.setCreator(authorName);
}
if (TextUtils.isEmpty(contribution.getCreator())) {
- Account currentAccount = sessionManager.getCurrentAccount();
+ final Account currentAccount = sessionManager.getCurrentAccount();
if (currentAccount == null) {
Timber.d("Current account is null");
ViewUtil.showLongToast(context, context.getString(R.string.user_not_logged_in));
@@ -135,23 +119,23 @@ public class UploadController {
contribution.setCaption("");
}
- String license = store.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3);
+ final String license = store.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3);
contribution.setLicense(license);
- uploadTask(contribution, onComplete);
+ uploadTask(contribution);
}
/**
* Initiates the upload task
* @param contribution
- * @param onComplete
* @return
*/
- private Disposable uploadTask(Contribution contribution, ContributionUploadProgress onComplete) {
- return Single.fromCallable(() -> makeUpload(contribution))
+ private Disposable uploadTask(final Contribution contribution) {
+ return Single.just(contribution)
+ .map(this::buildUpload)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(finalContribution -> onUploadCompleted(finalContribution, onComplete));
+ .subscribe(this::upload);
}
/**
@@ -159,71 +143,76 @@ public class UploadController {
* @param contribution
* @return
*/
- private Contribution makeUpload(Contribution contribution) {
- long length;
- ContentResolver contentResolver = context.getContentResolver();
+ private Contribution buildUpload(final Contribution contribution) {
+ final ContentResolver contentResolver = context.getContentResolver();
+
+ contribution.setDataLength(resolveDataLength(contentResolver, contribution));
+
+ final String mimeType = resolveMimeType(contentResolver, contribution);
+
+ if (mimeType != null) {
+ Timber.d("MimeType is: %s", mimeType);
+ contribution.setTag("mimeType", mimeType);
+ if(mimeType.startsWith("image/") && contribution.getDateCreated() == null){
+ contribution.setDateCreated(resolveDateTakenOrNow(contentResolver, contribution));
+ }
+ }
+
+ return contribution;
+ }
+
+ private String resolveMimeType(final ContentResolver contentResolver, final Contribution contribution) {
+ final String mimeType = (String) contribution.getTag("mimeType");
+ if (mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) {
+ return contentResolver.getType(contribution.getLocalUri());
+ }
+ return mimeType;
+ }
+
+ private long resolveDataLength(final ContentResolver contentResolver, final Media contribution) {
try {
if (contribution.getDataLength() <= 0) {
Timber.d("UploadController/doInBackground, contribution.getLocalUri():%s", contribution.getLocalUri());
- AssetFileDescriptor assetFileDescriptor = contentResolver
- .openAssetFileDescriptor(Uri.fromFile(new File(contribution.getLocalUri().getPath())), "r");
+ final AssetFileDescriptor assetFileDescriptor = contentResolver
+ .openAssetFileDescriptor(Uri.fromFile(new File(contribution.getLocalUri().getPath())), "r");
if (assetFileDescriptor != null) {
- length = assetFileDescriptor.getLength();
- if (length == -1) {
- // Let us find out the long way!
- length = countBytes(contentResolver
- .openInputStream(contribution.getLocalUri()));
- }
- contribution.setDataLength(length);
+ final long length = assetFileDescriptor.getLength();
+ return length != -1 ? length
+ : countBytes(contentResolver.openInputStream(contribution.getLocalUri()));
}
}
- } catch (IOException | NullPointerException | SecurityException e) {
+ } catch (final IOException | NullPointerException | SecurityException e) {
Timber.e(e, "Exception occurred while uploading image");
}
+ return contribution.getDataLength();
+ }
- String mimeType = (String) contribution.getTag("mimeType");
- boolean imagePrefix = false;
-
- if (mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) {
- mimeType = contentResolver.getType(contribution.getLocalUri());
- }
-
- if (mimeType != null) {
- contribution.setTag("mimeType", mimeType);
- imagePrefix = mimeType.startsWith("image/");
- Timber.d("MimeType is: %s", mimeType);
- }
-
- if (imagePrefix && contribution.getDateCreated() == null) {
- Timber.d("local uri %s", contribution.getLocalUri());
- Cursor cursor = contentResolver.query(contribution.getLocalUri(),
- new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null);
+ private Date resolveDateTakenOrNow(final ContentResolver contentResolver, final Media contribution) {
+ Timber.d("local uri %s", contribution.getLocalUri());
+ try(final Cursor cursor = dateTakenCursor(contentResolver, contribution)) {
if (cursor != null && cursor.getCount() != 0 && cursor.getColumnCount() != 0) {
cursor.moveToFirst();
- Date dateCreated = new Date(cursor.getLong(0));
- Date epochStart = new Date(0);
- if (dateCreated.equals(epochStart) || dateCreated.before(epochStart)) {
- // If date is incorrect (1st second of unix time) then set it to the current date
- dateCreated = new Date();
+ final Date dateCreated = new Date(cursor.getLong(0));
+ if (dateCreated.after(new Date(0))) {
+ return dateCreated;
}
- contribution.setDateCreated(dateCreated);
- cursor.close();
- } else {
- contribution.setDateCreated(new Date());
}
+ return new Date();
}
- return contribution;
+ }
+
+ private Cursor dateTakenCursor(final ContentResolver contentResolver, final Media contribution) {
+ return contentResolver.query(contribution.getLocalUri(),
+ new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null);
}
/**
* When the contribution object is completely formed, the item is queued to the upload service
* @param contribution
- * @param onComplete
*/
- private void onUploadCompleted(Contribution contribution, ContributionUploadProgress onComplete) {
+ private void upload(final Contribution contribution) {
//Starts the upload. If commented out, user can proceed to next Fragment but upload doesn't happen
uploadService.queue(UploadService.ACTION_UPLOAD_FILE, contribution);
- onComplete.onUploadStarted(contribution);
}
@@ -234,9 +223,9 @@ public class UploadController {
* @return the number of bytes in {@code stream}
* @throws IOException if an I/O error occurs
*/
- private long countBytes(InputStream stream) throws IOException {
+ private long countBytes(final InputStream stream) throws IOException {
long count = 0;
- BufferedInputStream bis = new BufferedInputStream(stream);
+ final BufferedInputStream bis = new BufferedInputStream(stream);
while (bis.read() != -1) {
count++;
}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetail.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetail.java
deleted file mode 100644
index e54720b2a..000000000
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetail.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package fr.free.nrw.commons.upload;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import timber.log.Timber;
-
-/**
- * Holds a description of an item being uploaded by {@link UploadActivity}
- */
-public class UploadMediaDetail {
-
- private String languageCode;
- private String descriptionText;
- public String captionText;
- private int selectedLanguageIndex = -1;
- private boolean isManuallyAdded=false;
-
- /**
- * Formatting captions to the Wikibase format for sending labels
- * @param uploadMediaDetails list of media Details
- */
-
- public static HashMap formatCaptions(List uploadMediaDetails) {
- HashMap caption = new HashMap<>();
- for (UploadMediaDetail uploadMediaDetail : uploadMediaDetails) {
- caption.put(uploadMediaDetail.getLanguageCode(),uploadMediaDetail.getCaptionText());
- }
- return caption;
- }
-
- public String getCaptionText() {
- return captionText;
- }
-
- public void setCaptionText(String captionText) {
- this.captionText = captionText;
- }
-
- /**
- * @return The language code ie. "en" or "fr"
- */
- String getLanguageCode() {
- return languageCode;
- }
-
- /**
- * @param languageCode The language code ie. "en" or "fr"
- */
- public void setLanguageCode(String languageCode) {
- this.languageCode = languageCode;
- }
-
- String getDescriptionText() {
- return descriptionText;
- }
-
- public void setDescriptionText(String descriptionText) {
- this.descriptionText = descriptionText;
- }
-
- /**
- * @return the index of the language selected in a spinner with {@link SpinnerLanguagesAdapter}
- */
- int getSelectedLanguageIndex() {
- return selectedLanguageIndex;
- }
-
- /**
- * @param selectedLanguageIndex the index of the language selected in a spinner with {@link SpinnerLanguagesAdapter}
- */
- void setSelectedLanguageIndex(int selectedLanguageIndex) {
- this.selectedLanguageIndex = selectedLanguageIndex;
- }
-
- /**
- * returns if the description was added manually (by the user, or we have added it programaticallly)
- * @return
- */
- public boolean isManuallyAdded() {
- return isManuallyAdded;
- }
-
- /**
- * sets to true if the description was manually added by the user
- * @param manuallyAdded
- */
- public void setManuallyAdded(boolean manuallyAdded) {
- isManuallyAdded = manuallyAdded;
- }
-
- /**
- * Formats the list of descriptions into the format Commons requires for uploads.
- *
- * @param descriptions the list of descriptions, description is ignored if text is null.
- * @return a string with the pattern of {{en|1=descriptionText}}
- */
- static String formatList(List descriptions) {
- StringBuilder descListString = new StringBuilder();
- for (UploadMediaDetail description : descriptions) {
- if (!description.isEmpty()) {
- String individualDescription = String.format("{{%s|1=%s}}", description.getLanguageCode(),
- description.getDescriptionText());
- descListString.append(individualDescription);
- }
- }
- return descListString.toString();
- }
-
- public boolean isEmpty() {
- return descriptionText == null || descriptionText.isEmpty();
- }
-}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetail.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetail.kt
new file mode 100644
index 000000000..08ad2b841
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetail.kt
@@ -0,0 +1,66 @@
+package fr.free.nrw.commons.upload
+
+import fr.free.nrw.commons.nearby.Place
+import java.util.*
+
+/**
+ * Holds a description of an item being uploaded by [UploadActivity]
+ */
+data class UploadMediaDetail constructor(
+ /**
+ * @return The language code ie. "en" or "fr"
+ */
+ /**
+ * @param languageCode The language code ie. "en" or "fr"
+ */
+ var languageCode: String? = null,
+ var descriptionText: String = "",
+ var captionText: String = ""
+) {
+ constructor(place: Place) : this(
+ Locale.getDefault().language,
+ place.longDescription,
+ place.name
+ )
+ /**
+ * @return the index of the language selected in a spinner with [SpinnerLanguagesAdapter]
+ */
+ /**
+ * @param selectedLanguageIndex the index of the language selected in a spinner with [SpinnerLanguagesAdapter]
+ */
+ var selectedLanguageIndex: Int = -1
+ /**
+ * returns if the description was added manually (by the user, or we have added it programaticallly)
+ * @return
+ */
+ /**
+ * sets to true if the description was manually added by the user
+ * @param manuallyAdded
+ */
+ var isManuallyAdded: Boolean = false
+
+ companion object {
+ /**
+ * Formatting captions to the Wikibase format for sending labels
+ * @param uploadMediaDetails list of media Details
+ */
+ @JvmStatic
+ fun formatCaptions(uploadMediaDetails: List) =
+ uploadMediaDetails.associate { it.languageCode to it.captionText }
+
+ /**
+ * Formats the list of descriptions into the format Commons requires for uploads.
+ *
+ * @param descriptions the list of descriptions, description is ignored if text is null.
+ * @return a string with the pattern of {{en|1=descriptionText}}
+ */
+ @JvmStatic
+ fun formatList(descriptions: List) =
+ descriptions.joinToString {
+ if (it.descriptionText.isNotEmpty())
+ "{{${it.languageCode}|1=${it.descriptionText}}}"
+ else
+ ""
+ }
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetailAdapter.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetailAdapter.java
index 26461aa4c..e1324cbd3 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetailAdapter.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadMediaDetailAdapter.java
@@ -2,9 +2,7 @@ package fr.free.nrw.commons.upload;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.text.Editable;
import android.text.TextUtils;
-import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -107,36 +105,11 @@ public class UploadMediaDetailAdapter extends RecyclerView.Adapter eventListener.onEvent(value.length() != 0)) );
if (position == 0) {
captionItemEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, getInfoIcon(),
@@ -174,13 +147,11 @@ public class UploadMediaDetailAdapter extends RecyclerView.Adapter uploadMediaDetails.get(position)
- .setCaptionText(captionText)));
+ captionText -> uploadMediaDetails.get(position).setCaptionText(captionText)));
initLanguageSpinner(position, uploadMediaDetail);
descItemEditText.addTextChangedListener(new AbstractTextWatcher(
- descriptionText -> uploadMediaDetails.get(position)
- .setDescriptionText(descriptionText)));
+ descriptionText -> uploadMediaDetails.get(position).setDescriptionText(descriptionText)));
initLanguageSpinner(position, uploadMediaDetail);
//If the description was manually added by the user, it deserves focus, if not, let the user decide
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java
index a87277507..0f84da7fb 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java
@@ -7,7 +7,6 @@ import androidx.annotation.Nullable;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.contributions.Contribution;
-import fr.free.nrw.commons.filepicker.MimeTypeMapWrapper;
import fr.free.nrw.commons.filepicker.UploadableFile;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.nearby.Place;
@@ -18,15 +17,17 @@ import io.reactivex.Single;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.subjects.BehaviorSubject;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import org.jetbrains.annotations.NotNull;
import timber.log.Timber;
@Singleton
@@ -37,23 +38,23 @@ public class UploadModel {
private final Context context;
private String license;
private final Map licensesByName;
- private List items = new ArrayList<>();
- private CompositeDisposable compositeDisposable = new CompositeDisposable();
+ private final List items = new ArrayList<>();
+ private final CompositeDisposable compositeDisposable = new CompositeDisposable();
- private SessionManager sessionManager;
- private FileProcessor fileProcessor;
+ private final SessionManager sessionManager;
+ private final FileProcessor fileProcessor;
private final ImageProcessingService imageProcessingService;
private List selectedCategories;
private ArrayList selectedDepictions;
@Inject
- UploadModel(@Named("licenses") List licenses,
- @Named("default_preferences") JsonKvStore store,
- @Named("licenses_by_name") Map licensesByName,
- Context context,
- SessionManager sessionManager,
- FileProcessor fileProcessor,
- ImageProcessingService imageProcessingService) {
+ UploadModel(@Named("licenses") final List licenses,
+ @Named("default_preferences") final JsonKvStore store,
+ @Named("licenses_by_name") final Map licensesByName,
+ final Context context,
+ final SessionManager sessionManager,
+ final FileProcessor fileProcessor,
+ final ImageProcessingService imageProcessingService) {
this.licenses = licenses;
this.store = store;
this.license = store.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3);
@@ -80,31 +81,29 @@ public class UploadModel {
}
public void setSelectedCategories(List selectedCategories) {
- if (null == selectedCategories) {
- selectedCategories = new ArrayList<>();
- }
- this.selectedCategories = selectedCategories;
+ this.selectedCategories = newListOf(selectedCategories);
}
/**
* pre process a one item at a time
*/
- public Observable preProcessImage(UploadableFile uploadableFile,
- Place place,
- String source,
- SimilarImageInterface similarImageInterface) {
- return Observable.just(getUploadItem(uploadableFile, place, source, similarImageInterface));
+ public Observable preProcessImage(final UploadableFile uploadableFile,
+ final Place place,
+ final String source,
+ final SimilarImageInterface similarImageInterface) {
+ return Observable.just(
+ createAndAddUploadItem(uploadableFile, place, source, similarImageInterface));
}
- public Single getImageQuality(UploadItem uploadItem) {
+ public Single getImageQuality(final UploadItem uploadItem) {
return imageProcessingService.validateImage(uploadItem);
}
- private UploadItem getUploadItem(UploadableFile uploadableFile,
- Place place,
- String source,
- SimilarImageInterface similarImageInterface) {
- UploadableFile.DateTimeWithSource dateTimeWithSource = uploadableFile
+ private UploadItem createAndAddUploadItem(final UploadableFile uploadableFile,
+ final Place place,
+ final String source,
+ final SimilarImageInterface similarImageInterface) {
+ final UploadableFile.DateTimeWithSource dateTimeWithSource = uploadableFile
.getFileCreatedDate(context);
long fileCreatedDate = -1;
String createdTimestampSource = "";
@@ -113,23 +112,15 @@ public class UploadModel {
createdTimestampSource = dateTimeWithSource.getSource();
}
Timber.d("File created date is %d", fileCreatedDate);
- ImageCoordinates imageCoordinates = fileProcessor
+ final ImageCoordinates imageCoordinates = fileProcessor
.processFileCoordinates(similarImageInterface, uploadableFile.getFilePath());
- UploadItem uploadItem = new UploadItem(uploadableFile.getContentUri(),
+ final UploadItem uploadItem = new UploadItem(uploadableFile.getContentUri(),
Uri.parse(uploadableFile.getFilePath()),
uploadableFile.getMimeType(context), source, imageCoordinates, place, fileCreatedDate,
createdTimestampSource);
if (place != null) {
uploadItem.title.setTitleText(place.name);
- if(uploadItem.uploadMediaDetails.isEmpty()) {
- uploadItem.uploadMediaDetails.add(new UploadMediaDetail());
- }
- uploadItem.uploadMediaDetails.get(0).setDescriptionText(place.getLongDescription());
- uploadItem.uploadMediaDetails.get(0).setLanguageCode("en");
- String languageCode = Locale.getDefault().getLanguage();
- uploadItem.uploadMediaDetails.get(0).setDescriptionText(place.getLongDescription());
- uploadItem.uploadMediaDetails.get(0).setLanguageCode(languageCode);
- uploadItem.uploadMediaDetails.get(0).setCaptionText(place.name);
+ uploadItem.getUploadMediaDetails().set(0, new UploadMediaDetail(place));
}
if (!items.contains(uploadItem)) {
items.add(uploadItem);
@@ -153,7 +144,7 @@ public class UploadModel {
return license;
}
- public void setSelectedLicense(String licenseName) {
+ public void setSelectedLicense(final String licenseName) {
this.license = licensesByName.get(licenseName);
store.putString(Prefs.DEFAULT_LICENSE, license);
}
@@ -161,11 +152,11 @@ public class UploadModel {
public Observable buildContributions() {
return Observable.fromIterable(items).map(item ->
{
- Contribution contribution = new Contribution(item.mediaUri, null,
+ final Contribution contribution = new Contribution(item.mediaUri, null,
item.getFileName(), item.uploadMediaDetails.size()!=0? UploadMediaDetail.formatCaptions(item.uploadMediaDetails):new HashMap<>(),
UploadMediaDetail.formatList(item.uploadMediaDetails), -1,
null, null, sessionManager.getAuthorName(),
- CommonsApplication.DEFAULT_EDIT_SUMMARY, selectedDepictions, item.gpsCoords.getDecimalCoords());
+ CommonsApplication.DEFAULT_EDIT_SUMMARY, new ArrayList<>(selectedDepictions), item.gpsCoords.getDecimalCoords());
if (item.place != null) {
contribution.setWikiDataEntityId(item.place.getWikiDataEntityId());
contribution.setWikiItemName(item.place.getName());
@@ -196,8 +187,8 @@ public class UploadModel {
});
}
- public void deletePicture(String filePath) {
- Iterator iterator = items.iterator();
+ public void deletePicture(final String filePath) {
+ final Iterator iterator = items.iterator();
while (iterator.hasNext()) {
if (iterator.next().mediaUri.toString().contains(filePath)) {
iterator.remove();
@@ -213,20 +204,22 @@ public class UploadModel {
return items;
}
- public void updateUploadItem(int index, UploadItem uploadItem) {
- UploadItem uploadItem1 = items.get(index);
+ public void updateUploadItem(final int index, final UploadItem uploadItem) {
+ final UploadItem uploadItem1 = items.get(index);
uploadItem1.setMediaDetails(uploadItem.uploadMediaDetails);
uploadItem1.setTitle(uploadItem.title);
}
- public void setSelectedDepictions(List selectedDepictions) {
- if (null == selectedDepictions) {
- selectedDepictions = new ArrayList<>();
- }
- this.selectedDepictions = (ArrayList) selectedDepictions;
+ public void setSelectedDepictions(final List selectedDepictions) {
+ this.selectedDepictions = newListOf(selectedDepictions);
}
- public void useSimilarPictureCoordinates(ImageCoordinates imageCoordinates, int uploadItemIndex) {
+ @NotNull
+ private ArrayList newListOf(final List items) {
+ return items != null ? new ArrayList<>(items) : new ArrayList<>();
+ }
+
+ public void useSimilarPictureCoordinates(final ImageCoordinates imageCoordinates, final int uploadItemIndex) {
fileProcessor.useImageCoords(imageCoordinates);
items.get(uploadItemIndex).setGpsCoords(imageCoordinates);
}
@@ -239,29 +232,23 @@ public class UploadModel {
private final String mimeType;
private final String source;
private ImageCoordinates gpsCoords;
-
- public void setGpsCoords(ImageCoordinates gpsCoords) {
- this.gpsCoords = gpsCoords;
- }
-
private Title title;
private List uploadMediaDetails;
- private Place place;
- private long createdTimestamp;
- private String createdTimestampSource;
- private BehaviorSubject imageQuality;
-
+ private final Place place;
+ private final long createdTimestamp;
+ private final String createdTimestampSource;
+ private final BehaviorSubject imageQuality;
@SuppressLint("CheckResult")
- UploadItem(Uri originalContentUri,
- Uri mediaUri, String mimeType, String source, ImageCoordinates gpsCoords,
- Place place,
- long createdTimestamp,
- String createdTimestampSource) {
+ UploadItem(final Uri originalContentUri,
+ final Uri mediaUri, final String mimeType, final String source, final ImageCoordinates gpsCoords,
+ final Place place,
+ final long createdTimestamp,
+ final String createdTimestampSource) {
this.originalContentUri = originalContentUri;
this.createdTimestampSource = createdTimestampSource;
title = new Title();
- uploadMediaDetails = new ArrayList<>();
- uploadMediaDetails.add(new UploadMediaDetail());
+ uploadMediaDetails = Collections.singletonList(new UploadMediaDetail());
+ uploadMediaDetails = new ArrayList<>(Arrays.asList(new UploadMediaDetail()));
this.place = place;
this.mediaUri = mediaUri;
this.mimeType = mimeType;
@@ -303,7 +290,7 @@ public class UploadModel {
return this.imageQuality.getValue();
}
- public void setImageQuality(int imageQuality) {
+ public void setImageQuality(final int imageQuality) {
this.imageQuality.onNext(imageQuality);
}
@@ -311,12 +298,12 @@ public class UploadModel {
return place;
}
- public void setTitle(Title title) {
+ public void setTitle(final Title title) {
this.title = title;
}
- public void setMediaDetails(List uploadMediaDetails) {
+ public void setMediaDetails(final List uploadMediaDetails) {
this.uploadMediaDetails = uploadMediaDetails;
}
@@ -325,7 +312,7 @@ public class UploadModel {
}
@Override
- public boolean equals(@Nullable Object obj) {
+ public boolean equals(@Nullable final Object obj) {
if (!(obj instanceof UploadItem)) {
return false;
}
@@ -345,6 +332,10 @@ public class UploadModel {
public String getFileName() {
return uploadMediaDetails.get(0).getCaptionText();
}
- }
+ public void setGpsCoords(final ImageCoordinates gpsCoords) {
+ this.gpsCoords = gpsCoords;
+ }
+
+ }
}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
index 0378f7bda..09e13eb9a 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
@@ -13,6 +13,7 @@ import androidx.core.app.NotificationManagerCompat;
import java.io.File;
import java.io.IOException;
+import java.text.ParseException;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
@@ -35,18 +36,8 @@ import fr.free.nrw.commons.utils.CommonsDateUtil;
import fr.free.nrw.commons.wikidata.WikidataEditService;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
-import io.reactivex.SingleObserver;
import io.reactivex.disposables.CompositeDisposable;
-import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
-import java.io.File;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.inject.Inject;
import timber.log.Timber;
public class UploadService extends HandlerService {
@@ -275,55 +266,59 @@ public class UploadService extends HandlerService {
uploadStash.getFilekey());
}
})
- .subscribe(uploadResult -> {
- Timber.d("Stash upload response 2 is %s", uploadResult.toString());
-
- notificationManager.cancel(notificationTag, NOTIFICATION_UPLOAD_IN_PROGRESS);
-
- String resultStatus = uploadResult.getResult();
- if (!resultStatus.equals("Success")) {
- Timber.d("Contribution upload failed. Wikidata entity won't be edited");
- showFailedNotification(contribution);
- } else {
- String canonicalFilename = "File:" + uploadResult.getFilename();
- final String wikiDataEntityId = contribution.getWikiDataEntityId();
- Timber.d("Contribution upload success. Initiating Wikidata edit for entity id %s",
- wikiDataEntityId);
- // to perform upload of depictions we pass on depiction entityId of the selected depictions to the wikidataEditService
- final String p18Value = contribution.getP18Value();
- final String wikiItemName = contribution.getWikiItemName();
- if (contribution.getDepictionsEntityIds() != null) {
- for (String depictionEntityId : contribution.getDepictionsEntityIds()) {
- wikidataEditService.createClaimWithLogging(depictionEntityId,
- wikiItemName, canonicalFilename, p18Value);
- }
- }
- Timber.d("Contribution upload success. Initiating Wikidata edit for"
- + " entity id %s if necessary (if P18 is null). P18 value is %s",
- wikiDataEntityId, p18Value);
- wikidataEditService.createClaimWithLogging(
- wikiDataEntityId, wikiItemName, canonicalFilename,p18Value);
-
- wikidataEditService.createLabelforWikidataEntity(
- wikiDataEntityId, canonicalFilename, contribution.getCaptions());
- contribution.setFilename(canonicalFilename);
- contribution.setImageUrl(uploadResult.getImageinfo().getOriginalUrl());
- contribution.setState(Contribution.STATE_COMPLETED);
- contribution.setDateUploaded(CommonsDateUtil.getIso8601DateFormatShort()
- .parse(uploadResult.getImageinfo().getTimestamp()));
- compositeDisposable.add(contributionDao
- .save(contribution)
- .subscribeOn(ioThreadScheduler)
- .observeOn(mainThreadScheduler)
- .subscribe());
- }
- }, throwable -> {
+ .subscribe(
+ uploadResult -> onUpload(contribution, notificationTag, uploadResult),
+ throwable -> {
Timber.w(throwable, "Exception during upload");
notificationManager.cancel(notificationTag, NOTIFICATION_UPLOAD_IN_PROGRESS);
showFailedNotification(contribution);
});
}
+ private void onUpload(Contribution contribution, String notificationTag,
+ UploadResult uploadResult) throws ParseException {
+ Timber.d("Stash upload response 2 is %s", uploadResult.toString());
+
+ notificationManager.cancel(notificationTag, NOTIFICATION_UPLOAD_IN_PROGRESS);
+
+ String resultStatus = uploadResult.getResult();
+ if (!resultStatus.equals("Success")) {
+ Timber.d("Contribution upload failed. Wikidata entity won't be edited");
+ showFailedNotification(contribution);
+ } else {
+ String canonicalFilename = "File:" + uploadResult.getFilename();
+ final String wikiDataEntityId = contribution.getWikiDataEntityId();
+ Timber.d("Contribution upload success. Initiating Wikidata edit for entity id %s",
+ wikiDataEntityId);
+ // to perform upload of depictions we pass on depiction entityId of the selected depictions to the wikidataEditService
+ final String p18Value = contribution.getP18Value();
+ final String wikiItemName = contribution.getWikiItemName();
+ if (contribution.getDepictionsEntityIds() != null) {
+ for (String depictionEntityId : contribution.getDepictionsEntityIds()) {
+ wikidataEditService.createClaimWithLogging(depictionEntityId,
+ wikiItemName, canonicalFilename, p18Value);
+ }
+ }
+ Timber.d("Contribution upload success. Initiating Wikidata edit for"
+ + " entity id %s if necessary (if P18 is null). P18 value is %s",
+ wikiDataEntityId, p18Value);
+ wikidataEditService.createClaimWithLogging(
+ wikiDataEntityId, wikiItemName, canonicalFilename,p18Value);
+
+ wikidataEditService.createLabelforWikidataEntity(canonicalFilename, contribution.getCaptions());
+ contribution.setFilename(canonicalFilename);
+ contribution.setImageUrl(uploadResult.getImageinfo().getOriginalUrl());
+ contribution.setState(Contribution.STATE_COMPLETED);
+ contribution.setDateUploaded(CommonsDateUtil.getIso8601DateFormatShort()
+ .parse(uploadResult.getImageinfo().getTimestamp()));
+ compositeDisposable.add(contributionDao
+ .save(contribution)
+ .subscribeOn(ioThreadScheduler)
+ .observeOn(mainThreadScheduler)
+ .subscribe());
+ }
+ }
+
@SuppressLint("StringFormatInvalid")
@SuppressWarnings("deprecation")
private void showFailedNotification(Contribution contribution) {
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java
index 5d7a45785..4ab51a3b6 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java
@@ -32,14 +32,12 @@ import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.settings.Prefs;
-import fr.free.nrw.commons.upload.Description;
-//import fr.free.nrw.commons.upload.DescriptionsAdapter;
-import fr.free.nrw.commons.upload.UploadMediaDetail;
-import fr.free.nrw.commons.upload.UploadMediaDetailAdapter;
import fr.free.nrw.commons.upload.ImageCoordinates;
import fr.free.nrw.commons.upload.SimilarImageDialogFragment;
import fr.free.nrw.commons.upload.Title;
import fr.free.nrw.commons.upload.UploadBaseFragment;
+import fr.free.nrw.commons.upload.UploadMediaDetail;
+import fr.free.nrw.commons.upload.UploadMediaDetailAdapter;
import fr.free.nrw.commons.upload.UploadModel;
import fr.free.nrw.commons.upload.UploadModel.UploadItem;
import fr.free.nrw.commons.utils.DialogUtil;
@@ -55,6 +53,8 @@ import javax.inject.Named;
import org.apache.commons.lang3.StringUtils;
import timber.log.Timber;
+//import fr.free.nrw.commons.upload.DescriptionsAdapter;
+
public class UploadMediaDetailFragment extends UploadBaseFragment implements
UploadMediaDetailsContract.View, UploadMediaDetailAdapter.EventListener {
@@ -282,10 +282,6 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
@Override
public void onImageProcessed(UploadItem uploadItem, Place place) {
this.uploadItem = uploadItem;
- if (uploadItem.getFileName() != null) {
- setDescriptionsInAdapter(uploadItem.getUploadMediaDetails());
- }
-
descriptions = uploadItem.getUploadMediaDetails();
photoViewBackgroundImage.setImageURI(uploadItem.getMediaUri());
setDescriptionsInAdapter(descriptions);
@@ -306,10 +302,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
place.getName()),
() -> {
etTitle.setText(place.getName());
- UploadMediaDetail description = new UploadMediaDetail();
- description.setLanguageCode("en");
- description.setDescriptionText(place.getLongDescription());
- descriptions = Arrays.asList(description);
+ descriptions = new ArrayList<>(Arrays.asList(new UploadMediaDetail()));
setDescriptionsInAdapter(descriptions);
},
() -> {
@@ -431,13 +424,6 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
}
private void setDescriptionsInAdapter(List uploadMediaDetails){
- if(uploadMediaDetails==null){
- uploadMediaDetails=new ArrayList<>();
- }
-
- if(uploadMediaDetails.size()==0){
- uploadMediaDetails.add(new UploadMediaDetail());
- }
uploadMediaDetailAdapter.setItems(uploadMediaDetails);
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java
index 873b44da4..bd1a3e995 100644
--- a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java
+++ b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java
@@ -10,7 +10,6 @@ import com.google.gson.JsonObject;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.kvstore.JsonKvStore;
-import fr.free.nrw.commons.media.MediaClient;
import fr.free.nrw.commons.upload.mediaDetails.CaptionInterface;
import fr.free.nrw.commons.utils.ConfigUtils;
import fr.free.nrw.commons.utils.ViewUtil;
@@ -26,7 +25,6 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.wikipedia.csrf.CsrfTokenClient;
-import org.wikipedia.dataclient.Service;
import timber.log.Timber;
/**
@@ -46,42 +44,31 @@ public class WikidataEditService {
private final CaptionInterface captionInterface;
private final WikiBaseClient wikiBaseClient;
private final WikidataClient wikidataClient;
- private final MediaClient mediaClient;
private final CsrfTokenClient csrfTokenClient;
- private final Service service;
@Inject
- public WikidataEditService(Context context,
- WikidataEditListener wikidataEditListener,
- MediaClient mediaClient,
- @Named("default_preferences") JsonKvStore directKvStore,
- WikiBaseClient wikiBaseClient,
- CaptionInterface captionInterface,
- WikidataClient wikidataClient,
- @Named("commons-csrf") CsrfTokenClient csrfTokenClient,
- @Named("commons-service") Service service) {
+ public WikidataEditService(final Context context,
+ final WikidataEditListener wikidataEditListener,
+ @Named("default_preferences") final JsonKvStore directKvStore,
+ final WikiBaseClient wikiBaseClient,
+ final CaptionInterface captionInterface,
+ final WikidataClient wikidataClient,
+ @Named("commons-csrf") final CsrfTokenClient csrfTokenClient) {
this.context = context;
this.wikidataEditListener = wikidataEditListener;
this.directKvStore = directKvStore;
this.captionInterface = captionInterface;
this.wikiBaseClient = wikiBaseClient;
- this.mediaClient = mediaClient;
this.wikidataClient = wikidataClient;
this.csrfTokenClient = csrfTokenClient;
- this.service = service;
- }
+ }
/**
* Create a P18 claim and log the edit with custom tag
-<<<<<<< HEAD
*
- * @param wikidataEntityId
- * @param fileName
-=======
* @param wikidataEntityId a unique id of each Wikidata items
* @param fileName name of the file we will upload
* @param p18Value pic attribute of Wikidata item
->>>>>>> origin/master
*/
public void createClaimWithLogging(String wikidataEntityId, String wikiItemName, String fileName, String p18Value) {
if (wikidataEntityId == null) {
@@ -104,8 +91,8 @@ public class WikidataEditService {
return;
}
- editWikidataProperty(wikidataEntityId, wikiItemName, fileName);
- //editWikiBaseDepictsProperty(wikidataEntityId, fileName);
+ editWikidataProperty(wikidataEntityId, wikiItemName, fileName);;
+ editWikiBaseDepictsProperty(wikidataEntityId, fileName);
}
@@ -122,7 +109,7 @@ public class WikidataEditService {
Timber.d("Upload successful with wiki data entity id as %s", wikidataEntityId);
Timber.d("Attempting to edit Wikidata property %s", wikidataEntityId);
- String propertyValue = getFileName(fileName);
+ final String propertyValue = getFileName(fileName);
Timber.d("Entity id is %s and property value is %s", wikidataEntityId, propertyValue);
wikidataClient.createClaim(wikidataEntityId, propertyValue)
@@ -148,7 +135,7 @@ public class WikidataEditService {
* @param fileName
*/
@SuppressLint("CheckResult")
- private void editWikiBaseDepictsProperty(String wikidataEntityId, String fileName) {
+ private void editWikiBaseDepictsProperty(final String wikidataEntityId, final String fileName) {
wikiBaseClient.getFileEntityId(fileName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -166,37 +153,37 @@ public class WikidataEditService {
}
@SuppressLint("CheckResult")
- private void addDepictsProperty(String entityId, String fileEntityId) {
+ private void addDepictsProperty(String entityId, final String fileEntityId) {
if (ConfigUtils.isBetaFlavour()) {
entityId = "Q10"; // Wikipedia:Sandbox (Q10)
}
- JsonObject value = new JsonObject();
+ final JsonObject value = new JsonObject();
value.addProperty("entity-type", "item");
value.addProperty("numeric-id", entityId.replace("Q", ""));
value.addProperty("id", entityId);
- JsonObject dataValue = new JsonObject();
+ final JsonObject dataValue = new JsonObject();
dataValue.add("value", value);
dataValue.addProperty("type", "wikibase-entityid");
- JsonObject mainSnak = new JsonObject();
+ final JsonObject mainSnak = new JsonObject();
mainSnak.addProperty("snaktype", "value");
mainSnak.addProperty("property", BuildConfig.DEPICTS_PROPERTY);
mainSnak.add("datavalue", dataValue);
- JsonObject claim = new JsonObject();
+ final JsonObject claim = new JsonObject();
claim.add("mainsnak", mainSnak);
claim.addProperty("type", "statement");
claim.addProperty("rank", "preferred");
- JsonArray claims = new JsonArray();
+ final JsonArray claims = new JsonArray();
claims.add(claim);
- JsonObject jsonData = new JsonObject();
+ final JsonObject jsonData = new JsonObject();
jsonData.add("claims", claims);
- String data = jsonData.toString();
+ final String data = jsonData.toString();
Observable.defer((Callable>) () ->
wikiBaseClient.postEditEntity(PAGE_ID_PREFIX + fileEntityId, data))
@@ -253,18 +240,19 @@ public class WikidataEditService {
* Adding captions as labels after image is successfully uploaded
*/
@SuppressLint("CheckResult")
- public void createLabelforWikidataEntity(String wikiDataEntityId, String fileName, Map captions) {
+ public void createLabelforWikidataEntity(final String fileName,
+ final Map captions) {
Observable.fromCallable(() -> wikiBaseClient.getFileEntityId(fileName))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(fileEntityId -> {
if (fileEntityId != null) {
- for (Map.Entry entry : captions.entrySet()) {
- Map caption = new HashMap<>();
+ for (final Map.Entry entry : captions.entrySet()) {
+ final Map caption = new HashMap<>();
caption.put(entry.getKey(), entry.getValue());
try {
- wikidataAddLabels(wikiDataEntityId, fileEntityId.toString(), caption);
- } catch (Throwable throwable) {
+ wikidataAddLabels(fileEntityId.toString(), caption);
+ } catch (final Throwable throwable) {
throwable.printStackTrace();
}
}
@@ -280,13 +268,12 @@ public class WikidataEditService {
/**
* Adds label to Wikidata using the fileEntityId and the edit token, obtained from csrfTokenClient
*
- * @param wikiDataEntityId entityId for the current contribution
* @param fileEntityId
* @param caption
*/
@SuppressLint("CheckResult")
- private void wikidataAddLabels(String wikiDataEntityId, String fileEntityId, Map caption) throws Throwable {
+ private void wikidataAddLabels(final String fileEntityId, final Map caption) {
Observable.fromCallable(() -> {
try {
return csrfTokenClient.getTokenBlocking();
diff --git a/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikidataEditServiceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikidataEditServiceTest.kt
index 39b9a7bf2..25e83c0cd 100644
--- a/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikidataEditServiceTest.kt
+++ b/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikidataEditServiceTest.kt
@@ -2,12 +2,14 @@ package fr.free.nrw.commons.wikidata
import android.content.Context
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
+import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse
import io.reactivex.Observable
import org.junit.Before
import org.junit.Test
-import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyString
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.*
@@ -15,19 +17,19 @@ import org.mockito.MockitoAnnotations
class WikidataEditServiceTest {
@Mock
- internal var context: Context? = null
- @Mock
- internal var wikidataEditListener: WikidataEditListener? = null
- @Mock
- internal var directKvStore: JsonKvStore? = null
- @Mock
- internal var wikidataClient: WikidataClient? = null
+ internal lateinit var context: Context
@Mock
- internal var wikibaseClient: WikiBaseClient? = null
+ internal lateinit var directKvStore: JsonKvStore
+
+ @Mock
+ internal lateinit var wikidataClient: WikidataClient
+
+ @Mock
+ internal lateinit var wikibaseClient: WikiBaseClient
@InjectMocks
- var wikidataEditService: WikidataEditService? = null
+ lateinit var wikidataEditService: WikidataEditService
@Before
@Throws(Exception::class)
@@ -37,40 +39,40 @@ class WikidataEditServiceTest {
@Test
fun noClaimsWhenEntityIdIsNull() {
- wikidataEditService!!.createClaimWithLogging(null, null,"Test.jpg","")
- verifyZeroInteractions(wikidataClient!!)
+ wikidataEditService.createClaimWithLogging(null, null,"Test.jpg","")
+ verifyZeroInteractions(wikidataClient)
}
@Test
fun noClaimsWhenFileNameIsNull() {
- wikidataEditService!!.createClaimWithLogging("Q1", "Test", null,"")
- verifyZeroInteractions(wikidataClient!!)
+ wikidataEditService.createClaimWithLogging("Q1", "Test", null,"")
+ verifyZeroInteractions(wikidataClient)
}
@Test
fun noClaimsWhenP18IsNotEmpty() {
- wikidataEditService!!.createClaimWithLogging("Q1", "Test","Test.jpg","Previous.jpg")
- verifyZeroInteractions(wikidataClient!!)
+ wikidataEditService.createClaimWithLogging("Q1", "Test","Test.jpg","Previous.jpg")
+ verifyZeroInteractions(wikidataClient)
}
@Test
fun noClaimsWhenLocationIsNotCorrect() {
- `when`(directKvStore!!.getBoolean("Picture_Has_Correct_Location", true))
- .thenReturn(false)
- wikidataEditService!!.createClaimWithLogging("Q1", "","Test.jpg","")
- verifyZeroInteractions(wikidataClient!!)
+ whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
+ .thenReturn(false)
+ wikidataEditService.createClaimWithLogging("Q1", "", "Test.jpg", "")
+ verifyZeroInteractions(wikidataClient)
}
@Test
fun createClaimWithLogging() {
- `when`(directKvStore!!.getBoolean("Picture_Has_Correct_Location", true))
- .thenReturn(true)
- `when`(wikidataClient!!.createClaim(ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
- .thenReturn(Observable.just(1L))
- `when`(wikidataClient!!.addEditTag(anyLong(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
- .thenReturn(Observable.just(mock(AddEditTagResponse::class.java)))
- wikidataEditService!!.createClaimWithLogging("Q1", "Test","Test.jpg","")
- verify(wikidataClient!!, times(1))
- .createClaim(ArgumentMatchers.anyString(), ArgumentMatchers.anyString())
+ whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
+ .thenReturn(true)
+ whenever(wikidataClient.createClaim(anyString(), anyString()))
+ .thenReturn(Observable.just(1L))
+ whenever(wikidataClient.addEditTag(anyLong(), anyString(), anyString()))
+ .thenReturn(Observable.just(mock(AddEditTagResponse::class.java)))
+ whenever(wikibaseClient.getFileEntityId(any())).thenReturn(Observable.just(1L))
+ wikidataEditService.createClaimWithLogging("Q1", "", "Test.jpg", "")
+ verify(wikidataClient, times(1)).createClaim(anyString(), anyString())
}
-}
\ No newline at end of file
+}