2016-03-27 09:52:59 -04:00
|
|
|
package net.filebot.media;
|
|
|
|
|
|
|
|
import static net.filebot.Logging.*;
|
|
|
|
import static net.filebot.Settings.*;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.util.Locale;
|
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
import net.filebot.Cache;
|
|
|
|
import net.filebot.Cache.Compute;
|
|
|
|
import net.filebot.CacheType;
|
2016-03-27 13:40:35 -04:00
|
|
|
import net.filebot.Resource;
|
2016-03-27 09:52:59 -04:00
|
|
|
import net.filebot.WebServices;
|
|
|
|
import net.filebot.web.Episode;
|
|
|
|
import net.filebot.web.Movie;
|
|
|
|
import net.filebot.web.SimpleDate;
|
|
|
|
|
|
|
|
public class XattrMetaInfo {
|
|
|
|
|
|
|
|
public static final XattrMetaInfo xattr = new XattrMetaInfo(useExtendedFileAttributes(), useCreationDate());
|
|
|
|
|
|
|
|
private final boolean useExtendedFileAttributes;
|
|
|
|
private final boolean useCreationDate;
|
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
private final Cache xattrMetaInfoCache = Cache.getCache(MetaAttributes.METADATA_KEY, CacheType.Ephemeral);
|
|
|
|
private final Cache xattrOriginalNameCache = Cache.getCache(MetaAttributes.FILENAME_KEY, CacheType.Ephemeral);
|
|
|
|
|
2016-03-27 09:52:59 -04:00
|
|
|
public XattrMetaInfo(boolean useExtendedFileAttributes, boolean useCreationDate) {
|
|
|
|
this.useExtendedFileAttributes = useExtendedFileAttributes;
|
|
|
|
this.useCreationDate = useCreationDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isMetaInfo(Object object) {
|
|
|
|
return object instanceof Episode || object instanceof Movie;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getTimeStamp(Object object) throws Exception {
|
|
|
|
if (object instanceof Episode) {
|
|
|
|
Episode episode = (Episode) object;
|
|
|
|
if (episode.getAirdate() != null) {
|
|
|
|
return episode.getAirdate().getTimeStamp();
|
|
|
|
}
|
|
|
|
} else if (object instanceof Movie) {
|
|
|
|
Movie movie = (Movie) object;
|
|
|
|
if (movie.getYear() > 0 && movie.getTmdbId() > 0) {
|
|
|
|
SimpleDate releaseDate = WebServices.TheMovieDB.getMovieInfo(movie, Locale.ENGLISH, false).getReleased();
|
|
|
|
if (releaseDate != null) {
|
|
|
|
return releaseDate.getTimeStamp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
public synchronized Object getMetaInfo(File file) {
|
|
|
|
return getCachedValue(xattrMetaInfoCache, file, key -> {
|
2016-03-27 13:58:01 -04:00
|
|
|
return xattr(file).getObject();
|
2016-03-27 12:56:54 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized String getOriginalName(File file) {
|
|
|
|
return (String) getCachedValue(xattrOriginalNameCache, file, key -> {
|
2016-03-27 13:40:35 -04:00
|
|
|
return xattr(file).getOriginalName();
|
2016-03-27 12:56:54 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-03-27 13:40:35 -04:00
|
|
|
private MetaAttributes xattr(File file) throws Exception {
|
|
|
|
return new MetaAttributes(file);
|
|
|
|
}
|
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
private Object getCachedValue(Cache cache, File file, Compute<?> compute) {
|
|
|
|
// try in-memory cache of previously stored xattr metadata
|
|
|
|
try {
|
|
|
|
return cache.computeIfAbsent(file, key -> {
|
|
|
|
if (useExtendedFileAttributes) {
|
|
|
|
return compute.apply(key);
|
2016-03-27 09:52:59 -04:00
|
|
|
}
|
2016-03-27 12:56:54 -04:00
|
|
|
return null;
|
|
|
|
});
|
|
|
|
} catch (Throwable e) {
|
|
|
|
debug.warning("Failed to read xattr: " + e.getMessage());
|
2016-03-27 09:52:59 -04:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
public synchronized void setMetaInfo(File file, Object model, String original) {
|
2016-03-27 09:52:59 -04:00
|
|
|
// only for Episode / Movie objects
|
2016-03-27 12:56:54 -04:00
|
|
|
if (!isMetaInfo(model) || !file.isFile()) {
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 09:52:59 -04:00
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
// set creation date to episode / movie release date
|
2016-03-27 13:40:35 -04:00
|
|
|
Resource<MetaAttributes> xattr = Resource.lazy(() -> xattr(file));
|
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
if (useCreationDate) {
|
|
|
|
try {
|
|
|
|
long t = getTimeStamp(model);
|
|
|
|
if (t > 0) {
|
2016-03-27 13:40:35 -04:00
|
|
|
xattr.get().setCreationDate(t);
|
2016-03-27 09:52:59 -04:00
|
|
|
}
|
2016-03-27 12:56:54 -04:00
|
|
|
} catch (Throwable e) {
|
|
|
|
debug.warning("Failed to set creation date: " + e.getMessage());
|
|
|
|
}
|
|
|
|
}
|
2016-03-27 09:52:59 -04:00
|
|
|
|
2016-03-27 12:56:54 -04:00
|
|
|
// store metadata object and original name as xattr
|
2016-03-27 13:40:35 -04:00
|
|
|
try {
|
|
|
|
if (isMetaInfo(model)) {
|
|
|
|
xattrMetaInfoCache.put(file, model);
|
2016-03-27 13:58:01 -04:00
|
|
|
|
2016-03-27 13:40:35 -04:00
|
|
|
if (useExtendedFileAttributes) {
|
|
|
|
xattr.get().setObject(model);
|
2016-03-27 09:52:59 -04:00
|
|
|
}
|
2016-03-27 13:40:35 -04:00
|
|
|
}
|
2016-03-27 13:58:01 -04:00
|
|
|
|
2016-03-27 13:40:35 -04:00
|
|
|
if (original != null && original.length() > 0 && getOriginalName(file) == null) {
|
|
|
|
xattrOriginalNameCache.put(file, original);
|
2016-03-27 13:58:01 -04:00
|
|
|
|
2016-03-27 13:40:35 -04:00
|
|
|
if (useExtendedFileAttributes) {
|
|
|
|
xattr.get().setOriginalName(original);
|
2016-03-27 12:56:54 -04:00
|
|
|
}
|
|
|
|
}
|
2016-03-27 13:40:35 -04:00
|
|
|
} catch (Throwable e) {
|
|
|
|
debug.warning("Failed to set xattr: " + e.getMessage());
|
2016-03-27 12:56:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized void clear(File file) {
|
|
|
|
// clear in-memory cache
|
|
|
|
xattrMetaInfoCache.remove(file);
|
|
|
|
xattrOriginalNameCache.remove(file);
|
|
|
|
|
|
|
|
if (useExtendedFileAttributes) {
|
|
|
|
try {
|
2016-03-27 13:40:35 -04:00
|
|
|
xattr(file).clear();
|
2016-03-27 12:56:54 -04:00
|
|
|
} catch (Throwable e) {
|
|
|
|
debug.warning("Failed to clear xattr: " + e.getMessage());
|
2016-03-27 09:52:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|