Refactored names of date fields, Created a ResourceManager to handle filesystem stuff
This commit is contained in:
parent
8212379c31
commit
0a099bd5d7
16 changed files with 2245 additions and 2214 deletions
|
|
@ -21,9 +21,9 @@ $(function(){
|
|||
<div class="gallery col-center col-md-11">
|
||||
<div class="row">
|
||||
<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">
|
||||
<img class="img-responsive" src="${subfolder.getThumbnailUrl()}" alt="${subfolder.getName()}" />
|
||||
<img class="img-responsive" src="${folder.getThumbnailUrl()}" alt="${folder.getName()}" />
|
||||
</div>
|
||||
</c:forEach>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ CREATE TABLE `Comments` (
|
|||
`image` int(11) DEFAULT NULL,
|
||||
`video` int(11) DEFAULT NULL,
|
||||
`user` int(11) DEFAULT NULL,
|
||||
`date` datetime DEFAULT NULL,
|
||||
`dateCreated` datetime DEFAULT NULL,
|
||||
`message` text
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ CREATE TABLE `Comments` (
|
|||
|
||||
CREATE TABLE `Folder` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`user` int(10) UNSIGNED DEFAULT NULL,
|
||||
`owner` int(10) UNSIGNED DEFAULT NULL,
|
||||
`path` text,
|
||||
`parent` int(10) UNSIGNED DEFAULT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
|
|
@ -41,12 +41,12 @@ CREATE TABLE `Folder` (
|
|||
CREATE TABLE `Image` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`folder` int(10) UNSIGNED NOT NULL,
|
||||
`filename` varchar(45) NOT NULL,
|
||||
`user` int(10) UNSIGNED NOT NULL,
|
||||
`fileName` varchar(45) NOT NULL,
|
||||
`fileExtension` varchar(5) NOT NULL,
|
||||
`owner` int(10) UNSIGNED NOT NULL,
|
||||
`title` varchar(55) DEFAULT NULL,
|
||||
`description` text,
|
||||
`date` datetime DEFAULT NULL,
|
||||
`rating` float DEFAULT NULL
|
||||
`dateUploaded` datetime DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
@ -63,7 +63,8 @@ CREATE TABLE `User` (
|
|||
`passwordHash` varchar(64) DEFAULT NULL,
|
||||
`passwordSalt` varchar(5) DEFAULT NULL,
|
||||
`ipHost` varchar(20) DEFAULT NULL,
|
||||
`loginDate` datetime DEFAULT NULL,
|
||||
`dateCreated` datetime DEFAULT NULL,
|
||||
`dateLastLogin` datetime DEFAULT NULL,
|
||||
`cookieHash` varchar(42) DEFAULT NULL,
|
||||
`superUser` tinyint(1) NOT NULL,
|
||||
`enabled` tinyint(1) NOT NULL
|
||||
|
|
@ -73,8 +74,8 @@ CREATE TABLE `User` (
|
|||
-- Dumping data for table `User`
|
||||
--
|
||||
|
||||
INSERT INTO `User` (`id`, `name`, `email`, `emailVerified`, `passwordHash`, `passwordSalt`, `ipHost`, `loginDate`, `cookieHash`, `superUser`, `enabled`) VALUES
|
||||
(1, 'Admin Admin', 'admin', 1, '6e88be8bad7eae9d9e10aa061224034fed48d03fcbad968b56006784539d5214', 'salt', '', '1970-01-01 01:00:0', '', 1, 1);
|
||||
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', '1970-01-01 01:00:0', '', 1, 1);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -85,12 +86,12 @@ INSERT INTO `User` (`id`, `name`, `email`, `emailVerified`, `passwordHash`, `pas
|
|||
CREATE TABLE `Video` (
|
||||
`id` int(10) UNSIGNED NOT NULL,
|
||||
`folder` int(10) UNSIGNED NOT NULL,
|
||||
`filename` varchar(45) NOT NULL,
|
||||
`user` int(10) UNSIGNED NOT NULL,
|
||||
`fileName` varchar(45) NOT NULL,
|
||||
`fileExtension` varchar(5) NOT NULL,
|
||||
`owner` int(10) UNSIGNED NOT NULL,
|
||||
`title` varchar(55) DEFAULT NULL,
|
||||
`description` text,
|
||||
`date` datetime DEFAULT NULL,
|
||||
`rating` float DEFAULT NULL,
|
||||
`dateUploaded` datetime DEFAULT NULL
|
||||
`transcoded` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`length` int(10) UNSIGNED NOT NULL DEFAULT '0'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
|
|
|||
3178
db_test_data.sql
3178
db_test_data.sql
File diff suppressed because it is too large
Load diff
|
|
@ -16,92 +16,85 @@ import javax.servlet.http.HttpSession;
|
|||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
|
||||
import zall.bean.Folder;
|
||||
import zall.bean.Image;
|
||||
import zall.bean.User;
|
||||
import zall.bean.Video;
|
||||
import zall.bean.*;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.io.file.FileUtil;
|
||||
import zutil.jee.upload.AjaxFileUpload;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
|
||||
public class UploadServlet extends AjaxFileUpload{
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Set<String> VIDEO_EXT = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
|
||||
"avi","mp4","mpeg","mpeg","divx","xvid","wmv","mov","flv","m4v")));
|
||||
public class UploadServlet extends AjaxFileUpload {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public String getProgressHTML() {
|
||||
return ""+
|
||||
"<DIV class='comment-author vcard'>"+
|
||||
" <IMG src='img/upload.png' class='photo avatar photo' height='80' width='80'>"+
|
||||
" <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>"+
|
||||
" <div class='progressbar'>"+
|
||||
" <b class='progress' style='width: 0%'> </b>"+
|
||||
" </div>"+
|
||||
" </SPAN>"+
|
||||
"</DIV>"+
|
||||
"<DIV class='comment-meta'>" +
|
||||
" <span class='uploaded'>0 KB</span>/ <span class='total'>0 KB</span> " +
|
||||
" - Speed: <span class='speed'>400 KB/s</span>" +
|
||||
"</DIV> ";
|
||||
}
|
||||
private static final Set<String> VIDEO_EXT = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
|
||||
"avi", "mp4", "mpeg", "mpeg", "divx", "xvid", "wmv", "mov", "flv", "m4v")));
|
||||
|
||||
@Override
|
||||
public void doUpload(HttpServletRequest request, HttpServletResponse response,
|
||||
Map<String,String> fields, List<FileItem> files) throws ServletException{
|
||||
DBConnection db = null;
|
||||
try {
|
||||
HttpSession session = request.getSession();
|
||||
db = Zallery.getDB();
|
||||
User user = (User) session.getAttribute("user");
|
||||
@Override
|
||||
public String getProgressHTML() {
|
||||
return "" +
|
||||
"<DIV class='comment-author vcard'>" +
|
||||
" <IMG src='img/upload.png' class='photo avatar photo' height='80' width='80'>" +
|
||||
" <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>" +
|
||||
" <div class='progressbar'>" +
|
||||
" <b class='progress' style='width: 0%'> </b>" +
|
||||
" </div>" +
|
||||
" </SPAN>" +
|
||||
"</DIV>" +
|
||||
"<DIV class='comment-meta'>" +
|
||||
" <span class='uploaded'>0 KB</span>/ <span class='total'>0 KB</span> " +
|
||||
" - Speed: <span class='speed'>400 KB/s</span>" +
|
||||
"</DIV> ";
|
||||
}
|
||||
|
||||
// Check if user is authentication
|
||||
if(user != null){
|
||||
Folder folder = Folder.load(db, Long.parseLong( fields.get("folder") ));
|
||||
@Override
|
||||
public void doUpload(HttpServletRequest request, HttpServletResponse response,
|
||||
Map<String, String> fields, List<FileItem> files) throws ServletException {
|
||||
DBConnection db = null;
|
||||
try {
|
||||
HttpSession session = request.getSession();
|
||||
db = Zallery.getDB();
|
||||
User user = (User) session.getAttribute("user");
|
||||
|
||||
// Handle files
|
||||
for(FileItem item : files){
|
||||
try{
|
||||
String ext = FileUtil.getFileExtension(item.getName()).toLowerCase();
|
||||
if( VIDEO_EXT.contains(ext) ){
|
||||
Video vid = new Video();
|
||||
vid.setTitle( item.getName() );
|
||||
vid.setFolder( folder );
|
||||
vid.setUser( user );
|
||||
vid.setFile( item );
|
||||
vid.save(db);
|
||||
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());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Error: Creating new Media(\""+item.getName()+"\")", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
item.delete();
|
||||
}
|
||||
response.getWriter().print("<html>OK</html>");
|
||||
}
|
||||
else
|
||||
response.getWriter().print("<html>Authentication Error</html>");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new ServletException(e);
|
||||
} finally{
|
||||
if(db != null) db.close();
|
||||
}
|
||||
}
|
||||
// Check if user is authentication
|
||||
if (user != null) {
|
||||
Folder folder = Folder.load(db, Long.parseLong(fields.get("folder")));
|
||||
|
||||
// Handle files
|
||||
for (FileItem item : files) {
|
||||
try {
|
||||
String ext = FileUtil.getFileExtension(item.getName()).toLowerCase();
|
||||
Media media;
|
||||
if (VIDEO_EXT.contains(ext)) {
|
||||
logger.fine("Video upload detected, extension: " + ext);
|
||||
media = new Video();
|
||||
} else {
|
||||
logger.fine("Image upload detected, extension: " + ext);
|
||||
media = new Image();
|
||||
}
|
||||
|
||||
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) {
|
||||
logger.log(Level.WARNING, "Error: Creating new media(" + item.getName() + ")", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
item.delete();
|
||||
}
|
||||
response.getWriter().print("<html>OK</html>");
|
||||
} else
|
||||
response.getWriter().print("<html>Authentication Error</html>");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new ServletException(e);
|
||||
} finally {
|
||||
if (db != null) db.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class CreateFolderAction extends ZalleryAction {
|
|||
if (parent == null) { // Create root folder
|
||||
parent = Folder.loadRoot(db, user); // get root folder
|
||||
folder = new Folder();
|
||||
folder.setUser(user);
|
||||
folder.setOwner(user);
|
||||
folder.setParent(parent);
|
||||
folder.setName("{NAME}");
|
||||
folder.save(db);
|
||||
|
|
@ -62,7 +62,7 @@ public class CreateFolderAction extends ZalleryAction {
|
|||
folder = Folder.load(db, path, user);
|
||||
if (folder == null) { // create folder
|
||||
folder = new Folder();
|
||||
folder.setUser(user);
|
||||
folder.setOwner(user);
|
||||
folder.setParent(parent);
|
||||
folder.setName(dir);
|
||||
folder.save(db);
|
||||
|
|
|
|||
|
|
@ -8,43 +8,39 @@ import zutil.db.bean.DBBean.*;
|
|||
import zutil.parser.BBCodeParser;
|
||||
|
||||
@DBTable("Comments")
|
||||
public class Comment extends DBBean{
|
||||
private static BBCodeParser parser = null;
|
||||
public class Comment extends DBBean {
|
||||
private static BBCodeParser parser = null;
|
||||
|
||||
protected User user;
|
||||
protected Date date;
|
||||
protected String message;
|
||||
|
||||
public Comment(){
|
||||
if( parser == null ){
|
||||
parser = new BBCodeParser();
|
||||
}
|
||||
setCurrentDate();
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public void setMessage(String msg) {
|
||||
if( msg != null ){
|
||||
msg = msg.replaceAll("<", "<");
|
||||
msg = msg.replaceAll(">", ">");
|
||||
this.message = parser.read( msg );
|
||||
}
|
||||
}
|
||||
public void setCurrentDate() {
|
||||
this.date = new Timestamp( System.currentTimeMillis() );
|
||||
}
|
||||
protected User user;
|
||||
protected Date dateCreated;
|
||||
protected String message;
|
||||
|
||||
public Comment() {
|
||||
if (parser == null) {
|
||||
parser = new BBCodeParser();
|
||||
}
|
||||
this.dateCreated = new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Date getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public void setMessage(String msg) {
|
||||
if (msg != null) {
|
||||
msg = msg.replaceAll("<", "<");
|
||||
msg = msg.replaceAll(">", ">");
|
||||
this.message = parser.read(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
package zall.bean;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
|
|
@ -16,18 +13,14 @@ import zutil.db.bean.DBBeanSQLResultHandler;
|
|||
import zutil.db.bean.DBBean.*;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import zall.Zallery;
|
||||
|
||||
@DBTable("Folder")
|
||||
public class Folder extends DBBean {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
private transient String name;
|
||||
protected long user = -1;
|
||||
protected transient User userInstance;
|
||||
private String path;
|
||||
protected Folder parent;
|
||||
protected Timestamp date;
|
||||
private String name;
|
||||
private User owner;
|
||||
private Folder parent;
|
||||
private Timestamp dateCreated;
|
||||
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 {
|
||||
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(2, folder.user);
|
||||
sql.setLong(2, folder.owner.getId());
|
||||
sql.setBoolean(3, requestingUser.isSuperUser());
|
||||
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db));
|
||||
}
|
||||
|
||||
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.setLong(2, user.getId());
|
||||
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 {
|
||||
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.setLong(2, user.getId());
|
||||
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 {
|
||||
if (user.getId() == null)
|
||||
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());
|
||||
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db));
|
||||
}
|
||||
|
||||
|
||||
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() {
|
||||
if (userInstance == null) {
|
||||
try {
|
||||
DBConnection db = Zallery.getDB();
|
||||
userInstance = User.load(db, user);
|
||||
db.close();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, null, e);
|
||||
}
|
||||
}
|
||||
return userInstance;
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user.getId();
|
||||
this.userInstance = null;
|
||||
public void setOwner(User user) {
|
||||
this.owner = user;
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return isPrivate;
|
||||
}
|
||||
|
||||
public void setPrivate(boolean priv) {
|
||||
this.isPrivate = priv;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
String tmp = path.replaceAll("\\{NAME\\}", getUser().getName());
|
||||
public String getName() {
|
||||
String userName = owner != null ? owner.getName() : "UNKNOWN";
|
||||
String tmp = name.replaceAll("\\{NAME\\}", userName);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
if (parent.path.endsWith("/"))
|
||||
this.path = parent.path + name;
|
||||
else
|
||||
this.path = parent.path + "/" + name;
|
||||
}
|
||||
|
||||
public void setParent(Folder parent) {
|
||||
if (this.parent != parent) {
|
||||
this.parent = parent;
|
||||
//parent.addSubFolder( this );
|
||||
if (parent.path.endsWith("/"))
|
||||
this.path = parent.path + name;
|
||||
else
|
||||
this.path = parent.path + "/" + name;
|
||||
}
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public Folder getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public Timestamp getDate() {
|
||||
return date;
|
||||
public Timestamp getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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() {
|
||||
public static Folder createRootFolder() {
|
||||
Folder root = new Folder();
|
||||
root.parent = null;
|
||||
root.path = "/";
|
||||
root.owner = null;
|
||||
root.name = "/";
|
||||
return root;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import javax.imageio.ImageIO;
|
|||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
|
||||
import zall.manager.ResourceManager;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
import zutil.db.bean.DBBeanSQLResultHandler;
|
||||
|
|
@ -63,27 +64,37 @@ public class Image extends Media {
|
|||
if (folder == null)
|
||||
throw new Exception("Folder not set for image!");
|
||||
// Generate unique filename
|
||||
filename = genFileName(item.getName());
|
||||
filename += "." + FileUtil.getFileExtension(item.getName());
|
||||
File file = folder.getFile(filename, Size.ORIGINAL);
|
||||
fileName = ResourceManager.generateFileName();
|
||||
fileExtension = FileUtil.getFileExtension(item.getName());
|
||||
File file = ResourceManager.getFile(this, Size.ORIGINAL);
|
||||
|
||||
// Move uploaded 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
|
||||
*/
|
||||
public File getFile(Size size) throws IOException {
|
||||
if (filename != null) {
|
||||
if (fileName != null) {
|
||||
switch (size) {
|
||||
case ORIGINAL:
|
||||
return folder.getFile(filename, Size.ORIGINAL);
|
||||
return ResourceManager.getFile(this, Size.ORIGINAL);
|
||||
default:
|
||||
File file = folder.getFile(FileUtil.replaceExtension(filename, IMAGE_FORMAT), size);
|
||||
File orgFile = folder.getFile(filename, Size.ORIGINAL);
|
||||
File file = ResourceManager.getFile(this, size);
|
||||
File orgFile = ResourceManager.getFile(this, Size.ORIGINAL);
|
||||
if (!file.exists()) {
|
||||
if (orgFile.exists() && orgFile.canRead()) {
|
||||
// Generate new thumbnail
|
||||
|
|
@ -103,7 +114,8 @@ public class Image extends Media {
|
|||
break;
|
||||
}
|
||||
ImageIO.write(image, IMAGE_FORMAT, file);
|
||||
} else if (!orgFile.exists())
|
||||
}
|
||||
else if (!orgFile.exists())
|
||||
logger.severe("Original image file missing: \"" + file.getAbsolutePath() + "\"");
|
||||
else if (orgFile.canRead())
|
||||
logger.severe("Can not read original image file: \"" + file.getAbsolutePath() + "\"");
|
||||
|
|
@ -115,7 +127,7 @@ public class Image extends Media {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
public Type getType() {
|
||||
return Type.IMAGE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package zall.bean;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
|
|
@ -12,123 +11,122 @@ import java.util.logging.Logger;
|
|||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
|
||||
import zutil.Hasher;
|
||||
import zall.manager.ResourceManager;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
public abstract class Media extends DBBean implements Comparable<Media>{
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
public static enum Size{
|
||||
ORIGINAL, LARGE, MEDIUM, SMALL
|
||||
}
|
||||
public abstract class Media extends DBBean implements Comparable<Media> {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
protected Folder folder;
|
||||
protected String filename;
|
||||
/** owner */
|
||||
protected User user;
|
||||
protected String title;
|
||||
protected String description;
|
||||
protected Timestamp date;
|
||||
protected float rating;
|
||||
|
||||
|
||||
/**
|
||||
* Loads all the media in a folder
|
||||
*/
|
||||
public final static List<Media> load(DBConnection db, Folder folder) throws SQLException{
|
||||
List<Image> image = Image.loadFolder(db, folder);
|
||||
List<Video> video = Video.loadFolder(db, folder);
|
||||
|
||||
List<Media> media = new LinkedList<Media>();
|
||||
media.addAll(image);
|
||||
media.addAll(video);
|
||||
Collections.sort( media );
|
||||
return media;
|
||||
}
|
||||
|
||||
public static Media load(DBConnection db, String type, long id) throws SQLException{
|
||||
if( type.equals(Image.type) )
|
||||
return Image.load(db, id);
|
||||
else if( type.equals(Video.type) )
|
||||
return Video.load(db, id);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public Media(){
|
||||
setCurrentDate();
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
IMAGE, VIDEO
|
||||
}
|
||||
public enum Size {
|
||||
ORIGINAL, LARGE, MEDIUM, SMALL
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
public Folder getFolder() {
|
||||
return folder;
|
||||
}
|
||||
public void setFolder(Folder folder) {
|
||||
this.folder = folder;
|
||||
}
|
||||
public void setImageUrl(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public void setDescription(String desc) {
|
||||
this.description = desc;
|
||||
}
|
||||
public Timestamp getDate() {
|
||||
return date;
|
||||
}
|
||||
public void setDate(Timestamp date) {
|
||||
this.date = date;
|
||||
}
|
||||
public void setCurrentDate() {
|
||||
this.date = new Timestamp( System.currentTimeMillis() );
|
||||
}
|
||||
protected Folder folder;
|
||||
protected String fileName;
|
||||
protected String fileExtension;
|
||||
protected User owner;
|
||||
protected String title;
|
||||
protected String description;
|
||||
protected Timestamp dateUploaded;
|
||||
|
||||
public String genFileName(String str){
|
||||
return Hasher.MD5( ""+this.getId()+str+user.getName()+date.getTime()+System.currentTimeMillis() );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(Media m) {
|
||||
return this.date.compareTo( m.date );
|
||||
}
|
||||
|
||||
public abstract LinkedList<Comment> getComments();
|
||||
public abstract void addComment(Comment cm);
|
||||
|
||||
public abstract void setFile(FileItem item) throws Exception;
|
||||
|
||||
public abstract File getFile(Size size) throws IOException;
|
||||
|
||||
public abstract String 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all the media in a folder
|
||||
*/
|
||||
public final static List<Media> load(DBConnection db, Folder folder) throws SQLException {
|
||||
List<Image> image = Image.loadFolder(db, folder);
|
||||
List<Video> video = Video.loadFolder(db, folder);
|
||||
|
||||
List<Media> media = new LinkedList<Media>();
|
||||
media.addAll(image);
|
||||
media.addAll(video);
|
||||
Collections.sort(media);
|
||||
return media;
|
||||
}
|
||||
|
||||
public static Media load(DBConnection db, String type, long id) throws SQLException {
|
||||
if (type.equals(Image.type))
|
||||
return Image.load(db, id);
|
||||
else if (type.equals(Video.type))
|
||||
return Video.load(db, id);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public Media() {
|
||||
this.dateUploaded = new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public Folder getFolder() {
|
||||
return folder;
|
||||
}
|
||||
public void setFolder(Folder folder) {
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
public void setOwner(User owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public void setDescription(String desc) {
|
||||
this.description = desc;
|
||||
}
|
||||
|
||||
public Timestamp getDateUploaded() {
|
||||
return dateUploaded;
|
||||
}
|
||||
|
||||
/* Overridden Methods */
|
||||
|
||||
@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
|
||||
public int compareTo(Media m) {
|
||||
return this.dateUploaded.compareTo(m.dateUploaded);
|
||||
}
|
||||
|
||||
/* Abstract Methods */
|
||||
|
||||
public abstract List<Comment> getComments();
|
||||
public abstract void addComment(Comment cm);
|
||||
|
||||
public abstract void setFile(FileItem item) throws Exception;
|
||||
|
||||
/**
|
||||
* @return the file extension for the specified size.
|
||||
*/
|
||||
public abstract String getFileExtension(Size size);
|
||||
|
||||
public abstract Type getType();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@ public class User extends DBBean {
|
|||
protected boolean emailVerified;
|
||||
protected String passwordHash;
|
||||
protected String passwordSalt;
|
||||
// Date
|
||||
protected Timestamp loginDate;
|
||||
// Dates
|
||||
protected Timestamp dateCreated;
|
||||
protected Timestamp dateLastLogin;
|
||||
// security
|
||||
protected transient AuthType authBy;
|
||||
protected String ipHost;
|
||||
|
|
@ -85,6 +86,7 @@ public class User extends DBBean {
|
|||
emailVerified = false;
|
||||
superUser = false;
|
||||
enabled = false;
|
||||
dateCreated = new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public boolean verifyEmail(String hash) {
|
||||
|
|
@ -96,14 +98,14 @@ public class User extends DBBean {
|
|||
}
|
||||
|
||||
|
||||
public Timestamp getLoginDate() {
|
||||
if (loginDate == null)
|
||||
loginDate = new Timestamp(0);
|
||||
return loginDate;
|
||||
public Timestamp getDateLastLogin() {
|
||||
if (dateLastLogin == null)
|
||||
dateLastLogin = new Timestamp(0);
|
||||
return dateLastLogin;
|
||||
}
|
||||
|
||||
public void setLoginDate(Timestamp loginDate) {
|
||||
this.loginDate = loginDate;
|
||||
public void setDateLastLogin(Timestamp dateLastLogin) {
|
||||
this.dateLastLogin = dateLastLogin;
|
||||
}
|
||||
|
||||
public void setAuthBy(AuthType authBy) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package zall.bean;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.LinkedList;
|
||||
|
|
@ -9,6 +7,7 @@ import java.util.List;
|
|||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
|
||||
import zall.manager.ResourceManager;
|
||||
import zall.transcoder.ZalleryTranscoder;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.bean.DBBean;
|
||||
|
|
@ -16,100 +15,105 @@ import zutil.db.bean.DBBeanSQLResultHandler;
|
|||
import zutil.db.bean.DBBean.*;
|
||||
import zutil.io.file.FileUtil;
|
||||
|
||||
@DBTable(value="Video", superBean = true)
|
||||
public class Video extends Media{
|
||||
public static final String type = "video";
|
||||
public static final String VIDEO_FORMAT = "mp4";
|
||||
|
||||
/** The progress of a transcoding in %, 0 if there is no transcoding running **/
|
||||
protected transient int transcodingProgress;
|
||||
/** If the Video is transcoded **/
|
||||
protected boolean transcoded;
|
||||
/** the time length of the video in seconds **/
|
||||
protected long length;
|
||||
|
||||
|
||||
@DBLinkTable(table="Comments", beanClass=Comment.class, idColumn="video")
|
||||
private LinkedList<Comment> comments;
|
||||
|
||||
/**
|
||||
* Loads all the Videos from a folder
|
||||
*/
|
||||
public static List<Video> loadFolder(DBConnection db, Folder folder) throws SQLException{
|
||||
if( folder == null || folder.getId() == null )
|
||||
return new LinkedList<Video>();
|
||||
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE folder=? ORDER BY date DESC");
|
||||
sql.setLong(1, folder.getId() );
|
||||
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db));
|
||||
}
|
||||
public static List<Video> loadUntransoded(DBConnection db) throws SQLException {
|
||||
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE transcoded=0 ORDER BY date DESC");
|
||||
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db));
|
||||
}
|
||||
public static Video load(DBConnection db, long id) throws SQLException{
|
||||
return DBBean.load(db, Video.class, id);
|
||||
}
|
||||
|
||||
|
||||
public Video(){
|
||||
super();
|
||||
transcoded = false;
|
||||
comments = new LinkedList<Comment>();
|
||||
}
|
||||
|
||||
public boolean isTranscoded(){
|
||||
return transcoded;
|
||||
}
|
||||
|
||||
public void setTranscoded(boolean transcoded){
|
||||
this.transcoded = transcoded;
|
||||
}
|
||||
|
||||
public void setTranscodingProgress(int trans){
|
||||
transcodingProgress = trans;
|
||||
}
|
||||
|
||||
public int getTranscodingProgress(){
|
||||
return transcodingProgress;
|
||||
}
|
||||
|
||||
public LinkedList<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
public void addComment(Comment cm){
|
||||
comments.add( cm );
|
||||
}
|
||||
|
||||
public void setFile(FileItem item) throws Exception{
|
||||
if( folder == null )
|
||||
throw new Exception("Folder not set for Video!");
|
||||
// Generate unique filename
|
||||
filename = this.genFileName( item.getName() );
|
||||
filename += "."+FileUtil.getFileExtension( item.getName() );
|
||||
// Move uploaded file
|
||||
item.write( folder.getFile( filename, Size.ORIGINAL ) );
|
||||
item.delete();
|
||||
ZalleryTranscoder.addVideo( this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file for the video
|
||||
*
|
||||
* @param size is the size of the image
|
||||
*/
|
||||
public File getFile(Size size) throws IOException{
|
||||
if( filename != null ){
|
||||
if( size == Size.SMALL )
|
||||
return folder.getFile( FileUtil.replaceExtension(filename, Image.IMAGE_FORMAT), size );
|
||||
else if( size == Size.MEDIUM )
|
||||
return folder.getFile( FileUtil.replaceExtension(filename, VIDEO_FORMAT), size );
|
||||
else
|
||||
return folder.getFile( filename, size );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
@DBTable(value = "Video", superBean = true)
|
||||
public class Video extends Media {
|
||||
public static final String type = "video";
|
||||
public static final String VIDEO_FORMAT = "mp4";
|
||||
|
||||
/**
|
||||
* The progress of a transcoding in %, 0 if there is no transcoding running
|
||||
**/
|
||||
protected transient int transcodingProgress;
|
||||
/**
|
||||
* If the Video is transcoded
|
||||
**/
|
||||
protected boolean transcoded;
|
||||
/**
|
||||
* the time length of the video in seconds
|
||||
**/
|
||||
protected long length;
|
||||
|
||||
|
||||
@DBLinkTable(table = "Comments", beanClass = Comment.class, idColumn = "video")
|
||||
private LinkedList<Comment> comments;
|
||||
|
||||
/**
|
||||
* Loads all the Videos from a folder
|
||||
*/
|
||||
public static List<Video> loadFolder(DBConnection db, Folder folder) throws SQLException {
|
||||
if (folder == null || folder.getId() == null)
|
||||
return new LinkedList<Video>();
|
||||
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE folder=? ORDER BY date DESC");
|
||||
sql.setLong(1, folder.getId());
|
||||
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db));
|
||||
}
|
||||
|
||||
public static List<Video> loadUntransoded(DBConnection db) throws SQLException {
|
||||
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Video WHERE transcoded=0 ORDER BY date DESC");
|
||||
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Video.class, db));
|
||||
}
|
||||
|
||||
public static Video load(DBConnection db, long id) throws SQLException {
|
||||
return DBBean.load(db, Video.class, id);
|
||||
}
|
||||
|
||||
|
||||
public Video() {
|
||||
super();
|
||||
transcoded = false;
|
||||
comments = new LinkedList<Comment>();
|
||||
}
|
||||
|
||||
public boolean isTranscoded() {
|
||||
return transcoded;
|
||||
}
|
||||
public void setTranscoded(boolean transcoded) {
|
||||
this.transcoded = transcoded;
|
||||
}
|
||||
|
||||
public void setTranscodingProgress(int trans) {
|
||||
transcodingProgress = trans;
|
||||
}
|
||||
public int getTranscodingProgress() {
|
||||
return transcodingProgress;
|
||||
}
|
||||
|
||||
public LinkedList<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
public void addComment(Comment cm) {
|
||||
comments.add(cm);
|
||||
}
|
||||
|
||||
public void setFile(FileItem item) throws Exception {
|
||||
if (folder == null)
|
||||
throw new Exception("Folder not set for Video!");
|
||||
// Generate unique filename
|
||||
fileName = ResourceManager.generateFileName();
|
||||
fileExtension = "." + FileUtil.getFileExtension(item.getName());
|
||||
// Move uploaded file
|
||||
item.write(ResourceManager.getFile(this, Size.ORIGINAL));
|
||||
item.delete();
|
||||
ZalleryTranscoder.addVideo(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileExtension(Size size) {
|
||||
if (fileName != null) {
|
||||
switch (size) {
|
||||
case SMALL:
|
||||
return Image.IMAGE_FORMAT;
|
||||
case MEDIUM:
|
||||
return VIDEO_FORMAT;
|
||||
default:
|
||||
return fileExtension;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.VIDEO;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class AuthenticationManager {
|
|||
|
||||
if (user != null) {
|
||||
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);
|
||||
return user;
|
||||
} 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 {
|
||||
user.setLoginDate(new Timestamp(System.currentTimeMillis()));
|
||||
user.setDateLastLogin(new Timestamp(System.currentTimeMillis()));
|
||||
user.setAuthBy(authType);
|
||||
user.setIpHost(request.getRemoteAddr());
|
||||
user.setCookieHash(Hasher.SHA1(Math.random()));
|
||||
|
|
@ -154,14 +154,14 @@ public class AuthenticationManager {
|
|||
* @return true if the specified user can edit the media
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
114
src/zall/manager/ResourceManager.java
Normal file
114
src/zall/manager/ResourceManager.java
Normal 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());
|
||||
}
|
||||
}
|
||||
|
|
@ -8,20 +8,16 @@ import java.sql.SQLException;
|
|||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.fileupload.util.Streams;
|
||||
|
||||
import zall.Zallery;
|
||||
import zall.ZalleryServlet;
|
||||
import zall.bean.Image;
|
||||
import zall.bean.Media;
|
||||
import zall.bean.User;
|
||||
import zall.bean.Video;
|
||||
import zall.manager.AuthenticationManager;
|
||||
import zall.manager.ResourceManager;
|
||||
import zutil.db.DBConnection;
|
||||
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 {
|
||||
String size = request.getParameter("size");
|
||||
|
||||
Media media = null;
|
||||
String contentType = "";
|
||||
|
|
@ -57,17 +52,18 @@ public class ContentServlet extends ZalleryServlet {
|
|||
}
|
||||
|
||||
if (media != null) {
|
||||
File file;
|
||||
if (size == null)
|
||||
file = media.getFile(Media.Size.ORIGINAL);
|
||||
else
|
||||
file = media.getFile(Media.Size.valueOf(size.toUpperCase()));
|
||||
Media.Size size = Media.Size.ORIGINAL;
|
||||
if (request.getParameter("size") != null)
|
||||
size = Media.Size.valueOf(request.getParameter("size").toUpperCase());
|
||||
|
||||
File file = ResourceManager.getFile(media, size);
|
||||
String extension = media.getFileExtension(size);
|
||||
|
||||
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()) {
|
||||
response.setContentType(contentType + "/" + FileUtil.getFileExtension(file));
|
||||
response.setContentType(contentType + "/" + extension);
|
||||
response.setContentLength((int) file.length());
|
||||
|
||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class GalleryServlet extends ZalleryServlet {
|
|||
folder = Folder.loadRoot(db, user);
|
||||
// Setup new root folder
|
||||
if (folder == null) {
|
||||
folder = Folder.genRoot();
|
||||
folder = Folder.createRootFolder();
|
||||
folder.save(db);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,167 +34,166 @@ import com.xuggle.xuggler.video.IConverter;
|
|||
import zall.Zallery;
|
||||
import zall.bean.Media.Size;
|
||||
import zall.bean.Video;
|
||||
import zall.manager.ResourceManager;
|
||||
import zutil.StringUtil;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
@WebServlet(value = "/transcoder", loadOnStartup = 100)
|
||||
public class ZalleryTranscoder extends HttpServlet{
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static final long serialVersionUID = 1L;
|
||||
public class ZalleryTranscoder extends HttpServlet {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// Media Queue
|
||||
private static Queue<Video> transcodingQueue;
|
||||
private static TranscoderThread worker;
|
||||
// Media Queue
|
||||
private static Queue<Video> transcodingQueue;
|
||||
private static TranscoderThread worker;
|
||||
|
||||
public void init( ServletConfig config ){
|
||||
try{
|
||||
transcodingQueue = new LinkedList<>();
|
||||
worker = new TranscoderThread();
|
||||
worker.start();
|
||||
public void init(ServletConfig config) {
|
||||
try {
|
||||
transcodingQueue = new LinkedList<>();
|
||||
worker = new TranscoderThread();
|
||||
worker.start();
|
||||
|
||||
// get not transcoded videos
|
||||
DBConnection db = null;
|
||||
try {
|
||||
db = Zallery.getDB();
|
||||
List<Video> incomplete = Video.loadUntransoded( db );
|
||||
synchronized (transcodingQueue) {
|
||||
transcodingQueue.addAll( incomplete );
|
||||
transcodingQueue.notify();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}finally{
|
||||
if( db != null ) db.close();
|
||||
}
|
||||
}
|
||||
catch(Exception e){
|
||||
logger.log(Level.SEVERE, "Unable to initialize ZalleryTranscoder!", e);
|
||||
}
|
||||
}
|
||||
// get not transcoded videos
|
||||
DBConnection db = null;
|
||||
try {
|
||||
db = Zallery.getDB();
|
||||
List<Video> incomplete = Video.loadUntransoded(db);
|
||||
synchronized (transcodingQueue) {
|
||||
transcodingQueue.addAll(incomplete);
|
||||
transcodingQueue.notify();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
} finally {
|
||||
if (db != null) db.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Unable to initialize ZalleryTranscoder!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy( ){
|
||||
worker.abort();
|
||||
}
|
||||
public void destroy() {
|
||||
worker.abort();
|
||||
}
|
||||
|
||||
|
||||
public static Video getProcessingVideo(){
|
||||
return worker.currentVideo;
|
||||
}
|
||||
public static Video getProcessingVideo() {
|
||||
return worker.currentVideo;
|
||||
}
|
||||
|
||||
public static Queue<Video> getQueue(){
|
||||
return transcodingQueue;
|
||||
}
|
||||
public static Queue<Video> getQueue() {
|
||||
return transcodingQueue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a video to the transcoding queue
|
||||
*
|
||||
* @param video is the video to transcode
|
||||
*/
|
||||
public static void addVideo(Video video) {
|
||||
if( transcodingQueue == null ){
|
||||
logger.severe("ZalleryTranscoder not initialized!");
|
||||
return;
|
||||
}
|
||||
if( !transcodingQueue.contains(video) && worker.currentVideo != video ){
|
||||
synchronized (transcodingQueue){
|
||||
transcodingQueue.add( video );
|
||||
transcodingQueue.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add a video to the transcoding queue
|
||||
*
|
||||
* @param video is the video to transcode
|
||||
*/
|
||||
public static void addVideo(Video video) {
|
||||
if (transcodingQueue == null) {
|
||||
logger.severe("ZalleryTranscoder not initialized!");
|
||||
return;
|
||||
}
|
||||
if (!transcodingQueue.contains(video) && worker.currentVideo != video) {
|
||||
synchronized (transcodingQueue) {
|
||||
transcodingQueue.add(video);
|
||||
transcodingQueue.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the class that is doing the actual work of transcoding videos
|
||||
*
|
||||
* @author Ziver
|
||||
*/
|
||||
private static class TranscoderThread extends Thread{
|
||||
private boolean stop;
|
||||
private long startTime;
|
||||
private Video currentVideo;
|
||||
/**
|
||||
* Is the class that is doing the actual work of transcoding videos
|
||||
*
|
||||
* @author Ziver
|
||||
*/
|
||||
private static class TranscoderThread extends Thread {
|
||||
private boolean stop;
|
||||
private long startTime;
|
||||
private Video currentVideo;
|
||||
|
||||
|
||||
public void run(){
|
||||
logger.info("Transcoder thread started.");
|
||||
try {
|
||||
while( !stop ){
|
||||
// Get video to transcode
|
||||
while( !transcodingQueue.isEmpty() ){
|
||||
currentVideo = transcodingQueue.poll();
|
||||
startTime = System.currentTimeMillis();
|
||||
logger.info("Starting transcoding video(id:"+currentVideo.getId()+")");
|
||||
public void run() {
|
||||
logger.info("Transcoder thread started.");
|
||||
try {
|
||||
while (!stop) {
|
||||
// Get video to transcode
|
||||
while (!transcodingQueue.isEmpty()) {
|
||||
currentVideo = transcodingQueue.poll();
|
||||
startTime = System.currentTimeMillis();
|
||||
logger.info("Starting transcoding video(id:" + currentVideo.getId() + ")");
|
||||
|
||||
File originalFile = currentVideo.getFile( Size.ORIGINAL );
|
||||
File mediumFile = currentVideo.getFile( Size.MEDIUM );
|
||||
File smallFile = currentVideo.getFile( Size.SMALL );
|
||||
|
||||
///////////// Start Transcoding
|
||||
// create a media reader
|
||||
IMediaReader reader = ToolFactory.makeReader( originalFile.getPath() );
|
||||
reader.addListener(new FrameGrabListener(reader, smallFile, 0.2));
|
||||
reader.addListener(new ProgressListener(reader));
|
||||
|
||||
VideoTranscoderListener converter = new VideoTranscoderListener(640, 360);
|
||||
reader.addListener(converter);
|
||||
|
||||
// create a media writer
|
||||
IMediaWriter writer = ToolFactory.makeWriter(mediumFile.getPath(), reader);
|
||||
converter.addListener(writer);
|
||||
File originalFile = ResourceManager.getFile(currentVideo, Size.ORIGINAL);
|
||||
File mediumFile = ResourceManager.getFile(currentVideo, Size.MEDIUM);
|
||||
File smallFile = ResourceManager.getFile(currentVideo, Size.SMALL);
|
||||
|
||||
// create a media viewer with stats enabled for debugging
|
||||
// add a viewer to the reader, to see the decoded media
|
||||
//IMediaViewer mediaViewer = ToolFactory.makeViewer(true);
|
||||
//reader.addListener(mediaViewer);
|
||||
//writer.addListener(mediaViewer);
|
||||
///////////// Start Transcoding
|
||||
// create a media reader
|
||||
IMediaReader reader = ToolFactory.makeReader(originalFile.getPath());
|
||||
reader.addListener(new FrameGrabListener(reader, smallFile, 0.2));
|
||||
reader.addListener(new ProgressListener(reader));
|
||||
|
||||
// read and decode packets from the source file and
|
||||
// and dispatch decoded audio and video to the writer
|
||||
while (reader.readPacket() == null);
|
||||
VideoTranscoderListener converter = new VideoTranscoderListener(640, 360);
|
||||
reader.addListener(converter);
|
||||
|
||||
// Incomplete transcoding
|
||||
if( reader.isOpen() ){
|
||||
logger.severe("Transcoding incomplete, removing incomplete files!");
|
||||
reader.close();
|
||||
mediumFile.delete();
|
||||
smallFile.delete();
|
||||
if( stop )
|
||||
return;
|
||||
}
|
||||
else{
|
||||
logger.info("Done transcoding video(id:"+currentVideo.getId()+") time: "+StringUtil.formatTimeToString(System.currentTimeMillis()-startTime));
|
||||
currentVideo.setTranscoded(true);
|
||||
try{
|
||||
DBConnection db = Zallery.getDB();
|
||||
currentVideo.save(db);
|
||||
db.close();
|
||||
}catch(Exception e){
|
||||
logger.log(Level.SEVERE, "Unable to save video bean!", e);
|
||||
}
|
||||
}
|
||||
currentVideo = null;
|
||||
}
|
||||
// Wait for new video to transcode
|
||||
synchronized (transcodingQueue) {
|
||||
transcodingQueue.wait();
|
||||
}
|
||||
}
|
||||
// create a media writer
|
||||
IMediaWriter writer = ToolFactory.makeWriter(mediumFile.getPath(), reader);
|
||||
converter.addListener(writer);
|
||||
|
||||
// create a media viewer with stats enabled for debugging
|
||||
// add a viewer to the reader, to see the decoded media
|
||||
//IMediaViewer mediaViewer = ToolFactory.makeViewer(true);
|
||||
//reader.addListener(mediaViewer);
|
||||
//writer.addListener(mediaViewer);
|
||||
|
||||
// read and decode packets from the source file and
|
||||
// and dispatch decoded audio and video to the writer
|
||||
while (reader.readPacket() == null) ;
|
||||
|
||||
// Incomplete transcoding
|
||||
if (reader.isOpen()) {
|
||||
logger.severe("Transcoding incomplete, removing incomplete files!");
|
||||
reader.close();
|
||||
mediumFile.delete();
|
||||
smallFile.delete();
|
||||
if (stop)
|
||||
return;
|
||||
} else {
|
||||
logger.info("Done transcoding video(id:" + currentVideo.getId() + ") time: " + StringUtil.formatTimeToString(System.currentTimeMillis() - startTime));
|
||||
currentVideo.setTranscoded(true);
|
||||
try {
|
||||
DBConnection db = Zallery.getDB();
|
||||
currentVideo.save(db);
|
||||
db.close();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Unable to save video bean!", e);
|
||||
}
|
||||
}
|
||||
currentVideo = null;
|
||||
}
|
||||
// Wait for new video to transcode
|
||||
synchronized (transcodingQueue) {
|
||||
transcodingQueue.wait();
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Transcoding thread has stopped!");
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Transcoding thread has crashed!", e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Transcoding thread has crashed!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void abort(){
|
||||
stop = true;
|
||||
synchronized (transcodingQueue) {
|
||||
transcodingQueue.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void abort() {
|
||||
stop = true;
|
||||
synchronized (transcodingQueue) {
|
||||
transcodingQueue.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue