mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
#3847 Convert Media and Contribution to Kotlin Data Classes - convert to data classes - compose a contribution with a media
This commit is contained in:
parent
799369d6b8
commit
1ac0dfc4aa
34 changed files with 335 additions and 742 deletions
4
.idea/inspectionProfiles/Project_Default.xml
generated
4
.idea/inspectionProfiles/Project_Default.xml
generated
|
|
@ -16,6 +16,10 @@
|
|||
<option name="REPORT_PARAMETERS" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LongLine" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="MissingOverrideAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="ignoreObjectMethods" value="true" />
|
||||
<option name="ignoreAnonymousClassMethods" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="NonFinalUtilityClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="OverlyStrongTypeCast" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoreInMatchingInstanceof" value="false" />
|
||||
|
|
|
|||
|
|
@ -1,426 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
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 fr.free.nrw.commons.location.LatLng;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.wikipedia.page.PageTitle;
|
||||
|
||||
@Entity
|
||||
public class Media implements Parcelable {
|
||||
|
||||
private String thumbUrl;
|
||||
private String imageUrl;
|
||||
private String filename;
|
||||
private String fallbackDescription; // monolingual description on input...
|
||||
@Nullable private Date dateUploaded;
|
||||
private String license;
|
||||
private String licenseUrl;
|
||||
private String creator;
|
||||
/**
|
||||
* Wikibase Identifier associated with media files
|
||||
*/
|
||||
@PrimaryKey
|
||||
@NonNull
|
||||
private String pageId;
|
||||
private List<String> categories; // as loaded at runtime?
|
||||
@Nullable private LatLng coordinates;
|
||||
@NotNull
|
||||
private Map<String, String> captions = Collections.emptyMap();
|
||||
@NotNull
|
||||
private Map<String, String> descriptions = Collections.emptyMap();
|
||||
|
||||
@NotNull
|
||||
private List<String> depictionIds = Collections.emptyList();
|
||||
|
||||
/**
|
||||
* Provides local constructor
|
||||
*/
|
||||
public Media() {
|
||||
pageId = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with all parameters
|
||||
*/
|
||||
public Media(final String thumbUrl,
|
||||
final String imageUrl,
|
||||
final String filename,
|
||||
final String fallbackDescription,
|
||||
@Nullable final Date dateUploaded,
|
||||
final String license,
|
||||
final String licenseUrl,
|
||||
final String creator,
|
||||
@NonNull final String pageId,
|
||||
final List<String> categories,
|
||||
@Nullable final LatLng coordinates,
|
||||
@NotNull final Map<String, String> captions,
|
||||
@NotNull final Map<String, String> descriptions,
|
||||
@NotNull final List<String> depictionIds) {
|
||||
this.thumbUrl = thumbUrl;
|
||||
this.imageUrl = imageUrl;
|
||||
this.filename = filename;
|
||||
this.fallbackDescription = fallbackDescription;
|
||||
this.dateUploaded = dateUploaded;
|
||||
this.license = license;
|
||||
this.licenseUrl = licenseUrl;
|
||||
this.creator = creator;
|
||||
this.pageId = pageId;
|
||||
this.categories = categories;
|
||||
this.coordinates = coordinates;
|
||||
this.captions = captions;
|
||||
this.descriptions = descriptions;
|
||||
this.depictionIds = depictionIds;
|
||||
}
|
||||
|
||||
public Media(Media media) {
|
||||
this(media.getThumbUrl(), media.getImageUrl(), media.getFilename(),
|
||||
media.getFallbackDescription(), media.getDateUploaded(), media.getLicense(),
|
||||
media.getLicenseUrl(), media.getCreator(), media.getPageId(), media.getCategories(),
|
||||
media.getCoordinates(), media.getCaptions(), media.getDescriptions(),
|
||||
media.getDepictionIds());
|
||||
}
|
||||
|
||||
public Media(final String filename,
|
||||
Map<String, String> captions, final String fallbackDescription,
|
||||
final String creator, final List<String> categories) {
|
||||
this();
|
||||
thumbUrl = null;
|
||||
this.imageUrl = null;
|
||||
this.filename = filename;
|
||||
this.fallbackDescription = fallbackDescription;
|
||||
this.dateUploaded = new Date();
|
||||
this.creator = creator;
|
||||
this.categories = categories;
|
||||
this.captions=captions;
|
||||
}
|
||||
|
||||
protected Media(final Parcel in) {
|
||||
this(in.readString(), in.readString(), in.readString(),
|
||||
in.readString(), readDateUploaded(in), in.readString(),
|
||||
in.readString(), in.readString(), in.readString(), readList(in),
|
||||
in.readParcelable(LatLng.class.getClassLoader()),
|
||||
((Map<String, String>) in.readSerializable()),
|
||||
((Map<String, String>) in.readSerializable()),
|
||||
readList(in));
|
||||
}
|
||||
|
||||
private static List<String> readList(Parcel in) {
|
||||
final List<String> list = new ArrayList<>();
|
||||
in.readStringList(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static Date readDateUploaded(Parcel in) {
|
||||
final long tmpDateUploaded = in.readLong();
|
||||
return tmpDateUploaded == -1 ? null : new Date(tmpDateUploaded);
|
||||
}
|
||||
|
||||
public static final Creator<Media> CREATOR = new Creator<Media>() {
|
||||
@Override
|
||||
public Media createFromParcel(final Parcel source) {
|
||||
return new Media(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Media[] newArray(final int size) {
|
||||
return new Media[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
public String getThumbUrl() {
|
||||
return thumbUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets media display title
|
||||
* @return Media title
|
||||
*/
|
||||
@NonNull public String getDisplayTitle() {
|
||||
return filename != null ? getPageTitle().getDisplayTextWithoutNamespace().replaceFirst("[.][^.]+$", "") : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets file page title
|
||||
* @return New media page title
|
||||
*/
|
||||
@NonNull public PageTitle getPageTitle() {
|
||||
return Utils.getPageTitle(getFilename());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets image URL
|
||||
* can be null.
|
||||
* @return Image URL
|
||||
*/
|
||||
@Nullable
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the file.
|
||||
* @return file name as a string
|
||||
*/
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return pageId for the current media object*/
|
||||
@NonNull
|
||||
public String getPageId() {
|
||||
return pageId;
|
||||
}
|
||||
|
||||
/**
|
||||
*sets pageId for the current media object
|
||||
*/
|
||||
public void setPageId(final String pageId) {
|
||||
this.pageId = pageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file description.
|
||||
* @return file description as a string
|
||||
*/
|
||||
public String getFallbackDescription() {
|
||||
return fallbackDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the file.
|
||||
* @param filename the new name of the file
|
||||
*/
|
||||
public void setFilename(final String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file description.
|
||||
* @param fallbackDescription the new description of the file
|
||||
*/
|
||||
public void setFallbackDescription(final String fallbackDescription) {
|
||||
this.fallbackDescription = fallbackDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the upload date of the file.
|
||||
* Can be null.
|
||||
* @return upload date as a Date
|
||||
*/
|
||||
public @Nullable
|
||||
Date getDateUploaded() {
|
||||
return dateUploaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the creator of the file.
|
||||
* @return creator name as a String
|
||||
*/
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the license name of the file.
|
||||
* @return license as a String
|
||||
*/
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
public String getLicenseUrl() {
|
||||
return licenseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the creator name of the file.
|
||||
* @param creator creator name as a string
|
||||
*/
|
||||
public void setCreator(final String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the coordinates of where the file was created.
|
||||
* @return file coordinates as a LatLng
|
||||
*/
|
||||
public @Nullable
|
||||
LatLng getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public void setThumbUrl(final String thumbUrl) {
|
||||
this.thumbUrl = thumbUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the categories the file falls under.
|
||||
* @return file categories as an ArrayList of Strings
|
||||
*/
|
||||
public List<String> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the coordinates of where the file was created.
|
||||
* @param coordinates file coordinates as a LatLng
|
||||
*/
|
||||
public void setCoordinates(@Nullable final LatLng coordinates) {
|
||||
this.coordinates = coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns wikicode to use the media file on a MediaWiki site
|
||||
* @return
|
||||
*/
|
||||
public String getWikiCode() {
|
||||
return String.format("[[%s|thumb|%s]]", filename, getMostRelevantCaption());
|
||||
}
|
||||
|
||||
public String getMostRelevantCaption() {
|
||||
final String languageAppropriateCaption = captions.get(Locale.getDefault().getLanguage());
|
||||
if (languageAppropriateCaption != null) {
|
||||
return languageAppropriateCaption;
|
||||
}
|
||||
for (String firstCaption : captions.values()) {
|
||||
return firstCaption;
|
||||
}
|
||||
return getDisplayTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the categories the file falls under.
|
||||
* </p>
|
||||
* Does not append: i.e. will clear the current categories
|
||||
* and then add the specified ones.
|
||||
* @param categories file categories as a list of Strings
|
||||
*/
|
||||
public void setCategories(final List<String> categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the license name of the file.
|
||||
*
|
||||
* @param license license name as a String
|
||||
*/
|
||||
public void setLicense(final String license) {
|
||||
this.license = license;
|
||||
}
|
||||
|
||||
public void setImageUrl(final String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public void setDateUploaded(@Nullable final Date dateUploaded) {
|
||||
this.dateUploaded = dateUploaded;
|
||||
}
|
||||
|
||||
public void setLicenseUrl(final String licenseUrl) {
|
||||
this.licenseUrl = licenseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a way to transfer information between two or more
|
||||
* activities.
|
||||
* @param dest Instance of Parcel
|
||||
* @param flags Parcel flag
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeString(thumbUrl);
|
||||
dest.writeString(imageUrl);
|
||||
dest.writeString(filename);
|
||||
dest.writeString(fallbackDescription);
|
||||
dest.writeLong(dateUploaded != null ? dateUploaded.getTime() : -1);
|
||||
dest.writeString(license);
|
||||
dest.writeString(licenseUrl);
|
||||
dest.writeString(creator);
|
||||
dest.writeString(pageId);
|
||||
dest.writeStringList(categories);
|
||||
dest.writeParcelable(coordinates, flags);
|
||||
dest.writeSerializable((Serializable) captions);
|
||||
dest.writeSerializable((Serializable) descriptions);
|
||||
dest.writeList(depictionIds);
|
||||
}
|
||||
|
||||
public Map<String, String> getCaptions() {
|
||||
return captions;
|
||||
}
|
||||
|
||||
public void setCaptions(Map<String, String> captions) {
|
||||
this.captions = captions;
|
||||
}
|
||||
|
||||
public Map<String, String> getDescriptions() {
|
||||
return descriptions;
|
||||
}
|
||||
|
||||
public void setDescriptions(Map<String, String> descriptions) {
|
||||
this.descriptions = descriptions;
|
||||
}
|
||||
|
||||
public List<String> getDepictionIds() {
|
||||
return depictionIds;
|
||||
}
|
||||
|
||||
public void setDepictionIds(final List<String> depictionIds) {
|
||||
this.depictionIds = depictionIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Media media = (Media) o;
|
||||
return Objects.equals(thumbUrl, media.thumbUrl) &&
|
||||
Objects.equals(imageUrl, media.imageUrl) &&
|
||||
Objects.equals(filename, media.filename) &&
|
||||
Objects.equals(fallbackDescription, media.fallbackDescription) &&
|
||||
Objects.equals(dateUploaded, media.dateUploaded) &&
|
||||
Objects.equals(license, media.license) &&
|
||||
Objects.equals(licenseUrl, media.licenseUrl) &&
|
||||
Objects.equals(creator, media.creator) &&
|
||||
pageId.equals(media.pageId) &&
|
||||
Objects.equals(categories, media.categories) &&
|
||||
Objects.equals(coordinates, media.coordinates) &&
|
||||
captions.equals(media.captions) &&
|
||||
descriptions.equals(media.descriptions) &&
|
||||
depictionIds.equals(media.depictionIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects
|
||||
.hash(thumbUrl, imageUrl, filename, fallbackDescription, dateUploaded, license,
|
||||
licenseUrl,
|
||||
creator, pageId, categories, coordinates, captions, descriptions, depictionIds);
|
||||
}
|
||||
}
|
||||
124
app/src/main/java/fr/free/nrw/commons/Media.kt
Normal file
124
app/src/main/java/fr/free/nrw/commons/Media.kt
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
package fr.free.nrw.commons
|
||||
|
||||
import android.os.Parcelable
|
||||
import fr.free.nrw.commons.location.LatLng
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import org.wikipedia.page.PageTitle
|
||||
import java.util.*
|
||||
|
||||
@Parcelize
|
||||
class Media constructor(
|
||||
/**
|
||||
* @return pageId for the current media object
|
||||
* Wikibase Identifier associated with media files
|
||||
*/
|
||||
val pageId: String = UUID.randomUUID().toString(),
|
||||
val thumbUrl: String? = null,
|
||||
|
||||
/**
|
||||
* Gets image URL
|
||||
* @return Image URL
|
||||
*/
|
||||
val imageUrl: String? = null,
|
||||
/**
|
||||
* Gets the name of the file.
|
||||
* @return file name as a string
|
||||
*/
|
||||
val filename: String? = null,
|
||||
/**
|
||||
* Gets the file description.
|
||||
* @return file description as a string
|
||||
*/
|
||||
// monolingual description on input...
|
||||
/**
|
||||
* Sets the file description.
|
||||
* @param fallbackDescription the new description of the file
|
||||
*/
|
||||
var fallbackDescription: String? = null,
|
||||
|
||||
/**
|
||||
* Gets the upload date of the file.
|
||||
* Can be null.
|
||||
* @return upload date as a Date
|
||||
*/
|
||||
val dateUploaded: Date? = null,
|
||||
/**
|
||||
* Gets the license name of the file.
|
||||
* @return license as a String
|
||||
*/
|
||||
/**
|
||||
* Sets the license name of the file.
|
||||
*
|
||||
* @param license license name as a String
|
||||
*/
|
||||
var license: String? = null,
|
||||
val licenseUrl: String? = null,
|
||||
/**
|
||||
* Gets the name of the creator of the file.
|
||||
* @return creator name as a String
|
||||
*/
|
||||
/**
|
||||
* Sets the creator name of the file.
|
||||
* @param creator creator name as a string
|
||||
*/
|
||||
var creator: String? = null,
|
||||
|
||||
/**
|
||||
* Gets the categories the file falls under.
|
||||
* @return file categories as an ArrayList of Strings
|
||||
*/
|
||||
val categories: List<String>? = null,
|
||||
/**
|
||||
* Gets the coordinates of where the file was created.
|
||||
* @return file coordinates as a LatLng
|
||||
*/
|
||||
val coordinates: LatLng? = null,
|
||||
val captions: Map<String, String> = emptyMap(),
|
||||
val descriptions: Map<String, String> = emptyMap(),
|
||||
val depictionIds: List<String> = emptyList()
|
||||
) : Parcelable {
|
||||
|
||||
constructor(
|
||||
captions: Map<String, String>,
|
||||
categories: List<String>?,
|
||||
filename: String?,
|
||||
fallbackDescription: String?,
|
||||
creator: String?
|
||||
) : this(
|
||||
filename = filename,
|
||||
fallbackDescription = fallbackDescription,
|
||||
dateUploaded = Date(),
|
||||
creator = creator,
|
||||
categories = categories,
|
||||
captions = captions
|
||||
)
|
||||
|
||||
/**
|
||||
* Gets media display title
|
||||
* @return Media title
|
||||
*/
|
||||
val displayTitle: String
|
||||
get() =
|
||||
if (filename != null)
|
||||
pageTitle.displayTextWithoutNamespace.replaceFirst("[.][^.]+$".toRegex(), "")
|
||||
else
|
||||
""
|
||||
|
||||
/**
|
||||
* Gets file page title
|
||||
* @return New media page title
|
||||
*/
|
||||
val pageTitle: PageTitle get() = Utils.getPageTitle(filename!!)
|
||||
|
||||
/**
|
||||
* Returns wikicode to use the media file on a MediaWiki site
|
||||
* @return
|
||||
*/
|
||||
val wikiCode: String
|
||||
get() = String.format("[[%s|thumb|%s]]", filename, mostRelevantCaption)
|
||||
|
||||
val mostRelevantCaption: String
|
||||
get() = captions[Locale.getDefault().language]
|
||||
?: captions.values.firstOrNull()
|
||||
?: displayTitle
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ class MediaDataExtractor @Inject constructor(private val mediaClient: MediaClien
|
|||
mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/" + media.filename)
|
||||
|
||||
fun fetchDiscussion(media: Media) =
|
||||
mediaClient.getPageHtml(media.filename.replace("File", "File talk"))
|
||||
mediaClient.getPageHtml(media.filename!!.replace("File", "File talk"))
|
||||
.map { HtmlCompat.fromHtml(it, HtmlCompat.FROM_HTML_MODE_LEGACY).toString() }
|
||||
.onErrorReturn {
|
||||
Timber.d("Error occurred while fetching discussion")
|
||||
|
|
|
|||
|
|
@ -144,4 +144,9 @@ public class BookmarksActivity extends NavigationBaseActivity
|
|||
public void onMediaClicked(int position) {
|
||||
//TODO use with pagination
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,6 +156,11 @@ public class CategoryDetailsActivity extends NavigationBaseActivity
|
|||
return categoriesMediaFragment.getTotalMediaCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method inflates the menu in the toolbar
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -160,6 +160,11 @@ public class CategoryImagesActivity
|
|||
return categoriesMediaFragment.getTotalMediaCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method inflates the menu in the toolbar
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,220 +0,0 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.room.Entity;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.upload.UploadItem;
|
||||
import fr.free.nrw.commons.upload.UploadMediaDetail;
|
||||
import fr.free.nrw.commons.upload.WikidataPlace;
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity(tableName = "contribution")
|
||||
public class Contribution extends Media {
|
||||
|
||||
// No need to be bitwise - they're mutually exclusive
|
||||
public static final int STATE_COMPLETED = -1;
|
||||
public static final int STATE_FAILED = 1;
|
||||
public static final int STATE_QUEUED = 2;
|
||||
public static final int STATE_IN_PROGRESS = 3;
|
||||
|
||||
private int state;
|
||||
private long transferred;
|
||||
private String decimalCoords;
|
||||
private String dateCreatedSource;
|
||||
private WikidataPlace wikidataPlace;
|
||||
/**
|
||||
* Each depiction loaded in depictions activity is associated with a wikidata entity id, this Id
|
||||
* is in turn used to upload depictions to wikibase
|
||||
*/
|
||||
private List<DepictedItem> depictedItems = new ArrayList<>();
|
||||
private String mimeType;
|
||||
@Nullable
|
||||
private Uri localUri;
|
||||
private long dataLength;
|
||||
private Date dateCreated;
|
||||
|
||||
public Contribution() {
|
||||
}
|
||||
|
||||
public Contribution(final UploadItem item, final SessionManager sessionManager,
|
||||
final List<DepictedItem> depictedItems, final List<String> categories) {
|
||||
super(
|
||||
item.getFileName(),
|
||||
UploadMediaDetail.formatCaptions(item.getUploadMediaDetails()),
|
||||
UploadMediaDetail.formatDescriptions(item.getUploadMediaDetails()),
|
||||
sessionManager.getAuthorName(),
|
||||
categories);
|
||||
localUri = item.getMediaUri();
|
||||
decimalCoords = item.getGpsCoords().getDecimalCoords();
|
||||
dateCreatedSource = "";
|
||||
this.depictedItems = depictedItems;
|
||||
wikidataPlace = WikidataPlace.from(item.getPlace());
|
||||
}
|
||||
|
||||
public void setDateCreatedSource(final String dateCreatedSource) {
|
||||
this.dateCreatedSource = dateCreatedSource;
|
||||
}
|
||||
|
||||
public String getDateCreatedSource() {
|
||||
return dateCreatedSource;
|
||||
}
|
||||
|
||||
public long getTransferred() {
|
||||
return transferred;
|
||||
}
|
||||
|
||||
public void setTransferred(final long transferred) {
|
||||
this.transferred = transferred;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(final int state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array list of entityids for the depictions
|
||||
*/
|
||||
public List<DepictedItem> getDepictedItems() {
|
||||
return depictedItems;
|
||||
}
|
||||
|
||||
public void setWikidataPlace(final WikidataPlace wikidataPlace) {
|
||||
this.wikidataPlace = wikidataPlace;
|
||||
}
|
||||
|
||||
public WikidataPlace getWikidataPlace() {
|
||||
return wikidataPlace;
|
||||
}
|
||||
|
||||
public String getDecimalCoords() {
|
||||
return decimalCoords;
|
||||
}
|
||||
|
||||
public void setDecimalCoords(final String decimalCoords) {
|
||||
this.decimalCoords = decimalCoords;
|
||||
}
|
||||
|
||||
public void setDepictedItems(final List<DepictedItem> depictedItems) {
|
||||
this.depictedItems = depictedItems;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public void setMimeType(final String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(state);
|
||||
dest.writeLong(transferred);
|
||||
dest.writeString(decimalCoords);
|
||||
dest.writeString(dateCreatedSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that takes Media object and state as parameters and builds a new Contribution object
|
||||
* @param media
|
||||
* @param state
|
||||
*/
|
||||
public Contribution(Media media, int state) {
|
||||
super(media);
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
protected Contribution(final Parcel in) {
|
||||
super(in);
|
||||
state = in.readInt();
|
||||
transferred = in.readLong();
|
||||
decimalCoords = in.readString();
|
||||
dateCreatedSource = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator<Contribution> CREATOR = new Creator<Contribution>() {
|
||||
@Override
|
||||
public Contribution createFromParcel(final Parcel source) {
|
||||
return new Contribution(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Contribution[] newArray(final int size) {
|
||||
return new Contribution[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
public Uri getLocalUri() {
|
||||
return localUri;
|
||||
}
|
||||
|
||||
public void setLocalUri(@Nullable Uri localUri) {
|
||||
this.localUri = localUri;
|
||||
}
|
||||
|
||||
public long getDataLength() {
|
||||
return dataLength;
|
||||
}
|
||||
|
||||
public void setDataLength(long dataLength) {
|
||||
this.dataLength = dataLength;
|
||||
}
|
||||
|
||||
public Date getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
public void setDateCreated(Date dateCreated) {
|
||||
this.dateCreated = dateCreated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
final Contribution that = (Contribution) o;
|
||||
return state == that.state &&
|
||||
transferred == that.transferred &&
|
||||
dataLength == that.dataLength &&
|
||||
Objects.equals(decimalCoords, that.decimalCoords) &&
|
||||
Objects.equals(dateCreatedSource, that.dateCreatedSource) &&
|
||||
Objects.equals(wikidataPlace, that.wikidataPlace) &&
|
||||
Objects.equals(depictedItems, that.depictedItems) &&
|
||||
Objects.equals(mimeType, that.mimeType) &&
|
||||
Objects.equals(localUri, that.localUri) &&
|
||||
Objects.equals(dateCreated, that.dateCreated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects
|
||||
.hash(super.hashCode(), state, transferred, decimalCoords, dateCreatedSource,
|
||||
wikidataPlace,
|
||||
depictedItems, mimeType, localUri, dataLength, dateCreated);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package fr.free.nrw.commons.contributions
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.upload.UploadItem
|
||||
import fr.free.nrw.commons.upload.UploadMediaDetail
|
||||
import fr.free.nrw.commons.upload.WikidataPlace
|
||||
import fr.free.nrw.commons.upload.WikidataPlace.Companion.from
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import java.util.*
|
||||
|
||||
@Entity(tableName = "contribution")
|
||||
@Parcelize
|
||||
data class Contribution constructor(
|
||||
@Embedded(prefix = "media_") val media: Media,
|
||||
@PrimaryKey val pageId: String = media.pageId,
|
||||
var state: Int = 0,
|
||||
var transferred: Long = 0,
|
||||
val decimalCoords: String? = null,
|
||||
var dateCreatedSource: String? = null,
|
||||
var wikidataPlace: WikidataPlace? = null,
|
||||
/**
|
||||
* @return array list of entityids for the depictions
|
||||
*/
|
||||
/**
|
||||
* Each depiction loaded in depictions activity is associated with a wikidata entity id, this Id
|
||||
* is in turn used to upload depictions to wikibase
|
||||
*/
|
||||
val depictedItems: List<DepictedItem> = ArrayList(),
|
||||
var mimeType: String? = null,
|
||||
val localUri: Uri? = null,
|
||||
var dataLength: Long = 0,
|
||||
var dateCreated: Date? = null
|
||||
) : Parcelable {
|
||||
|
||||
fun completeWith(media: Media): Contribution {
|
||||
return copy(pageId = media.pageId, media = media, state = STATE_COMPLETED)
|
||||
}
|
||||
|
||||
constructor(
|
||||
item: UploadItem,
|
||||
sessionManager: SessionManager,
|
||||
depictedItems: List<DepictedItem>,
|
||||
categories: List<String>
|
||||
) : this(
|
||||
Media(
|
||||
formatCaptions(item.uploadMediaDetails),
|
||||
categories,
|
||||
item.fileName,
|
||||
formatDescriptions(item.uploadMediaDetails),
|
||||
sessionManager.authorName
|
||||
),
|
||||
localUri = item.mediaUri,
|
||||
decimalCoords = item.gpsCoords.decimalCoords,
|
||||
dateCreatedSource = "",
|
||||
depictedItems = depictedItems,
|
||||
wikidataPlace = from(item.place)
|
||||
)
|
||||
|
||||
companion object {
|
||||
const val STATE_COMPLETED = -1
|
||||
const val STATE_FAILED = 1
|
||||
const val STATE_QUEUED = 2
|
||||
const val STATE_IN_PROGRESS = 3
|
||||
|
||||
/**
|
||||
* Formatting captions to the Wikibase format for sending labels
|
||||
* @param uploadMediaDetails list of media Details
|
||||
*/
|
||||
fun formatCaptions(uploadMediaDetails: List<UploadMediaDetail>) =
|
||||
uploadMediaDetails.associate { it.languageCode!! to it.captionText }
|
||||
.filter { it.value.isNotBlank() }
|
||||
|
||||
/**
|
||||
* 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}}
|
||||
*/
|
||||
fun formatDescriptions(descriptions: List<UploadMediaDetail>) =
|
||||
descriptions.filter { it.descriptionText.isNotEmpty() }
|
||||
.joinToString { "{{${it.languageCode}|1=${it.descriptionText}}}" }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package fr.free.nrw.commons.contributions
|
||||
|
||||
import androidx.paging.PagedList.BoundaryCallback
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.di.CommonsApplicationModule
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
|
|
@ -53,9 +52,9 @@ class ContributionBoundaryCallback @Inject constructor(
|
|||
fun fetchContributions() {
|
||||
compositeDisposable.add(
|
||||
mediaClient.getMediaListForUser(sessionManager.userName!!)
|
||||
.map { mediaList: List<Media?> ->
|
||||
.map { mediaList ->
|
||||
mediaList.map {
|
||||
Contribution(it, Contribution.STATE_COMPLETED)
|
||||
Contribution(media=it, state=Contribution.STATE_COMPLETED)
|
||||
}
|
||||
}
|
||||
.subscribeOn(ioThreadScheduler)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import java.util.List;
|
|||
@Dao
|
||||
public abstract class ContributionDao {
|
||||
|
||||
@Query("SELECT * FROM contribution order by dateUploaded DESC")
|
||||
@Query("SELECT * FROM contribution order by media_dateUploaded DESC")
|
||||
abstract DataSource.Factory<Integer, Contribution> fetchContributions();
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
|
|
@ -50,7 +50,7 @@ public abstract class ContributionDao {
|
|||
.fromAction(() -> deleteSynchronous(contribution));
|
||||
}
|
||||
|
||||
@Query("SELECT * from contribution WHERE filename=:fileName")
|
||||
@Query("SELECT * from contribution WHERE media_filename=:fileName")
|
||||
public abstract List<Contribution> getContributionWithTitle(String fileName);
|
||||
|
||||
@Query("SELECT * from contribution WHERE pageId=:pageId")
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
public void init(final int position, final Contribution contribution) {
|
||||
this.contribution = contribution;
|
||||
this.position = position;
|
||||
titleView.setText(contribution.getMostRelevantCaption());
|
||||
final String imageSource = chooseImageSource(contribution.getThumbUrl(),
|
||||
titleView.setText(contribution.getMedia().getMostRelevantCaption());
|
||||
final String imageSource = chooseImageSource(contribution.getMedia().getThumbUrl(),
|
||||
contribution.getLocalUri());
|
||||
if (!TextUtils.isEmpty(imageSource)) {
|
||||
final ImageRequest imageRequest =
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
|||
import fr.free.nrw.commons.nearby.NearbyController;
|
||||
import fr.free.nrw.commons.nearby.NearbyNotificationCardView;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.settings.Prefs;
|
||||
import fr.free.nrw.commons.upload.UploadService;
|
||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||
import fr.free.nrw.commons.utils.DialogUtil;
|
||||
|
|
@ -490,5 +489,10 @@ public class ContributionsFragment
|
|||
public int getTotalMediaCount() {
|
||||
return contributionsListFragment.getTotalMediaCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return contributionsListFragment.getContributionStateAt(position);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
|||
|
||||
|
||||
public Media getMediaAtPosition(final int i) {
|
||||
return adapter.getContributionForPosition(i);
|
||||
return adapter.getContributionForPosition(i).getMedia();
|
||||
}
|
||||
|
||||
public int getTotalMediaCount() {
|
||||
|
|
@ -292,7 +292,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
|||
@Override
|
||||
public void onConfirmClicked(@Nullable Contribution contribution, boolean copyWikicode) {
|
||||
if(copyWikicode) {
|
||||
String wikicode = contribution.getWikiCode();
|
||||
String wikicode = contribution.getMedia().getWikiCode();
|
||||
Utils.copy("wikicode", wikicode, getContext());
|
||||
}
|
||||
|
||||
|
|
@ -301,6 +301,10 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
|||
Utils.handleWebUrl(getContext(), Uri.parse(url));
|
||||
}
|
||||
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return adapter.getContributionForPosition(position).getState();
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
|
||||
void retryUpload(Contribution contribution);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class WikipediaInstructionsDialogFragment : DialogFragment() {
|
|||
) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
contribution = arguments!!.getParcelable(ARG_CONTRIBUTION)
|
||||
tv_wikicode.setText(contribution?.wikiCode)
|
||||
tv_wikicode.setText(contribution?.media?.wikiCode)
|
||||
instructions_cancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import fr.free.nrw.commons.contributions.ContributionDao
|
|||
* The database for accessing the respective DAOs
|
||||
*
|
||||
*/
|
||||
@Database(entities = [Contribution::class], version = 3, exportSchema = false)
|
||||
@Database(entities = [Contribution::class], version = 4, exportSchema = false)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun contributionDao(): ContributionDao
|
||||
|
|
|
|||
|
|
@ -134,6 +134,11 @@ public class ExploreActivity
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called on success of API call for featured images or mobile uploads.
|
||||
* The viewpager will notified that number of items have changed.
|
||||
|
|
|
|||
|
|
@ -176,6 +176,11 @@ public class SearchActivity extends NavigationBaseActivity
|
|||
return searchMediaFragment.getTotalMediaCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called on success of API call for image Search.
|
||||
* The viewpager will notified that number of items have changed.
|
||||
|
|
|
|||
|
|
@ -173,6 +173,11 @@ public class WikidataItemDetailsActivity extends NavigationBaseActivity implemen
|
|||
return depictionImagesListFragment.getTotalMediaCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getContributionStateAt(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumers should be simply using this method to use this activity.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,14 +17,11 @@ import java.util.*
|
|||
import javax.inject.Inject
|
||||
|
||||
class MediaConverter @Inject constructor() {
|
||||
fun convert(
|
||||
page: MwQueryPage,
|
||||
entity: Entities.Entity,
|
||||
imageInfo: ImageInfo
|
||||
): Media {
|
||||
fun convert(page: MwQueryPage, entity: Entities.Entity, imageInfo: ImageInfo): Media {
|
||||
val metadata = imageInfo.metadata
|
||||
requireNotNull(metadata) { "No metadata" }
|
||||
return Media(
|
||||
page.pageId().toString(),
|
||||
imageInfo.thumbUrl.takeIf { it.isNotBlank() } ?: imageInfo.originalUrl,
|
||||
imageInfo.originalUrl,
|
||||
page.title(),
|
||||
|
|
@ -33,14 +30,12 @@ class MediaConverter @Inject constructor() {
|
|||
metadata.licenseShortName(),
|
||||
metadata.prefixedLicenseUrl,
|
||||
getArtist(metadata),
|
||||
page.pageId().toString(),
|
||||
MediaDataExtractorUtil.extractCategoriesFromList(metadata.categories),
|
||||
metadata.latLng,
|
||||
entity.labels().mapValues { it.value.value() },
|
||||
entity.descriptions().mapValues { it.value.value() },
|
||||
entity.depictionIds()
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -49,4 +49,6 @@ abstract class PageableMediaFragment : BasePagingFragment<Media>(), MediaDetailP
|
|||
}
|
||||
|
||||
override fun getTotalMediaCount(): Int = pagedListAdapter.itemCount
|
||||
|
||||
override fun getContributionStateAt(position: Int) = null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,7 +188,8 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
|||
return;
|
||||
}
|
||||
|
||||
Media m = provider.getMediaAtPosition(pager.getCurrentItem());
|
||||
final int position = pager.getCurrentItem();
|
||||
Media m = provider.getMediaAtPosition(position);
|
||||
if (m != null) {
|
||||
// Enable default set of actions, then re-enable different set of actions only if it is a failed contrib
|
||||
menu.findItem(R.id.menu_browser_current_image).setEnabled(true).setVisible(true);
|
||||
|
|
@ -204,10 +205,9 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
|||
BookmarkPicturesContentProvider.uriForName(m.getFilename())
|
||||
);
|
||||
updateBookmarkState(menu.findItem(R.id.menu_bookmark_current_image));
|
||||
|
||||
if (m instanceof Contribution) {
|
||||
Contribution c = (Contribution) m;
|
||||
switch (c.getState()) {
|
||||
final Integer contributionState = provider.getContributionStateAt(position);
|
||||
if (contributionState != null) {
|
||||
switch (contributionState) {
|
||||
case Contribution.STATE_FAILED:
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
case Contribution.STATE_QUEUED:
|
||||
|
|
@ -289,6 +289,8 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
|||
Media getMediaAtPosition(int i);
|
||||
|
||||
int getTotalMediaCount();
|
||||
|
||||
Integer getContributionStateAt(int position);
|
||||
}
|
||||
|
||||
//FragmentStatePagerAdapter allows user to swipe across collection of images (no. of images undetermined)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.upload;
|
|||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
import fr.free.nrw.commons.filepicker.UploadableFile.DateTimeWithSource;
|
||||
import fr.free.nrw.commons.settings.Prefs.Licenses;
|
||||
|
|
@ -30,13 +31,14 @@ class PageContentsCreator {
|
|||
|
||||
public String createFrom(Contribution contribution) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
final Media media = contribution.getMedia();
|
||||
buffer
|
||||
.append("== {{int:filedesc}} ==\n")
|
||||
.append("{{Information\n")
|
||||
.append("|description=").append(contribution.getFallbackDescription()).append("\n")
|
||||
.append("|description=").append(media.getFallbackDescription()).append("\n")
|
||||
.append("|source=").append("{{own}}\n")
|
||||
.append("|author=[[User:").append(contribution.getCreator()).append("|")
|
||||
.append(contribution.getCreator()).append("]]\n");
|
||||
.append("|author=[[User:").append(media.getCreator()).append("|")
|
||||
.append(media.getCreator()).append("]]\n");
|
||||
|
||||
String templatizedCreatedDate = getTemplatizedCreatedDate(
|
||||
contribution.getDateCreated(), contribution.getDateCreatedSource());
|
||||
|
|
@ -53,10 +55,10 @@ class PageContentsCreator {
|
|||
}
|
||||
|
||||
buffer.append("== {{int:license-header}} ==\n")
|
||||
.append(licenseTemplateFor(contribution.getLicense())).append("\n\n")
|
||||
.append(licenseTemplateFor(media.getLicense())).append("\n\n")
|
||||
.append("{{Uploaded from Mobile|platform=Android|version=")
|
||||
.append(ConfigUtils.getVersionNameWithSha(context)).append("}}\n");
|
||||
final List<String> categories = contribution.getCategories();
|
||||
final List<String> categories = media.getCategories();
|
||||
if (categories != null && categories.size() != 0) {
|
||||
for (int i = 0; i < categories.size(); i++) {
|
||||
buffer.append("\n[[Category:").append(categories.get(i)).append("]]");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import android.net.Uri;
|
|||
import android.os.IBinder;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.TextUtils;
|
||||
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;
|
||||
|
|
@ -93,12 +94,13 @@ public class UploadController {
|
|||
//Set creator, desc, and license
|
||||
|
||||
// If author name is enabled and set, use it
|
||||
final Media media = contribution.getMedia();
|
||||
if (store.getBoolean("useAuthorName", false)) {
|
||||
final String authorName = store.getString("authorName", "");
|
||||
contribution.setCreator(authorName);
|
||||
media.setCreator(authorName);
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(contribution.getCreator())) {
|
||||
if (TextUtils.isEmpty(media.getCreator())) {
|
||||
final Account currentAccount = sessionManager.getCurrentAccount();
|
||||
if (currentAccount == null) {
|
||||
Timber.d("Current account is null");
|
||||
|
|
@ -106,15 +108,15 @@ public class UploadController {
|
|||
sessionManager.forceLogin(context);
|
||||
return;
|
||||
}
|
||||
contribution.setCreator(sessionManager.getAuthorName());
|
||||
media.setCreator(sessionManager.getAuthorName());
|
||||
}
|
||||
|
||||
if (contribution.getFallbackDescription() == null) {
|
||||
contribution.setFallbackDescription("");
|
||||
if (media.getFallbackDescription() == null) {
|
||||
media.setFallbackDescription("");
|
||||
}
|
||||
|
||||
final String license = store.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA_3);
|
||||
contribution.setLicense(license);
|
||||
media.setLicense(license);
|
||||
|
||||
uploadTask(contribution);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,24 +41,4 @@ data class UploadMediaDetail constructor(
|
|||
*/
|
||||
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<UploadMediaDetail>) =
|
||||
uploadMediaDetails.associate { it.languageCode to it.captionText }.filter { it.value.isNotBlank() }
|
||||
|
||||
/**
|
||||
* 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 formatDescriptions(descriptions: List<UploadMediaDetail>) =
|
||||
descriptions.filter { it.descriptionText.isNotEmpty() }
|
||||
.joinToString { "{{${it.languageCode}|1=${it.descriptionText}}}" }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import androidx.core.app.NotificationCompat;
|
|||
import androidx.core.app.NotificationManagerCompat;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
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;
|
||||
|
|
@ -224,25 +225,27 @@ public class UploadService extends CommonsDaggerService {
|
|||
File localFile = new File(localUri.getPath());
|
||||
|
||||
Timber.d("Before execution!");
|
||||
final Media media = contribution.getMedia();
|
||||
final String displayTitle = media.getDisplayTitle();
|
||||
curNotification.setContentTitle(getString(R.string.upload_progress_notification_title_start,
|
||||
contribution.getDisplayTitle()))
|
||||
displayTitle))
|
||||
.setContentText(getResources()
|
||||
.getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload,
|
||||
toUpload))
|
||||
.setTicker(getString(R.string.upload_progress_notification_title_in_progress,
|
||||
contribution.getDisplayTitle()))
|
||||
displayTitle))
|
||||
.setOngoing(true);
|
||||
notificationManager
|
||||
.notify(notificationTag, NOTIFICATION_UPLOAD_IN_PROGRESS, curNotification.build());
|
||||
|
||||
String filename = contribution.getFilename();
|
||||
String filename = media.getFilename();
|
||||
|
||||
NotificationUpdateProgressListener notificationUpdater = new NotificationUpdateProgressListener(
|
||||
notificationTag,
|
||||
getString(R.string.upload_progress_notification_title_in_progress,
|
||||
contribution.getDisplayTitle()),
|
||||
displayTitle),
|
||||
getString(R.string.upload_progress_notification_title_finishing,
|
||||
contribution.getDisplayTitle()),
|
||||
displayTitle),
|
||||
contribution
|
||||
);
|
||||
|
||||
|
|
@ -320,13 +323,7 @@ public class UploadService extends CommonsDaggerService {
|
|||
|
||||
private void saveCompletedContribution(Contribution contribution, UploadResult uploadResult) {
|
||||
compositeDisposable.add(mediaClient.getMedia("File:" + uploadResult.getFilename())
|
||||
.map(media -> {
|
||||
Contribution newContribution = new Contribution(media, Contribution.STATE_COMPLETED);
|
||||
if (contribution.getWikidataPlace() != null) {
|
||||
newContribution.setWikidataPlace(contribution.getWikidataPlace());
|
||||
}
|
||||
return newContribution;
|
||||
})
|
||||
.map(contribution::completeWith)
|
||||
.flatMapCompletable(
|
||||
newContribution -> contributionDao.saveAndDelete(contribution, newContribution))
|
||||
.subscribe());
|
||||
|
|
@ -335,10 +332,9 @@ public class UploadService extends CommonsDaggerService {
|
|||
@SuppressLint("StringFormatInvalid")
|
||||
@SuppressWarnings("deprecation")
|
||||
private void showFailedNotification(Contribution contribution) {
|
||||
curNotification.setTicker(
|
||||
getString(R.string.upload_failed_notification_title, contribution.getDisplayTitle()))
|
||||
.setContentTitle(
|
||||
getString(R.string.upload_failed_notification_title, contribution.getDisplayTitle()))
|
||||
final String displayTitle = contribution.getMedia().getDisplayTitle();
|
||||
curNotification.setTicker(getString(R.string.upload_failed_notification_title, displayTitle))
|
||||
.setContentTitle(getString(R.string.upload_failed_notification_title, displayTitle))
|
||||
.setContentText(getString(R.string.upload_failed_notification_subtitle))
|
||||
.setProgress(0, 0, false)
|
||||
.setOngoing(false);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import fr.free.nrw.commons.nearby.Place
|
|||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
internal data class WikidataPlace(
|
||||
data class WikidataPlace(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
val imageValue: String?,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package fr.free.nrw.commons.upload.structure.depictions
|
||||
|
||||
import android.os.Parcelable
|
||||
import fr.free.nrw.commons.nearby.Place
|
||||
import fr.free.nrw.commons.upload.WikidataItem
|
||||
import fr.free.nrw.commons.wikidata.WikidataProperties
|
||||
import fr.free.nrw.commons.wikidata.WikidataProperties.*
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import org.wikipedia.wikidata.DataValue
|
||||
import org.wikipedia.wikidata.Entities
|
||||
import org.wikipedia.wikidata.Statement_partial
|
||||
|
|
@ -17,6 +19,7 @@ const val THUMB_IMAGE_SIZE = "70px"
|
|||
/**
|
||||
* Model class for Depicted Item in Upload and Explore
|
||||
*/
|
||||
@Parcelize
|
||||
data class DepictedItem constructor(
|
||||
override val name: String,
|
||||
val description: String?,
|
||||
|
|
@ -25,7 +28,7 @@ data class DepictedItem constructor(
|
|||
val commonsCategories: List<String>,
|
||||
var isSelected: Boolean,
|
||||
override val id: String
|
||||
) : WikidataItem {
|
||||
) : WikidataItem, Parcelable {
|
||||
|
||||
constructor(entity: Entities.Entity) : this(
|
||||
entity,
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ public class WikidataEditService {
|
|||
}
|
||||
|
||||
private Observable<Boolean> captionEdits(Contribution contribution, Long fileEntityId) {
|
||||
return Observable.fromIterable(contribution.getCaptions().entrySet())
|
||||
return Observable.fromIterable(contribution.getMedia().getCaptions().entrySet())
|
||||
.concatMap(entry -> addCaption(fileEntityId, entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,11 @@ fun media(
|
|||
pageId: String = "pageId",
|
||||
categories: List<String>? = listOf("categories"),
|
||||
coordinates: LatLng? = LatLng(0.0, 0.0, 0.0f),
|
||||
captions: Map<String?, String?> = mapOf("en" to "caption"),
|
||||
descriptions: Map<String?, String?> = mapOf("en" to "description"),
|
||||
captions: Map<String, String> = mapOf("en" to "caption"),
|
||||
descriptions: Map<String, String> = mapOf("en" to "description"),
|
||||
depictionIds: List<String> = listOf("depictionId")
|
||||
) = Media(
|
||||
pageId,
|
||||
thumbUrl,
|
||||
imageUrl,
|
||||
filename,
|
||||
|
|
@ -56,7 +57,6 @@ fun media(
|
|||
license,
|
||||
licenseUrl,
|
||||
creator,
|
||||
pageId,
|
||||
categories,
|
||||
coordinates,
|
||||
captions,
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
|||
import com.nhaarman.mockitokotlin2.verify
|
||||
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import io.reactivex.Scheduler
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import media
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
|
@ -57,9 +57,8 @@ class ContributionBoundaryCallbackTest {
|
|||
whenever(repository.save(anyList<Contribution>()))
|
||||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
)
|
||||
whenever(mediaClient.getMediaListForUser(anyString()))
|
||||
.thenReturn(Single.just(listOf(media())))
|
||||
contributionBoundaryCallback.onZeroItemsLoaded()
|
||||
verify(repository).save(anyList<Contribution>());
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
|
|
@ -70,9 +69,8 @@ class ContributionBoundaryCallbackTest {
|
|||
whenever(repository.save(anyList<Contribution>()))
|
||||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
)
|
||||
whenever(mediaClient.getMediaListForUser(anyString()))
|
||||
.thenReturn(Single.just(listOf(media())))
|
||||
contributionBoundaryCallback.onItemAtEndLoaded(mock(Contribution::class.java))
|
||||
verify(repository).save(anyList());
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
|
|
@ -83,9 +81,8 @@ class ContributionBoundaryCallbackTest {
|
|||
whenever(repository.save(anyList<Contribution>()))
|
||||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
)
|
||||
whenever(mediaClient.getMediaListForUser(anyString()))
|
||||
.thenReturn(Single.just(listOf(media())))
|
||||
contributionBoundaryCallback.onItemAtFrontLoaded(mock(Contribution::class.java))
|
||||
verify(repository).save(anyList());
|
||||
verify(mediaClient).getMediaListForUser(anyString());
|
||||
|
|
@ -97,7 +94,7 @@ class ContributionBoundaryCallbackTest {
|
|||
.thenReturn(Single.just(listOf(1L, 2L)))
|
||||
whenever(sessionManager.userName).thenReturn("Test")
|
||||
whenever(mediaClient.getMediaListForUser(anyString())).thenReturn(
|
||||
Single.just(listOf(mock(Media::class.java)))
|
||||
Single.just(listOf(media()))
|
||||
)
|
||||
contributionBoundaryCallback.fetchContributions()
|
||||
verify(repository).save(anyList());
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class DeleteHelperTest {
|
|||
.thenReturn(Observable.just(true))
|
||||
|
||||
whenever(media.displayTitle).thenReturn("Test file")
|
||||
media.filename ="Test file.jpg"
|
||||
whenever(media.filename).thenReturn("Test file.jpg")
|
||||
|
||||
whenever(media.creator).thenReturn(null)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package fr.free.nrw.commons.review
|
||||
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import junit.framework.Assert.assertNotNull
|
||||
import junit.framework.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
|
|
@ -61,7 +61,7 @@ class ReviewHelperTest {
|
|||
.thenReturn(Observable.just(mockResponse))
|
||||
|
||||
val media = mock(Media::class.java)
|
||||
media.filename="File:Test.jpg"
|
||||
whenever(media.filename).thenReturn("Test file.jpg")
|
||||
`when`(mediaClient?.getMedia(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Single.just(media))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ package fr.free.nrw.commons.upload
|
|||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
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.kvstore.JsonKvStore
|
||||
|
|
@ -47,7 +50,9 @@ class UploadControllerTest {
|
|||
@Test
|
||||
fun startUpload() {
|
||||
val contribution = mock(Contribution::class.java)
|
||||
`when`(contribution.getCreator()).thenReturn("Creator")
|
||||
val media = mock<Media>()
|
||||
whenever(contribution.media).thenReturn(media)
|
||||
whenever(media.creator).thenReturn("Creator")
|
||||
uploadController!!.startUpload(contribution)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue