[WIP] Fix both timezone problem and saved date problem (#5019)

* Fix both timezone problem and saved date problem

* Fixaccidental test code and add comments

* Add issue link to the comments

* Fix format issue and null checks
This commit is contained in:
neslihanturan 2022-08-03 14:09:07 +03:00 committed by GitHub
parent cb3094b51c
commit 98143aa969
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 11 deletions

View file

@ -38,6 +38,7 @@ data class Contribution constructor(
val localUri: Uri? = null, val localUri: Uri? = null,
var dataLength: Long = 0, var dataLength: Long = 0,
var dateCreated: Date? = null, var dateCreated: Date? = null,
var dateCreatedString: String? = null,
var dateModified: Date? = null, var dateModified: Date? = null,
var hasInvalidLocation : Int = 0, var hasInvalidLocation : Int = 0,
var contentUri: Uri? = null, var contentUri: Uri? = null,
@ -67,7 +68,8 @@ data class Contribution constructor(
dateCreatedSource = "", dateCreatedSource = "",
depictedItems = depictedItems, depictedItems = depictedItems,
wikidataPlace = from(item.place), wikidataPlace = from(item.place),
contentUri = item.contentUri contentUri = item.contentUri,
dateCreatedString = item.fileCreatedDateString
) )
/** /**

View file

@ -14,7 +14,7 @@ import fr.free.nrw.commons.upload.depicts.DepictsDao
* The database for accessing the respective DAOs * The database for accessing the respective DAOs
* *
*/ */
@Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class], version = 12, exportSchema = false) @Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class], version = 13, exportSchema = false)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
abstract fun contributionDao(): ContributionDao abstract fun contributionDao(): ContributionDao

View file

@ -12,6 +12,8 @@ import androidx.exifinterface.media.ExifInterface;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import fr.free.nrw.commons.upload.FileUtils; import fr.free.nrw.commons.upload.FileUtils;
@ -124,13 +126,30 @@ public class UploadableFile implements Parcelable {
private DateTimeWithSource getDateTimeFromExif() { private DateTimeWithSource getDateTimeFromExif() {
try { try {
ExifInterface exif = new ExifInterface(file.getAbsolutePath()); ExifInterface exif = new ExifInterface(file.getAbsolutePath());
@SuppressLint("RestrictedApi") Long dateTime = exif.getDateTime(); // TAG_DATETIME returns the last edited date, we need TAG_DATETIME_ORIGINAL for creation date
if(dateTime != null){ // See issue https://github.com/commons-app/apps-android-commons/issues/1971
Date date = new Date(dateTime); String dateTimeSubString = exif.getAttribute(ExifInterface.TAG_DATETIME_ORIGINAL);
return new DateTimeWithSource(date, DateTimeWithSource.EXIF_SOURCE); if (dateTimeSubString!=null) { //getAttribute may return null
String year = dateTimeSubString.substring(0,4);
String month = dateTimeSubString.substring(5,7);
String day = dateTimeSubString.substring(8,10);
// This date is stored as a string (not as a date), the rason is we don't want to include timezones
String dateCreatedString = String.format("%04d-%02d-%02d", Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day));
if (dateCreatedString.length() == 10) { //yyyy-MM-dd format of date is expected
@SuppressLint("RestrictedApi") Long dateTime = exif.getDateTimeOriginal();
if(dateTime != null){
Date date = new Date(dateTime);
return new DateTimeWithSource(date, dateCreatedString, DateTimeWithSource.EXIF_SOURCE);
}
}
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
} }
return null; return null;
} }
@ -149,6 +168,7 @@ public class UploadableFile implements Parcelable {
public static final String EXIF_SOURCE = "exif"; public static final String EXIF_SOURCE = "exif";
private final long epochDate; private final long epochDate;
private String dateString; // this does not includes timezone information
private final String source; private final String source;
public DateTimeWithSource(long epochDate, String source) { public DateTimeWithSource(long epochDate, String source) {
@ -161,10 +181,20 @@ public class UploadableFile implements Parcelable {
this.source = source; this.source = source;
} }
public DateTimeWithSource(Date date, String dateString, String source) {
this.epochDate = date.getTime();
this.dateString = dateString;
this.source = source;
}
public long getEpochDate() { public long getEpochDate() {
return epochDate; return epochDate;
} }
public String getDateString() {
return dateString;
}
public String getSource() { public String getSource() {
return source; return source;
} }

View file

@ -48,7 +48,7 @@ class PageContentsCreator {
.append(media.getAuthor()).append("]]\n"); .append(media.getAuthor()).append("]]\n");
final String templatizedCreatedDate = getTemplatizedCreatedDate( final String templatizedCreatedDate = getTemplatizedCreatedDate(
contribution.getDateCreated(), contribution.getDateCreatedSource()); contribution.getDateCreatedString(), contribution.getDateCreated(), contribution.getDateCreatedSource());
if (!StringUtils.isBlank(templatizedCreatedDate)) { if (!StringUtils.isBlank(templatizedCreatedDate)) {
buffer.append("|date=").append(templatizedCreatedDate); buffer.append("|date=").append(templatizedCreatedDate);
} }
@ -90,12 +90,12 @@ class PageContentsCreator {
* @param dateCreatedSource * @param dateCreatedSource
* @return * @return
*/ */
private String getTemplatizedCreatedDate(Date dateCreated, String dateCreatedSource) { private String getTemplatizedCreatedDate(String dateCreatedString, Date dateCreated, String dateCreatedSource) {
if (dateCreated != null) { if (dateCreated != null) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
return String.format(Locale.ENGLISH, return String.format(Locale.ENGLISH,
isExif(dateCreatedSource) ? TEMPLATE_DATE_ACC_TO_EXIF : TEMPLATE_DATA_OTHER_SOURCE, isExif(dateCreatedSource) ? TEMPLATE_DATE_ACC_TO_EXIF : TEMPLATE_DATA_OTHER_SOURCE,
dateFormat.format(dateCreated) isExif(dateCreatedSource) ? dateCreatedString: dateFormat.format(dateCreated)
) + "\n"; ) + "\n";
} }
return ""; return "";

View file

@ -25,6 +25,7 @@ public class UploadItem {
private boolean hasInvalidLocation; private boolean hasInvalidLocation;
private boolean isWLMUpload = false; private boolean isWLMUpload = false;
private String countryCode; private String countryCode;
private String fileCreatedDateString; //according to EXIF data
/** /**
* Uri of uploadItem * Uri of uploadItem
@ -40,7 +41,8 @@ public class UploadItem {
final Place place, final Place place,
final long createdTimestamp, final long createdTimestamp,
final String createdTimestampSource, final String createdTimestampSource,
final Uri contentUri) { final Uri contentUri,
final String fileCreatedDateString) {
this.createdTimestampSource = createdTimestampSource; this.createdTimestampSource = createdTimestampSource;
uploadMediaDetails = new ArrayList<>(Collections.singletonList(new UploadMediaDetail())); uploadMediaDetails = new ArrayList<>(Collections.singletonList(new UploadMediaDetail()));
this.place = place; this.place = place;
@ -50,6 +52,7 @@ public class UploadItem {
this.createdTimestamp = createdTimestamp; this.createdTimestamp = createdTimestamp;
this.contentUri = contentUri; this.contentUri = contentUri;
imageQuality = BehaviorSubject.createDefault(ImageUtils.IMAGE_WAIT); imageQuality = BehaviorSubject.createDefault(ImageUtils.IMAGE_WAIT);
this.fileCreatedDateString = fileCreatedDateString;
} }
public String getCreatedTimestampSource() { public String getCreatedTimestampSource() {
@ -83,6 +86,8 @@ public class UploadItem {
*/ */
public Uri getContentUri() { return contentUri; } public Uri getContentUri() { return contentUri; }
public String getFileCreatedDateString() { return fileCreatedDateString; }
public void setImageQuality(final int imageQuality) { public void setImageQuality(final int imageQuality) {
this.imageQuality.onNext(imageQuality); this.imageQuality.onNext(imageQuality);
} }

View file

@ -102,8 +102,10 @@ public class UploadModel {
.getFileCreatedDate(context); .getFileCreatedDate(context);
long fileCreatedDate = -1; long fileCreatedDate = -1;
String createdTimestampSource = ""; String createdTimestampSource = "";
String fileCreatedDateString = "";
if (dateTimeWithSource != null) { if (dateTimeWithSource != null) {
fileCreatedDate = dateTimeWithSource.getEpochDate(); fileCreatedDate = dateTimeWithSource.getEpochDate();
fileCreatedDateString = dateTimeWithSource.getDateString();
createdTimestampSource = dateTimeWithSource.getSource(); createdTimestampSource = dateTimeWithSource.getSource();
} }
Timber.d("File created date is %d", fileCreatedDate); Timber.d("File created date is %d", fileCreatedDate);
@ -113,7 +115,8 @@ public class UploadModel {
Uri.parse(uploadableFile.getFilePath()), Uri.parse(uploadableFile.getFilePath()),
uploadableFile.getMimeType(context), imageCoordinates, place, fileCreatedDate, uploadableFile.getMimeType(context), imageCoordinates, place, fileCreatedDate,
createdTimestampSource, createdTimestampSource,
uploadableFile.getContentUri()); uploadableFile.getContentUri(),
fileCreatedDateString);
if (place != null) { if (place != null) {
uploadItem.getUploadMediaDetails().set(0, new UploadMediaDetail(place)); uploadItem.getUploadMediaDetails().set(0, new UploadMediaDetail(place));
} }