Moved email stuff to zutil and moved transoced to its own package

This commit is contained in:
Ziver Koc 2016-12-22 16:24:46 +01:00
parent 05048442a1
commit 7cac4e155c
20 changed files with 518 additions and 537 deletions

View file

@ -61,7 +61,7 @@
<servlet> <servlet>
<servlet-name>transcoder</servlet-name> <servlet-name>transcoder</servlet-name>
<servlet-class>zall.ZalleryTranscoder</servlet-class> <servlet-class>zall.transcoder.ZalleryTranscoder</servlet-class>
<load-on-startup>1</load-on-startup> <load-on-startup>1</load-on-startup>
</servlet> </servlet>

3
Zallery.iml Normal file → Executable file
View file

@ -11,8 +11,7 @@
<src_folder value="file://$MODULE_DIR$/src" expected_position="0" /> <src_folder value="file://$MODULE_DIR$/src" expected_position="0" />
</src_description> </src_description>
</component> </component>
<component name="NewModuleRootManager" inherit-compiler-output="false"> <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<output url="file://$MODULE_DIR$/build/classes" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />

View file

@ -23,10 +23,10 @@
<!--classpath included when building--> <!--classpath included when building-->
<path id="classpath.build"> <path id="classpath.build">
<fileset dir="${libDir}"> <fileset dir="${libDir}">
<include name="**/*.jar"/> <include name="**/*.jar" />
</fileset> </fileset>
<fileset dir="${libExpDir}"> <fileset dir="${libExpDir}">
<include name="**/*.jar"/> <include name="**/*.jar" />
</fileset> </fileset>
<pathelement location="${buildDir}" /> <pathelement location="${buildDir}" />
</path> </path>
@ -40,7 +40,7 @@
<!--clean all build paths--> <!--clean all build paths-->
<target name="clean"> <target name="clean">
<delete includeemptydirs="true" failonerror="false"> <delete includeemptydirs="true" failonerror="false">
<fileset dir="${outputRoot}" includes="**/*"/> <fileset dir="${outputRoot}" includes="**/*" />
</delete> </delete>
</target> </target>
@ -56,10 +56,10 @@
<target name="package" depends="build"> <target name="package" depends="build">
<war destfile="${releaseDir}/Zallery.war" webxml="WebContent/WEB-INF/web.xml"> <war destfile="${releaseDir}/Zallery.war" webxml="WebContent/WEB-INF/web.xml">
<fileset dir="WebContent"/> <fileset dir="WebContent" />
<fileset dir="${srcDir}"/> <!-- <fileset dir="${srcDir}"/> -->
<lib dir="WebContent/WEB-INF/lib"/> <lib dir="WebContent/WEB-INF/lib" />
<classes dir="${buildDir}"/> <classes dir="${buildDir}" />
</war> </war>
</target> </target>

View file

@ -22,7 +22,8 @@ import zall.bean.Folder;
import zall.bean.Image; import zall.bean.Image;
import zall.bean.Media; import zall.bean.Media;
import zall.bean.User; import zall.bean.User;
import zall.util.Email; import zall.util.ZalleryEmail;
import zutil.net.smtp.Email;
import zall.util.msg.UserMessage; import zall.util.msg.UserMessage;
import zall.util.msg.UserMessage.MessageType; import zall.util.msg.UserMessage.MessageType;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -54,7 +55,7 @@ public class Zallery extends HttpServlet{
WEBSITE_URL = (String)context.lookup("java:comp/env/WEBSITE_URL"); WEBSITE_URL = (String)context.lookup("java:comp/env/WEBSITE_URL");
if( WEBSITE_URL.charAt(WEBSITE_URL.length()-1) != '/') if( WEBSITE_URL.charAt(WEBSITE_URL.length()-1) != '/')
WEBSITE_URL += "/"; WEBSITE_URL += "/";
Email.setServer( (String)context.lookup("java:comp/env/SMTP_HOST") ); ZalleryEmail.setSMTPHost( (String)context.lookup("java:comp/env/SMTP_HOST") );
DATA_PATH = (String)context.lookup("java:comp/env/DATA_PATH"); DATA_PATH = (String)context.lookup("java:comp/env/DATA_PATH");
LogUtil.setLevel("zall", Level.FINEST); LogUtil.setLevel("zall", Level.FINEST);
@ -93,7 +94,7 @@ public class Zallery extends HttpServlet{
if( action.equalsIgnoreCase("verfemail") ){ if( action.equalsIgnoreCase("verfemail") ){
User verfuser = User.load(db, Long.parseLong(request.getParameter("id"))); User verfuser = User.load(db, Long.parseLong(request.getParameter("id")));
if( verfuser.verifyEmail(request.getParameter("hash")) ){ if( verfuser.verifyEmail(request.getParameter("hash")) ){
ZalleryAjax.sendEmailNewUserToAdmin(verfuser, db); ZalleryEmail.sendNewUserRegistrationToAdmin(verfuser, db);
verfuser.save(db); verfuser.save(db);
msgs.add(MessageType.INFO, "Your email has been successfully verified."); msgs.add(MessageType.INFO, "Your email has been successfully verified.");
msgs.add(MessageType.WARNING, "The account is waiting account activation by an admin."); msgs.add(MessageType.WARNING, "The account is waiting account activation by an admin.");

42
src/zall/ZalleryAjax.java Normal file → Executable file
View file

@ -19,8 +19,8 @@ import zall.action.*;
import zall.action.media.*; import zall.action.media.*;
import zall.action.user.*; import zall.action.user.*;
import zall.bean.*; import zall.bean.*;
import zall.util.Email; import zutil.net.smtp.Email;
import zall.util.Email.ContentType; import zutil.net.smtp.Email.ContentType;
import zall.util.msg.UserMessage; import zall.util.msg.UserMessage;
import zall.util.msg.UserMessage.MessageType; import zall.util.msg.UserMessage.MessageType;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -57,7 +57,7 @@ public class ZalleryAjax extends HttpServlet{
protected void registerAction(ZalleryAction action){ protected void registerAction(ZalleryAction action){
if(actions == null) if(actions == null)
actions = new HashMap<String,ZalleryAction>(); actions = new HashMap<>();
actions.put(action.getActionId().toLowerCase(), action); actions.put(action.getActionId().toLowerCase(), action);
} }
@ -76,7 +76,7 @@ public class ZalleryAjax extends HttpServlet{
/** /**
* @param out is the PrintStream that will be used, no output will be generated if it is null * @param out is the PrintStream that will be used, no output will be generated if it is null
*/ */
public void doGet(HttpServletRequest request, HttpServletResponse response, PrintWriter out) throws ServletException{ private void doGet(HttpServletRequest request, HttpServletResponse response, PrintWriter out) throws ServletException{
DBConnection db = null; DBConnection db = null;
try { try {
String actionStr = request.getParameter("action").toLowerCase(); String actionStr = request.getParameter("action").toLowerCase();
@ -126,38 +126,4 @@ public class ZalleryAjax extends HttpServlet{
if(db != null) db.close(); if(db != null) db.close();
} }
} }
public static void sendEmailVerification(User user) throws IOException{
// Email
Email smtpEmail = new Email("admin@koc.se", user.getEmail());
smtpEmail.setNiceFrom("Koc.se Admin");
smtpEmail.setSubject("Registration at "+Zallery.getWebsiteName());
smtpEmail.setContentType(ContentType.HTML);
smtpEmail.setMessage("You receive this message because you have requested an account" +
"<br>at "+Zallery.getWebsiteName()+". Please click the link to verify your email address: " +
"<p><a href='"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"'>"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"</a>" +
"<p> You will have to wait for an admin to activate your account after you have verified your email.");
smtpEmail.send();
}
public static void sendEmailNewUserToAdmin(User newuser, DBConnection db) throws SQLException, IOException{
// Email the admin about new user
Email email = new Email("admin@koc.se", "admin@koc.se");
email.setNiceFrom("Koc.se Admin");
email.setSubject("New user activation request at "+Zallery.getWebsiteName());
email.setContentType(ContentType.HTML);
email.setMessage("A new user has registered for an account at " +
"<a href='"+Zallery.getWebsiteURL()+"'>"+Zallery.getWebsiteName()+"</a>:" +
"<p>Email: <b>" + newuser.getEmail() + "</b>" +
"<br>Name: <b>" + newuser.getName() + "</b>" +
"<br>Facebook: <a href='http://www.facebook.com/profile.php?id="+newuser.getFacebookUid()+"'>"+newuser.getFacebookUid()+"</a>");
List<User> admins = User.loadSuperUsers(db);
for(User admin : admins){
if( admin.isEmailVerified() ){
email.setTo( admin.getEmail() );
email.send();
}
}
}
} }

View file

@ -1,364 +0,0 @@
package zall;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.AudioSamplesEvent;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.mediatool.event.IAudioSamplesEvent;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.mediatool.event.VideoPictureEvent;
import com.xuggle.xuggler.IAudioResampler;
import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.IVideoResampler;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;
import zall.bean.Media.Size;
import zall.bean.Video;
import zutil.StringUtil;
import zutil.db.DBConnection;
import zutil.log.LogUtil;
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;
public void init( ServletConfig config ){
try{
transcodingQueue = new LinkedList<Video>();
worker = new TranscoderThread();
worker.start();
// get untranscoded 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 static Video getProcessingVideo(){
return worker.currentVideo;
}
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();
}
}
}
/**
* Is the class that is doing the actual work of transcoding videos
*
* @author Ziver
*/
private static class TranscoderThread extends Thread{
private boolean stop;
protected long startTime;
protected Video currentVideo;
public void run(){
logger.info("ZalleryTranscoder thread started.");
try {
while( true ){
// 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);
// 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();
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Transcoding thread has crashed!", e);
}
}
public void abort(){
stop = true;
}
}
}
class MyVideoListener extends MediaToolAdapter {
private Integer width;
private Integer height;
public MyVideoListener(Integer aWidth, Integer aHeight) {
this.width = aWidth;
this.height = aHeight;
}
@Override
public void onAddStream(IAddStreamEvent event) {
int streamIndex = event.getStreamIndex();
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
} else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
streamCoder.setWidth(width);
streamCoder.setHeight(height);
}
super.onAddStream(event);
}
}
class VideoTranscoderListener extends MediaToolAdapter{
private int width;
private int height;
public VideoTranscoderListener(int width, int height) {
this.width = width;
this.height = height;
}
private IVideoResampler videoResampler = null;
private IAudioResampler audioResampler = null;
@Override
public void onAddStream(IAddStreamEvent event) {
int streamIndex = event.getStreamIndex();
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
streamCoder.setSampleRate( 44100 );
//streamCoder.setCodec( ICodec.ID.CODEC_ID_AAC );
//streamCoder.setBitRate( 128 );
}
else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
streamCoder.setWidth( width );
streamCoder.setHeight( height );
//streamCoder.setCodec(ICodec.findEncodingCodec( ICodec.ID.CODEC_ID_H264 ));
//streamCoder.setBitRate( 800000 );
/*
int retval = Configuration.configure("/usr/local/xuggler/share/ffmpeg/libx264-superfast.ffpreset", streamCoder);
if (retval<0)
throw new RuntimeException("cound not cofigure coder from preset file");
*/
}
super.onAddStream(event);
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
IVideoPicture pic = event.getPicture();
if (videoResampler == null) {
videoResampler = IVideoResampler.make(width, height, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
}
IVideoPicture out = IVideoPicture.make(pic.getPixelType(), width, height);
videoResampler.resample(out, pic);
IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
super.onVideoPicture(asc);
out.delete();
}
@Override
public void onAudioSamples(IAudioSamplesEvent event) {
IAudioSamples samples = event.getAudioSamples();
if (audioResampler == null) {
audioResampler = IAudioResampler.make(2, samples.getChannels(), 44100, samples.getSampleRate());
}
if (event.getAudioSamples().getNumSamples() > 0) {
IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
audioResampler.resample(out, samples, samples.getNumSamples());
AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
super.onAudioSamples(asc);
out.delete();
}
}
}
class ProgressListener extends MediaToolAdapter {
private long currentLength;
private long totalLength;
private int progress = -1;
public ProgressListener(IMediaReader reader) {
if( !reader.isOpen() )
reader.open(); // read container
this.totalLength = reader.getContainer().getDuration();
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
currentLength = event.getTimeStamp();
if( (int)(100*getProgress()) != progress ){
progress = (int)(100*getProgress());
System.out.print("\n"+(int)(100*getProgress())+"% ");
}
else System.out.print(".");
}
public long getProcessedLength(){
return currentLength;
}
public long getTotalLength(){
return totalLength;
}
public double getProgress(){
if(totalLength > 0)
return ((double)currentLength/totalLength);
return 0;
}
}
class FrameGrabListener extends MediaToolAdapter {
private long totalLength;
private long grabAt;
private File outputFile;
public FrameGrabListener(IMediaReader reader, File outputFile, double at) {
if( !reader.isOpen() )
reader.open(); // read container
this.totalLength = reader.getContainer().getDuration();
this.outputFile = outputFile;
setAtProgress(at);
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
try{
long currentLength = event.getTimeStamp();
if( grabAt > 0 && currentLength > grabAt ){
System.out.println("\nScreanshoot!!!");
ConverterFactory.Type mConverterType = ConverterFactory.findRegisteredConverter(
ConverterFactory.XUGGLER_BGR_24);
IConverter mVideoConverter = ConverterFactory.createConverter(
mConverterType.getDescriptor(),
event.getPicture());
ImageIO.write(
mVideoConverter.toImage(event.getPicture()),
"png",
outputFile);
grabAt = -1;
}
}catch(IOException e){
e.printStackTrace();
}
}
public void setAtProgress(double procent){
grabAt = (long)(totalLength * procent);
}
}

3
src/zall/action/RegisterAction.java Normal file → Executable file
View file

@ -11,6 +11,7 @@ import javax.servlet.http.HttpSession;
import zall.ZalleryAjax; import zall.ZalleryAjax;
import zall.bean.User; import zall.bean.User;
import zall.util.ZalleryEmail;
import zall.util.msg.UserMessage; import zall.util.msg.UserMessage;
import zall.util.msg.UserMessage.MessageType; import zall.util.msg.UserMessage.MessageType;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -40,7 +41,7 @@ public class RegisterAction extends ZalleryAction{
user.setPassword( request.getParameter("password") ); user.setPassword( request.getParameter("password") );
user.setName( request.getParameter("name") ); user.setName( request.getParameter("name") );
user.save(db); user.save(db);
ZalleryAjax.sendEmailVerification( user ); ZalleryEmail.sendVerificationEmail( user );
logger.info("Registered new user: "+user.getName()+"."); logger.info("Registered new user: "+user.getName()+".");
session.setAttribute("user", user); session.setAttribute("user", user);
if(out != null) out.println("{ \"id\":"+user.getId()+" }"); if(out != null) out.println("{ \"id\":"+user.getId()+" }");

11
src/zall/action/user/ModifyUserAction.java Normal file → Executable file
View file

@ -11,8 +11,9 @@ import javax.servlet.http.HttpSession;
import zall.Zallery; import zall.Zallery;
import zall.action.ZalleryAction; import zall.action.ZalleryAction;
import zall.bean.User; import zall.bean.User;
import zall.util.Email; import zall.util.ZalleryEmail;
import zall.util.Email.ContentType; import zutil.net.smtp.Email;
import zutil.net.smtp.Email.ContentType;
import zall.util.msg.UserMessage; import zall.util.msg.UserMessage;
import zall.util.msg.UserMessage.MessageType; import zall.util.msg.UserMessage.MessageType;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -34,11 +35,7 @@ public class ModifyUserAction extends ZalleryAction{
if( request.getParameter("enable") != null ){ if( request.getParameter("enable") != null ){
target_user.setEnabled( true ); target_user.setEnabled( true );
// Email the user about the activation // Email the user about the activation
Email email = new Email("admin@koc.se", target_user.getEmail()); ZalleryEmail.sendActivationEmail(target_user);
email.setSubject("Account activation at "+Zallery.getWebsiteName());
email.setContentType(ContentType.HTML);
email.setMessage("Your account has now been activated by an admin. You can now login and use the site. " +
"<a href='"+Zallery.getWebsiteURL()+"'>"+Zallery.getWebsiteURL()+"</a>");
} }
// Disable user, can not disable one self! // Disable user, can not disable one self!
else if( request.getParameter("disable") != null && !user.equals( target_user ) ) else if( request.getParameter("disable") != null && !user.equals( target_user ) )

4
src/zall/action/user/ModifyUserStatusAction.java Normal file → Executable file
View file

@ -8,9 +8,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import zall.ZalleryAjax;
import zall.action.ZalleryAction; import zall.action.ZalleryAction;
import zall.bean.User; import zall.bean.User;
import zall.util.ZalleryEmail;
import zall.util.msg.UserMessage; import zall.util.msg.UserMessage;
import zall.util.msg.UserMessage.MessageType; import zall.util.msg.UserMessage.MessageType;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -50,7 +50,7 @@ public class ModifyUserStatusAction extends ZalleryAction{
target_user.setName( request.getParameter("name") ); target_user.setName( request.getParameter("name") );
target_user.save(db); target_user.save(db);
if( !user.isEmailVerified() ) if( !user.isEmailVerified() )
ZalleryAjax.sendEmailVerification( target_user ); ZalleryEmail.sendVerificationEmail( target_user );
if( out != null ) if( out != null )
out.println("{ }"); out.println("{ }");
else else

4
src/zall/action/user/SendVerificationEmailAction.java Normal file → Executable file
View file

@ -9,9 +9,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import zall.ZalleryAjax;
import zall.action.ZalleryAction; import zall.action.ZalleryAction;
import zall.bean.User; import zall.bean.User;
import zall.util.ZalleryEmail;
import zall.util.msg.UserMessage; import zall.util.msg.UserMessage;
import zall.util.msg.UserMessage.MessageType; import zall.util.msg.UserMessage.MessageType;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -39,7 +39,7 @@ public class SendVerificationEmailAction extends ZalleryAction{
if( target_user != null ){ if( target_user != null ){
if( user.isSuperUser() ){ if( user.isSuperUser() ){
ZalleryAjax.sendEmailVerification(target_user); ZalleryEmail.sendVerificationEmail(target_user);
logger.info("Verification email sent successfully to: "+user.getEmail()); logger.info("Verification email sent successfully to: "+user.getEmail());
if( out != null ) out.println("{ }"); if( out != null ) out.println("{ }");

11
src/zall/action/user/VerifyEmailAction.java Normal file → Executable file
View file

@ -11,6 +11,7 @@ import javax.servlet.http.HttpSession;
import zall.ZalleryAjax; import zall.ZalleryAjax;
import zall.action.ZalleryAction; import zall.action.ZalleryAction;
import zall.bean.User; import zall.bean.User;
import zall.util.ZalleryEmail;
import zall.util.msg.UserMessage; import zall.util.msg.UserMessage;
import zall.util.msg.UserMessage.MessageType; import zall.util.msg.UserMessage.MessageType;
import zutil.db.DBConnection; import zutil.db.DBConnection;
@ -25,17 +26,17 @@ public class VerifyEmailAction extends ZalleryAction{
public void handleRequest(DBConnection db, HttpServletRequest request, HttpServletResponse response, HttpSession session, public void handleRequest(DBConnection db, HttpServletRequest request, HttpServletResponse response, HttpSession session,
PrintWriter out, User user, UserMessage msgs) throws SQLException, IOException { PrintWriter out, User user, UserMessage msgs) throws SQLException, IOException {
User verfuser = User.load(db, Long.parseLong(request.getParameter("id"))); User verifiedUser = User.load(db, Long.parseLong(request.getParameter("id")));
if( verfuser.verifyEmail(request.getParameter("hash")) ){ if( verifiedUser.verifyEmail(request.getParameter("hash")) ){
if( verfuser.isEnabled() ) if( verifiedUser.isEnabled() )
if(out != null) out.println("{ }"); if(out != null) out.println("{ }");
else msgs.add(MessageType.INFO, "Your email has been successfully verified"); else msgs.add(MessageType.INFO, "Your email has been successfully verified");
else { else {
ZalleryAjax.sendEmailNewUserToAdmin(verfuser, db); ZalleryEmail.sendNewUserRegistrationToAdmin(verifiedUser, db);
if(out != null) out.println("{ }"); if(out != null) out.println("{ }");
else msgs.add(MessageType.INFO, "Your email has been successfully verified, the account is waiting account activation by an admin."); else msgs.add(MessageType.INFO, "Your email has been successfully verified, the account is waiting account activation by an admin.");
} }
verfuser.save(db); verifiedUser.save(db);
} }
else if(out != null) out.println("{ \"error\":\"Invalid email verification hash!\" }"); else if(out != null) out.println("{ \"error\":\"Invalid email verification hash!\" }");
else msgs.add(MessageType.ERROR, "Invalid email verification hash!"); else msgs.add(MessageType.ERROR, "Invalid email verification hash!");

7
src/zall/bean/User.java Normal file → Executable file
View file

@ -28,7 +28,6 @@ public class User extends DBBean{
protected String email; protected String email;
protected boolean emailVerified; protected boolean emailVerified;
protected String password; protected String password;
protected String facebookUid;
// Date // Date
protected Timestamp loginDate; protected Timestamp loginDate;
protected transient Timestamp prevLoginDate; protected transient Timestamp prevLoginDate;
@ -259,12 +258,6 @@ public class User extends DBBean{
public String getSessionHash() { public String getSessionHash() {
return sessionHash; return sessionHash;
} }
public void setFacebookUid(String uid) {
facebookUid = uid;
}
public String getFacebookUid(){
return facebookUid;
}
public boolean isSuperUser(){ public boolean isSuperUser(){
return superUser; return superUser;
} }

2
src/zall/bean/Video.java Normal file → Executable file
View file

@ -9,7 +9,7 @@ import java.util.List;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItem;
import zall.ZalleryTranscoder; import zall.transcoder.ZalleryTranscoder;
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;

View file

@ -0,0 +1,57 @@
package zall.transcoder;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
/**
*
*/
class FrameGrabListener extends MediaToolAdapter {
private long totalLength;
private long grabAt;
private File outputFile;
public FrameGrabListener(IMediaReader reader, File outputFile, double at) {
if( !reader.isOpen() )
reader.open(); // read container
this.totalLength = reader.getContainer().getDuration();
this.outputFile = outputFile;
setAtProgress(at);
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
try{
long currentLength = event.getTimeStamp();
if( grabAt > 0 && currentLength > grabAt ){
System.out.println("\nScreanshoot!!!");
ConverterFactory.Type mConverterType = ConverterFactory.findRegisteredConverter(
ConverterFactory.XUGGLER_BGR_24);
IConverter mVideoConverter = ConverterFactory.createConverter(
mConverterType.getDescriptor(),
event.getPicture());
ImageIO.write(
mVideoConverter.toImage(event.getPicture()),
"png",
outputFile);
grabAt = -1;
}
}catch(IOException e){
e.printStackTrace();
}
}
public void setAtProgress(double procent){
grabAt = (long)(totalLength * procent);
}
}

View file

@ -0,0 +1,32 @@
package zall.transcoder;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IStreamCoder;
/**
*
*/
class MyVideoListener extends MediaToolAdapter {
private Integer width;
private Integer height;
public MyVideoListener(Integer aWidth, Integer aHeight) {
this.width = aWidth;
this.height = aHeight;
}
@Override
public void onAddStream(IAddStreamEvent event) {
int streamIndex = event.getStreamIndex();
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
} else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
streamCoder.setWidth(width);
streamCoder.setHeight(height);
}
super.onAddStream(event);
}
}

View file

@ -0,0 +1,45 @@
package zall.transcoder;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.IVideoPictureEvent;
/**
*
*/
class ProgressListener extends MediaToolAdapter {
private long currentLength;
private long totalLength;
private int progress = -1;
public ProgressListener(IMediaReader reader) {
if( !reader.isOpen() )
reader.open(); // read container
this.totalLength = reader.getContainer().getDuration();
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
currentLength = event.getTimeStamp();
if( (int)(100*getProgress()) != progress ){
progress = (int)(100*getProgress());
System.out.print("\n"+(int)(100*getProgress())+"% ");
}
else System.out.print(".");
}
public long getProcessedLength(){
return currentLength;
}
public long getTotalLength(){
return totalLength;
}
public double getProgress(){
if(totalLength > 0)
return ((double)currentLength/totalLength);
return 0;
}
}

View file

@ -0,0 +1,76 @@
package zall.transcoder;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.*;
import com.xuggle.xuggler.*;
/**
*
*/
class VideoTranscoderListener extends MediaToolAdapter {
private int width;
private int height;
public VideoTranscoderListener(int width, int height) {
this.width = width;
this.height = height;
}
private IVideoResampler videoResampler = null;
private IAudioResampler audioResampler = null;
@Override
public void onAddStream(IAddStreamEvent event) {
int streamIndex = event.getStreamIndex();
IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
streamCoder.setSampleRate( 44100 );
//streamCoder.setCodec( ICodec.ID.CODEC_ID_AAC );
//streamCoder.setBitRate( 128 );
}
else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
streamCoder.setWidth( width );
streamCoder.setHeight( height );
//streamCoder.setCodec(ICodec.findEncodingCodec( ICodec.ID.CODEC_ID_H264 ));
//streamCoder.setBitRate( 800000 );
/*
int retval = Configuration.configure("/usr/local/xuggler/share/ffmpeg/libx264-superfast.ffpreset", streamCoder);
if (retval<0)
throw new RuntimeException("cound not cofigure coder from preset file");
*/
}
super.onAddStream(event);
}
@Override
public void onVideoPicture(IVideoPictureEvent event) {
IVideoPicture pic = event.getPicture();
if (videoResampler == null) {
videoResampler = IVideoResampler.make(width, height, pic.getPixelType(), pic.getWidth(), pic.getHeight(), pic.getPixelType());
}
IVideoPicture out = IVideoPicture.make(pic.getPixelType(), width, height);
videoResampler.resample(out, pic);
IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
super.onVideoPicture(asc);
out.delete();
}
@Override
public void onAudioSamples(IAudioSamplesEvent event) {
IAudioSamples samples = event.getAudioSamples();
if (audioResampler == null) {
audioResampler = IAudioResampler.make(2, samples.getChannels(), 44100, samples.getSampleRate());
}
if (event.getAudioSamples().getNumSamples() > 0) {
IAudioSamples out = IAudioSamples.make(samples.getNumSamples(), samples.getChannels());
audioResampler.resample(out, samples, samples.getNumSamples());
AudioSamplesEvent asc = new AudioSamplesEvent(event.getSource(), out, event.getStreamIndex());
super.onAudioSamples(asc);
out.delete();
}
}
}

View file

@ -0,0 +1,199 @@
package zall.transcoder;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.AudioSamplesEvent;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.mediatool.event.IAudioSamplesEvent;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.mediatool.event.VideoPictureEvent;
import com.xuggle.xuggler.IAudioResampler;
import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.IVideoResampler;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;
import zall.Zallery;
import zall.bean.Media.Size;
import zall.bean.Video;
import zutil.StringUtil;
import zutil.db.DBConnection;
import zutil.log.LogUtil;
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;
public void init( ServletConfig config ){
try{
transcodingQueue = new LinkedList<Video>();
worker = new TranscoderThread();
worker.start();
// get untranscoded 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 static Video getProcessingVideo(){
return worker.currentVideo;
}
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();
}
}
}
/**
* 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()+")");
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);
// 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);
}
}
public void abort(){
stop = true;
synchronized (transcodingQueue) {
transcodingQueue.notifyAll();
}
}
}
}

View file

@ -1,97 +0,0 @@
package zall.util;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import sun.net.smtp.SmtpClient;
/**
* Simplifies sending of a email
*
* @author Ziver
*/
public class Email {
public static enum ContentType{
PLAIN, HTML
}
private static final SimpleDateFormat dateFormatter =
new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
private static String host = "localhost";
private String from;
private String niceFrom = null;
private String to;
private String replyTo = null;
private ContentType type = ContentType.PLAIN;
private String subject;
private String message;
public Email(String from, String to){
this.from = from;
this.to = to;
}
public void setFrom(String f){
from = f;
}
public void setNiceFrom(String nf){
niceFrom = nf;
}
public void setReplyTo(String rpt){
replyTo = rpt;
}
public void setTo(String t){
to = t;
}
public void setContentType(ContentType t){
type = t;
}
public void setSubject(String s){
subject = s;
}
public void setMessage(String msg){
message = msg;
}
public static void setServer(String host){
Email.host = host;
}
public void send() throws IOException{
if(from == null)
throw new IllegalArgumentException("From value missing!");
if(to == null)
throw new IllegalArgumentException("To value missing!");
SmtpClient smtp = new SmtpClient( host );
smtp.from(from);
smtp.to(to);
PrintStream msg = smtp.startMessage();
//************ Headers
msg.println("From: "+(niceFrom!=null ? "\""+niceFrom+"\"" : "")+" <"+from+">");
msg.println("Reply-To: <"+replyTo+">");
if( replyTo != null )
msg.println("Reply-To: <"+replyTo+">");
msg.println("To: " + to); // so mailers will display the To: address
msg.println("Subject: "+subject);
// Date
msg.println("Date: "+dateFormatter.format(new Date(System.currentTimeMillis())));
// Content type
switch( type ){
case HTML:
msg.println("Content-Type: text/html;"); break;
default:
msg.println("Content-Type: text/plain;"); break;
}
msg.println();
//*********** Mesasge
msg.println( message );
smtp.closeServer();
}
}

75
src/zall/util/ZalleryEmail.java Executable file
View file

@ -0,0 +1,75 @@
package zall.util;
import zall.Zallery;
import zall.bean.User;
import zutil.db.DBConnection;
import zutil.net.smtp.Email;
import zutil.net.smtp.SMTPClient;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
/**
*
*/
public class ZalleryEmail {
private static String host;
public static void setSMTPHost(String host){
ZalleryEmail.host = host;
}
public static void sendVerificationEmail(User user) throws IOException {
// Email
Email email = new Email();
email.setFrom("admin@koc.se", "Koc.se Admin");
email.setTo(user.getEmail());
email.setSubject("Registration at "+ Zallery.getWebsiteName());
email.setContentType(Email.ContentType.HTML);
email.setMessage("You receive this message because you have requested an account" +
"<br>at "+Zallery.getWebsiteName()+". Please click the link to verify your email address: " +
"<p><a href='"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"'>"+Zallery.getWebsiteURL()+"?action=verfemail&id="+user.getId()+"&hash="+user.getEmailVerificationHash()+"</a>" +
"<p> You will have to wait for an admin to activate your account after you have verified your email.");
SMTPClient smtp = new SMTPClient(host);
smtp.send(email);
smtp.close();
}
public static void sendActivationEmail(User user) throws IOException {
Email email = new Email();
email.setFrom("admin@koc.se", "Koc.se Admin");
email.setTo(user.getEmail());
email.setSubject("Account activation at " + Zallery.getWebsiteName());
email.setContentType(Email.ContentType.HTML);
email.setMessage("Your account has now been activated by an admin. You can now login and use the site. " +
"<a href='" + Zallery.getWebsiteURL() + "'>" + Zallery.getWebsiteURL() + "</a>");
SMTPClient smtp = new SMTPClient(host);
smtp.send(email);
smtp.close();
}
public static void sendNewUserRegistrationToAdmin(User user, DBConnection db) throws SQLException, IOException{
// Email the admin about new user
Email email = new Email();
email.setFrom("admin@koc.se", "Koc.se Admin");
email.setSubject("New user activation request at "+Zallery.getWebsiteName());
email.setContentType(Email.ContentType.HTML);
email.setMessage("A new user has registered for an account at " +
"<a href='"+Zallery.getWebsiteURL()+"'>"+Zallery.getWebsiteName()+"</a>:" +
"<p>Email: <b>" + user.getEmail() + "</b>" +
"<br>Name: <b>" + user.getName() + "</b>"
);
SMTPClient smtp = new SMTPClient(host);
for(User admin : User.loadSuperUsers(db)){
if( admin.isEmailVerified() ){
email.setTo( admin.getEmail() );
smtp.send(email);
}
}
smtp.close();
}
}