ryerson.daspub.mobile.AssignmentPage.java Source code

Java tutorial

Introduction

Here is the source code for ryerson.daspub.mobile.AssignmentPage.java

Source

/*
 * Copyright (c) 2011 Davis Marques
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
package ryerson.daspub.mobile;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import ryerson.daspub.Config;
import ryerson.daspub.Config.SUBMISSION_EVALUATION;
import ryerson.daspub.Config.SUBMISSION_TYPE;
import ryerson.daspub.model.Assignment;
import ryerson.daspub.model.Submission;
import ryerson.daspub.utility.ImageUtils;
import ryerson.daspub.utility.PDFUtils;
import ryerson.daspub.utility.VideoUtils;

/**
 * Assignment page.
 * @author dmarques
 */
public class AssignmentPage {

    private static String FULL_DIR = "full";
    private static String THUMB_DIR = "thumb";
    private static String VIDEO_DIR = "video";

    private static String HANDOUT_FILENAME = "handout.jpg";
    private static String HANDOUT_THUMB_FILENAME = "handout-thumb.jpg";

    private static final Logger logger = Logger.getLogger(AssignmentPage.class.getName());

    //--------------------------------------------------------------------------

    /**
     * HTML thumbnail index of document Submissions matching the evaluation
     * value E.
     * @param A Assignment
     * @param E Evaluation value
     * @param Id Block identifier
     * @param Title Block title
     * @param Output Assignment output folder
     * @return PhotoSwipe gallery index
     */
    public static String buildDocumentSubmissionIndex(Assignment A, SUBMISSION_EVALUATION E, String Id,
            String Title, File Output) {
        List<Submission> ls = A.getSubmissions(SUBMISSION_TYPE.IMAGE, E);
        StringBuilder sb = new StringBuilder();
        if (ls.size() > 0) {
            // create output directories
            File full = new File(Output, FULL_DIR);
            if (!full.exists()) {
                full.mkdirs();
            }
            File thumb = new File(Output, THUMB_DIR);
            if (!thumb.exists()) {
                thumb.mkdirs();
            }
            // javascript for gallery function
            sb.append("\n\t<script type=\"text/javascript\">");
            sb.append("\n\t\t$(document).ready(function(){");
            sb.append("\n\t\tvar ");
            sb.append(Id);
            sb.append("Swipe = $(\"#");
            sb.append(Id);
            sb.append(" a\").photoSwipe({ enableMouseWheel: false , enableKeyboard: false });");
            sb.append("\n\t\t\t});");
            sb.append("\n\t</script>");
            // submission index
            sb.append("\n\t<div data-role=\"collapsible\" data-collapsed=\"true\">");
            sb.append("\n\t\t<h3>");
            sb.append(Title);
            sb.append("</h3>");
            sb.append("\n\t<ul id=\"");
            sb.append(Id);
            sb.append("\" class=\"gallery\">");
            // for each submission, add an index item
            Iterator<Submission> its = ls.iterator();
            List<File> images;
            List<File> thumbs;
            while (its.hasNext()) {
                Submission s = its.next();
                if (s.getSourceFile().exists()) {
                    // write thumbnails, full size images
                    images = writeImage(s, thumb, Config.THUMB_MAX_WIDTH, Config.THUMB_MAX_HEIGHT);
                    thumbs = writeImage(s, full, Config.IMAGE_MAX_WIDTH, Config.IMAGE_MAX_HEIGHT);
                    // build html
                    for (int i = 0; i < images.size(); i++) {
                        File f = images.get(i);
                        File t = thumbs.get(i);
                        sb.append("\n\t\t<li>");
                        sb.append("<a href=\"");
                        sb.append(A.getURLSafeName());
                        sb.append("/");
                        sb.append(FULL_DIR);
                        sb.append("/");
                        sb.append(f.getName());
                        sb.append("\" rel=\"external\"><img src=\"");
                        sb.append(A.getURLSafeName());
                        sb.append("/");
                        sb.append(THUMB_DIR);
                        sb.append("/");
                        sb.append(t.getName());
                        sb.append("\" alt=\"");
                        sb.append(s.getAssignmentName());
                        sb.append(", ");
                        sb.append(s.getAuthor());
                        if (s.isMultiPagePDF()) {
                            sb.append(getPageNumberLabel(s, f.getName()));
                        }
                        sb.append(" (");
                        sb.append(s.getEvaluationString());
                        sb.append(")\" /></a></li>");
                    }
                }
            }
            sb.append("\n\t</ul>\n</div>");
        }
        // return result
        return sb.toString();
    }

    /**
     * HTML thumbnail index of course handout
     * @param A Assignment
     * @param Output Assignment output folder
     * @return PhotoSwipe gallery index
     */
    public static String buildSyllabusIndex(Assignment A, File Output) {
        StringBuilder sb = new StringBuilder();
        if (A.hasSyllabusFile()) {
            // javascript for gallery function
            sb.append("\n<script type=\"text/javascript\">");
            sb.append("\n\t$(document).ready(function(){");
            sb.append(
                    "\n\t\tvar sPhotoswipe = $(\"#syllabus a\").photoSwipe({enableMouseWheel:false,enableKeyboard:false});");
            sb.append("\n\t\t});");
            sb.append("\n</script>");
            // syllabus index
            File thumb = new File(Output, HANDOUT_THUMB_FILENAME);
            File full = new File(Output, HANDOUT_FILENAME);
            try {
                List<File> thumbs;
                List<File> images;
                thumbs = PDFUtils.writeJPGImageAllPDFPages(A.getSyllabusFile(), thumb, Config.THUMB_MAX_WIDTH,
                        Config.THUMB_MAX_HEIGHT);
                images = PDFUtils.writeJPGImageAllPDFPages(A.getSyllabusFile(), full, Config.IMAGE_MAX_WIDTH,
                        Config.IMAGE_MAX_HEIGHT);
                // for each page of the syllabus, write out an index thumbnail
                String url = A.getURLSafeName();
                sb.append("\n<ul id=\"syllabus\" class=\"gallery\">");
                for (int i = 0; i < images.size(); i++) {
                    File f = images.get(i);
                    File t = thumbs.get(i);
                    sb.append("\n\t<li>");
                    sb.append("<a href=\"");
                    sb.append(url);
                    sb.append("/");
                    sb.append(f.getName());
                    sb.append("\" rel=\"external\"><img src=\"");
                    sb.append(url);
                    sb.append("/");
                    sb.append(t.getName());
                    sb.append("\" alt=\"");
                    sb.append("Page ");
                    sb.append(i + 1);
                    sb.append(" of ");
                    sb.append(images.size());
                    sb.append("\" /></a></li>");
                }
                sb.append("\n</ul>");
            } catch (Exception ex) {
                String stack = ExceptionUtils.getStackTrace(ex);
                logger.log(Level.SEVERE, "Could not write handout gallery for {0}\n\n{1}",
                        new Object[] { A.getFolder().getAbsolutePath(), stack });
            }
        }
        // return result
        return sb.toString();
    }

    /**
     * HTML thumbnail index of video submissions matching the evaluation value
     * E.
     * @param A Assignment
     * @param Evaluation Evaluation value
     * @param Id Block identifier
     * @param Title Block title
     * @param Output Assignment output folder
     * @return Video gallery index
     */
    public static String buildVideoSubmissionIndex(Assignment A, SUBMISSION_EVALUATION Evaluation, String Id,
            String Title, File Output) {
        StringBuilder sb = new StringBuilder();
        List<Submission> ls = A.getSubmissions(SUBMISSION_TYPE.VIDEO, Evaluation);
        if (ls.size() > 0) {
            // create output subdirectory if it does not exist
            File output = new File(Output, VIDEO_DIR);
            if (!output.exists()) {
                output.mkdirs();
            }
            // submission index
            sb.append("\n<div data-role=\"collapsible\" data-collapsed=\"true\">");
            sb.append("\n\t<h3>");
            sb.append(Title);
            sb.append("</h3>");
            sb.append("\n\t<ul id=\"");
            sb.append(Id);
            sb.append("\" class=\"videogallery\">");
            Iterator<Submission> its = ls.iterator();
            // for each video, create a player and a poster image, copy the
            // source file to the output folder
            Dimension dim = null;
            File poster = null;
            while (its.hasNext()) {
                Submission s = its.next();
                if (s.getSourceFile().exists()) {
                    try {
                        // get video metadata
                        dim = VideoUtils.getSize(s.getSourceFile());
                        // write poster for video
                        poster = VideoUtils.writePosterImage(s.getSourceFile(), output);
                        // copy the source file to the output folder
                        copyVideo(s.getSourceFile(), output);
                        // write html player
                        sb.append("\n<li>");
                        sb.append("\n\t<video id=\"");
                        sb.append("randomplayerid");
                        sb.append("\" ");
                        sb.append("\n\t\tclass=\"video-js vjs-default-skin\" ");
                        sb.append("\n\t\tcontrols preload=\"none\" ");
                        sb.append("\n\t\twidth=\"");
                        sb.append(String.valueOf(dim.getSize().getWidth())); // do you really want to do this or should all video be the same size??
                        sb.append("\" ");
                        sb.append("\n\t\theight=\"");
                        sb.append(String.valueOf(dim.getSize().getHeight()));
                        sb.append("\" ");
                        sb.append("\n\t\tposter=\"");
                        sb.append(A.getURLSafeName());
                        sb.append("/");
                        sb.append(VIDEO_DIR);
                        sb.append("/");
                        sb.append(poster.getName());
                        sb.append("\"");
                        sb.append("\n\t\tdata-setup=\"{}\">");
                        sb.append("\n\t\t<source src=\"");
                        sb.append(A.getURLSafeName());
                        sb.append("/");
                        sb.append(VIDEO_DIR);
                        sb.append("/");
                        sb.append(s.getSourceFileName());
                        sb.append("\" type=\"");
                        sb.append(VideoUtils.getMimeType(s.getSourceFile()));
                        sb.append("\" />");
                        sb.append("\n\t</video>");
                        sb.append("\n</li>");
                    } catch (Exception ex) {
                        String stack = ExceptionUtils.getStackTrace(ex);
                        logger.log(Level.SEVERE, "Could not process video file {0}\n\n{1}",
                                new Object[] { s.getSourceFile().getAbsolutePath(), stack });
                    }
                }
            }
            sb.append("\n\t</ul>");
            sb.append("\n</div>");
        }
        // return result
        return sb.toString();
    }

    /**
     * Copy video file from source to output.
     * @param Input Input file
     * @param Output Output file or folder
     * @throws IOException
     */
    private static void copyVideo(File Input, File Output) throws IOException {
        File output = Output;
        if (output.isDirectory()) {
            output = new File(output, Input.getName());
        }
        FileUtils.copyFile(Input, output);
    }

    /**
     * Create a page number label from the submission object and file name.
     * @return
     */
    private static String getPageNumberLabel(Submission S, String Name) {
        // get page number of file
        int i = Name.lastIndexOf("-");
        int j = Name.lastIndexOf(".");
        CharSequence val = Name.subSequence(i + 1, j);
        Integer page = Integer.valueOf(val.toString());
        page += 1; // pages are enumerated on a zero based index
        // build label
        int total = S.getPageCount();
        StringBuilder sb = new StringBuilder();
        sb.append(". Page ");
        sb.append(String.valueOf(page));
        sb.append(" of ");
        sb.append(String.valueOf(total));
        return sb.toString();
    }

    /**
     * Get thumbnail file name.
     * @param S Submission
     * @return
     */
    public static String getThumbnailFileName(Submission S) {
        if (S.getSourceFile().exists()) {
            return ImageUtils.getJPGFileName(S.getSourceFile().getName());
        }
        return "";
    }

    /**
     * Write assignment page.
     * @param A Assignment
     * @param Output Output folder
     */
    public static void Write(Assignment A, File Output) {
        logger.log(Level.INFO, "Writing assignment folder \"{0}\"", Output.getAbsolutePath());
        // create the output folder
        Output.mkdirs();
        try {
            // load template
            String page = FileUtils.readFileToString(new File(Config.ASSIGNMENT_TEMPLATE_PATH));
            // replace template variable fields
            page = page.replace("${title}", A.getName());
            page = page.replace("${description}", A.getDescription());
            // build index for syllabus
            if (A.hasSyllabusFile()) {
                page = page.replace("${syllabus}", buildSyllabusIndex(A, Output));
            } else {
                page = page.replace("${syllabus}", "\n<p>Assignment handout not available.</p>");
            }
            // build indicies for high pass and low pass document submissions
            if (A.hasImageSubmissions()) {
                String index = "\n<div data-role=\"collapsible-set\">";
                index += buildDocumentSubmissionIndex(A, SUBMISSION_EVALUATION.HIGH_PASS, "imagesHighPass",
                        "Documents - High Pass", Output);
                index += buildDocumentSubmissionIndex(A, SUBMISSION_EVALUATION.LOW_PASS, "imagesLowPass",
                        "Documents - Low Pass", Output);
                index += "\n</div>";
                page = page.replace("${images}", index);
            } else {
                page = page.replace("${images}", "");
            }
            // build indicies for high pass and low pass video submissions
            if (A.hasVideoSubmission()) {
                String index = "\n<div data-role=\"collapsible-set\">";
                index += buildVideoSubmissionIndex(A, SUBMISSION_EVALUATION.HIGH_PASS, "videoHighPass",
                        "Animations and Videos - High Pass", Output);
                index += buildVideoSubmissionIndex(A, SUBMISSION_EVALUATION.LOW_PASS, "videoLowPass",
                        "Animations and Videos - Low Pass", Output);
                index += "\n</div>";
                page = page.replace("${video}", index);
            } else {
                page = page.replace("${video}", "");
            }
            // write assignment html page
            File html = new File(Output, "index.html");
            logger.log(Level.INFO, "Writing assignment page \"{0}\"", html.getAbsolutePath());
            FileUtils.write(html, page);
        } catch (Exception ex) {
            String stack = ExceptionUtils.getStackTrace(ex);
            logger.log(Level.SEVERE, "Could not write assignment {0} to {1}\n\n{2}",
                    new Object[] { A.getName(), Output, stack });
        }
    }

    /**
     * Write JPG thumbnail image of submission source file. If the source file
     * is a multi-page PDF, write all pages.
     * @param S Submission
     * @param Output Output folder
     * @param Width Maximum image width
     * @param Height Maximum image height
     * @return List of output files.
     */
    private static List<File> writeImage(Submission S, File Output, int Width, int Height) {
        // if output is a directory
        File output = Output;
        if (output.isDirectory()) {
            output = new File(output, S.getSourceFileName());
        }
        // create parent directory if it does not exist
        if (!output.getParentFile().exists()) {
            output.getParentFile().mkdirs();
        }
        // write output file(s)
        File input = S.getSourceFile();
        List<File> files = new ArrayList<File>();
        try {
            if (S.isMultiPagePDF()) {
                files = PDFUtils.writeJPGImageAllPDFPages(input, output, Width, Height);
            } else if (S.isSinglePagePDF()) {
                files = PDFUtils.writeJPGImage(input, output, Width, Height);
            } else if (S.isImage()) {
                ImageUtils.writeJPGImage(input, output, Width, Height);
                files.add(output);
            } else if (S.isVideo()) {
                VideoUtils.writePosterImage(input, output);
                files.add(output);
            }
        } catch (Exception ex) {
            String stack = ExceptionUtils.getStackTrace(ex);
            logger.log(Level.SEVERE, "Could not write image {0} for {1}\n\n{2}",
                    new Object[] { output.getAbsolutePath(), input.getAbsolutePath(), stack });
        }
        // return list of output files
        return files;
    }

} // end class