package com.robertlancer.supershare.servlets;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import com.google.api.services.drive.model.Permission;
import com.google.api.services.gmail.Gmail;
import com.robertlancer.supershare.util.DriveBackoff;
import com.robertlancer.supershare.util.Mail;
import com.robertlancer.supershare.util.Mime;
import com.robertlancer.supershare.util.ServiceFactory;
import javax.mail.MessagingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
public class DocumentViewer extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String pathInfo = req.getPathInfo();
if (pathInfo == null || pathInfo.length() <= 1) {
sendError(404, resp);
return;
}
String fileTitle = pathInfo.substring(1).replace("-", " ").replace("'", "");
if (fileTitle.equalsIgnoreCase("favicon.ico"))
return;
String folderId = System.getProperty("folder");
String email = System.getProperty("email");
File fileToOutput = getFile(fileTitle, folderId, email);
if (fileToOutput == null) {
sendError(404, resp);
return;
} else {
boolean anyoneHasAccess = false;
for (Permission permission : fileToOutput.getPermissions()) {
if (permission.getType().equalsIgnoreCase("anyone")) {
anyoneHasAccess = true;
break;
}
}
if (!anyoneHasAccess) {
Permission permission = new Permission();
permission.setType("anyone");
permission.setRole("reader");
permission.setWithLink(true);
Drive.Permissions.Insert updatePermissionReq = ServiceFactory.getDriveService(email).permissions().insert(fileToOutput.getId(), permission);
Permission inserted = new DriveBackoff<Permission>().execute(updatePermissionReq, false);
}
resp.getWriter().write(outputFile(fileToOutput));
sendViewAlert(fileToOutput, req);
}
}
public static void sendViewAlert(File fileToOutput, HttpServletRequest req) {
String description = fileToOutput.getDescription();
if (description == null)
return;
boolean sendAlert = description.contains("#SSALERT");
if (!sendAlert)
return;
String email = fileToOutput.getOwners().get(0).getEmailAddress();
Gmail gmail = ServiceFactory.getGmailService(email);
String ipAddress = req.getRemoteAddr();
String body = fileToOutput.getTitle() + " was viewed.\n\n" +
"IP: " + ipAddress + "\n" +
"User Agent: " + req.getHeader("User-Agent") + "\n" + new Date().toLocaleString();
try {
Mail.sendMessage(gmail, "me", Mail.createEmail(email, email, fileToOutput.getTitle(), body));
} catch (MessagingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static String outputFile(File fileToOutput) {
String url = outputFileAsIFrameGetURL(fileToOutput);
String iframe = "<iframe src='" + url + "' frameborder=0 style='width:100%;height:100%;' /></iframe>";
StringBuilder output = new StringBuilder();
output.append("<html>");
output.append("<head><title>" + fileToOutput.getTitle() + "</title>");
output.append("<link rel=\"icon\" type=\"image/png\"\n" +
" href=\"" + fileToOutput.getIconLink() + "\" />");
output.append("</head>");
output.append("<body>");
output.append("<style>\n");
output.append("html, body { overflow:hidden; height:100%; padding:0px; margin:0px; }");
output.append("\n</style>");
output.append(iframe);
output.append("</body></html>");
return output.toString();
}
public static String outputFileAsIFrameGetURL(File fileToOutput) {
String domain = fileToOutput.getOwners().get(0).getEmailAddress().split("@")[1];
String id = fileToOutput.getId();
switch (fileToOutput.getMimeType()) {
case Mime.DOCUMENT:
return "https://docs.google.com/a/" + domain + "/document/d/" + id + "/preview";
case Mime.SPREADSHEET:
return "https://docs.google.com/a/" + domain + "/spreadsheet/ccc?key=" + id + "&output=html&widget=true&chrome=false";
case Mime.PRESENTATION:
return "https://docs.google.com/a/" + domain + "/presentation/d/" + id + "/preview";
case Mime.DRAWING:
return "https://docs.google.com/a/" + domain + "/drawings/d/" + id + "/preview";
default:
return "https://docs.google.com/a/" + domain + "/file/d/" + id + "/preview";
}
}
public static File getFile(String title, String folderId, String email) throws IOException {
String operator;
if (System.getProperty("allowPartialMatches").equals("false")) {
operator = "=";
} else {
operator = "contains";
}
Drive drive = ServiceFactory.getDriveService(email);
Drive.Files.List request = drive.files().list().setQ("'" + folderId + "' in parents and trashed = false and title " + operator + " '" + title + "'").setFields("items(description,owners,id,downloadUrl,iconLink,mimeType,permissions,title)").setMaxResults(1000);
List<File> items = new DriveBackoff<FileList>().execute(request, false).getItems();
if (items.isEmpty())
return null;
if (items.size() == 1)
return items.get(0);
else {
for (File file : items) {
if (file.getTitle().equalsIgnoreCase(title))
return file;
}
}
return items.get(0);
}
public void sendError(int code, HttpServletResponse resp) {
try {
resp.setStatus(code);
if (code == 404)
resp.getWriter().write("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"+
"<html><head><title>404 Not Found</title></head>"+
"<body><h1>Not Found</h1><p>The requested resource was not found.</p>"+
"<hr><address>Google Frontend</address></body></html>");
else
resp.getWriter().write("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"+
"<html><head><title>500 Internal Server Error</title></head>"+
"<body><h1>Not Found</h1><p>The server encountered an "+
"internal error and was unable to complete your request.</p>"+
"<hr><address>Google Frontend</address></body></html>");
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}