Major overhaul of navigation. Now shows directories and navigation buttons.

This commit is contained in:
knut 2008-12-29 01:13:02 +00:00
parent 79a499ceec
commit 9d2fb0ea6e
14 changed files with 206 additions and 64 deletions

View file

@ -0,0 +1,2 @@
cover=valdemar-dahl.jpg

View file

@ -74,7 +74,7 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
<!-- <scope>test</scope> -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>

View file

@ -0,0 +1,84 @@
/**
*
*/
package org.forkalsrud.album.exif;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* @author knut
*
*/
public class Album {
Entry cover;
List<Entry> contents = new ArrayList<Entry>();
public Entry getCover() {
return cover;
}
public List<Entry> getContents() {
return contents;
}
public void setCover(Entry cover) {
this.cover = cover;
}
public void addContents(Entry entry) {
contents.add(entry);
}
public void sort() {
Collections.sort(contents, new Comparator<Entry>() {
public int compare(Entry e1, Entry e2) {
if (!e1.isFile() && e2.isFile()) {
return -1;
} else if (e1.isFile() && !e2.isFile()) {
return +1;
}
Date d1 = e1.getDate();
Date d2 = e2.getDate();
if (d1 != null && d2 != null) {
return d1.compareTo(d2);
} else if (d1 != null) {
return -1;
} else if (d2 != null) {
return +1;
} else {
return 0;
}
}
});
fillLinkedList();
}
void fillLinkedList() {
Entry prev = null;
for (Entry e : contents) {
e.prev = prev;
if (prev != null) {
prev.next = e;
}
prev = e;
}
if (prev != null) {
prev.next = null;
}
}
}

View file

@ -15,7 +15,9 @@ import java.util.Date;
*/
public class Entry {
boolean isFile;
String name;
String path;
Dimension size;
String caption;
Date date;
@ -25,6 +27,17 @@ public class Entry {
String etag;
public boolean isFile() {
return isFile;
}
public void setFile(boolean isFile) {
this.isFile = isFile;
}
/**
* @return Returns the name.
*/
@ -132,4 +145,15 @@ public class Entry {
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}

View file

@ -17,8 +17,6 @@ import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
@ -54,7 +52,7 @@ public class EntryDao {
return directory.lastModified() <= new File(directory, CACHE_FILE).lastModified();
}
public List<Entry> read(File directory) throws FileNotFoundException, IOException, JpegProcessingException, MetadataException, ParseException {
public Album read(File directory) throws FileNotFoundException, IOException, JpegProcessingException, MetadataException, ParseException {
List<Entry> entries = new ArrayList<Entry>();
@ -73,46 +71,25 @@ public class EntryDao {
Properties combined = new Properties();
combined.putAll(cachedProps);
combined.putAll(overrideProps);
populate(combined, entries);
Collections.sort(entries, new Comparator<Entry>() {
Entry cover = populate(combined, entries);
public int compare(Entry e1, Entry e2) {
Date d1 = e1.getDate();
Date d2 = e2.getDate();
if (d1 != null && d2 != null) {
return d1.compareTo(d2);
} else if (d1 != null) {
return -1;
} else if (d2 != null) {
return +1;
} else {
return 0;
}
}
});
fillLinkedList(entries);
return entries;
}
void fillLinkedList(List<Entry> entries) {
Entry prev = null;
Album alb = new Album();
alb.setCover(cover);
for (Entry e : entries) {
e.prev = prev;
if (prev != null) {
prev.next = e;
}
prev = e;
}
if (prev != null) {
prev.next = null;
alb.addContents(e);
}
generateDirectoryEntries(directory, alb);
alb.sort();
return alb;
}
private void populate(Properties cachedProps, List<Entry> entries) throws ParseException {
private Entry populate(Properties cachedProps, List<Entry> entries) throws ParseException {
Entry cover = null;
String coverFileName = cachedProps.getProperty("cover");
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
Iterator i = cachedProps.keySet().iterator();
@ -122,22 +99,28 @@ public class EntryDao {
String name = key.substring("file.".length(), key.length() - ".dimensions".length());
if (!entryMap.containsKey(name)) {
Entry entry = new Entry();
entry.setFile(true);
entry.setName(name);
entry.setPath(name);
entry.setDate(sdf.parse(cachedProps.getProperty("file." + name + ".captureDate")));
entry.setSize(new Dimension(cachedProps.getProperty("file." + name + ".dimensions")));
entry.setCaption(cachedProps.getProperty("file." + name + ".caption"));
entry.setOrientation(Integer.parseInt(cachedProps.getProperty("file." + name + ".orientation")));
entry.setEtag(cachedProps.getProperty("file." + name + ".etag"));
entries.add(entry);
if (name != null && name.equals(coverFileName)) {
cover = entry;
}
}
}
}
return cover;
}
public Entry readFile(File file) throws FileNotFoundException, IOException, JpegProcessingException, MetadataException, ParseException {
List<Entry> dir = read(file.getParentFile());
List<Entry> dir = read(file.getParentFile()).getContents();
String name = file.getName();
for (Entry e : dir) {
if (name.equals(e.name)) {
@ -149,11 +132,46 @@ public class EntryDao {
void generateEntries(File directory, Properties cachedProps) throws JpegProcessingException, MetadataException, FileNotFoundException, IOException {
generateFileEntries(directory, cachedProps);
File dst = new File(directory, CACHE_FILE);
if (directory.canWrite()) {
cachedProps.store(new FileOutputStream(dst), "Extra Comments");
}
}
void generateDirectoryEntries(File directory, Album album) throws FileNotFoundException, JpegProcessingException, MetadataException, IOException, ParseException {
File[] dirs = directory.listFiles(new FileFilter() {
public boolean accept(File file) {
return !file.isHidden() && file.isDirectory() && !CACHE_FILE.equals(file.getName()) && !OVERRIDE_FILE.equals(file.getName());
}
});
for (File dir : dirs) {
Album childAlbum = read(dir);
Entry childCover = childAlbum.getCover();
if (childCover != null) {
childCover.setFile(false);
childCover.setName(dir.getName());
childCover.setPath(dir.getName() + "/" + childCover.getPath());
album.addContents(childCover);
}
}
}
void generateFileEntries(File directory, Properties cachedProps)
throws JpegProcessingException, MetadataException, IOException {
File[] files = directory.listFiles(new FileFilter() {
public boolean accept(File file) {
return !file.isHidden() && !file.isDirectory() && !CACHE_FILE.equals(file.getName()) && !OVERRIDE_FILE.equals(file.getName());
String name = file.getName();
boolean isImageFile = name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".JPG");
return isImageFile && !file.isHidden() && !file.isDirectory() && !CACHE_FILE.equals(file.getName()) && !OVERRIDE_FILE.equals(file.getName());
}
});
@ -213,10 +231,6 @@ public class EntryDao {
}
}
}
File dst = new File(directory, CACHE_FILE);
if (directory.canWrite()) {
cachedProps.store(new FileOutputStream(dst), "Extra Comments");
}
}
Dimension decodeImageForDimensions(File file) throws IOException {

View file

@ -52,8 +52,13 @@ public class AlbumServlet
pathInfo = pathInfo.substring(0, pathInfo.length() - ".photo".length());
page = "photo";
}
int parentPos = pathInfo.substring(0, pathInfo.length() - 1).lastIndexOf('/');
if (parentPos >= 0) {
req.setAttribute("parent", req.getServletPath() + pathInfo.substring(0, parentPos) + "/");
}
req.setAttribute("assets", "/" + req.getContextPath() + "assets");
File file = new File(basePath + pathInfo);
// System.out.println("path=" + file);
// System.out.println("path=" + req.getContextPath());
if (!file.canRead()) {
res.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
@ -61,7 +66,7 @@ public class AlbumServlet
if (file.isDirectory()) {
try {
List<Entry> entries = dao.read(file);
List<Entry> entries = dao.read(file).getContents();
res.setContentType("text/html");
req.setAttribute("directory", file.getName());
req.setAttribute("path", req.getServletPath());
@ -169,7 +174,7 @@ public class AlbumServlet
@Override
public String getServletInfo() {
return "Display a directory as an org.forkalsrud.album";
return "Display of org.forkalsrud.album";
}
}

View file

@ -14,6 +14,9 @@
margin: 10px auto;
text-align: center;
}
h1 {
text-align: left;
}
a:link, a:visited {
text-decoration: none;
color: #4c4c4c;
@ -30,18 +33,27 @@
img {
padding: 5px;
}
.nav {
border: 0 none;
padding: 0px;
vertical-align: middle;
}
</style>
</head>
<body>
<h1>$directory</h1>
<h1>#if($prev && $prev.isFile())<a href="${prev.name}.photo"><img class="nav" src="${assets}/left.png"/></a>#else<img class="nav" src="${assets}/left-inactive.png"/>#end#if($parent)<a href="$parent"><img class="nav" src="${assets}/up.png"/></a>#else<img class="nav" src="${assets}/up-inactive.png"/>#end#if($next && $next.isFile())<a href="${next.name}.photo"><img class="nav" src="${assets}/right.png"/></a>#else<img class="nav" src="${assets}/right-inactive.png"/>#end$directory</h1>
<hr/>
#set($thmb = 150)
#foreach($entry in $entries)
#set($dim = $entry.size.scaled($thmb))
<div class="home_entry_table">
<span class="name">$entry.name</span><br/>
<a href="${entry.name}.photo"><img src="$entry.name?size=$thmb" border="0" width="$dim.width" height="$dim.height"/></a><br/>
#if($entry.isFile())
<a href="${entry.name}.photo"><img src="$entry.path?size=$thmb" border="0" width="$dim.width" height="$dim.height"/></a><br/>
#else
<a href="${entry.name}/"><img src="$entry.path?size=$thmb" border="0" width="$dim.width" height="$dim.height"/></a><br/>
#end
<span class="caption">$!entry.caption</span>
</div>
#end

View file

@ -14,6 +14,9 @@
margin: 10px auto;
text-align: center;
}
h1 {
text-align: left;
}
a:link, a:visited {
text-decoration: none;
color: #4c4c4c;
@ -30,23 +33,21 @@
img {
padding: 5px;
}
.nav {
border: 0 none;
padding: 0px;
vertical-align: middle;
}
</style>
</head>
<body>
<center>
#if($prev)
<a href="${prev.name}.photo">&lt;--</a>
#end
#if($next)
<a href="${next.name}.photo">--&gt;</a>
#end
</center>
<h1>#if($prev && $prev.isFile())<a href="${prev.name}.photo"><img class="nav" src="${assets}/left.png"/></a>#else<img class="nav" src="${assets}/left-inactive.png"/>#end#if($parent)<a href="$parent"><img class="nav" src="${assets}/up.png"/></a>#else<img class="nav" src="${assets}/up-inactive.png"/>#end#if($next && $next.isFile())<a href="${next.name}.photo"><img class="nav" src="${assets}/right.png"/></a>#else<img class="nav" src="${assets}/right-inactive.png"/>#end$entry.name</h1>
<hr/>
#set($thmb = 480)
#set($dim = $entry.size.scaled($thmb))
<div class="photo">
<span class="name">$entry.name</span><br/>
<span class="name"></span><br/>
<a href="$entry.name"><img src="$entry.name?size=$thmb" border="0" width="$dim.width" height="$dim.height"/></a><br/>
<span class="caption">$!entry.caption</span>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

BIN
webapp/assets/left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

BIN
webapp/assets/right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

BIN
webapp/assets/up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B