summaryrefslogblamecommitdiffstats
path: root/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/MailGenerator.java
blob: 932849b8178a4e92b843788d9993869614ccd1b7 (plain) (tree)
1
2
3
4
5
6
7
8
                                  

                             
                               


                           
                        



                               
                                                             



                                                                  
                                                         
                                                              
                                                      
                                           
                                      







                                                         
                            
 


                                                                                             
                                                                                   
 






                                                                                   
                                                                                                           

                                     
                                                         
                                                                              

                                                                                    
                                                             

                                                                                                                    
                                                                                   



                         






                                                                              
                                                                                                             

                                     
                                                         
                                                                              




                                                                                                                            
                                                             
                                                                                   




                                                                              

                                     
                                                         
                                                                              
                                                                                                                     


                                                                                                                       
                                                             
                                                                                   



                         

                                                                                         

                                     






                                                                                               









                                                                                                    

                                             
                                                                                 
                                         
                                                                                                             


                                            
                                                                                        
                                                                                                                    
                                                                       
                                                             
                         
                                                                                                               

                                                                                 
                                                                                                                   
                         
                 

                                                                    
                                                                           


                 
                                                                                                          

                                     






                                                                                                               

                                                                                                            


                                                                                                             

                                                                                                        

                                                                                                                               


                               

                                                                    
                                                                           


                 
                                                                                   

                                     
                                                                      
                                                                                                                      
                                                     
                                                                           


                 








































































                                                                                             
































































                                                                                                                            
 
package org.openslx.bwlp.sat.mail;

import java.sql.SQLException;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.mappers.DbConfiguration;
import org.openslx.bwlp.sat.database.mappers.DbImage;
import org.openslx.bwlp.sat.database.mappers.DbImagePermissions;
import org.openslx.bwlp.sat.database.mappers.DbLecturePermissions;
import org.openslx.bwlp.sat.database.mappers.DbUser;
import org.openslx.bwlp.sat.database.mappers.DbUser.User;
import org.openslx.bwlp.sat.database.models.LocalImageVersion;
import org.openslx.bwlp.sat.mail.MailQueue.MailConfig;
import org.openslx.bwlp.sat.util.Formatter;
import org.openslx.bwlp.sat.util.Util;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImagePermissions;
import org.openslx.bwlp.thrift.iface.ImageVersionDetails;
import org.openslx.bwlp.thrift.iface.LecturePermissions;
import org.openslx.bwlp.thrift.iface.LectureSummary;
import org.openslx.bwlp.thrift.iface.TNotFoundException;
import org.openslx.bwlp.thrift.iface.UserInfo;

public class MailGenerator {

	// TODO Hard-Coded template mess. Strings and messages changed a lot while testing :(
	// This is best we could do for Sept. release

	private static final Logger LOGGER = Logger.getLogger(MailGenerator.class);

	/**
	 * Called when an image has been updated, and linked lectures will be moved
	 * to the new image version.
	 * 
	 * @param lectures List of affected lectures
	 * @param newVersion version id of new image
	 */
	public static void lectureAutoUpdate(List<LectureSummary> lectures, LocalImageVersion newVersion) {
		if (!hasMailConfig())
			return;
		for (LectureSummary lecture : lectures) {
			List<UserInfo> relevantUsers = getUserToMail(lecture);
			String message = "Zur Veranstaltung '" + lecture.lectureName
					+ "' gehörige VM wurde aktualisiert.";
			for (UserInfo user : relevantUsers) {
				if (newVersion.uploaderId.equals(user.userId)) // Don't notice about changes by user
					continue;
				MailQueue.queue(new Mail(user, wordWrap(message)));
			}
		}
	}

	/**
	 * Called when a lecture is downgraded, or a lecture is updated and it
	 * doesn't have auto-updates enabled.
	 * 
	 * @param lectures list of affected lectures
	 * @param newVersion the new version being switched to
	 */
	public static void lectureForcedUpdate(List<LectureSummary> lectures, LocalImageVersion newVersion) {
		if (!hasMailConfig())
			return;
		for (LectureSummary lecture : lectures) {
			List<UserInfo> relevantUsers = getUserToMail(lecture);
			String message = "Die verlinkte VM zur Veranstaltung '" + lecture.lectureName
					+ "' wurde gelöscht oder ist beschädigt,"
					+ " daher verweist sie jetzt auf die VM-Version vom "
					+ Formatter.date(newVersion.createTime) + "."
					+ " Bitte überprüfen Sie ggf., ob diese VM-Version für Ihren Kurs geeignet ist.";
			for (UserInfo user : relevantUsers) {
				MailQueue.queue(new Mail(user, wordWrap(message)));
			}
		}
	}

	public static void lectureDeactivated(List<LectureSummary> lectures) {
		if (!hasMailConfig())
			return;
		for (LectureSummary lecture : lectures) {
			List<UserInfo> relevantUsers = getUserToMail(lecture);
			String message = "Die Veranstaltung '" + lecture.lectureName + "' musste deaktiviert werden,"
					+ " da die verknüpfte VM gelöscht oder beschädigt wurde. Bitte überprüfen"
					+ " Sie die Veranstaltung und ändern Sie ggf. die Verlinkung,"
					+ " damit die Veranstaltung wieder verwendbar ist.";
			for (UserInfo user : relevantUsers) {
				MailQueue.queue(new Mail(user, wordWrap(message)));
			}
		}
	}

	public static void versionDeleted(String imageBaseId, LocalImageVersion oldLocal,
			LocalImageVersion newLocal) {
		if (!hasMailConfig())
			return;
		ImageDetailsRead image;
		try {
			image = DbImage.getImageDetails(null, imageBaseId);
		} catch (TNotFoundException | SQLException e) {
			LOGGER.warn("Version Deleted for image=" + imageBaseId + " failed", e);
			return;
		}
		ImageVersionDetails oldVersion = null;
		ImageVersionDetails newVersion = null;
		for (ImageVersionDetails version : image.versions) {
			if (oldLocal != null && version.versionId.equals(oldLocal.imageVersionId)) {
				oldVersion = version;
			}
			if (newLocal != null && version.versionId.equals(newLocal.imageVersionId)) {
				newVersion = version;
			}
		}
		if (oldVersion == newVersion)
			return;
		String message = "Virtuelle Maschine '" + image.imageName + "':";
		if (newVersion == null) {
			message += " Die letzte verbliebene Version der VM wurde gelöscht; VM deaktiviert.";
		} else {
			String uploaderName;
			try {
				User uploader = DbUser.getCached(newVersion.uploaderId);
				uploaderName = Formatter.userFullName(uploader.ui) + " <" + uploader.ui.eMail + ">";
			} catch (TNotFoundException | SQLException e) {
				uploaderName = "(unbekannt)";
			}
			message += "\n  Neueste Version ist jetzt vom " + Formatter.date(newVersion.createTime)
					+ " (erstellt von " + uploaderName + ")";
			if (oldVersion != null) {
				message += "\n  Vorherige Verson war vom " + Formatter.date(oldVersion.createTime);
			}
		}
		List<UserInfo> relevantUsers = getUserToMail(image);
		for (UserInfo user : relevantUsers) {
			MailQueue.queue(new Mail(user, wordWrap(message)));
		}
	}

	public static void sendDeletionReminder(LocalImageVersion version, int days, boolean mailForced) {
		if (!hasMailConfig())
			return;
		ImageDetailsRead image;
		try {
			image = DbImage.getImageDetails(null, version.imageBaseId);
		} catch (TNotFoundException | SQLException e) {
			LOGGER.warn("Could not get image details for image version " + version.imageVersionId);
			return;
		}
		String message;
		if (image.latestVersionId == null || image.latestVersionId.equals(version.imageVersionId)) {
			message = "Die aktuellste Version der VM '" + image.imageName + "' läuft in " + days
					+ " Tag(en) ab. Bitte aktualisieren Sie die VM, da verknüpfte"
					+ " Veranstaltungen sonst deaktiviert werden.";
		} else if (mailForced) {
			message = "Eine alte Version der VM '" + image.imageName + "' läuft in " + days
					+ " Tag(en) ab (Version vom " + Formatter.date(version.createTime) + ")."
					+ " Eine aktuellere Version ist vorhanden, diese Nachricht dient nur der Information.";
		} else {
			return;
		}
		List<UserInfo> relevantUsers = getUserToMail(image);
		for (UserInfo user : relevantUsers) {
			MailQueue.queue(new Mail(user, wordWrap(message)));
		}
	}

	public static void sendEndDateRemainder(LectureSummary lecture, int days) {
		if (!hasMailConfig())
			return;
		List<UserInfo> relevantUsers = getUserToMail(lecture);
		String message = "Die Veranstaltung '" + lecture.lectureName + "' läuft in " + days + " Tag(en) ab.";
		for (UserInfo user : relevantUsers) {
			MailQueue.queue(new Mail(user, wordWrap(message)));
		}
	}

	public static boolean isValidMailConfig(MailConfig conf) {
		return conf != null && conf.port != 0 && !Util.isEmptyString(conf.host)
				&& !Util.isEmptyString(conf.senderAddress);
	}

	private static boolean hasMailConfig() {
		MailConfig conf;
		try {
			conf = DbConfiguration.getMailConfig();
		} catch (SQLException e) {
			return false;
		}
		return isValidMailConfig(conf);
	}

	private static List<UserInfo> getUserToMail(LectureSummary lecture) {
		Map<String, LecturePermissions> users;
		try {
			users = DbLecturePermissions.getForLecture(lecture.lectureId, false);
		} catch (SQLException e) {
			users = new HashMap<>();
		}
		users.put(lecture.ownerId, new LecturePermissions(true, true));
		List<UserInfo> list = new ArrayList<>(users.size());
		for (Entry<String, LecturePermissions> entry : users.entrySet()) {
			LecturePermissions perms = entry.getValue();
			if (!perms.admin && !perms.edit)
				continue;
			User user;
			try {
				user = DbUser.getCached(entry.getKey());
			} catch (TNotFoundException e) {
				LOGGER.warn("UserID " + entry.getKey() + " unknown");
				continue;
			} catch (SQLException e) {
				continue; // Logging happened in DbUser
			}
			if (user.local.emailNotifications) {
				list.add(user.ui);
			}
		}
		return list;
	}

	private static List<UserInfo> getUserToMail(ImageDetailsRead image) {
		Map<String, ImagePermissions> users;
		try {
			users = DbImagePermissions.getForImageBase(image.imageBaseId, false);
		} catch (SQLException e) {
			users = new HashMap<>();
		}
		users.put(image.ownerId, new ImagePermissions(true, true, true, true));
		List<UserInfo> list = new ArrayList<>(users.size());
		for (Entry<String, ImagePermissions> entry : users.entrySet()) {
			ImagePermissions perms = entry.getValue();
			if (!perms.admin && !perms.edit)
				continue;
			User user;
			try {
				user = DbUser.getCached(entry.getKey());
			} catch (TNotFoundException e) {
				LOGGER.warn("UserID " + entry.getKey() + " unknown");
				continue;
			} catch (SQLException e) {
				continue; // Logging happened in DbUser
			}
			if (user.local.emailNotifications) {
				list.add(user.ui);
			}
		}
		return list;
	}

	private static String wordWrap(String input) {
		return wordWrap(input, 76, "\n  ", Locale.GERMAN);
	}

	private static String wordWrap(String input, int width, String nlString, Locale locale) {
		if (input == null) {
			return "";
		} else if (width < 5) {
			return input;
		} else if (width >= input.length()) {
			return input;
		}

		StringBuilder buf = new StringBuilder(input);
		boolean endOfLine = false;
		int lineStart = 0;

		for (int i = 0; i < buf.length(); i++) {
			if (buf.charAt(i) == '\n') {
				lineStart = i + 1;
				endOfLine = true;
			}

			// handle splitting at width character
			if (i > lineStart + width - 1) {
				if (endOfLine) {
					buf.insert(i, nlString);
					lineStart = i + nlString.length();
					endOfLine = false;
				} else {
					int limit = i - lineStart - 1;
					BreakIterator breaks = BreakIterator.getLineInstance(locale);
					breaks.setText(buf.substring(lineStart, i));
					int end = breaks.last();

					// if the last character in the search string isn't a space,
					// we can't split on it (looks bad). Search for a previous
					// break character
					if (end == limit + 1) {
						if (!Character.isWhitespace(buf.charAt(lineStart + end))) {
							end = breaks.preceding(end - 1);
						}
					}

					// if the last character is a space, replace it with a \n
					if (end != BreakIterator.DONE && end == limit + 1) {
						buf.replace(lineStart + end, lineStart + end + 1, nlString.substring(0, 1));
						buf.insert(lineStart + end + 1, nlString.substring(1));
						lineStart = lineStart + end + nlString.length() - 1;
					}
					// otherwise, just insert a \n
					else if (end != BreakIterator.DONE && end != 0) {
						buf.insert(lineStart + end, nlString);
						lineStart = lineStart + end + nlString.length();
					} else {
						buf.insert(i, nlString);
						lineStart = i + nlString.length();
					}
				}
			}
		}

		return buf.toString();
	}

}