better sorting of directories
This commit is contained in:
parent
7386a1a36e
commit
0a7867cf14
4 changed files with 233 additions and 191 deletions
|
|
@ -44,8 +44,8 @@ public class ComparatorFactory {
|
||||||
|
|
||||||
public int compare(Entry e1, Entry e2) {
|
public int compare(Entry e1, Entry e2) {
|
||||||
|
|
||||||
Date d1 = e1.getDate();
|
Date d1 = e1.getEarliest();
|
||||||
Date d2 = e2.getDate();
|
Date d2 = e2.getEarliest();
|
||||||
if (d1 != null && d2 != null) {
|
if (d1 != null && d2 != null) {
|
||||||
return d1.compareTo(d2);
|
return d1.compareTo(d2);
|
||||||
} else if (d1 != null) {
|
} else if (d1 != null) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
@ -46,6 +47,7 @@ public class DirectoryEntry extends Entry {
|
||||||
List<Entry> children = new ArrayList<Entry>();
|
List<Entry> children = new ArrayList<Entry>();
|
||||||
boolean childrenLoaded = false;
|
boolean childrenLoaded = false;
|
||||||
Comparator<Entry> sort = null;
|
Comparator<Entry> sort = null;
|
||||||
|
Date earliest = null;
|
||||||
|
|
||||||
public DirectoryEntry(File file) {
|
public DirectoryEntry(File file) {
|
||||||
super(file);
|
super(file);
|
||||||
|
|
@ -137,7 +139,7 @@ public class DirectoryEntry extends Entry {
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties generateCache() throws MetadataException, JpegProcessingException, IOException {
|
Properties generateCache() throws MetadataException, JpegProcessingException, IOException, ParseException {
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
|
|
@ -151,8 +153,9 @@ public class DirectoryEntry extends Entry {
|
||||||
|
|
||||||
|
|
||||||
void generateFileEntries(Properties props)
|
void generateFileEntries(Properties props)
|
||||||
throws IOException, MetadataException, JpegProcessingException {
|
throws IOException, MetadataException, JpegProcessingException, ParseException {
|
||||||
|
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||||
File[] files = file.listFiles();
|
File[] files = file.listFiles();
|
||||||
for (File f : files) {
|
for (File f : files) {
|
||||||
|
|
||||||
|
|
@ -174,7 +177,11 @@ public class DirectoryEntry extends Entry {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".JPG")) {
|
if (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".JPG")) {
|
||||||
generateThumbnailProperties(props, f);
|
String base = "file." + f.getName() + ".";
|
||||||
|
Map<String, String> p = generateThumbnailProperties(f);
|
||||||
|
for (Map.Entry<String, String> e : p.entrySet()) {
|
||||||
|
props.setProperty(base + e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,10 +193,10 @@ public class DirectoryEntry extends Entry {
|
||||||
props.setProperty("dir." + name, "present");
|
props.setProperty("dir." + name, "present");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateThumbnailProperties(Properties props, File f)
|
private Map<String, String> generateThumbnailProperties(File f)
|
||||||
throws JpegProcessingException, MetadataException, IOException {
|
throws JpegProcessingException, MetadataException, IOException {
|
||||||
|
HashMap<String, String> props = new HashMap<String, String>();
|
||||||
String name = f.getName();
|
String name = f.getName();
|
||||||
String base = "file." + name + ".";
|
|
||||||
boolean hasDate = false;
|
boolean hasDate = false;
|
||||||
boolean hasOrientation = false;
|
boolean hasOrientation = false;
|
||||||
boolean hasDim = false;
|
boolean hasDim = false;
|
||||||
|
|
@ -202,52 +209,53 @@ public class DirectoryEntry extends Entry {
|
||||||
Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
|
Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {
|
if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {
|
||||||
int orientation = exifDirectory.getInt(ExifDirectory.TAG_ORIENTATION);
|
int orientation = exifDirectory.getInt(ExifDirectory.TAG_ORIENTATION);
|
||||||
props.setProperty(base + "orientation", nf.format(orientation));
|
props.put("orientation", nf.format(orientation));
|
||||||
hasOrientation = true;
|
hasOrientation = true;
|
||||||
}
|
}
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH) &&
|
if (exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH) &&
|
||||||
exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
|
exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
|
||||||
int width = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);
|
int width = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);
|
||||||
int height = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT);
|
int height = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT);
|
||||||
props.setProperty(base + "dimensions", new Dimension(width, height).toString());
|
props.put("dimensions", new Dimension(width, height).toString());
|
||||||
hasDim = true;
|
hasDim = true;
|
||||||
}
|
}
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
|
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
|
||||||
Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL);
|
Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL);
|
||||||
if (captureDate != null) {
|
if (captureDate != null) {
|
||||||
props.setProperty(base + "captureDate", sdf.format(captureDate));
|
props.put("captureDate", sdf.format(captureDate));
|
||||||
hasDate = true;
|
hasDate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) {
|
if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) {
|
||||||
String comment = exifDirectory.getString(ExifDirectory.TAG_USER_COMMENT);
|
String comment = exifDirectory.getString(ExifDirectory.TAG_USER_COMMENT);
|
||||||
props.setProperty(base + "comment", comment);
|
props.put("comment", comment);
|
||||||
}
|
}
|
||||||
Directory jpegDirectory = metadata.getDirectory(JpegDirectory.class);
|
Directory jpegDirectory = metadata.getDirectory(JpegDirectory.class);
|
||||||
if (jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH) &&
|
if (jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH) &&
|
||||||
jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT)) {
|
jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT)) {
|
||||||
int width = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
|
int width = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
|
||||||
int height = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT);
|
int height = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT);
|
||||||
props.setProperty(base + "dimensions", new Dimension(width, height).toString());
|
props.put("dimensions", new Dimension(width, height).toString());
|
||||||
hasDim = true;
|
hasDim = true;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("problem reading file " + f.getPath(), e);
|
throw new RuntimeException("problem reading file " + f.getPath(), e);
|
||||||
}
|
}
|
||||||
props.setProperty(base + "etag", Integer.toHexString(name.hashCode() + Long.valueOf(f.lastModified()).hashCode()));
|
props.put("etag", Integer.toHexString(name.hashCode() + Long.valueOf(f.lastModified()).hashCode()));
|
||||||
if (!hasDate) {
|
if (!hasDate) {
|
||||||
props.setProperty(base + "captureDate", sdf.format(new Date(f.lastModified())));
|
props.put("captureDate", sdf.format(new Date(f.lastModified())));
|
||||||
}
|
}
|
||||||
if (!hasOrientation) {
|
if (!hasOrientation) {
|
||||||
props.setProperty(base + "orientation", "1");
|
props.put("orientation", "1");
|
||||||
}
|
}
|
||||||
if (!hasDim) {
|
if (!hasDim) {
|
||||||
Dimension dim = decodeImageForDimensions(f);
|
Dimension dim = decodeImageForDimensions(f);
|
||||||
if (dim != null) {
|
if (dim != null) {
|
||||||
props.setProperty(base + "dimensions", dim.toString());
|
props.put("dimensions", dim.toString());
|
||||||
hasDim = true;
|
hasDim = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException {
|
private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException {
|
||||||
|
|
@ -305,9 +313,13 @@ public class DirectoryEntry extends Entry {
|
||||||
String caption = props.getProperty("caption");
|
String caption = props.getProperty("caption");
|
||||||
setCaption(caption);
|
setCaption(caption);
|
||||||
sort = ComparatorFactory.getSort(props.getProperty("sort"));
|
sort = ComparatorFactory.getSort(props.getProperty("sort"));
|
||||||
|
|
||||||
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
|
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||||
Iterator i = props.keySet().iterator();
|
|
||||||
|
Date oldest = new Date(file.lastModified());
|
||||||
|
|
||||||
|
Iterator<Object> i = props.keySet().iterator();
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
String key = (String)i.next();
|
String key = (String)i.next();
|
||||||
if (key.startsWith("file.") && key.endsWith(".dimensions")) {
|
if (key.startsWith("file.") && key.endsWith(".dimensions")) {
|
||||||
|
|
@ -317,7 +329,11 @@ public class DirectoryEntry extends Entry {
|
||||||
FileEntry entry = new FileEntry(this, f);
|
FileEntry entry = new FileEntry(this, f);
|
||||||
Thumbnail thumbnail = new Thumbnail(f);
|
Thumbnail thumbnail = new Thumbnail(f);
|
||||||
entry.setCaption(props.getProperty("file." + name + ".caption"));
|
entry.setCaption(props.getProperty("file." + name + ".caption"));
|
||||||
entry.setDate(sdf.parse(props.getProperty("file." + name + ".captureDate")));
|
Date fileDate = sdf.parse(props.getProperty("file." + name + ".captureDate"));
|
||||||
|
if (fileDate.before(oldest)) {
|
||||||
|
oldest = fileDate;
|
||||||
|
}
|
||||||
|
entry.setDate(fileDate);
|
||||||
thumbnail.setSize(new Dimension(props.getProperty("file." + name + ".dimensions")));
|
thumbnail.setSize(new Dimension(props.getProperty("file." + name + ".dimensions")));
|
||||||
thumbnail.setOrientation(Integer.parseInt(props.getProperty("file." + name + ".orientation")));
|
thumbnail.setOrientation(Integer.parseInt(props.getProperty("file." + name + ".orientation")));
|
||||||
thumbnail.setEtag(props.getProperty("file." + name + ".etag"));
|
thumbnail.setEtag(props.getProperty("file." + name + ".etag"));
|
||||||
|
|
@ -334,13 +350,26 @@ public class DirectoryEntry extends Entry {
|
||||||
String name = key.substring("dir.".length());
|
String name = key.substring("dir.".length());
|
||||||
boolean hidden = Boolean.parseBoolean(props.getProperty("dir." + name + ".hidden"));
|
boolean hidden = Boolean.parseBoolean(props.getProperty("dir." + name + ".hidden"));
|
||||||
if (!hidden) {
|
if (!hidden) {
|
||||||
children.add(new DirectoryEntry(this, new File(file, name)));
|
DirectoryEntry dir = new DirectoryEntry(this, new File(file, name));
|
||||||
|
children.add(dir);
|
||||||
|
Date fileDate = dir.getEarliest();
|
||||||
|
if (fileDate != null && fileDate.before(oldest)) {
|
||||||
|
oldest = fileDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
this.earliest = oldest;
|
||||||
if (thumbnail == null && !children.isEmpty()) {
|
if (thumbnail == null && !children.isEmpty()) {
|
||||||
setThumbnail(children.get(0).getThumbnail());
|
setThumbnail(children.get(0).getThumbnail());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getEarliest() {
|
||||||
|
loadChildren();
|
||||||
|
return earliest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,4 +100,8 @@ public abstract class Entry {
|
||||||
public File getPath() {
|
public File getPath() {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Date getEarliest() {
|
||||||
|
return getDate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package org.forkalsrud.album.web;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
|
|
@ -230,7 +232,6 @@ public class AlbumServlet
|
||||||
public class Mapper {
|
public class Mapper {
|
||||||
|
|
||||||
public String map(File file) {
|
public String map(File file) {
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
return appendFile(buf, file).toString();
|
return appendFile(buf, file).toString();
|
||||||
}
|
}
|
||||||
|
|
@ -245,7 +246,15 @@ public class AlbumServlet
|
||||||
return appendFile(buf, file.getParentFile()).append('/').append(file.getName());
|
return appendFile(buf, file.getParentFile()).append('/').append(file.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
|
||||||
|
public String year(Date d) {
|
||||||
|
cal.setTime(d);
|
||||||
|
return String.valueOf(cal.get(Calendar.YEAR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// eof
|
// eof
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue