Skip to content

Commit

Permalink
Merge branch 'master' into FDroid
Browse files Browse the repository at this point in the history
  • Loading branch information
k3b committed Mar 13, 2017
2 parents c9451c4 + e32add2 commit 15c6965
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ before_install:

script:
- jdk_switcher use oraclejdk8
- ./gradlew assemble
- ./gradlew assemble test
5 changes: 3 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ android {
// 0.5.4.161112 (23)
// 0.5.5.161220 (24) Image Picker
// 0.6.0.170309 (25) Tag support
// 0.6.0.170315 (26) Bugfix for new Tag support

versionCode = 25
versionName = '0.6.0.170309'
versionCode = 26
versionName = '0.6.0.170315'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public String getPath() {
@Override
public Date getDateTimeTaken() {
if (colDateTimeTaken == -1) return null;
Integer value = cursor.getInt(colDateTimeTaken);
return (value != null) ? new Date(value.intValue()) : null;
Long value = cursor.getLong(colDateTimeTaken);
return (value != null) ? new Date(value.longValue()) : null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,8 +673,8 @@ public static IGeoPoint execGetPosition(Context context, String fullPath, long i
/**
* @return returns a hashmap filename => mediaID
*/
public static Map<String, Integer> execGetPathIdMap(Context context, String... fileNames) {
Map<String, Integer> result = new HashMap<String, Integer>();
public static Map<String, Long> execGetPathIdMap(Context context, String... fileNames) {
Map<String, Long> result = new HashMap<String, Long>();

String whereFileNames = getWhereInFileNames(fileNames);
if (whereFileNames != null) {
Expand All @@ -688,7 +688,7 @@ public static Map<String, Integer> execGetPathIdMap(Context context, String... f
try {
c = createCursorForQuery("execGetPathIdMap", context, query, IGalleryFilter.VISIBILITY_PRIVATE_PUBLIC);
while (c.moveToNext()) {
result.put(c.getString(1),c.getInt(0));
result.put(c.getString(1),c.getLong(0));
}
} catch (Exception ex) {
Log.e(Global.LOG_CONTEXT, "FotoSql.execGetPathIdMap: error executing " + query, ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ static class TagWorflowItem {
final long xmpLastModifiedDate;
final String path;
final List<String> tags;
boolean xmpMoreRecentThanSql = false;

public TagWorflowItem(long id, String path, List<String> tags, long xmpLastModifiedDate) {
this.tags = tags;
Expand Down Expand Up @@ -323,8 +324,8 @@ public static List<TagWorflowItem> loadTagWorflowItems(Context context, String s
c = createCursorForQuery("loadTagWorflowItems", context, query, IGalleryFilter.VISIBILITY_PRIVATE_PUBLIC);
if (c.moveToFirst()) {
do {
result.add(new TagWorflowItem(c.getInt(0), c.getString(1), TagConverter.fromString(c.getString(2)),
c.getInt(3)));
result.add(new TagWorflowItem(c.getLong(0), c.getString(1), TagConverter.fromString(c.getString(2)),
c.getLong(3)));
} while (c.moveToNext());
}
} catch (Exception ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;

import java.io.File;
import java.io.IOException;
Expand All @@ -35,6 +36,7 @@
import de.k3b.android.util.MediaScannerEx;
import de.k3b.database.SelectedFiles;
import de.k3b.io.FileUtils;
import de.k3b.io.ListUtils;
import de.k3b.media.MediaUtil;
import de.k3b.media.MediaXmpSegment;
import de.k3b.tagDB.Tag;
Expand Down Expand Up @@ -64,8 +66,10 @@ public TagWorflow init(Activity context, SelectedFiles selectedItems, List<Tag>
for (TagSql.TagWorflowItem item : items) {
List<String> tags = item.tags;
File xmpFile = FileUtils.getXmpFile(item.path);
if (xmpFile.exists() && (item.xmpLastModifiedDate < xmpFile.lastModified()) || (tags == null) || (tags.size() == 0)) {
if (xmpFile.exists() && (item.xmpLastModifiedDate < xmpFile.lastModified())){ // || (tags == null) || (tags.size() == 0)) {
// xmp has been updated since last db update.
tags = loadTags(xmpFile);
item.xmpMoreRecentThanSql = true;
}
registerExistingTags(tags);
}
Expand Down Expand Up @@ -97,22 +101,26 @@ public int updateTags(List<String> addedTags, List<String> removedTags) {
/** update one file if tags change or xmp does not exist yet: xmp-sidecar-file, media-db and batch */
@NonNull
protected File updateTags(TagSql.TagWorflowItem tagWorflowItemFromDB, List<String> addedTags, List<String> removedTags) {
boolean mustSave = false;
boolean mustSave = tagWorflowItemFromDB.xmpMoreRecentThanSql;
String dbgSaveReason = (mustSave) ? "xmpMoreRecentThanSql." : "";
MediaXmpSegment xmp = null;

List<String> currentItemTags = tagWorflowItemFromDB.tags;
File xmpFile = FileUtils.getXmpFile(tagWorflowItemFromDB.path);

if (xmpFile.exists()) { //
if (xmpFile.exists()) {
xmp = new MediaScannerEx(context).loadXmp(null, xmpFile);
if (xmp != null) {
// current tags is all db-tags + xmp-tags or null if no changes
List<String> xmpTagsFromDbAndXmpModified = this.getUpdated(currentItemTags, xmp.getTags(), null);
List<String> currentXmpTags = xmp.getTags();// current tags is all db-tags + xmp-tags or null if no changes

List<String> xmpTagsFromDbAndXmpModified = this.getUpdated(currentItemTags, currentXmpTags, null);
if (xmpTagsFromDbAndXmpModified != null) {
// either db or xmp is not up to date yet
mustSave = true;
dbgSaveReason += "xmp has more tags than sql.";
currentItemTags = xmpTagsFromDbAndXmpModified;
} else if (ListUtils.toString(currentItemTags).compareTo(ListUtils.toString(currentXmpTags)) != 0) {
dbgSaveReason += "sql has more tags than xmp.";
mustSave = true;
}
}
} // else xmp-file does not exist yet.
Expand All @@ -123,6 +131,7 @@ protected File updateTags(TagSql.TagWorflowItem tagWorflowItemFromDB, List<Strin
// tags have changed.
currentItemTags = modifiedTags;
mustSave = true;
dbgSaveReason += "tags modified.";
}

if (mustSave) {
Expand All @@ -147,8 +156,11 @@ protected File updateTags(TagSql.TagWorflowItem tagWorflowItemFromDB, List<Strin
// update xmp-sidecar-file
try {
xmp.save(xmpFile, Global.saveXmpAsHumanReadable);
if (Global.debugEnabledSql) {
Log.d(Global.LOG_CONTEXT,"saveXmp(" + xmpFile + "): " + dbgSaveReason);
}
} catch (IOException e) {
e.printStackTrace();
Log.e(Global.LOG_CONTEXT,"error: saveXmp(" + xmpFile + ", " + dbgSaveReason + ") : " + e.getMessage(),e);
}

// update tag repository
Expand All @@ -157,9 +169,18 @@ protected File updateTags(TagSql.TagWorflowItem tagWorflowItemFromDB, List<Strin
// update media database
ContentValues dbValues = new ContentValues();
MediaContentValues mediaContentValues = new MediaContentValues().set(dbValues, null);

// #77: does only copy non-null values
MediaUtil.copyXmp(mediaContentValues, xmp,false, true);
TagSql.setXmpFileModifyDate(dbValues, new Date());
TagSql.execUpdate("updateTags", this.context, tagWorflowItemFromDB.id, dbValues);

// #77: fix make shure that tags might be set to null
mediaContentValues.setTags(currentItemTags);

// #77: make shure that db-date is newer than xmp-file-date
TagSql.setXmpFileModifyDate(dbValues, new Date(xmpFile.lastModified() +1));


TagSql.execUpdate("updateTags " + dbgSaveReason, this.context, tagWorflowItemFromDB.id, dbValues);

// update batch
long now = new Date().getTime();
Expand Down Expand Up @@ -202,9 +223,12 @@ private MediaXmpSegment loadXmp(File xmpFile) {
try {
MediaXmpSegment xmp = new MediaXmpSegment();
xmp.load(xmpFile);
if (Global.debugEnabledSql) {
Log.d(Global.LOG_CONTEXT,"loadXmp(" + xmpFile + ")");
}
return xmp;
} catch (IOException e) {
e.printStackTrace();
Log.e(Global.LOG_CONTEXT,"error: loadXmp(" + xmpFile + ") : " + e.getMessage(),e);
}
}
return null;
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/de/k3b/android/util/MediaScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,11 @@ private int insertIntoMediaDatabase(Context context, String[] newPathNames) {
Log.i(Global.LOG_CONTEXT, CONTEXT + "A42 scanner starting with " + newPathNames.length + " files " + newPathNames[0] + "...");
}

Map<String, Integer> inMediaDb = FotoSql.execGetPathIdMap(context.getApplicationContext(), newPathNames);
Map<String, Long> inMediaDb = FotoSql.execGetPathIdMap(context.getApplicationContext(), newPathNames);

for (String fileName : newPathNames) {
if (fileName != null) {
Integer id = inMediaDb.get(fileName);
Long id = inMediaDb.get(fileName);
if (id != null) {
// already exists
modifyCount += update_Android42("MediaScanner.insertIntoMediaDatabase already existing ", context, id, new File(fileName));
Expand Down Expand Up @@ -406,7 +406,7 @@ private void setFieldIfNeccessary(ContentValues values, String fieldName, String
}
}

private int update_Android42(String dbgContext, Context context, int id, File file) {
private int update_Android42(String dbgContext, Context context, long id, File file) {
if ((file != null) && file.exists() && file.canRead()) {
ContentValues values = new ContentValues();
getExifFromFile(values, file);
Expand Down
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ dependencies:

test:
override:
- ./gradlew assemble
- ./gradlew assemble test
41 changes: 22 additions & 19 deletions fotolib2/src/test/java/de/k3b/io/FileCommandTests.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2015-2016 by k3b.
* Copyright (c) 2015-2017 by k3b.
*
* This file is part of AndroFotoFinder.
* This file is part of AndroFotoFinder / #APhotoManager.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -29,7 +29,8 @@
* Created by k3b on 06.08.2015.
*/
public class FileCommandTests {
private static final File X_FAKE_OUTPUT_DIR = new File("x:/fakeOutputDir");
private static final File X_FAKE_OUTPUT_DIR = new File("/fakeOutputDir").getAbsoluteFile();
private static final File X_FAKE_INPUT_DIR = new File("/fakeInputDir").getAbsoluteFile();
private FileCommands sut;

@Before
Expand All @@ -43,29 +44,29 @@ public void setUp() {
@Test
public void shouldCopy() {
registerFakeFiles(sut);
sut.moveOrCopyFilesTo(false, X_FAKE_OUTPUT_DIR, createIds(1), createTestFiles("a.jpg"));
sut.moveOrCopyFilesTo(false, X_FAKE_OUTPUT_DIR, createIds(1), createTestFiles(X_FAKE_OUTPUT_DIR, "a.jpg"));

verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "/a.jpg"), createTestFile("a.jpg"));
verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a.jpg"), createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg"));

}

@Test
public void shouldCopyWitRenameExistingMultiple() {
registerFakeFiles(sut, "a.jpg", "b.png", "b(1).png");
sut.moveOrCopyFilesTo(false, X_FAKE_OUTPUT_DIR, createIds(2), createTestFiles("a.jpg", "b.png"));
sut.moveOrCopyFilesTo(false, X_FAKE_OUTPUT_DIR, createIds(2), createTestFiles(X_FAKE_INPUT_DIR, "a.jpg", "b.png"));

verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a(1).jpg"), createTestFile("a.jpg"));
verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "b(2).png"), createTestFile("b.png"));
verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a(1).jpg"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg"));
verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "b(2).png"), createTestFile(X_FAKE_INPUT_DIR, "b.png"));
}

@Test
public void shouldCopyRenameExistingWithXmp() {
registerFakeFiles(sut, "a.jpg", "a.xmp", "a(1).xmp", "a(2).jpg"); // a(3) is next possible

sut.moveOrCopyFilesTo(false, X_FAKE_OUTPUT_DIR, createIds(1), createTestFiles("a.jpg"));
sut.moveOrCopyFilesTo(false, X_FAKE_OUTPUT_DIR, createIds(1), createTestFiles(X_FAKE_INPUT_DIR, "a.jpg"));

verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a(3).jpg"), createTestFile("a.jpg"));
verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a(3).xmp"), createTestFile("a.xmp"));
verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a(3).jpg"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg"));
verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a(3).xmp"), createTestFile(X_FAKE_INPUT_DIR, "a.xmp"));
}

private Long[] createIds(int count) {
Expand All @@ -79,10 +80,10 @@ private Long[] createIds(int count) {
@Test
public void shouldDeleteExistingWithXmp() {
registerFakeFiles(sut, "a.jpg", "a.xmp");
sut.deleteFiles(createTestFile("a.jpg").getAbsolutePath());
sut.deleteFiles(createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg").getAbsolutePath());

verify(sut).osDeleteFile(createTestFile("a.jpg"));
verify(sut).osDeleteFile(createTestFile("a.xmp"));
verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg"));
verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.xmp"));
}

/** these files exist in source-dir and in dest-dir */
Expand All @@ -92,21 +93,23 @@ private static void registerFakeFiles(FileCommands sut, String... filenames) {
} else {
for (String filename : filenames) {
doReturn(true).when(sut).osFileExists(new File(X_FAKE_OUTPUT_DIR, filename));
doReturn(true).when(sut).osFileExists(createTestFile(filename));
doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_OUTPUT_DIR, filename));
doReturn(true).when(sut).osFileExists(new File(X_FAKE_INPUT_DIR, filename));
doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_INPUT_DIR, filename));
}
}
}

private static File[] createTestFiles(String... files) {
private static File[] createTestFiles(File destDir, String... files) {
File[] result = new File[files.length];
int pos = 0;
for (String file : files) {
result[pos++] = createTestFile(file);
result[pos++] = createTestFile(destDir, file);
}
return result;
}

private static File createTestFile(String name) {
return new File(name).getAbsoluteFile();
private static File createTestFile(File destDir, String name) {
return new File(destDir, name);
}
}

0 comments on commit 15c6965

Please sign in to comment.