package fr.free.nrw.commons; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.Nullable; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import fr.free.nrw.commons.location.LatLng; public class Media implements Parcelable { public static Creator CREATOR = new Creator() { @Override public Media createFromParcel(Parcel parcel) { return new Media(parcel); } @Override public Media[] newArray(int i) { return new Media[0]; } }; private static Pattern displayTitlePattern = Pattern.compile("(.*)(\\.\\w+)", Pattern.CASE_INSENSITIVE); // Primary metadata fields protected Uri localUri; protected String imageUrl; protected String filename; protected String description; // monolingual description on input... protected long dataLength; protected Date dateCreated; protected @Nullable Date dateUploaded; protected int width; protected int height; protected String license; protected String creator; protected ArrayList categories; // as loaded at runtime? private Map descriptions; // multilingual descriptions as loaded private HashMap tags = new HashMap<>(); private @Nullable LatLng coordinates; protected Media() { this.categories = new ArrayList<>(); this.descriptions = new HashMap<>(); } public Media(String filename) { this(); this.filename = filename; } public Media(Uri localUri, String imageUrl, String filename, String description, long dataLength, Date dateCreated, @Nullable Date dateUploaded, String creator) { this(); this.localUri = localUri; this.imageUrl = imageUrl; this.filename = filename; this.description = description; this.dataLength = dataLength; this.dateCreated = dateCreated; this.dateUploaded = dateUploaded; this.creator = creator; } @SuppressWarnings("unchecked") public Media(Parcel in) { localUri = in.readParcelable(Uri.class.getClassLoader()); imageUrl = in.readString(); filename = in.readString(); description = in.readString(); dataLength = in.readLong(); dateCreated = (Date) in.readSerializable(); dateUploaded = (Date) in.readSerializable(); creator = in.readString(); tags = (HashMap) in.readSerializable(); width = in.readInt(); height = in.readInt(); license = in.readString(); if (categories != null) { in.readStringList(categories); } descriptions = in.readHashMap(ClassLoader.getSystemClassLoader()); } public Object getTag(String key) { return tags.get(key); } public void setTag(String key, Object value) { tags.put(key, value); } public String getDisplayTitle() { if (filename == null) { return ""; } // FIXME: Gross hack bercause my regex skills suck maybe or I am too lazy who knows String title = getFilePageTitle().getDisplayText().replaceFirst("^File:", ""); Matcher matcher = displayTitlePattern.matcher(title); if (matcher.matches()) { return matcher.group(1); } else { return title; } } public PageTitle getFilePageTitle() { return new PageTitle("File:" + getFilename().replaceFirst("^File:", "")); } public Uri getLocalUri() { return localUri; } @Nullable public String getImageUrl() { if (imageUrl == null && this.getFilename() != null) { imageUrl = Utils.makeThumbBaseUrl(this.getFilename()); } return imageUrl; } /** * Gets the name of the file. * @return file name as a string */ public String getFilename() { return filename; } /** * Sets the name of the file. * @param filename the new name of the file */ public void setFilename(String filename) { this.filename = filename; } /** * Gets the file description. * @return file description as a string */ public String getDescription() { return description; } /** * Sets the file description. * @param description the new description of the file */ public void setDescription(String description) { this.description = description; } /** * Gets the datalength of the file. * @return file datalength as a long */ public long getDataLength() { return dataLength; } /** * Sets the datalength of the file. * @param dataLength as a long */ public void setDataLength(long dataLength) { this.dataLength = dataLength; } /** * Gets the creation date of the file. * @return creation date as a Date */ public Date getDateCreated() { return dateCreated; } /** * Sets the creation date of the file. * @param date creation date as a Date */ public void setDateCreated(Date date) { this.dateCreated = date; } /** * 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; } /** * Sets the creator name of the file. * @param creator creator name as a string */ public void setCreator(String creator) { this.creator = creator; } /** * Gets the width of the media. * @return file width as an int */ public int getWidth() { return width; } /** * Sets the width of the media. * @param width file width as an int */ public void setWidth(int width) { this.width = width; } /** * Gets the height of the media. * @return file height as an int */ public int getHeight() { return height; } /** * Sets the height of the media. * @param height file height as an int */ public void setHeight(int height) { this.height = height; } /** * Gets the license name of the file. * @return license as a String */ public String getLicense() { return license; } /** * Sets the license name of the file. * @param license license name as a String */ public void setLicense(String license) { this.license = license; } /** * Gets the coordinates of the file. *

* Presumably indicates upload location. * @return file coordinates as a LatLng */ public @Nullable LatLng getCoordinates() { return coordinates; } /** * Sets the coordinates of the file. * @param coordinates file coordinates as a LatLng */ public void setCoordinates(@Nullable LatLng coordinates) { this.coordinates = coordinates; } /** * Gets the categories the file falls under. * @return file categories as an ArrayList of Strings */ @SuppressWarnings("unchecked") public ArrayList getCategories() { return (ArrayList) categories.clone(); // feels dirty } /** * Sets the categories the file falls under. *

* 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(List categories) { this.categories.clear(); this.categories.addAll(categories); } void setDescriptions(Map descriptions) { for (String key : this.descriptions.keySet()) { this.descriptions.remove(key); } for (String key : descriptions.keySet()) { this.descriptions.put(key, descriptions.get(key)); } } public String getDescription(String preferredLanguage) { if (descriptions.containsKey(preferredLanguage)) { // See if the requested language is there. return descriptions.get(preferredLanguage); } else if (descriptions.containsKey("en")) { // Ah, English. Language of the world, until the Chinese crush us. return descriptions.get("en"); } else if (descriptions.containsKey("default")) { // No languages marked... return descriptions.get("default"); } else { // FIXME: return the first available non-English description? return ""; } } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeParcelable(localUri, flags); parcel.writeString(imageUrl); parcel.writeString(filename); parcel.writeString(description); parcel.writeLong(dataLength); parcel.writeSerializable(dateCreated); parcel.writeSerializable(dateUploaded); parcel.writeString(creator); parcel.writeSerializable(tags); parcel.writeInt(width); parcel.writeInt(height); parcel.writeString(license); parcel.writeStringList(categories); parcel.writeMap(descriptions); } }