suumo-search

Perform advanced searches on Suumo.jp
git clone https://git.neuralcrash.com/suumo-search.git
Log | Files | Refs | README

EmailSender.java (5146B)


      1 package xyz.kebigon.housesearch.mail;
      2 
      3 import java.io.IOException;
      4 import java.util.Collection;
      5 import java.util.Properties;
      6 
      7 import javax.mail.Session;
      8 
      9 import org.apache.commons.mail.Email;
     10 import org.apache.commons.mail.EmailException;
     11 import org.apache.commons.mail.HtmlEmail;
     12 
     13 import xyz.kebigon.housesearch.HouseSearchApplication;
     14 import xyz.kebigon.housesearch.domain.Posting;
     15 import xyz.kebigon.housesearch.domain.Route;
     16 import xyz.kebigon.housesearch.domain.SearchConditions;
     17 
     18 public class EmailSender
     19 {
     20 	private static final String ONE_POSTING_TITLE = "[%1$s] %2$syo house found near %3$s station for %4$s万円";
     21 	private static final String SEVERAL_POSTINGS_TITLE = "[%1$s] %2$s houses found";
     22 
     23 	private final Session mailSession;
     24 
     25 	public EmailSender() throws IOException
     26 	{
     27 		final Properties mailProperties = new Properties();
     28 		mailProperties.load(HouseSearchApplication.class.getClassLoader().getResourceAsStream("mail.cfg"));
     29 		mailSession = Session.getInstance(mailProperties);
     30 	}
     31 
     32 	public void send(Collection<Posting> postings, SearchConditions conditions) throws EmailException
     33 	{
     34 		// Send email separately
     35 		if (postings.size() <= 3)
     36 		{
     37 			for (final Posting posting : postings)
     38 			{
     39 				final String title = String.format(ONE_POSTING_TITLE, conditions.getName(), posting.getAge(), posting.getStation(), posting.getPrice() / 10000);
     40 
     41 				final StringBuilder builder = new StringBuilder();
     42 				appendPosting(posting, builder);
     43 				send(title, builder.toString());
     44 			}
     45 		}
     46 		// Send one email with all results
     47 		else
     48 		{
     49 			final String title = String.format(SEVERAL_POSTINGS_TITLE, conditions.getName(), postings.size());
     50 
     51 			final StringBuilder builder = new StringBuilder();
     52 			for (final Posting posting : postings)
     53 				appendPosting(posting, builder);
     54 			send(title, builder.toString());
     55 		}
     56 	}
     57 
     58 	private void send(String title, String content) throws EmailException
     59 	{
     60 		final Email email = new HtmlEmail();
     61 		email.setMailSession(mailSession);
     62 		email.setSubject(title);
     63 		email.setCharset("UTF-8");
     64 		email.setMsg(content);
     65 
     66 		String from = mailSession.getProperty("housesearch.mail.from");
     67 		String to = mailSession.getProperty("housesearch.mail.to");
     68 		String bcc = mailSession.getProperty("housesearch.mail.bcc");
     69 
     70 		if (from != null && !(from = from.trim()).isEmpty())
     71 			email.setFrom(from);
     72 
     73 		if (to != null && !(to = to.trim()).isEmpty())
     74 			for (final String address : to.split(","))
     75 				email.addTo(address.trim());
     76 
     77 		if (bcc != null && !(bcc = bcc.trim()).isEmpty())
     78 			for (final String address : bcc.split(","))
     79 				email.addBcc(address.trim());
     80 
     81 		email.send();
     82 	}
     83 
     84 	private static void appendPosting(Posting posting, StringBuilder builder)
     85 	{
     86 		builder.append("<p><a href=\"").append(posting.getUrl()).append("\">");
     87 		builder.append(posting.getAge()).append("yo house near ").append(posting.getStation()).append(" station for ").append(posting.getPrice() / 10000)
     88 				.append("万円");
     89 		builder.append("</a>");
     90 		builder.append("<br>House surface: ").append(Math.round(posting.getHouseSurface())).append("m2 / ")
     91 				.append(Math.round(posting.getHouseSurface() * 0.3025)).append("坪");
     92 		builder.append("<br>Land surface: ").append(Math.round(posting.getLandSurface())).append("m2 / ").append(Math.round(posting.getLandSurface() * 0.3025))
     93 				.append("坪");
     94 
     95 		appendRoutes(posting, builder);
     96 
     97 		builder.append("</p>");
     98 	}
     99 
    100 	private static void appendRoutes(Posting posting, StringBuilder builder)
    101 	{
    102 		final Route fastestRoute = posting.getFastestRoute();
    103 		final Route cheapestRoute = posting.getCheapestRoute();
    104 		final Route easiestRoute = posting.getEasiestRoute();
    105 
    106 		// No route have been analyzed
    107 		if (fastestRoute == null && cheapestRoute == null && easiestRoute == null)
    108 			return;
    109 
    110 		builder.append("<br>Routes: ");
    111 
    112 		if (fastestRoute == cheapestRoute)
    113 			if (fastestRoute == easiestRoute)
    114 				appendRoute("Best", posting, fastestRoute, builder);
    115 			else
    116 			{
    117 				appendRoute("Fastest & Cheapest", posting, fastestRoute, builder);
    118 				appendRoute("Easiest", posting, easiestRoute, builder);
    119 			}
    120 		else if (fastestRoute == easiestRoute)
    121 		{
    122 			appendRoute("Fastest & Easiest", posting, fastestRoute, builder);
    123 			appendRoute("Cheapest", posting, cheapestRoute, builder);
    124 		}
    125 		else
    126 		{
    127 			appendRoute("Fastest", posting, fastestRoute, builder);
    128 
    129 			if (cheapestRoute == easiestRoute)
    130 				appendRoute("Cheapest & Easiest", posting, cheapestRoute, builder);
    131 			else
    132 			{
    133 				appendRoute("Cheapest", posting, cheapestRoute, builder);
    134 				appendRoute("Easiest", posting, easiestRoute, builder);
    135 			}
    136 		}
    137 	}
    138 
    139 	private static void appendRoute(String label, Posting property, Route route, StringBuilder builder)
    140 	{
    141 		if (route == null)
    142 			return;
    143 
    144 		builder.append("<br>- ").append(label).append(": ");
    145 		builder.append(route.getTime() + property.getWalkTimeToStation()).append("min to ").append(route.getTo());
    146 		builder.append(" (walk: ").append(property.getWalkTimeToStation()).append("min, train: ").append(route.getTime()).append("min)");
    147 		builder.append(" / ").append(route.getFare()).append("円");
    148 		builder.append(" / ").append(route.getTransfer()).append(" transfer");
    149 	}
    150 }