Refactored names of date fields, Created a ResourceManager to handle filesystem stuff

This commit is contained in:
Ziver Koc 2018-08-11 12:53:40 +02:00
parent 8212379c31
commit 0a099bd5d7
16 changed files with 2245 additions and 2214 deletions

View file

@ -21,9 +21,9 @@ $(function(){
<div class="gallery col-center col-md-11"> <div class="gallery col-center col-md-11">
<div class="row"> <div class="row">
<div class="grid folder-grid"> <div class="grid folder-grid">
<c:forEach items="${subfolders}" var="subfolder"> <c:forEach items="${subfolders}" var="folder">
<div class="grid-item folder-thumb col-md-2 col-sm-3 col-xs-4"> <div class="grid-item folder-thumb col-md-2 col-sm-3 col-xs-4">
<img class="img-responsive" src="${subfolder.getThumbnailUrl()}" alt="${subfolder.getName()}" /> <img class="img-responsive" src="${folder.getThumbnailUrl()}" alt="${folder.getName()}" />
</div> </div>
</c:forEach> </c:forEach>
</div> </div>

View file

@ -13,7 +13,7 @@ CREATE TABLE `Comments` (
`image` int(11) DEFAULT NULL, `image` int(11) DEFAULT NULL,
`video` int(11) DEFAULT NULL, `video` int(11) DEFAULT NULL,
`user` int(11) DEFAULT NULL, `user` int(11) DEFAULT NULL,
`date` datetime DEFAULT NULL, `dateCreated` datetime DEFAULT NULL,
`message` text `message` text
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
@ -25,7 +25,7 @@ CREATE TABLE `Comments` (
CREATE TABLE `Folder` ( CREATE TABLE `Folder` (
`id` int(10) UNSIGNED NOT NULL, `id` int(10) UNSIGNED NOT NULL,
`user` int(10) UNSIGNED DEFAULT NULL, `owner` int(10) UNSIGNED DEFAULT NULL,
`path` text, `path` text,
`parent` int(10) UNSIGNED DEFAULT NULL, `parent` int(10) UNSIGNED DEFAULT NULL,
`date` datetime NOT NULL, `date` datetime NOT NULL,
@ -41,12 +41,12 @@ CREATE TABLE `Folder` (
CREATE TABLE `Image` ( CREATE TABLE `Image` (
`id` int(10) UNSIGNED NOT NULL, `id` int(10) UNSIGNED NOT NULL,
`folder` int(10) UNSIGNED NOT NULL, `folder` int(10) UNSIGNED NOT NULL,
`filename` varchar(45) NOT NULL, `fileName` varchar(45) NOT NULL,
`user` int(10) UNSIGNED NOT NULL, `fileExtension` varchar(5) NOT NULL,
`owner` int(10) UNSIGNED NOT NULL,
`title` varchar(55) DEFAULT NULL, `title` varchar(55) DEFAULT NULL,
`description` text, `description` text,
`date` datetime DEFAULT NULL, `dateUploaded` datetime DEFAULT NULL
`rating` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -63,7 +63,8 @@ CREATE TABLE `User` (
`passwordHash` varchar(64) DEFAULT NULL, `passwordHash` varchar(64) DEFAULT NULL,
`passwordSalt` varchar(5) DEFAULT NULL, `passwordSalt` varchar(5) DEFAULT NULL,
`ipHost` varchar(20) DEFAULT NULL, `ipHost` varchar(20) DEFAULT NULL,
`loginDate` datetime DEFAULT NULL, `dateCreated` datetime DEFAULT NULL,
`dateLastLogin` datetime DEFAULT NULL,
`cookieHash` varchar(42) DEFAULT NULL, `cookieHash` varchar(42) DEFAULT NULL,
`superUser` tinyint(1) NOT NULL, `superUser` tinyint(1) NOT NULL,
`enabled` tinyint(1) NOT NULL `enabled` tinyint(1) NOT NULL
@ -73,8 +74,8 @@ CREATE TABLE `User` (
-- Dumping data for table `User` -- Dumping data for table `User`
-- --
INSERT INTO `User` (`id`, `name`, `email`, `emailVerified`, `passwordHash`, `passwordSalt`, `ipHost`, `loginDate`, `cookieHash`, `superUser`, `enabled`) VALUES INSERT INTO `User` (`id`, `name`, `email`, `emailVerified`, `passwordHash`, `passwordSalt`, `ipHost`, `dateCreated`, `dateLastLogin`, `cookieHash`, `superUser`, `enabled`) VALUES
(1, 'Admin Admin', 'admin', 1, '6e88be8bad7eae9d9e10aa061224034fed48d03fcbad968b56006784539d5214', 'salt', '', '1970-01-01 01:00:0', '', 1, 1); (1, 'Admin Admin', 'admin', 1, '6e88be8bad7eae9d9e10aa061224034fed48d03fcbad968b56006784539d5214', 'salt', '', '1970-01-01 01:00:0', '1970-01-01 01:00:0', '', 1, 1);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -85,12 +86,12 @@ INSERT INTO `User` (`id`, `name`, `email`, `emailVerified`, `passwordHash`, `pas
CREATE TABLE `Video` ( CREATE TABLE `Video` (
`id` int(10) UNSIGNED NOT NULL, `id` int(10) UNSIGNED NOT NULL,
`folder` int(10) UNSIGNED NOT NULL, `folder` int(10) UNSIGNED NOT NULL,
`filename` varchar(45) NOT NULL, `fileName` varchar(45) NOT NULL,
`user` int(10) UNSIGNED NOT NULL, `fileExtension` varchar(5) NOT NULL,
`owner` int(10) UNSIGNED NOT NULL,
`title` varchar(55) DEFAULT NULL, `title` varchar(55) DEFAULT NULL,
`description` text, `description` text,
`date` datetime DEFAULT NULL, `dateUploaded` datetime DEFAULT NULL
`rating` float DEFAULT NULL,
`transcoded` tinyint(1) NOT NULL DEFAULT '0', `transcoded` tinyint(1) NOT NULL DEFAULT '0',
`length` int(10) UNSIGNED NOT NULL DEFAULT '0' `length` int(10) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

File diff suppressed because it is too large Load diff

View file

@ -16,35 +16,32 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItem;
import zall.bean.Folder; import zall.bean.*;
import zall.bean.Image;
import zall.bean.User;
import zall.bean.Video;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
import zutil.jee.upload.AjaxFileUpload; import zutil.jee.upload.AjaxFileUpload;
import zutil.log.LogUtil; import zutil.log.LogUtil;
public class UploadServlet extends AjaxFileUpload{ public class UploadServlet extends AjaxFileUpload {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Set<String> VIDEO_EXT = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList( private static final Set<String> VIDEO_EXT = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
"avi","mp4","mpeg","mpeg","divx","xvid","wmv","mov","flv","m4v"))); "avi", "mp4", "mpeg", "mpeg", "divx", "xvid", "wmv", "mov", "flv", "m4v")));
@Override @Override
public String getProgressHTML() { public String getProgressHTML() {
return ""+ return "" +
"<DIV class='comment-author vcard'>"+ "<DIV class='comment-author vcard'>" +
" <IMG src='img/upload.png' class='photo avatar photo' height='80' width='80'>"+ " <IMG src='img/upload.png' class='photo avatar photo' height='80' width='80'>" +
" <SPAN class='fn n'>"+ " <SPAN class='fn n'>" +
" <span class='status'>Unknown</span>: <span class='filename' style='font-weight: normal;'>Unknown</span> - <span class='message' style='font-weight: normal;'>Unknown</span>"+ " <span class='status'>Unknown</span>: <span class='filename' style='font-weight: normal;'>Unknown</span> - <span class='message' style='font-weight: normal;'>Unknown</span>" +
" <div class='progressbar'>"+ " <div class='progressbar'>" +
" <b class='progress' style='width: 0%'> </b>"+ " <b class='progress' style='width: 0%'> </b>" +
" </div>"+ " </div>" +
" </SPAN>"+ " </SPAN>" +
"</DIV>"+ "</DIV>" +
"<DIV class='comment-meta'>" + "<DIV class='comment-meta'>" +
" <span class='uploaded'>0 KB</span>/ <span class='total'>0 KB</span> " + " <span class='uploaded'>0 KB</span>/ <span class='total'>0 KB</span> " +
" - Speed: <span class='speed'>400 KB/s</span>" + " - Speed: <span class='speed'>400 KB/s</span>" +
@ -53,7 +50,7 @@ public class UploadServlet extends AjaxFileUpload{
@Override @Override
public void doUpload(HttpServletRequest request, HttpServletResponse response, public void doUpload(HttpServletRequest request, HttpServletResponse response,
Map<String,String> fields, List<FileItem> files) throws ServletException{ Map<String, String> fields, List<FileItem> files) throws ServletException {
DBConnection db = null; DBConnection db = null;
try { try {
HttpSession session = request.getSession(); HttpSession session = request.getSession();
@ -61,46 +58,42 @@ public class UploadServlet extends AjaxFileUpload{
User user = (User) session.getAttribute("user"); User user = (User) session.getAttribute("user");
// Check if user is authentication // Check if user is authentication
if(user != null){ if (user != null) {
Folder folder = Folder.load(db, Long.parseLong( fields.get("folder") )); Folder folder = Folder.load(db, Long.parseLong(fields.get("folder")));
// Handle files // Handle files
for(FileItem item : files){ for (FileItem item : files) {
try{ try {
String ext = FileUtil.getFileExtension(item.getName()).toLowerCase(); String ext = FileUtil.getFileExtension(item.getName()).toLowerCase();
if( VIDEO_EXT.contains(ext) ){ Media media;
Video vid = new Video(); if (VIDEO_EXT.contains(ext)) {
vid.setTitle( item.getName() ); logger.fine("Video upload detected, extension: " + ext);
vid.setFolder( folder ); media = new Video();
vid.setUser( user ); } else {
vid.setFile( item ); logger.fine("Image upload detected, extension: " + ext);
vid.save(db); media = new Image();
logger.info("Video upload successful: "+vid.getFolder().getPath());
}
else{
Image img = new Image();
img.setTitle( item.getName() );
img.setFolder( folder );
img.setUser( user );
img.setFile( item );
img.save(db);
logger.info("Image upload successful: "+img.getFolder().getPath());
} }
media.setTitle(item.getName());
media.setFolder(folder);
media.setOwner(user);
media.setFile(item);
media.save(db);
logger.fine("Media upload successful: " + item.getName());
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.WARNING, "Error: Creating new Media(\""+item.getName()+"\")", e); logger.log(Level.WARNING, "Error: Creating new media(" + item.getName() + ")", e);
e.printStackTrace(); e.printStackTrace();
} }
item.delete(); item.delete();
} }
response.getWriter().print("<html>OK</html>"); response.getWriter().print("<html>OK</html>");
} } else
else
response.getWriter().print("<html>Authentication Error</html>"); response.getWriter().print("<html>Authentication Error</html>");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
throw new ServletException(e); throw new ServletException(e);
} finally{ } finally {
if(db != null) db.close(); if (db != null) db.close();
} }
} }

View file

@ -47,7 +47,7 @@ public class CreateFolderAction extends ZalleryAction {
if (parent == null) { // Create root folder if (parent == null) { // Create root folder
parent = Folder.loadRoot(db, user); // get root folder parent = Folder.loadRoot(db, user); // get root folder
folder = new Folder(); folder = new Folder();
folder.setUser(user); folder.setOwner(user);
folder.setParent(parent); folder.setParent(parent);
folder.setName("{NAME}"); folder.setName("{NAME}");
folder.save(db); folder.save(db);
@ -62,7 +62,7 @@ public class CreateFolderAction extends ZalleryAction {
folder = Folder.load(db, path, user); folder = Folder.load(db, path, user);
if (folder == null) { // create folder if (folder == null) { // create folder
folder = new Folder(); folder = new Folder();
folder.setUser(user); folder.setOwner(user);
folder.setParent(parent); folder.setParent(parent);
folder.setName(dir); folder.setName(dir);
folder.save(db); folder.save(db);

View file

@ -8,18 +8,18 @@ import zutil.db.bean.DBBean.*;
import zutil.parser.BBCodeParser; import zutil.parser.BBCodeParser;
@DBTable("Comments") @DBTable("Comments")
public class Comment extends DBBean{ public class Comment extends DBBean {
private static BBCodeParser parser = null; private static BBCodeParser parser = null;
protected User user; protected User user;
protected Date date; protected Date dateCreated;
protected String message; protected String message;
public Comment(){ public Comment() {
if( parser == null ){ if (parser == null) {
parser = new BBCodeParser(); parser = new BBCodeParser();
} }
setCurrentDate(); this.dateCreated = new Timestamp(System.currentTimeMillis());
} }
public User getUser() { public User getUser() {
@ -28,23 +28,19 @@ public class Comment extends DBBean{
public void setUser(User user) { public void setUser(User user) {
this.user = user; this.user = user;
} }
public Date getDate() {
return date; public Date getDateCreated() {
} return dateCreated;
public void setDate(Date date) {
this.date = date;
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
public void setMessage(String msg) { public void setMessage(String msg) {
if( msg != null ){ if (msg != null) {
msg = msg.replaceAll("<", "&lt;"); msg = msg.replaceAll("<", "&lt;");
msg = msg.replaceAll(">", "&gt;"); msg = msg.replaceAll(">", "&gt;");
this.message = parser.read( msg ); this.message = parser.read(msg);
} }
} }
public void setCurrentDate() {
this.date = new Timestamp( System.currentTimeMillis() );
}
} }

View file

@ -1,14 +1,11 @@
package zall.bean; package zall.bean;
import java.io.File;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
@ -16,18 +13,14 @@ import zutil.db.bean.DBBeanSQLResultHandler;
import zutil.db.bean.DBBean.*; import zutil.db.bean.DBBean.*;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import zall.Zallery;
@DBTable("Folder") @DBTable("Folder")
public class Folder extends DBBean { public class Folder extends DBBean {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private transient String name; private String name;
protected long user = -1; private User owner;
protected transient User userInstance; private Folder parent;
private String path; private Timestamp dateCreated;
protected Folder parent;
protected Timestamp date;
private boolean isPrivate; private boolean isPrivate;
@ -36,15 +29,15 @@ public class Folder extends DBBean {
} }
public static List<Folder> loadSubFolders(DBConnection db, Folder folder, User requestingUser) throws SQLException { public static List<Folder> loadSubFolders(DBConnection db, Folder folder, User requestingUser) throws SQLException {
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE parent=? AND (isPrivate=0 OR user=? OR ?)"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE parent=? AND (isPrivate=0 OR owner=? OR ?)");
sql.setLong(1, folder.getId()); sql.setLong(1, folder.getId());
sql.setLong(2, folder.user); sql.setLong(2, folder.owner.getId());
sql.setBoolean(3, requestingUser.isSuperUser()); sql.setBoolean(3, requestingUser.isSuperUser());
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db));
} }
public static Folder loadRoot(DBConnection db, User user) throws SQLException { public static Folder loadRoot(DBConnection db, User user) throws SQLException {
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND (isPrivate=0 OR user=? OR ?)"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND (isPrivate=0 OR owner=? OR ?)");
sql.setString(1, "/"); sql.setString(1, "/");
sql.setLong(2, user.getId()); sql.setLong(2, user.getId());
sql.setBoolean(3, user.isSuperUser()); sql.setBoolean(3, user.isSuperUser());
@ -52,7 +45,7 @@ public class Folder extends DBBean {
} }
public static Folder load(DBConnection db, String path, User user) throws SQLException { public static Folder load(DBConnection db, String path, User user) throws SQLException {
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND user=?"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND owner=?");
sql.setString(1, path); sql.setString(1, path);
sql.setLong(2, user.getId()); sql.setLong(2, user.getId());
return DBConnection.exec(sql, DBBeanSQLResultHandler.create(Folder.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.create(Folder.class, db));
@ -61,138 +54,61 @@ public class Folder extends DBBean {
public static List<Folder> load(DBConnection db, User user) throws SQLException { public static List<Folder> load(DBConnection db, User user) throws SQLException {
if (user.getId() == null) if (user.getId() == null)
return Collections.emptyList(); return Collections.emptyList();
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE user=?"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE owner=?");
sql.setLong(1, user.getId()); sql.setLong(1, user.getId());
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db));
} }
public Folder() { public Folder() {
date = new Timestamp(System.currentTimeMillis()); dateCreated = new Timestamp(System.currentTimeMillis());
} }
public String getName() {
if (name == null) {
String[] tmp = path.split("/");
name = tmp[tmp.length - 1];
}
String userName = getUser() != null ? getUser().getName() : "UNKNOWN";
String tmp = name.replaceAll("\\{NAME\\}", userName);
return tmp;
}
public User getUser() { public User getOwner() {
if (userInstance == null) { return owner;
try {
DBConnection db = Zallery.getDB();
userInstance = User.load(db, user);
db.close();
} catch (Exception e) {
logger.log(Level.WARNING, null, e);
} }
} public void setOwner(User user) {
return userInstance; this.owner = user;
}
public void setUser(User user) {
this.user = user.getId();
this.userInstance = null;
} }
public boolean isPrivate() { public boolean isPrivate() {
return isPrivate; return isPrivate;
} }
public void setPrivate(boolean priv) { public void setPrivate(boolean priv) {
this.isPrivate = priv; this.isPrivate = priv;
} }
public String getPath() { public String getName() {
String tmp = path.replaceAll("\\{NAME\\}", getUser().getName()); String userName = owner != null ? owner.getName() : "UNKNOWN";
String tmp = name.replaceAll("\\{NAME\\}", userName);
return tmp; return tmp;
} }
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
if (parent.path.endsWith("/"))
this.path = parent.path + name;
else
this.path = parent.path + "/" + name;
} }
public void setParent(Folder parent) { public void setParent(Folder parent) {
if (this.parent != parent) {
this.parent = parent; this.parent = parent;
//parent.addSubFolder( this );
if (parent.path.endsWith("/"))
this.path = parent.path + name;
else
this.path = parent.path + "/" + name;
} }
}
public Folder getParent() { public Folder getParent() {
return parent; return parent;
} }
public Timestamp getDate() { public Timestamp getDateCreated() {
return date; return dateCreated;
} }
/** public static Folder createRootFolder() {
* @param filename is the name of the file
* @param size specifies the size of the image
* @return a File object that points to the physical file on the disk,
* or null if the user or the filename is null
*/
public File getFile(String filename, Image.Size size) {
// Zallery not initialized.
if (Zallery.DATA_PATH.isEmpty()) {
throw new NullPointerException("Zallery not initialized yet or DATA_PATH not set!");
}
if (user < 0 || filename == null)
return null;
StringBuilder tmp = new StringBuilder();
// Get the Root path of the given size
tmp.append(Zallery.DATA_PATH);
if (tmp.charAt(tmp.length() - 1) != File.separatorChar)
tmp.append(File.separatorChar);
tmp.append(size.toString());
if (path.charAt(0) != '/')
tmp.append(File.separatorChar);
// Add UserID and this folders path
String tmp_path = path.replaceAll("\\{NAME\\}", "" + user);
tmp_path = tmp_path.replaceAll("/", Matcher.quoteReplacement(File.separator));
tmp.append(tmp_path);
// check if folder exists or else create it
File folder = new File(tmp.toString());
if (!folder.exists())
if (!folder.mkdirs()) {
logger.warning("Unable to create new folders: '" + folder + "'");
throw new RuntimeException("Unable to create new folders: '" + folder + "'");
}
// Add the filename
if (tmp.charAt(tmp.length() - 1) != File.separatorChar)
tmp.append(File.separatorChar);
tmp.append(filename);
logger.finest("File path: " + tmp.toString());
return new File(tmp.toString());
}
public static Folder genRoot() {
Folder root = new Folder(); Folder root = new Folder();
root.parent = null; root.parent = null;
root.path = "/"; root.owner = null;
root.name = "/";
return root; return root;
} }
public boolean isEmpty(DBConnection db) throws SQLException { public boolean isEmpty(DBConnection db) throws SQLException {
return Folder.loadSubFolders(db, this, getUser()).isEmpty() && Media.load(db, this).isEmpty(); return Folder.loadSubFolders(db, this, getOwner()).isEmpty() && Media.load(db, this).isEmpty();
} }
} }

View file

@ -13,6 +13,7 @@ import javax.imageio.ImageIO;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItem;
import zall.manager.ResourceManager;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
import zutil.db.bean.DBBeanSQLResultHandler; import zutil.db.bean.DBBeanSQLResultHandler;
@ -63,27 +64,37 @@ public class Image extends Media {
if (folder == null) if (folder == null)
throw new Exception("Folder not set for image!"); throw new Exception("Folder not set for image!");
// Generate unique filename // Generate unique filename
filename = genFileName(item.getName()); fileName = ResourceManager.generateFileName();
filename += "." + FileUtil.getFileExtension(item.getName()); fileExtension = FileUtil.getFileExtension(item.getName());
File file = folder.getFile(filename, Size.ORIGINAL); File file = ResourceManager.getFile(this, Size.ORIGINAL);
// Move uploaded file // Move uploaded file
item.write(file); item.write(file);
} }
@Override
public String getFileExtension(Size size) {
switch (size) {
case ORIGINAL:
return fileExtension;
default:
return IMAGE_FORMAT;
}
}
/** /**
* Returns the file for the image, and generates an thumbnail if there is no thumbnail * Returns the file for the image, and generates a thumbnail if the specified size is missing
* *
* @param size is the size of the image * @param size is the size of the image
*/ */
public File getFile(Size size) throws IOException { public File getFile(Size size) throws IOException {
if (filename != null) { if (fileName != null) {
switch (size) { switch (size) {
case ORIGINAL: case ORIGINAL:
return folder.getFile(filename, Size.ORIGINAL); return ResourceManager.getFile(this, Size.ORIGINAL);
default: default:
File file = folder.getFile(FileUtil.replaceExtension(filename, IMAGE_FORMAT), size); File file = ResourceManager.getFile(this, size);
File orgFile = folder.getFile(filename, Size.ORIGINAL); File orgFile = ResourceManager.getFile(this, Size.ORIGINAL);
if (!file.exists()) { if (!file.exists()) {
if (orgFile.exists() && orgFile.canRead()) { if (orgFile.exists() && orgFile.canRead()) {
// Generate new thumbnail // Generate new thumbnail
@ -103,7 +114,8 @@ public class Image extends Media {
break; break;
} }
ImageIO.write(image, IMAGE_FORMAT, file); ImageIO.write(image, IMAGE_FORMAT, file);
} else if (!orgFile.exists()) }
else if (!orgFile.exists())
logger.severe("Original image file missing: \"" + file.getAbsolutePath() + "\""); logger.severe("Original image file missing: \"" + file.getAbsolutePath() + "\"");
else if (orgFile.canRead()) else if (orgFile.canRead())
logger.severe("Can not read original image file: \"" + file.getAbsolutePath() + "\""); logger.severe("Can not read original image file: \"" + file.getAbsolutePath() + "\"");
@ -115,7 +127,7 @@ public class Image extends Media {
} }
@Override @Override
public String getType() { public Type getType() {
return type; return Type.IMAGE;
} }
} }

View file

@ -1,6 +1,5 @@
package zall.bean; package zall.bean;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
@ -12,123 +11,122 @@ import java.util.logging.Logger;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItem;
import zutil.Hasher; import zall.manager.ResourceManager;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
import zutil.log.LogUtil; import zutil.log.LogUtil;
public abstract class Media extends DBBean implements Comparable<Media>{ public abstract class Media extends DBBean implements Comparable<Media> {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
public static enum Size{ public enum Type {
IMAGE, VIDEO
}
public enum Size {
ORIGINAL, LARGE, MEDIUM, SMALL ORIGINAL, LARGE, MEDIUM, SMALL
} }
protected Folder folder; protected Folder folder;
protected String filename; protected String fileName;
/** owner */ protected String fileExtension;
protected User user; protected User owner;
protected String title; protected String title;
protected String description; protected String description;
protected Timestamp date; protected Timestamp dateUploaded;
protected float rating;
/** /**
* Loads all the media in a folder * Loads all the media in a folder
*/ */
public final static List<Media> load(DBConnection db, Folder folder) throws SQLException{ public final static List<Media> load(DBConnection db, Folder folder) throws SQLException {
List<Image> image = Image.loadFolder(db, folder); List<Image> image = Image.loadFolder(db, folder);
List<Video> video = Video.loadFolder(db, folder); List<Video> video = Video.loadFolder(db, folder);
List<Media> media = new LinkedList<Media>(); List<Media> media = new LinkedList<Media>();
media.addAll(image); media.addAll(image);
media.addAll(video); media.addAll(video);
Collections.sort( media ); Collections.sort(media);
return media; return media;
} }
public static Media load(DBConnection db, String type, long id) throws SQLException{ public static Media load(DBConnection db, String type, long id) throws SQLException {
if( type.equals(Image.type) ) if (type.equals(Image.type))
return Image.load(db, id); return Image.load(db, id);
else if( type.equals(Video.type) ) else if (type.equals(Video.type))
return Video.load(db, id); return Video.load(db, id);
return null; return null;
} }
public Media(){ public Media() {
setCurrentDate(); this.dateUploaded = new Timestamp(System.currentTimeMillis());
} }
public String getFilename() { public String getFileName() {
return filename; return fileName;
} }
public Folder getFolder() { public Folder getFolder() {
return folder; return folder;
} }
public void setFolder(Folder folder) { public void setFolder(Folder folder) {
this.folder = folder; this.folder = folder;
} }
public void setImageUrl(String filename) {
this.filename = filename; public User getOwner() {
return owner;
} }
public User getUser() { public void setOwner(User owner) {
return user; this.owner = owner;
}
public void setUser(User user) {
this.user = user;
} }
public String getTitle() { public String getTitle() {
return title; return title;
} }
public void setTitle(String title) { public void setTitle(String title) {
this.title = title; this.title = title;
} }
public String getDescription() { public String getDescription() {
return description; return description;
} }
public void setDescription(String desc) { public void setDescription(String desc) {
this.description = desc; this.description = desc;
} }
public Timestamp getDate() {
return date; public Timestamp getDateUploaded() {
} return dateUploaded;
public void setDate(Timestamp date) {
this.date = date;
}
public void setCurrentDate() {
this.date = new Timestamp( System.currentTimeMillis() );
} }
public String genFileName(String str){ /* Overridden Methods */
return Hasher.MD5( ""+this.getId()+str+user.getName()+date.getTime()+System.currentTimeMillis() );
}
@Override
public void delete(DBConnection db) throws SQLException {
try {
ResourceManager.delete(this);
super.delete(db);
} catch (IOException e) {
logger.log(Level.SEVERE, null, e);
}
}
@Override @Override
public int compareTo(Media m) { public int compareTo(Media m) {
return this.date.compareTo( m.date ); return this.dateUploaded.compareTo(m.dateUploaded);
} }
public abstract LinkedList<Comment> getComments(); /* Abstract Methods */
public abstract List<Comment> getComments();
public abstract void addComment(Comment cm); public abstract void addComment(Comment cm);
public abstract void setFile(FileItem item) throws Exception; public abstract void setFile(FileItem item) throws Exception;
public abstract File getFile(Size size) throws IOException; /**
* @return the file extension for the specified size.
*/
public abstract String getFileExtension(Size size);
public abstract String getType(); public abstract Type getType();
public void delete(DBConnection db) throws SQLException{
super.delete(db);
for( Size s : Size.values() )
try {
this.getFile(s).delete();
logger.finer("Removed media(id: "+this.getId()+") file(size: "+s+")");
} catch (IOException e) {
logger.log(Level.SEVERE, "Can not delete \""+s+"\" file!", e);
}
}
} }

View file

@ -24,8 +24,9 @@ public class User extends DBBean {
protected boolean emailVerified; protected boolean emailVerified;
protected String passwordHash; protected String passwordHash;
protected String passwordSalt; protected String passwordSalt;
// Date // Dates
protected Timestamp loginDate; protected Timestamp dateCreated;
protected Timestamp dateLastLogin;
// security // security
protected transient AuthType authBy; protected transient AuthType authBy;
protected String ipHost; protected String ipHost;
@ -85,6 +86,7 @@ public class User extends DBBean {
emailVerified = false; emailVerified = false;
superUser = false; superUser = false;
enabled = false; enabled = false;
dateCreated = new Timestamp(System.currentTimeMillis());
} }
public boolean verifyEmail(String hash) { public boolean verifyEmail(String hash) {
@ -96,14 +98,14 @@ public class User extends DBBean {
} }
public Timestamp getLoginDate() { public Timestamp getDateLastLogin() {
if (loginDate == null) if (dateLastLogin == null)
loginDate = new Timestamp(0); dateLastLogin = new Timestamp(0);
return loginDate; return dateLastLogin;
} }
public void setLoginDate(Timestamp loginDate) { public void setDateLastLogin(Timestamp dateLastLogin) {
this.loginDate = loginDate; this.dateLastLogin = dateLastLogin;
} }
public void setAuthBy(AuthType authBy) { public void setAuthBy(AuthType authBy) {

View file

@ -1,7 +1,5 @@
package zall.bean; package zall.bean;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.LinkedList; import java.util.LinkedList;
@ -9,6 +7,7 @@ import java.util.List;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItem;
import zall.manager.ResourceManager;
import zall.transcoder.ZalleryTranscoder; import zall.transcoder.ZalleryTranscoder;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
@ -16,100 +15,105 @@ import zutil.db.bean.DBBeanSQLResultHandler;
import zutil.db.bean.DBBean.*; import zutil.db.bean.DBBean.*;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
@DBTable(value="Video", superBean = true) @DBTable(value = "Video", superBean = true)
public class Video extends Media{ public class Video extends Media {
public static final String type = "video"; public static final String type = "video";
public static final String VIDEO_FORMAT = "mp4"; public static final String VIDEO_FORMAT = "mp4";
/** The progress of a transcoding in %, 0 if there is no transcoding running **/ /**
* The progress of a transcoding in %, 0 if there is no transcoding running
**/
protected transient int transcodingProgress; protected transient int transcodingProgress;
/** If the Video is transcoded **/ /**
* If the Video is transcoded
**/
protected boolean transcoded; protected boolean transcoded;
/** the time length of the video in seconds **/ /**
* the time length of the video in seconds
**/
protected long length; protected long length;
@DBLinkTable(table="Comments", beanClass=Comment.class, idColumn="video") @DBLinkTable(table = "Comments", beanClass = Comment.class, idColumn = "video")
private LinkedList<Comment> comments; private LinkedList<Comment> comments;
/** /**
* Loads all the Videos from a folder * Loads all the Videos from a folder
*/ */
public static List<Video> loadFolder(DBConnection db, Folder folder) throws SQLException{ public static List<Video> loadFolder(DBConnection db, Folder folder) throws SQLException {
if( folder == null || folder.getId() == null ) if (folder == null || folder.getId() == null)
return new LinkedList<Video>(); return new LinkedList<Video>();
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE folder=? ORDER BY date DESC"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE folder=? ORDER BY date DESC");
sql.setLong(1, folder.getId() ); sql.setLong(1, folder.getId());
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db));
} }
public static List<Video> loadUntransoded(DBConnection db) throws SQLException { public static List<Video> loadUntransoded(DBConnection db) throws SQLException {
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE transcoded=0 ORDER BY date DESC"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE transcoded=0 ORDER BY date DESC");
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db));
} }
public static Video load(DBConnection db, long id) throws SQLException{
public static Video load(DBConnection db, long id) throws SQLException {
return DBBean.load(db, Video.class, id); return DBBean.load(db, Video.class, id);
} }
public Video(){ public Video() {
super(); super();
transcoded = false; transcoded = false;
comments = new LinkedList<Comment>(); comments = new LinkedList<Comment>();
} }
public boolean isTranscoded(){ public boolean isTranscoded() {
return transcoded; return transcoded;
} }
public void setTranscoded(boolean transcoded) {
public void setTranscoded(boolean transcoded){
this.transcoded = transcoded; this.transcoded = transcoded;
} }
public void setTranscodingProgress(int trans){ public void setTranscodingProgress(int trans) {
transcodingProgress = trans; transcodingProgress = trans;
} }
public int getTranscodingProgress() {
public int getTranscodingProgress(){
return transcodingProgress; return transcodingProgress;
} }
public LinkedList<Comment> getComments() { public LinkedList<Comment> getComments() {
return comments; return comments;
} }
public void addComment(Comment cm){ public void addComment(Comment cm) {
comments.add( cm ); comments.add(cm);
} }
public void setFile(FileItem item) throws Exception{ public void setFile(FileItem item) throws Exception {
if( folder == null ) if (folder == null)
throw new Exception("Folder not set for Video!"); throw new Exception("Folder not set for Video!");
// Generate unique filename // Generate unique filename
filename = this.genFileName( item.getName() ); fileName = ResourceManager.generateFileName();
filename += "."+FileUtil.getFileExtension( item.getName() ); fileExtension = "." + FileUtil.getFileExtension(item.getName());
// Move uploaded file // Move uploaded file
item.write( folder.getFile( filename, Size.ORIGINAL ) ); item.write(ResourceManager.getFile(this, Size.ORIGINAL));
item.delete(); item.delete();
ZalleryTranscoder.addVideo( this ); ZalleryTranscoder.addVideo(this);
} }
/** @Override
* Returns the file for the video public String getFileExtension(Size size) {
* if (fileName != null) {
* @param size is the size of the image switch (size) {
*/ case SMALL:
public File getFile(Size size) throws IOException{ return Image.IMAGE_FORMAT;
if( filename != null ){ case MEDIUM:
if( size == Size.SMALL ) return VIDEO_FORMAT;
return folder.getFile( FileUtil.replaceExtension(filename, Image.IMAGE_FORMAT), size ); default:
else if( size == Size.MEDIUM ) return fileExtension;
return folder.getFile( FileUtil.replaceExtension(filename, VIDEO_FORMAT), size ); }
else
return folder.getFile( filename, size );
} }
return null; return null;
} }
@Override @Override
public String getType() { public Type getType() {
return type; return Type.VIDEO;
} }
} }

View file

@ -58,7 +58,7 @@ public class AuthenticationManager {
if (user != null) { if (user != null) {
if (request.getRemoteAddr().equals(user.getIpHost()) && if (request.getRemoteAddr().equals(user.getIpHost()) &&
user.getLoginDate().getTime() + SESSION_TIMEOUT > System.currentTimeMillis()) { user.getDateLastLogin().getTime() + SESSION_TIMEOUT > System.currentTimeMillis()) {
setUserAuthenticated(db, user, User.AuthType.COOKIE, request, response); setUserAuthenticated(db, user, User.AuthType.COOKIE, request, response);
return user; return user;
} else { } else {
@ -72,7 +72,7 @@ public class AuthenticationManager {
} }
private static void setUserAuthenticated(DBConnection db, User user, User.AuthType authType, HttpServletRequest request, HttpServletResponse response) throws SQLException { private static void setUserAuthenticated(DBConnection db, User user, User.AuthType authType, HttpServletRequest request, HttpServletResponse response) throws SQLException {
user.setLoginDate(new Timestamp(System.currentTimeMillis())); user.setDateLastLogin(new Timestamp(System.currentTimeMillis()));
user.setAuthBy(authType); user.setAuthBy(authType);
user.setIpHost(request.getRemoteAddr()); user.setIpHost(request.getRemoteAddr());
user.setCookieHash(Hasher.SHA1(Math.random())); user.setCookieHash(Hasher.SHA1(Math.random()));
@ -154,14 +154,14 @@ public class AuthenticationManager {
* @return true if the specified user can edit the media * @return true if the specified user can edit the media
*/ */
public static boolean canEdit(User user, Media target) { public static boolean canEdit(User user, Media target) {
return target != null && (user.isSuperUser() || target.getUser().equals(user)); return target != null && (user.isSuperUser() || target.getOwner().equals(user));
} }
/** /**
* @return true if the specified user can edit the media * @return true if the specified user can edit the media
*/ */
public static boolean canEdit(User user, Folder target) { public static boolean canEdit(User user, Folder target) {
return target != null && (user.isSuperUser() || user.equals(target.getUser())); return target != null && (user.isSuperUser() || user.equals(target.getOwner()));
} }
/** /**

View file

@ -0,0 +1,114 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package zall.manager;
import zall.Zallery;
import zall.bean.Folder;
import zall.bean.Image;
import zall.bean.Media;
import zutil.Hasher;
import zutil.log.LogUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Logger;
/**
* Manages resources on the filesystem and associates
* them to a Media object.
*/
public class ResourceManager {
private static final Logger logger = LogUtil.getLogger();
/**
* @param media is the media to find on the filesystem
* @param size specifies the size of the media.
* @return a File object that points to the physical file on the disk, or null.
*/
public static File getFile(Media media, Image.Size size) throws FileNotFoundException {
// Pre checks
if (Zallery.DATA_PATH.isEmpty()) {
throw new NullPointerException("Zallery not initialized yet or DATA_PATH not set!");
}
if (media == null) {
throw new NullPointerException("No path available for null media.");
}
if (media.getFolder() == null) {
throw new NullPointerException("Media not in any folder.");
}
// Get the Root path
File rootFolder = new File(Zallery.DATA_PATH);
if (!rootFolder.exists())
throw new FileNotFoundException("Could not find data folder: " + rootFolder.getAbsolutePath());
// Size based folder
File sizeRootFolder = new File(rootFolder, size.toString());
// check if folder exists or else create it
File folder = new File(sizeRootFolder, getFolderPath(media.getFolder()));
if (!folder.exists()) {
if (!folder.mkdirs()) {
throw new RuntimeException("Unable to create new folders: '" + folder + "'.");
}
}
// Add the filename
File mediaFile = new File(folder, media.getFileName());
logger.finest("File path: " + mediaFile.getAbsolutePath());
return mediaFile;
}
public static void delete(Media media) throws IOException {
for (Media.Size size : Media.Size.values()) {
File file = getFile(media, size);
if (file.exists()) {
if (file.delete())
throw new IOException("Was unable to delete file '" + file.getAbsolutePath() + "'");
logger.finer("Removed media(id: " + media.getId() + ", name: " + media.getTitle() + ") file(" + file + ")");
}
}
}
public static String getFolderPath(Folder folder) {
StringBuilder path = new StringBuilder();
for (Folder currentFolder = folder;
currentFolder != null;
currentFolder = currentFolder.getParent()) {
path.insert(0, currentFolder.getName());
if (path.charAt(0) != '/')
path.insert(0, '/');
}
return path.toString();
}
public static String generateFileName() {
return Hasher.MD5(Math.random());
}
}

View file

@ -8,20 +8,16 @@ import java.sql.SQLException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.util.Streams; import org.apache.commons.fileupload.util.Streams;
import zall.Zallery;
import zall.ZalleryServlet; import zall.ZalleryServlet;
import zall.bean.Image; import zall.bean.Image;
import zall.bean.Media; import zall.bean.Media;
import zall.bean.User;
import zall.bean.Video; import zall.bean.Video;
import zall.manager.AuthenticationManager; import zall.manager.ResourceManager;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.io.file.FileUtil; import zutil.io.file.FileUtil;
@ -41,7 +37,6 @@ public class ContentServlet extends ZalleryServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response, DBConnection db) throws ServletException, SQLException, IOException { public void doGet(HttpServletRequest request, HttpServletResponse response, DBConnection db) throws ServletException, SQLException, IOException {
String size = request.getParameter("size");
Media media = null; Media media = null;
String contentType = ""; String contentType = "";
@ -57,17 +52,18 @@ public class ContentServlet extends ZalleryServlet {
} }
if (media != null) { if (media != null) {
File file; Media.Size size = Media.Size.ORIGINAL;
if (size == null) if (request.getParameter("size") != null)
file = media.getFile(Media.Size.ORIGINAL); size = Media.Size.valueOf(request.getParameter("size").toUpperCase());
else
file = media.getFile(Media.Size.valueOf(size.toUpperCase())); File file = ResourceManager.getFile(media, size);
String extension = media.getFileExtension(size);
if (request.getParameter("download") != null) if (request.getParameter("download") != null)
response.setHeader("Content-disposition", "attachment; filename=" + media.getTitle() + "." + FileUtil.getFileExtension(file)); response.setHeader("Content-disposition", "attachment; filename=" + media.getTitle() + "." + extension);
if (file.exists()) { if (file.exists()) {
response.setContentType(contentType + "/" + FileUtil.getFileExtension(file)); response.setContentType(contentType + "/" + extension);
response.setContentLength((int) file.length()); response.setContentLength((int) file.length());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));

View file

@ -40,7 +40,7 @@ public class GalleryServlet extends ZalleryServlet {
folder = Folder.loadRoot(db, user); folder = Folder.loadRoot(db, user);
// Setup new root folder // Setup new root folder
if (folder == null) { if (folder == null) {
folder = Folder.genRoot(); folder = Folder.createRootFolder();
folder.save(db); folder.save(db);
} }
} }

View file

@ -34,12 +34,13 @@ import com.xuggle.xuggler.video.IConverter;
import zall.Zallery; import zall.Zallery;
import zall.bean.Media.Size; import zall.bean.Media.Size;
import zall.bean.Video; import zall.bean.Video;
import zall.manager.ResourceManager;
import zutil.StringUtil; import zutil.StringUtil;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.log.LogUtil; import zutil.log.LogUtil;
@WebServlet(value = "/transcoder", loadOnStartup = 100) @WebServlet(value = "/transcoder", loadOnStartup = 100)
public class ZalleryTranscoder extends HttpServlet{ public class ZalleryTranscoder extends HttpServlet {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -47,8 +48,8 @@ public class ZalleryTranscoder extends HttpServlet{
private static Queue<Video> transcodingQueue; private static Queue<Video> transcodingQueue;
private static TranscoderThread worker; private static TranscoderThread worker;
public void init( ServletConfig config ){ public void init(ServletConfig config) {
try{ try {
transcodingQueue = new LinkedList<>(); transcodingQueue = new LinkedList<>();
worker = new TranscoderThread(); worker = new TranscoderThread();
worker.start(); worker.start();
@ -57,32 +58,31 @@ public class ZalleryTranscoder extends HttpServlet{
DBConnection db = null; DBConnection db = null;
try { try {
db = Zallery.getDB(); db = Zallery.getDB();
List<Video> incomplete = Video.loadUntransoded( db ); List<Video> incomplete = Video.loadUntransoded(db);
synchronized (transcodingQueue) { synchronized (transcodingQueue) {
transcodingQueue.addAll( incomplete ); transcodingQueue.addAll(incomplete);
transcodingQueue.notify(); transcodingQueue.notify();
} }
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, null, e); logger.log(Level.SEVERE, null, e);
}finally{ } finally {
if( db != null ) db.close(); if (db != null) db.close();
} }
} } catch (Exception e) {
catch(Exception e){
logger.log(Level.SEVERE, "Unable to initialize ZalleryTranscoder!", e); logger.log(Level.SEVERE, "Unable to initialize ZalleryTranscoder!", e);
} }
} }
public void destroy( ){ public void destroy() {
worker.abort(); worker.abort();
} }
public static Video getProcessingVideo(){ public static Video getProcessingVideo() {
return worker.currentVideo; return worker.currentVideo;
} }
public static Queue<Video> getQueue(){ public static Queue<Video> getQueue() {
return transcodingQueue; return transcodingQueue;
} }
@ -93,13 +93,13 @@ public class ZalleryTranscoder extends HttpServlet{
* @param video is the video to transcode * @param video is the video to transcode
*/ */
public static void addVideo(Video video) { public static void addVideo(Video video) {
if( transcodingQueue == null ){ if (transcodingQueue == null) {
logger.severe("ZalleryTranscoder not initialized!"); logger.severe("ZalleryTranscoder not initialized!");
return; return;
} }
if( !transcodingQueue.contains(video) && worker.currentVideo != video ){ if (!transcodingQueue.contains(video) && worker.currentVideo != video) {
synchronized (transcodingQueue){ synchronized (transcodingQueue) {
transcodingQueue.add( video ); transcodingQueue.add(video);
transcodingQueue.notify(); transcodingQueue.notify();
} }
} }
@ -110,29 +110,29 @@ public class ZalleryTranscoder extends HttpServlet{
* *
* @author Ziver * @author Ziver
*/ */
private static class TranscoderThread extends Thread{ private static class TranscoderThread extends Thread {
private boolean stop; private boolean stop;
private long startTime; private long startTime;
private Video currentVideo; private Video currentVideo;
public void run(){ public void run() {
logger.info("Transcoder thread started."); logger.info("Transcoder thread started.");
try { try {
while( !stop ){ while (!stop) {
// Get video to transcode // Get video to transcode
while( !transcodingQueue.isEmpty() ){ while (!transcodingQueue.isEmpty()) {
currentVideo = transcodingQueue.poll(); currentVideo = transcodingQueue.poll();
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
logger.info("Starting transcoding video(id:"+currentVideo.getId()+")"); logger.info("Starting transcoding video(id:" + currentVideo.getId() + ")");
File originalFile = currentVideo.getFile( Size.ORIGINAL ); File originalFile = ResourceManager.getFile(currentVideo, Size.ORIGINAL);
File mediumFile = currentVideo.getFile( Size.MEDIUM ); File mediumFile = ResourceManager.getFile(currentVideo, Size.MEDIUM);
File smallFile = currentVideo.getFile( Size.SMALL ); File smallFile = ResourceManager.getFile(currentVideo, Size.SMALL);
///////////// Start Transcoding ///////////// Start Transcoding
// create a media reader // create a media reader
IMediaReader reader = ToolFactory.makeReader( originalFile.getPath() ); IMediaReader reader = ToolFactory.makeReader(originalFile.getPath());
reader.addListener(new FrameGrabListener(reader, smallFile, 0.2)); reader.addListener(new FrameGrabListener(reader, smallFile, 0.2));
reader.addListener(new ProgressListener(reader)); reader.addListener(new ProgressListener(reader));
@ -151,25 +151,24 @@ public class ZalleryTranscoder extends HttpServlet{
// read and decode packets from the source file and // read and decode packets from the source file and
// and dispatch decoded audio and video to the writer // and dispatch decoded audio and video to the writer
while (reader.readPacket() == null); while (reader.readPacket() == null) ;
// Incomplete transcoding // Incomplete transcoding
if( reader.isOpen() ){ if (reader.isOpen()) {
logger.severe("Transcoding incomplete, removing incomplete files!"); logger.severe("Transcoding incomplete, removing incomplete files!");
reader.close(); reader.close();
mediumFile.delete(); mediumFile.delete();
smallFile.delete(); smallFile.delete();
if( stop ) if (stop)
return; return;
} } else {
else{ logger.info("Done transcoding video(id:" + currentVideo.getId() + ") time: " + StringUtil.formatTimeToString(System.currentTimeMillis() - startTime));
logger.info("Done transcoding video(id:"+currentVideo.getId()+") time: "+StringUtil.formatTimeToString(System.currentTimeMillis()-startTime));
currentVideo.setTranscoded(true); currentVideo.setTranscoded(true);
try{ try {
DBConnection db = Zallery.getDB(); DBConnection db = Zallery.getDB();
currentVideo.save(db); currentVideo.save(db);
db.close(); db.close();
}catch(Exception e){ } catch (Exception e) {
logger.log(Level.SEVERE, "Unable to save video bean!", e); logger.log(Level.SEVERE, "Unable to save video bean!", e);
} }
} }
@ -188,7 +187,7 @@ public class ZalleryTranscoder extends HttpServlet{
} }
public void abort(){ public void abort() {
stop = true; stop = true;
synchronized (transcodingQueue) { synchronized (transcodingQueue) {
transcodingQueue.notifyAll(); transcodingQueue.notifyAll();