mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-28 21:33:53 +01:00
Convert UploadModel to kotlin
This commit is contained in:
parent
75ba0f5065
commit
a6c4731f74
11 changed files with 282 additions and 341 deletions
|
|
@ -101,7 +101,7 @@ data class Contribution constructor(
|
|||
*/
|
||||
fun formatCaptions(uploadMediaDetails: List<UploadMediaDetail>) =
|
||||
uploadMediaDetails
|
||||
.associate { it.languageCode!! to it.captionText }
|
||||
.associate { it.languageCode!! to it.captionText!! }
|
||||
.filter { it.value.isNotBlank() }
|
||||
|
||||
/**
|
||||
|
|
@ -112,7 +112,7 @@ data class Contribution constructor(
|
|||
*/
|
||||
fun formatDescriptions(descriptions: List<UploadMediaDetail>) =
|
||||
descriptions
|
||||
.filter { it.descriptionText.isNotEmpty() }
|
||||
.filter { it.descriptionText!!.isNotEmpty() }
|
||||
.joinToString(separator = "") { "{{${it.languageCode}|1=${it.descriptionText}}}" }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,11 +272,11 @@ class DescriptionEditActivity :
|
|||
applicationContext,
|
||||
media,
|
||||
mediaDetail.languageCode!!,
|
||||
mediaDetail.captionText,
|
||||
mediaDetail.captionText!!,
|
||||
).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { s: Boolean? ->
|
||||
updatedCaptions[mediaDetail.languageCode!!] = mediaDetail.captionText
|
||||
updatedCaptions[mediaDetail.languageCode!!] = mediaDetail.captionText!!
|
||||
media.captions = updatedCaptions
|
||||
Timber.d("Caption is added.")
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1569,7 +1569,7 @@ class MediaDetailFragment : CommonsDaggerSupportFragment(), CategoryEditHelper.C
|
|||
mediaDetail: UploadMediaDetail,
|
||||
updatedCaptions: MutableMap<String, String>
|
||||
) {
|
||||
updatedCaptions[mediaDetail.languageCode!!] = mediaDetail.captionText
|
||||
updatedCaptions[mediaDetail.languageCode!!] = mediaDetail.captionText!!
|
||||
media!!.captions = updatedCaptions
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class UploadRepository @Inject constructor(
|
|||
* @return
|
||||
*/
|
||||
fun getUploads(): List<UploadItem> {
|
||||
return uploadModel.getUploads()
|
||||
return uploadModel.uploads
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -275,7 +275,7 @@ class UploadRepository @Inject constructor(
|
|||
* @param selectedExistingDepictions existing depicts
|
||||
*/
|
||||
fun setSelectedExistingDepictions(selectedExistingDepictions: List<String>) {
|
||||
uploadModel.selectedExistingDepictions = selectedExistingDepictions
|
||||
uploadModel.selectedExistingDepictions = selectedExistingDepictions.toMutableList()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class FileProcessor
|
|||
* Processes filePath coordinates, either from EXIF data or user location
|
||||
*/
|
||||
fun processFileCoordinates(
|
||||
similarImageInterface: SimilarImageInterface,
|
||||
similarImageInterface: SimilarImageInterface?,
|
||||
filePath: String?,
|
||||
inAppPictureLocation: LatLng?,
|
||||
): ImageCoordinates {
|
||||
|
|
@ -146,7 +146,7 @@ class FileProcessor
|
|||
*/
|
||||
private fun findOtherImages(
|
||||
fileBeingProcessed: File,
|
||||
similarImageInterface: SimilarImageInterface,
|
||||
similarImageInterface: SimilarImageInterface?,
|
||||
) {
|
||||
val oneHundredAndTwentySeconds = 120 * 1000L
|
||||
// Time when the original image was created
|
||||
|
|
@ -161,7 +161,7 @@ class FileProcessor
|
|||
.map { Pair(it, readImageCoordinates(it)) }
|
||||
.firstOrNull { it.second?.decimalCoords != null }
|
||||
?.let { fileCoordinatesPair ->
|
||||
similarImageInterface.showSimilarImageFragment(
|
||||
similarImageInterface?.showSimilarImageFragment(
|
||||
fileBeingProcessed.path,
|
||||
fileCoordinatesPair.first.absolutePath,
|
||||
fileCoordinatesPair.second,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import kotlinx.parcelize.Parcelize
|
|||
* Holds a description of an item being uploaded by [UploadActivity]
|
||||
*/
|
||||
@Parcelize
|
||||
data class UploadMediaDetail constructor(
|
||||
data class UploadMediaDetail(
|
||||
/**
|
||||
* The language code ie. "en" or "fr".
|
||||
* @param languageCode The language code ie. "en" or "fr".
|
||||
|
|
@ -18,19 +18,19 @@ data class UploadMediaDetail constructor(
|
|||
* The description text for the item being uploaded.
|
||||
* @param descriptionText The description text.
|
||||
*/
|
||||
var descriptionText: String = "",
|
||||
var descriptionText: String? = "",
|
||||
/**
|
||||
* The caption text for the item being uploaded.
|
||||
* @param captionText The caption text.
|
||||
*/
|
||||
var captionText: String = "",
|
||||
var captionText: String? = "",
|
||||
) : Parcelable {
|
||||
fun javaCopy() = copy()
|
||||
|
||||
constructor(place: Place) : this(
|
||||
place.language,
|
||||
place.longDescription,
|
||||
place.name,
|
||||
constructor(place: Place?) : this(
|
||||
place?.language,
|
||||
place?.longDescription,
|
||||
place?.name,
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,297 +0,0 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.filepicker.UploadableFile;
|
||||
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.structure.depictions.DepictedItem;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
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
|
||||
public class UploadModel {
|
||||
|
||||
private final JsonKvStore store;
|
||||
private final List<String> licenses;
|
||||
private final Context context;
|
||||
private String license;
|
||||
private final Map<String, String> licensesByName;
|
||||
private final List<UploadItem> items = new ArrayList<>();
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
private final SessionManager sessionManager;
|
||||
private final FileProcessor fileProcessor;
|
||||
private final ImageProcessingService imageProcessingService;
|
||||
private final List<String> selectedCategories = new ArrayList<>();
|
||||
private final List<DepictedItem> selectedDepictions = new ArrayList<>();
|
||||
/**
|
||||
* Existing depicts which are selected
|
||||
*/
|
||||
private List<String> selectedExistingDepictions = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
UploadModel(@Named("licenses") final List<String> licenses,
|
||||
@Named("default_preferences") final JsonKvStore store,
|
||||
@Named("licenses_by_name") final Map<String, String> 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);
|
||||
this.licensesByName = licensesByName;
|
||||
this.context = context;
|
||||
this.sessionManager = sessionManager;
|
||||
this.fileProcessor = fileProcessor;
|
||||
this.imageProcessingService = imageProcessingService;
|
||||
}
|
||||
|
||||
/**
|
||||
* cleanup the resources, I am Singleton, preparing for fresh upload
|
||||
*/
|
||||
public void cleanUp() {
|
||||
compositeDisposable.clear();
|
||||
fileProcessor.cleanup();
|
||||
items.clear();
|
||||
selectedCategories.clear();
|
||||
selectedDepictions.clear();
|
||||
selectedExistingDepictions.clear();
|
||||
}
|
||||
|
||||
public void setSelectedCategories(List<String> selectedCategories) {
|
||||
this.selectedCategories.clear();
|
||||
this.selectedCategories.addAll(selectedCategories);
|
||||
}
|
||||
|
||||
/**
|
||||
* pre process a one item at a time
|
||||
*/
|
||||
public Observable<UploadItem> preProcessImage(final UploadableFile uploadableFile,
|
||||
final Place place,
|
||||
final SimilarImageInterface similarImageInterface,
|
||||
LatLng inAppPictureLocation) {
|
||||
return Observable.just(
|
||||
createAndAddUploadItem(uploadableFile, place, similarImageInterface, inAppPictureLocation));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls validateImage() of ImageProcessingService to check quality of image
|
||||
*
|
||||
* @param uploadItem UploadItem whose quality is to be checked
|
||||
* @param inAppPictureLocation In app picture location (if any)
|
||||
* @return Quality of UploadItem
|
||||
*/
|
||||
public Single<Integer> getImageQuality(final UploadItem uploadItem, LatLng inAppPictureLocation) {
|
||||
return imageProcessingService.validateImage(uploadItem, inAppPictureLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls checkDuplicateImage() of ImageProcessingService to check if image is duplicate
|
||||
*
|
||||
* @param filePath file to be checked
|
||||
* @return IMAGE_DUPLICATE or IMAGE_OK
|
||||
*/
|
||||
public Single<Integer> checkDuplicateImage(String filePath){
|
||||
return imageProcessingService.checkDuplicateImage(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls validateCaption() of ImageProcessingService to check caption of image
|
||||
*
|
||||
* @param uploadItem UploadItem whose caption is to be checked
|
||||
* @return Quality of caption of the UploadItem
|
||||
*/
|
||||
public Single<Integer> getCaptionQuality(final UploadItem uploadItem) {
|
||||
return imageProcessingService.validateCaption(uploadItem);
|
||||
}
|
||||
|
||||
private UploadItem createAndAddUploadItem(final UploadableFile uploadableFile,
|
||||
final Place place,
|
||||
final SimilarImageInterface similarImageInterface,
|
||||
LatLng inAppPictureLocation) {
|
||||
final UploadableFile.DateTimeWithSource dateTimeWithSource = uploadableFile
|
||||
.getFileCreatedDate(context);
|
||||
long fileCreatedDate = -1;
|
||||
String createdTimestampSource = "";
|
||||
String fileCreatedDateString = "";
|
||||
if (dateTimeWithSource != null) {
|
||||
fileCreatedDate = dateTimeWithSource.getEpochDate();
|
||||
fileCreatedDateString = dateTimeWithSource.getDateString();
|
||||
createdTimestampSource = dateTimeWithSource.getSource();
|
||||
}
|
||||
Timber.d("File created date is %d", fileCreatedDate);
|
||||
final ImageCoordinates imageCoordinates = fileProcessor
|
||||
.processFileCoordinates(similarImageInterface, uploadableFile.getFilePath(),
|
||||
inAppPictureLocation);
|
||||
final UploadItem uploadItem = new UploadItem(
|
||||
Uri.parse(uploadableFile.getFilePath()),
|
||||
uploadableFile.getMimeType(context), imageCoordinates, place, fileCreatedDate,
|
||||
createdTimestampSource,
|
||||
uploadableFile.getContentUri(),
|
||||
fileCreatedDateString);
|
||||
|
||||
// If an uploadItem of the same uploadableFile has been created before, we return that.
|
||||
// This is to avoid multiple instances of uploadItem of same file passed around.
|
||||
if (items.contains(uploadItem)) {
|
||||
return items.get(items.indexOf(uploadItem));
|
||||
}
|
||||
|
||||
if (place != null) {
|
||||
uploadItem.getUploadMediaDetails().set(0, new UploadMediaDetail(place));
|
||||
}
|
||||
if (!items.contains(uploadItem)) {
|
||||
items.add(uploadItem);
|
||||
}
|
||||
return uploadItem;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
public List<UploadItem> getUploads() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public List<String> getLicenses() {
|
||||
return licenses;
|
||||
}
|
||||
|
||||
public String getSelectedLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
public void setSelectedLicense(final String licenseName) {
|
||||
this.license = licensesByName.get(licenseName);
|
||||
store.putString(Prefs.DEFAULT_LICENSE, license);
|
||||
}
|
||||
|
||||
public Observable<Contribution> buildContributions() {
|
||||
return Observable.fromIterable(items).map(item ->
|
||||
{
|
||||
String imageSHA1 = FileUtils.INSTANCE.getSHA1(context.getContentResolver().openInputStream(item.getContentUri()));
|
||||
|
||||
final Contribution contribution = new Contribution(
|
||||
item, sessionManager, newListOf(selectedDepictions), newListOf(selectedCategories), imageSHA1);
|
||||
|
||||
contribution.setHasInvalidLocation(item.hasInvalidLocation());
|
||||
|
||||
Timber.d("Created timestamp while building contribution is %s, %s",
|
||||
item.getCreatedTimestamp(),
|
||||
new Date(item.getCreatedTimestamp()));
|
||||
|
||||
if (item.getCreatedTimestamp() != -1L) {
|
||||
contribution.setDateCreated(new Date(item.getCreatedTimestamp()));
|
||||
contribution.setDateCreatedSource(item.getCreatedTimestampSource());
|
||||
//Set the date only if you have it, else the upload service is gonna try it the other way
|
||||
}
|
||||
|
||||
if (contribution.getWikidataPlace() != null) {
|
||||
if (item.isWLMUpload()) {
|
||||
contribution.getWikidataPlace().setMonumentUpload(true);
|
||||
} else {
|
||||
contribution.getWikidataPlace().setMonumentUpload(false);
|
||||
}
|
||||
}
|
||||
contribution.setCountryCode(item.getCountryCode());
|
||||
return contribution;
|
||||
});
|
||||
}
|
||||
|
||||
public void deletePicture(final String filePath) {
|
||||
final Iterator<UploadItem> iterator = items.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next().getMediaUri().toString().contains(filePath)) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (items.isEmpty()) {
|
||||
cleanUp();
|
||||
}
|
||||
}
|
||||
|
||||
public List<UploadItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void onDepictItemClicked(DepictedItem depictedItem, Media media) {
|
||||
if (media == null) {
|
||||
if (depictedItem.isSelected()) {
|
||||
selectedDepictions.add(depictedItem);
|
||||
} else {
|
||||
selectedDepictions.remove(depictedItem);
|
||||
}
|
||||
} else {
|
||||
if (depictedItem.isSelected()) {
|
||||
if (media.getDepictionIds().contains(depictedItem.getId())) {
|
||||
selectedExistingDepictions.add(depictedItem.getId());
|
||||
} else {
|
||||
selectedDepictions.add(depictedItem);
|
||||
}
|
||||
} else {
|
||||
if (media.getDepictionIds().contains(depictedItem.getId())) {
|
||||
selectedExistingDepictions.remove(depictedItem.getId());
|
||||
if (!media.getDepictionIds().contains(depictedItem.getId())) {
|
||||
final List<String> depictsList = new ArrayList<>();
|
||||
depictsList.add(depictedItem.getId());
|
||||
depictsList.addAll(media.getDepictionIds());
|
||||
media.setDepictionIds(depictsList);
|
||||
}
|
||||
} else {
|
||||
selectedDepictions.remove(depictedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <T> List<T> newListOf(final List<T> items) {
|
||||
return items != null ? new ArrayList<>(items) : new ArrayList<>();
|
||||
}
|
||||
|
||||
public void useSimilarPictureCoordinates(final ImageCoordinates imageCoordinates, final int uploadItemIndex) {
|
||||
fileProcessor.prePopulateCategoriesAndDepictionsBy(imageCoordinates);
|
||||
items.get(uploadItemIndex).setGpsCoords(imageCoordinates);
|
||||
}
|
||||
|
||||
public List<DepictedItem> getSelectedDepictions() {
|
||||
return selectedDepictions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides selected existing depicts
|
||||
*
|
||||
* @return selected existing depicts
|
||||
*/
|
||||
public List<String> getSelectedExistingDepictions() {
|
||||
return selectedExistingDepictions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize existing depicts
|
||||
*
|
||||
* @param selectedExistingDepictions existing depicts
|
||||
*/
|
||||
public void setSelectedExistingDepictions(final List<String> selectedExistingDepictions) {
|
||||
this.selectedExistingDepictions = selectedExistingDepictions;
|
||||
}
|
||||
}
|
||||
242
app/src/main/java/fr/free/nrw/commons/upload/UploadModel.kt
Normal file
242
app/src/main/java/fr/free/nrw/commons/upload/UploadModel.kt
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.contributions.Contribution
|
||||
import fr.free.nrw.commons.filepicker.UploadableFile
|
||||
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.FileUtils.getSHA1
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import timber.log.Timber
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class UploadModel @Inject internal constructor(
|
||||
@param:Named("licenses") val licenses: List<String>,
|
||||
@param:Named("default_preferences") val store: JsonKvStore,
|
||||
@param:Named("licenses_by_name") val licensesByName: Map<String, String>,
|
||||
val context: Context,
|
||||
val sessionManager: SessionManager,
|
||||
val fileProcessor: FileProcessor,
|
||||
val imageProcessingService: ImageProcessingService
|
||||
) {
|
||||
var license: String? = store.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3)
|
||||
val items: MutableList<UploadItem> = mutableListOf()
|
||||
val compositeDisposable: CompositeDisposable = CompositeDisposable()
|
||||
val selectedCategories: MutableList<String> = mutableListOf()
|
||||
val selectedDepictions: MutableList<DepictedItem> = mutableListOf()
|
||||
|
||||
/**
|
||||
* Existing depicts which are selected
|
||||
*/
|
||||
var selectedExistingDepictions: MutableList<String> = mutableListOf()
|
||||
val count: Int
|
||||
get() = items.size
|
||||
|
||||
val uploads: List<UploadItem>
|
||||
get() = items
|
||||
|
||||
var selectedLicense: String?
|
||||
get() = license
|
||||
set(licenseName) {
|
||||
license = licensesByName[licenseName]
|
||||
if (license == null) {
|
||||
store.remove(Prefs.DEFAULT_LICENSE)
|
||||
} else {
|
||||
store.putString(Prefs.DEFAULT_LICENSE, license!!)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cleanup the resources, I am Singleton, preparing for fresh upload
|
||||
*/
|
||||
fun cleanUp() {
|
||||
compositeDisposable.clear()
|
||||
fileProcessor.cleanup()
|
||||
items.clear()
|
||||
selectedCategories.clear()
|
||||
selectedDepictions.clear()
|
||||
selectedExistingDepictions.clear()
|
||||
}
|
||||
|
||||
fun setSelectedCategories(categories: List<String>) {
|
||||
selectedCategories.clear()
|
||||
selectedCategories.addAll(categories)
|
||||
}
|
||||
|
||||
/**
|
||||
* pre process a one item at a time
|
||||
*/
|
||||
fun preProcessImage(
|
||||
uploadableFile: UploadableFile?,
|
||||
place: Place?,
|
||||
similarImageInterface: SimilarImageInterface?,
|
||||
inAppPictureLocation: LatLng?
|
||||
): Observable<UploadItem> = Observable.just(
|
||||
createAndAddUploadItem(uploadableFile, place, similarImageInterface, inAppPictureLocation)
|
||||
)
|
||||
|
||||
/**
|
||||
* Calls validateImage() of ImageProcessingService to check quality of image
|
||||
*
|
||||
* @param uploadItem UploadItem whose quality is to be checked
|
||||
* @param inAppPictureLocation In app picture location (if any)
|
||||
* @return Quality of UploadItem
|
||||
*/
|
||||
fun getImageQuality(uploadItem: UploadItem, inAppPictureLocation: LatLng?): Single<Int> =
|
||||
imageProcessingService.validateImage(uploadItem, inAppPictureLocation)
|
||||
|
||||
/**
|
||||
* Calls checkDuplicateImage() of ImageProcessingService to check if image is duplicate
|
||||
*
|
||||
* @param filePath file to be checked
|
||||
* @return IMAGE_DUPLICATE or IMAGE_OK
|
||||
*/
|
||||
fun checkDuplicateImage(filePath: String?): Single<Int> =
|
||||
imageProcessingService.checkDuplicateImage(filePath)
|
||||
|
||||
/**
|
||||
* Calls validateCaption() of ImageProcessingService to check caption of image
|
||||
*
|
||||
* @param uploadItem UploadItem whose caption is to be checked
|
||||
* @return Quality of caption of the UploadItem
|
||||
*/
|
||||
fun getCaptionQuality(uploadItem: UploadItem): Single<Int> =
|
||||
imageProcessingService.validateCaption(uploadItem)
|
||||
|
||||
private fun createAndAddUploadItem(
|
||||
uploadableFile: UploadableFile?,
|
||||
place: Place?,
|
||||
similarImageInterface: SimilarImageInterface?,
|
||||
inAppPictureLocation: LatLng?
|
||||
): UploadItem {
|
||||
val dateTimeWithSource = uploadableFile?.getFileCreatedDate(context)
|
||||
var fileCreatedDate: Long = -1
|
||||
var createdTimestampSource = ""
|
||||
var fileCreatedDateString: String? = ""
|
||||
if (dateTimeWithSource != null) {
|
||||
fileCreatedDate = dateTimeWithSource.epochDate
|
||||
fileCreatedDateString = dateTimeWithSource.dateString
|
||||
createdTimestampSource = dateTimeWithSource.source
|
||||
}
|
||||
Timber.d("File created date is %d", fileCreatedDate)
|
||||
val imageCoordinates = fileProcessor
|
||||
.processFileCoordinates(
|
||||
similarImageInterface, uploadableFile?.getFilePath(),
|
||||
inAppPictureLocation
|
||||
)
|
||||
val uploadItem = UploadItem(
|
||||
Uri.parse(uploadableFile?.getFilePath()),
|
||||
uploadableFile?.getMimeType(context), imageCoordinates, place, fileCreatedDate,
|
||||
createdTimestampSource,
|
||||
uploadableFile?.contentUri,
|
||||
fileCreatedDateString
|
||||
)
|
||||
|
||||
// If an uploadItem of the same uploadableFile has been created before, we return that.
|
||||
// This is to avoid multiple instances of uploadItem of same file passed around.
|
||||
if (items.contains(uploadItem)) {
|
||||
return items[items.indexOf(uploadItem)]
|
||||
}
|
||||
|
||||
uploadItem.uploadMediaDetails[0] = UploadMediaDetail(place)
|
||||
if (!items.contains(uploadItem)) {
|
||||
items.add(uploadItem)
|
||||
}
|
||||
return uploadItem
|
||||
}
|
||||
|
||||
fun buildContributions(): Observable<Contribution> {
|
||||
return Observable.fromIterable(items).map { item: UploadItem ->
|
||||
val imageSHA1 = getSHA1(
|
||||
context.contentResolver.openInputStream(item.contentUri!!)!!
|
||||
)
|
||||
val contribution = Contribution(
|
||||
item,
|
||||
sessionManager,
|
||||
buildList { addAll(selectedDepictions) },
|
||||
buildList { addAll(selectedCategories) },
|
||||
imageSHA1
|
||||
)
|
||||
|
||||
contribution.setHasInvalidLocation(item.hasInvalidLocation())
|
||||
|
||||
Timber.d(
|
||||
"Created timestamp while building contribution is %s, %s",
|
||||
item.createdTimestamp,
|
||||
Date(item.createdTimestamp)
|
||||
)
|
||||
|
||||
if (item.createdTimestamp != -1L) {
|
||||
contribution.dateCreated = Date(item.createdTimestamp)
|
||||
contribution.dateCreatedSource = item.createdTimestampSource
|
||||
//Set the date only if you have it, else the upload service is gonna try it the other way
|
||||
}
|
||||
|
||||
if (contribution.wikidataPlace != null) {
|
||||
contribution.wikidataPlace!!.isMonumentUpload = item.isWLMUpload
|
||||
}
|
||||
contribution.countryCode = item.countryCode
|
||||
contribution
|
||||
}
|
||||
}
|
||||
|
||||
fun deletePicture(filePath: String) {
|
||||
val iterator = items.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next().mediaUri.toString().contains(filePath)) {
|
||||
iterator.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
if (items.isEmpty()) {
|
||||
cleanUp()
|
||||
}
|
||||
}
|
||||
|
||||
fun onDepictItemClicked(depictedItem: DepictedItem, media: Media?) {
|
||||
if (media == null) {
|
||||
if (depictedItem.isSelected) {
|
||||
selectedDepictions.add(depictedItem)
|
||||
} else {
|
||||
selectedDepictions.remove(depictedItem)
|
||||
}
|
||||
} else {
|
||||
if (depictedItem.isSelected) {
|
||||
if (media.depictionIds.contains(depictedItem.id)) {
|
||||
selectedExistingDepictions.add(depictedItem.id)
|
||||
} else {
|
||||
selectedDepictions.add(depictedItem)
|
||||
}
|
||||
} else {
|
||||
if (media.depictionIds.contains(depictedItem.id)) {
|
||||
selectedExistingDepictions.remove(depictedItem.id)
|
||||
if (!media.depictionIds.contains(depictedItem.id)) {
|
||||
media.depictionIds = mutableListOf<String>().apply {
|
||||
add(depictedItem.id)
|
||||
addAll(media.depictionIds)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
selectedDepictions.remove(depictedItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun useSimilarPictureCoordinates(imageCoordinates: ImageCoordinates, uploadItemIndex: Int) {
|
||||
fileProcessor.prePopulateCategoriesAndDepictionsBy(imageCoordinates)
|
||||
items[uploadItemIndex].gpsCoords = imageCoordinates
|
||||
}
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ class CategoriesPresenter
|
|||
*/
|
||||
private fun getImageTitleList(): List<String> =
|
||||
repository.getUploads()
|
||||
.map { it.uploadMediaDetails[0].captionText }
|
||||
.map { it.uploadMediaDetails[0].captionText!! }
|
||||
.filterNot { TextUtils.isEmpty(it) }
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -140,6 +140,6 @@ class UploadModelUnitTest {
|
|||
@Ignore
|
||||
@Test
|
||||
fun testSetSelectedExistingDepictions() {
|
||||
uploadModel.selectedExistingDepictions = listOf("")
|
||||
uploadModel.selectedExistingDepictions = mutableListOf("")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.category.CategoriesModel
|
||||
import fr.free.nrw.commons.category.CategoryItem
|
||||
|
|
@ -17,6 +19,7 @@ import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
|||
import io.reactivex.Completable
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import org.junit.Assert.assertSame
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
|
@ -118,7 +121,9 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetUploads() {
|
||||
assertEquals(repository.getUploads(), uploadModel.uploads)
|
||||
val result = listOf(uploadItem)
|
||||
whenever(uploadModel.uploads).thenReturn(result)
|
||||
assertSame(result, repository.getUploads())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -136,10 +141,10 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testSearchAll() {
|
||||
assertEquals(
|
||||
repository.searchAll("", listOf(), listOf()),
|
||||
categoriesModel.searchAll("", listOf(), listOf()),
|
||||
)
|
||||
val empty = Observable.empty<List<CategoryItem>>()
|
||||
whenever(categoriesModel.searchAll(any(), any(), any())).thenReturn(empty)
|
||||
assertSame(empty, repository.searchAll("", listOf(), listOf()))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -164,7 +169,9 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetLicenses() {
|
||||
assertEquals(repository.getLicenses(), uploadModel.licenses)
|
||||
whenever(uploadModel.licenses).thenReturn(listOf())
|
||||
repository.getLicenses()
|
||||
verify(uploadModel).licenses
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -208,10 +215,10 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetUploadItemCaseNonNull() {
|
||||
`when`(uploadModel.items).thenReturn(listOf(uploadItem))
|
||||
`when`(uploadModel.items).thenReturn(mutableListOf(uploadItem))
|
||||
assertEquals(
|
||||
repository.getUploadItem(0),
|
||||
uploadModel.items[0],
|
||||
uploadItem,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -220,19 +227,6 @@ class UploadRepositoryUnitTest {
|
|||
assertEquals(repository.getUploadItem(-1), null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetSelectedLicense() {
|
||||
assertEquals(repository.setSelectedLicense(""), uploadModel.setSelectedLicense(""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetSelectedExistingDepictions() {
|
||||
assertEquals(
|
||||
repository.setSelectedExistingDepictions(listOf("")),
|
||||
uploadModel.setSelectedExistingDepictions(listOf("")),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnDepictItemClicked() {
|
||||
assertEquals(
|
||||
|
|
@ -243,12 +237,14 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetSelectedDepictions() {
|
||||
assertEquals(repository.getSelectedDepictions(), uploadModel.selectedDepictions)
|
||||
repository.getSelectedDepictions()
|
||||
verify(uploadModel).selectedDepictions
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSelectedExistingDepictions() {
|
||||
assertEquals(repository.getSelectedExistingDepictions(), uploadModel.selectedExistingDepictions)
|
||||
repository.getSelectedExistingDepictions()
|
||||
verify(uploadModel).selectedExistingDepictions
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -324,8 +320,8 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testIsWMLSupportedForThisPlace() {
|
||||
`when`(uploadModel.items).thenReturn(listOf(uploadItem))
|
||||
`when`(uploadItem.isWLMUpload).thenReturn(true)
|
||||
whenever(uploadModel.items).thenReturn(mutableListOf(uploadItem))
|
||||
whenever(uploadItem.isWLMUpload).thenReturn(true)
|
||||
assertEquals(
|
||||
repository.isWMLSupportedForThisPlace(),
|
||||
true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue