Improved support for read / writing CRC32 checksum to / from xattr (and enable by default)

This commit is contained in:
Reinhard Pointner 2019-02-03 01:44:17 +07:00
parent 501bb8f709
commit 342ced903d
2 changed files with 80 additions and 17 deletions

View File

@ -42,11 +42,8 @@ import java.util.stream.IntStream;
import java.util.stream.Stream;
import net.filebot.ApplicationFolder;
import net.filebot.Cache;
import net.filebot.CacheType;
import net.filebot.Language;
import net.filebot.MediaTypes;
import net.filebot.MetaAttributeView;
import net.filebot.Resource;
import net.filebot.Settings;
import net.filebot.hash.HashType;
@ -56,6 +53,7 @@ import net.filebot.media.LocalDatasource.PhotoFile;
import net.filebot.media.MetaAttributes;
import net.filebot.media.NamingStandard;
import net.filebot.media.VideoFormat;
import net.filebot.media.XattrChecksum;
import net.filebot.mediainfo.MediaInfo;
import net.filebot.mediainfo.MediaInfo.StreamKind;
import net.filebot.mediainfo.MediaInfoException;
@ -511,20 +509,8 @@ public class MediaBindingBean {
return checksum;
}
// try CRC32 xattr (as stored by verify script)
try {
MetaAttributeView xattr = new MetaAttributeView(inferredMediaFile);
checksum = xattr.get("CRC32");
if (checksum != null) {
return checksum;
}
} catch (Exception e) {
// ignore if xattr metadata is not supported for the given file
}
// calculate checksum from file
Cache cache = Cache.getCache("crc32", CacheType.Ephemeral);
return (String) cache.computeIfAbsent(inferredMediaFile, it -> crc32(inferredMediaFile));
// compute and store to xattr
return XattrChecksum.CRC32.computeIfAbsent(inferredMediaFile);
}
@Define("fn")

View File

@ -0,0 +1,77 @@
package net.filebot.media;
import static net.filebot.Logging.*;
import static net.filebot.Settings.*;
import static net.filebot.hash.VerificationUtilities.*;
import java.io.File;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import net.filebot.MetaAttributeView;
import net.filebot.hash.HashType;
public enum XattrChecksum {
CRC32;
private final Cache<File, String> cache = CacheBuilder.newBuilder().expireAfterAccess(24, TimeUnit.HOURS).build();
public String computeIfAbsent(File file) throws Exception {
return cache.get(file, () -> {
if (!useExtendedFileAttributes()) {
return computeHash(file, getHashType());
}
// read xattr
MetaAttributeView xattr = new MetaAttributeView(file);
String value = xattr.get(getKey());
if (value != null) {
return value;
}
// compute checksum
value = computeHash(file, getHashType());
// store checksum (and make sure Last-Modified date is not changed)
long t = file.lastModified();
try {
xattr.put(getKey(), value); // may or may not change Last-Modified date
} catch (Exception e) {
debug.warning(cause("Failed to set xattr", e));
} finally {
file.setLastModified(t);
}
return value;
});
}
public void clear(File file) {
cache.invalidate(cache);
if (useExtendedFileAttributes()) {
try {
new MetaAttributeView(file).put(getKey(), null);
} catch (Exception e) {
debug.warning(cause("Failed to set xattr", e));
}
}
}
private String getKey() {
return name();
}
private HashType getHashType() {
switch (this) {
case CRC32:
return HashType.SFV;
}
return null;
}
}