Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6a35fd6

Browse files
authoredJan 11, 2017
Merge pull request #15 from NUSComputingDev/develop
v0.1 First Working Version
2 parents a91dac1 + 583f5e0 commit 6a35fd6

17 files changed

+770
-1
lines changed
 

‎.classpath

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" path="src"/>
4+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
5+
<classpathentry kind="lib" path="lib/javax.mail.jar"/>
6+
<classpathentry kind="output" path="bin"/>
7+
</classpath>

‎.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
.mtj.tmp/
55

66
# Package Files #
7-
*.jar
87
*.war
98
*.ear
109

@@ -61,3 +60,9 @@ $RECYCLE.BIN/
6160

6261
# Windows shortcuts
6362
*.lnk
63+
/bin/
64+
65+
# private information
66+
privateinfo.txt
67+
sampleOut
68+
sample/sampleTest.html

‎.project

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>CompClubEmailBlast</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.jdt.core.javanature</nature>
16+
</natures>
17+
</projectDescription>

‎README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# CompClubEmailBlast #
2+
3+
`CompClubEmailBlast` is designed to automate the process of sending e-mail blast for NUS Computing Club. It uses the e-mail blast template for the Club.
4+
5+
There is no error checking, the inputs are assumed to be correct.
6+
7+
## Assumptions ##
8+
9+
The programme takes many assumptions. Some of them are:
10+
11+
1. The inputs are well formed as expected by the programme, there is no error checking done by the programme
12+
2. For every e-mail item, there's at least a title; the image, text, and link are optional
13+
3. The information on the no. of items, titles, and links must be available in `main.txt` in the folder that contains all the contents. Each item is listed in `main.txt` chronologically. A title is needed for each item while the link&link-text pair is optional
14+
4. Text files are named as `txti.html` where `i` is a number greater than or equal to `1`
15+
5. Image files are named as `imgi.html` where `i` is a number greater than or equal to `1`
16+
17+
## Email Template ##
18+
19+
The e-mail template can be viewed as consisting of the following:
20+
21+
1. Header
22+
2. Content Item(s), each with:
23+
* Title
24+
* Image(optional)
25+
* Text(optional)
26+
* Link(optional)
27+
3. Footer
28+
29+
## Dependencies ##
30+
31+
These dependencies are included in the programme
32+
33+
* JavaMail API (`https://java.net/projects/javamail/pages/Home`)
34+
35+
## Argument inputs for CCmailer ##
36+
37+
`CCmailer` takes in 5 arguments:
38+
* name of the file containing private info (either relative path or static path)
39+
* input folder containing the inputs (ending with "/")
40+
* output folder to write the output to (ending with "/")
41+
* name of the output html file (This html file will be placed in the output folder)
42+
* type of e-mail (either emailBlast or acadAdvisory)
43+
44+
## Sample Instructions ##
45+
46+
These steps will demonstrate the basic functionality of the programme using the sample files
47+
48+
1. update `samplePrivateInfo.txt` file with the required information
49+
2. remove `acadliaison-logo.png` from the sample folder unless you are test sending Academic Advisory
50+
3. Run `CCmailer` using the 5 arguments: `samplePrivateInfo.txt sample/ sample/ sampleTest.html emailBlast` using Eclipse IDE <b>OR</b> for manual compilation, follow these steps:
51+
1. run `compile.sh` which will compile the files in the folder `src`. If you can't run it, ensure that you have the execution rights for the file
52+
2. Change to the `src` folder
53+
3. run CCmailer with the classpath and the 5 arguments: For example, `java -cp ".:../lib/javax.mail.jar" CCmailer ../../samplePrivateinfo.txt ../sample/ ../sample/ sampleTest.html emailBlast`
54+
4. Check that you receive the sample e-mail
55+
5. The ouput html, `sampleTest.html`, is in the `sample/` folder
56+
57+
## Special Instructions ##
58+
59+
`java -cp ".:../lib/javax.mail.jar" CCmailer ../../privateinfo.txt ../../../Documents/2016.09.12/ ../../../Websites/newsletters.nuscomputing.com/2016/September/12/ index.html acadAdvisory`

‎compile.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
javac -classpath lib/javax.mail.jar src/*.java

‎lib/javax.mail.jar

589 KB
Binary file not shown.

‎sample/acadliaison-logo.png

27.3 KB
Loading

‎sample/compclub-logo.png

3.95 KB
Loading

‎sample/img1.png

28.3 KB
Loading

‎sample/img2.png

27.3 KB
Loading

‎sample/main.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
1
2+
title: Comp Club Message 1
3+
2
4+
title: Acad Advisory
5+
link: http://nuscomputing.com
6+
link-text: Find out more about our club here!

‎sample/txt1.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>The text is prepared in <b>html</b> format</p>

‎sample/txt2.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<p><i>HELLO WORLD!</i></p>
2+
<p>I am the second message!</p>

‎samplePrivateInfo.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
host: email_host_server
2+
username: sender_email_username
3+
password: sender_email_password
4+
to: recipient_email_address
5+
to-name: recipient_name
6+
cc: cc_email_address_remove_entire_line_if_not_needed
7+
bcc: bcc_email_address_remove_entire_line_if_not_needed
8+
reply-to: reply_to_email_address_remove_entire_line_if_not_needed
9+
reply-to-name: reply_to_name_address_remove_entire_line_if_not_needed
10+
from: sender_email_address
11+
from-name: sender_name

‎src/CCmailer.java

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
import java.io.BufferedReader;
2+
import java.io.FileInputStream;
3+
import java.io.IOException;
4+
import java.io.InputStreamReader;
5+
import java.io.UnsupportedEncodingException;
6+
import java.util.ArrayList;
7+
import java.util.HashMap;
8+
import java.util.Properties;
9+
10+
import javax.mail.BodyPart;
11+
import javax.mail.Message;
12+
import javax.mail.MessagingException;
13+
import javax.mail.Session;
14+
import javax.mail.Transport;
15+
import javax.mail.internet.AddressException;
16+
import javax.mail.internet.InternetAddress;
17+
import javax.mail.internet.MimeBodyPart;
18+
import javax.mail.internet.MimeMessage;
19+
import javax.mail.internet.MimeMultipart;
20+
21+
/**
22+
* <p>
23+
* Reads in the required files and send an e-mail based on the template in used
24+
* for Computing Club's e-mail blast
25+
* </p>
26+
* <p>
27+
* <b>Main References:</b><br>
28+
* http://stackoverflow.com/questions/46663/how-can-i-send-an-email-
29+
* by-java-application-using-gmail-yahoo-or-hotmail<br>
30+
* http://www.tutorialspoint.com
31+
* /javamail_api/javamail_api_send_inlineimage_in_email.htm<br>
32+
* http://www.codejava.net/java-ee/javamail/embedding-images-into-e-mail-with-
33+
* javamail
34+
* </p>
35+
*/
36+
public class CCmailer {
37+
38+
private static final String MSG_WRONG_TYPE =
39+
"You have indicated: %s, please indicate either %s or %s";
40+
private static final String MSG_EMAIL_SELECTED = "You have selected %s";
41+
private static final String FLAG_EMAIL_BLAST = "emailBlast";
42+
private static final String FLAG_ACAD_ADVISORY = "acadAdvisory";
43+
44+
private static final String SERVER_CONNECTED = "Mail server connected";
45+
private static final String SERVER_CONNECTING =
46+
"Attempting to connect to the mail server";
47+
private static final String EMAIL_SENT = "Your email is sent!";
48+
49+
private static final String EMAIL_SEND = "You are sending from: %s (%s)";
50+
private static final String EMAIL_TO = "You are sending to: %s (%s)";
51+
private static final String EMAIL_CC = "You are cc-ing: %s";
52+
private static final String EMAIL_BCC = "You are bcc-ing: %s";
53+
private static final String EMAIL_REPLY_TO = "They will reply to: %s (%s)";
54+
55+
private String privateInfoFile;
56+
private String folderPath;
57+
private String outputPath;
58+
private String outputName;
59+
private String emailType;
60+
61+
private HashMap<String, String> infoMap = new HashMap<String, String>();
62+
63+
private ArrayList<InternetAddress> to = new ArrayList<InternetAddress>();
64+
private ArrayList<InternetAddress> cc = new ArrayList<InternetAddress>();
65+
private ArrayList<InternetAddress> bcc = new ArrayList<InternetAddress>();
66+
private ArrayList<InternetAddress> replyTo =
67+
new ArrayList<InternetAddress>();
68+
69+
private BufferedReader bufferedInput;
70+
71+
private HtmlGenerator htmlGenerator;
72+
73+
/**
74+
* register the paths to the various files needed
75+
*
76+
* @param privateInfoFile
77+
* the file containing all the private information
78+
*
79+
* @param folderPath
80+
* the folder containing all the email items
81+
*
82+
* @param outputPath
83+
* the folder to put the generate html file (does not need to be
84+
* existing)
85+
*
86+
* @param outputName
87+
* the name of the html file to be generated
88+
*
89+
* @param emailType
90+
* emailBlast or acadAdvisory
91+
*/
92+
public CCmailer(String privateInfoFile, String folderPath,
93+
String outputPath, String outputName, String emailType) {
94+
this.privateInfoFile = privateInfoFile;
95+
this.folderPath = folderPath;
96+
this.outputPath = outputPath;
97+
this.outputName = outputName;
98+
this.emailType = emailType;
99+
htmlGenerator = HtmlGenerator.getInstance();
100+
}
101+
102+
/**
103+
* open the privateInfoFile and read the inputs into a hashmap for
104+
* subsequent use
105+
*
106+
* @throws IOException
107+
* when the file cannot be reached
108+
*/
109+
public void readPrivateInfo() throws IOException {
110+
bufferedInput =
111+
new BufferedReader(new InputStreamReader(new FileInputStream(
112+
privateInfoFile)));
113+
String line;
114+
int colonIndex;
115+
while ((line = bufferedInput.readLine()) != null) {
116+
colonIndex = line.indexOf(": ");
117+
infoMap.put(line.substring(0, colonIndex),
118+
line.substring(colonIndex + 2, line.length()));
119+
}
120+
bufferedInput.close();
121+
}
122+
123+
/**
124+
* Assumes successful call to readPrivateInfo()<br>
125+
* Uses the private information given to build up the e-mail addresses
126+
* involved in this e-mail<br>
127+
* The addresses include:
128+
* <ol>
129+
* <li>Recipient's address</li>
130+
* <li>CC</li>
131+
* <li>BCC</li>
132+
* <li>Reply-to</li>
133+
* </ol>
134+
*
135+
* @throws UnsupportedEncodingException
136+
* @throws AddressException
137+
*/
138+
public void populateEmailAddresses() throws UnsupportedEncodingException,
139+
AddressException {
140+
if (infoMap.containsKey("to")) {
141+
to.add(new InternetAddress(infoMap.get("to"), infoMap
142+
.get("to-name")));
143+
System.out.println(String.format(EMAIL_TO,
144+
infoMap.get("to-name"), infoMap.get("to")));
145+
}
146+
if (infoMap.containsKey("cc")) {
147+
cc.add(new InternetAddress(infoMap.get("cc")));
148+
System.out.println(String.format(EMAIL_CC, infoMap.get("cc")));
149+
}
150+
if (infoMap.containsKey("bcc")) {
151+
bcc.add(new InternetAddress(infoMap.get("bcc")));
152+
System.out.println(String.format(EMAIL_BCC, infoMap.get("bcc")));
153+
}
154+
if (infoMap.containsKey("reply-to")) {
155+
replyTo.add(new InternetAddress(infoMap.get("reply-to"), infoMap
156+
.get("reply-to-name")));
157+
System.out.println(String.format(EMAIL_REPLY_TO,
158+
infoMap.get("reply-to-name"), infoMap.get("reply-to")));
159+
}
160+
}
161+
162+
private void setEmailAddresses(MimeMessage message)
163+
throws MessagingException, UnsupportedEncodingException {
164+
InternetAddress internetAddressArray[] = {};
165+
if (infoMap.containsKey("from")) {
166+
message.setFrom(new InternetAddress(infoMap.get("from"), infoMap
167+
.get("from-name")));
168+
System.out.println(String.format(EMAIL_SEND,
169+
infoMap.get("from-name"), infoMap.get("from")));
170+
}
171+
if (!to.isEmpty()) {
172+
message.setRecipients(Message.RecipientType.TO,
173+
to.toArray(internetAddressArray));
174+
}
175+
if (!cc.isEmpty()) {
176+
message.setRecipients(Message.RecipientType.CC,
177+
cc.toArray(internetAddressArray));
178+
}
179+
if (!bcc.isEmpty()) {
180+
message.setRecipients(Message.RecipientType.BCC,
181+
bcc.toArray(internetAddressArray));
182+
}
183+
if (!replyTo.isEmpty()) {
184+
message.setReplyTo(replyTo.toArray(internetAddressArray));
185+
}
186+
}
187+
188+
private MimeMultipart generateHtml() throws MessagingException, IOException {
189+
MimeMultipart multipart = new MimeMultipart("related");
190+
BodyPart messageBodyPart = new MimeBodyPart();
191+
192+
String htmlText =
193+
htmlGenerator.generateHtml(folderPath, outputPath, outputName,
194+
emailType);
195+
196+
messageBodyPart.setContent(htmlText, "text/html");
197+
multipart.addBodyPart(messageBodyPart);
198+
199+
htmlGenerator.writeHtml(outputPath, outputName, htmlText);
200+
201+
return multipart;
202+
}
203+
204+
/**
205+
* Assumes successful call to readPrivateInfo() and populateEmailAddresses()<br>
206+
* Send an e-mail to the addresses given in the following steps:
207+
* <ol>
208+
* <li>Set the e-mail addresses from the populated list</li>
209+
* <li>Generate the html content through the class HtmlGenerator</li>
210+
* <li>Set the subject for the e-mail</li>
211+
* <li>Connect to the e-mail server</li>
212+
* <li>Send the e-mail</li>
213+
* </ol>
214+
*
215+
* @throws MessagingException
216+
* @throws IOException
217+
*/
218+
public void sendEmail() throws MessagingException, IOException {
219+
Properties properties = System.getProperties();
220+
221+
properties.put("mail.smtp.starttls.enable", "true");
222+
223+
Session session = Session.getInstance(properties);
224+
MimeMessage message = new MimeMessage(session);
225+
226+
setEmailAddresses(message);
227+
228+
message.setContent(generateHtml());
229+
message.setSubject(htmlGenerator.getTitles());
230+
231+
System.out.println(SERVER_CONNECTING);
232+
Transport transport = session.getTransport("smtp");
233+
transport.connect(infoMap.get("host"), infoMap.get("username"),
234+
infoMap.get("password"));
235+
System.out.println(SERVER_CONNECTED);
236+
transport.sendMessage(message, message.getAllRecipients());
237+
System.out.println(EMAIL_SENT);
238+
transport.close();
239+
}
240+
241+
/**
242+
*
243+
* @param args
244+
* <ol>
245+
* <li>the file containing all the private information</li>
246+
* <li>the folder containing all the email items</li>
247+
* <li>the folder to put the generate html file (does not need to
248+
* be existing)</li>
249+
* <li>the name of the html file to be generated</li>
250+
* </ol>
251+
*
252+
* @throws IOException
253+
*/
254+
public static void main(String[] args) {
255+
256+
if (!args[4].equals(FLAG_EMAIL_BLAST)
257+
&& !args[4].equals(FLAG_ACAD_ADVISORY)) {
258+
System.out.println(String.format(MSG_WRONG_TYPE, args[4],
259+
FLAG_EMAIL_BLAST, FLAG_ACAD_ADVISORY));
260+
} else {
261+
System.out.println(String.format(MSG_EMAIL_SELECTED, args[4]));
262+
CCmailer ccMailer = new CCmailer(args[0], args[1], args[2], args[3],
263+
args[4]);
264+
try {
265+
ccMailer.readPrivateInfo();
266+
ccMailer.populateEmailAddresses();
267+
ccMailer.sendEmail();
268+
} catch (Exception exception) {
269+
exception.printStackTrace();
270+
}
271+
}
272+
}
273+
}

‎src/HtmlConstants.java

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
public final class HtmlConstants {
2+
public static final String OPENING =
3+
"<html>\n"
4+
+ " <head>\n"
5+
+ " <meta http-equiv=\"content-type\" content=\"text/html; "
6+
+ "charset=UTF-8\">\n"
7+
+ " </head>\n"
8+
+ " <body bgcolor=\"#FFFFFF\" text=\"#000000\">\n"
9+
+ " <br>\n"
10+
+ " <div>\n"
11+
+ " <div>\n"
12+
+ " <center>\n"
13+
+ " <div style=\"word-wrap:break-word\">\n"
14+
+ " <table style=\"border:none;width:600px;color:"
15+
+ "rgb(85,85,85);font-family:Optima,\'Trebuchet MS\',sans-serif\" "
16+
+ "border=\"0\" width=\"600\">\n"
17+
+ " <tbody>\n"
18+
+ " <tr>\n"
19+
+ " <td style=\"padding:10px 20px;vertical-align:"
20+
+ "middle;width:auto;text-align:center;font-size:9pt;margin:0px\""
21+
+ ">Having trouble reading this? View it in your browser "
22+
+ "<a href=\"%s\">here</a>!</td>\n"
23+
+ " </tr>\n"
24+
+ " <tr>\n"
25+
+ " <td style=\"padding:10px 20px;vertical-align:"
26+
+ "top;width:auto;text-align:justify;font-size:10pt\">";
27+
public static final String AFTER_DATE =
28+
"</td>\n"
29+
+ " </tr>\n"
30+
+ " <tr>\n"
31+
+ " <td style=\"padding:10px 20px;vertical-align:"
32+
+ "middle;width:auto;text-align:justify;font-size:26pt;margin:0px\""
33+
+ "><img src=\"http://newsletters.nuscomputing.com/compclub-logo.png"
34+
+ "\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
35+
+ "&nbsp;&nbsp;%s</td>\n"
36+
+ " </tr>\n"
37+
+ " </tbody>\n"
38+
+ " </table>\n";
39+
public static final String ACAD_LOGO =
40+
" <div style=\"width:556px;min-height:10px;"
41+
+ "text-align:center;vertical-align:middle;background-repeat:"
42+
+ "initial initial\"><img src=\"http://newsletters.nuscomputing.com/"
43+
+ "acadliaison-logo.png\"></div>\n";
44+
public static final String CONTENT_START =
45+
" <table style=\"border:none;width:600px;table-layout"
46+
+ ":fixed;color:rgb(85,85,85);font-family:Optima,'Trebuchet MS',"
47+
+ "sans-serif\" border=\"0\" width=\"600\">\n"
48+
+ " <tbody>\n"
49+
+ " <tr>\n"
50+
+ " <td style=\"padding:10px 20px;vertical-align:"
51+
+ "top;width:auto;text-align:justify;font-size:12pt\">\n";
52+
public static final String CONTENT_TITLE =
53+
" <p style=\"text-align:center;color:rgb"
54+
+ "(17,17,17);font-size:24pt;margin:10px 0px\">%s</p>\n";
55+
public static final String CONTENT_IMG =
56+
" <div style=\"width:556px;min-height:10px;"
57+
+ "text-align:center;vertical-align:middle;background-repeat:"
58+
+ "initial initial\"><img src=\"%s\"></div>\n";
59+
public static final String CONTENT_LINK =
60+
" <div style=\"text-align:right;font-size:20px"
61+
+ "\"><a href=\"%s\">%s &rarr;</a></div>\n";
62+
public static final String CONTENT_END =
63+
" </td>\n"
64+
+ " </tr>\n"
65+
+ " </tbody>\n"
66+
+ " </table>\n";
67+
public static final String SPONSOR_TITLE =
68+
" <table style=\"border:none;width:600px;color:rgb"
69+
+ "(85,85,85);font-family:Optima,'Trebuchet MS',sans-serif\" "
70+
+ "border=\"0\" width=\"600\">\n"
71+
+ " <tbody>\n"
72+
+ " <tr>\n"
73+
+ " <td style=\"padding:10px 20px;vertical"
74+
+ "-align:middle;width:auto;text-align:justify;font-size:26pt;"
75+
+ "margin:0px\">&nbsp;Other Events and Promotions</td>\n"
76+
+ " </tr>\n"
77+
+ " </tbody>\n"
78+
+ " </table>\n";
79+
public static final String ENDING =
80+
" <table style=\"border:none;width:600px;color:rgb"
81+
+ "(85,85,85);font-family:Optima,'Trebuchet MS',sans-serif\" "
82+
+ "border=\"0\" width=\"600\">\n"
83+
+ " <tbody>\n"
84+
+ " <tr>\n"
85+
+ " <td style=\"padding:10px 20px;vertical-align:"
86+
+ "top;width:auto;text-align:justify;font-size:12pt\">\n"
87+
+ " <p style=\"color:rgb(17,17,17);font-size:"
88+
+ "24pt;margin:10px 0px\">Contact Us</p>\n"
89+
+ " <p style=\"font-size:20pt;margin:10px 0px\">"
90+
+ "NUS Students' Computing Club</p>\n"
91+
+ " <p style=\"font-size:10pt;margin:10px 0px\">"
92+
+ "A Constituent Club of the NUS Students' Union</p>\n"
93+
+ " <p>COM1 02-14, 13 Computing Drive, Singapore"
94+
+ " 117417</p>\n"
95+
+ " <p>Website: <a href=\"http://nuscomputing."
96+
+ "com\" style=\"color:rgb(34,118,244);text-decoration:none\">"
97+
+ "nuscomputing.com</a><br>\n"
98+
+ " Facebook: <a href=\"http://fb.com/"
99+
+ "nuscomputing\" style=\"color:rgb(34,118,244);text-decoration:"
100+
+ "none\">fb.com/nuscomputing</a><br>\n"
101+
+ " Instagram: <a href=\"http://instagr.am/"
102+
+ "nuscomputingclub\" style=\"color:rgb(34,118,244);text-decoration:"
103+
+ "none\">instagr.am/nuscomputingclub</a><br>\n"
104+
+ " E-mail: <a href=\"mailto:connect@nuscomputing"
105+
+ ".com\" style=\"color:rgb(34,118,244);text-decoration:none\" "
106+
+ "target=\"_blank\">connect@nuscomputing.com</a>\n"
107+
+ " </p>\n"
108+
+ " </td>\n"
109+
+ " </tr>\n"
110+
+ " </tbody>\n"
111+
+ " </table>\n"
112+
+ " </div>\n"
113+
+ " </center>\n"
114+
+ " </div>\n"
115+
+ " <br>\n"
116+
+ " </div>\n"
117+
+ " <br>\n"
118+
+ " <br>\n"
119+
+ " </body>\n"
120+
+ "</html>\n";
121+
}

‎src/HtmlGenerator.java

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
import java.io.BufferedReader;
2+
import java.io.BufferedWriter;
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.FileOutputStream;
6+
import java.io.IOException;
7+
import java.io.InputStreamReader;
8+
import java.io.OutputStreamWriter;
9+
import java.nio.file.Files;
10+
import java.nio.file.Path;
11+
import java.nio.file.Paths;
12+
import java.text.DateFormat;
13+
import java.text.SimpleDateFormat;
14+
import java.util.Date;
15+
16+
/**
17+
* <p>
18+
* class HtmlGenerator generates the complete html file using the Email blast
19+
* template.
20+
* </p>
21+
*/
22+
public class HtmlGenerator {
23+
24+
private static final String ACAD_ADVISORY = "Academic Advisory";
25+
private static final String CC_NEWSLETTER = "Computing Club Newsletter";
26+
27+
private static final String TITLE_PREFIX_CC = "[Comp Club] ";
28+
private static final String TITLE_PREFIX_AA = "[Acad Advisory] ";
29+
private static final String MAIN_TXT = "main.txt";
30+
31+
private static final String FLAG_EMAIL_BLAST = "emailBlast";
32+
private static final String FLAG_ACAD_ADVISORY = "acadAdvisory";
33+
34+
private static HtmlGenerator theHtmlGenerator;
35+
36+
private BufferedWriter bufferedOutput;
37+
private BufferedReader bufferedInput;
38+
39+
private String titles;
40+
41+
private HtmlGenerator() {
42+
}
43+
44+
/**
45+
* @return HtmlGenerator object (Singleton)
46+
*/
47+
public static HtmlGenerator getInstance() {
48+
if (theHtmlGenerator == null) {
49+
theHtmlGenerator = new HtmlGenerator();
50+
}
51+
return theHtmlGenerator;
52+
}
53+
54+
private String getDate() {
55+
DateFormat dateFormat = new SimpleDateFormat("dd MMMM YYYY");
56+
Date date = new Date();
57+
return dateFormat.format(date);
58+
}
59+
60+
private String setContentEndAndStart(String html, char index) {
61+
if (index != '1') {
62+
// indicates that the previous item has ended, except when it's the
63+
// first item
64+
html += HtmlConstants.CONTENT_END;
65+
}
66+
html += HtmlConstants.CONTENT_START;
67+
return html;
68+
}
69+
70+
private String setTitle(String title, int index, boolean isSponsor) {
71+
if (!isSponsor) {
72+
if (index != 1) {
73+
titles += " | ";
74+
}
75+
titles += title;
76+
}
77+
return String.format(HtmlConstants.CONTENT_TITLE, title);
78+
}
79+
80+
private String setImage(String folderPath, String outputPath, int index)
81+
throws IOException {
82+
if ((new File(folderPath + "img" + index + ".png")).exists()) {
83+
Path source = Paths.get(folderPath).resolve("img" + index + ".png");
84+
Files.copy(source,
85+
Paths.get(outputPath + "contents/").resolve(source.getFileName()),
86+
java.nio.file.StandardCopyOption.REPLACE_EXISTING);
87+
int urlStart = outputPath.indexOf("newsletters.nuscomputing.com");
88+
return String.format(HtmlConstants.CONTENT_IMG, "http://"
89+
+ outputPath.substring(urlStart, outputPath.length())
90+
+ "contents/img" + index + ".png");
91+
}
92+
return "";
93+
}
94+
95+
private String setText(String folderPath, int index) {
96+
if ((new File(folderPath + "txt" + index + ".html")).exists()) {
97+
return "txt" + index;
98+
}
99+
return "";
100+
}
101+
102+
private String setLink(String html, String link) throws IOException {
103+
String linkText = bufferedInput.readLine();
104+
return String.format(HtmlConstants.CONTENT_LINK, link,
105+
linkText.substring(11, linkText.length()));
106+
}
107+
108+
private String updateTexts(String folderPath, String html, int index)
109+
throws IOException {
110+
String line;
111+
for (int i = 1; i < index; i++) {
112+
if (html.contains("txt" + i)) {
113+
String text = "";
114+
bufferedInput =
115+
new BufferedReader(new InputStreamReader(
116+
new FileInputStream(folderPath + "txt" + i
117+
+ ".html")));
118+
while ((line = bufferedInput.readLine()) != null) {
119+
text += " " + line + "\n";
120+
}
121+
bufferedInput.close();
122+
html = html.replace("txt" + i, text);
123+
}
124+
}
125+
return html;
126+
}
127+
128+
private String generateContent(String folderPath, String outputPath,
129+
String emailType) throws IOException {
130+
String html = "";
131+
132+
if (emailType.equals(FLAG_EMAIL_BLAST)) {
133+
titles = TITLE_PREFIX_CC;
134+
} else if (emailType.equals(FLAG_ACAD_ADVISORY)) {
135+
titles = TITLE_PREFIX_AA;
136+
}
137+
138+
bufferedInput =
139+
new BufferedReader(new InputStreamReader(new FileInputStream(
140+
folderPath + MAIN_TXT)));
141+
String line;
142+
char index = '1';
143+
boolean isSponsor = false;
144+
while ((line = bufferedInput.readLine()) != null) {
145+
if (line.charAt(0) == index) {
146+
html = setContentEndAndStart(html, index);
147+
index++;
148+
} else if (line.contains("title: ")) {
149+
html += setTitle(line.substring(7, line.length()),
150+
index - '1', isSponsor);
151+
html += setImage(folderPath, outputPath, index - '1');
152+
html += setText(folderPath, index - '1');
153+
} else if (line.equals("Sponsor")) {
154+
html += HtmlConstants.CONTENT_END;
155+
html += HtmlConstants.SPONSOR_TITLE;
156+
html += HtmlConstants.CONTENT_START;
157+
isSponsor = true;
158+
} else {
159+
html += setLink(html, line.substring(6, line.length()));
160+
}
161+
}
162+
html += HtmlConstants.CONTENT_END;
163+
bufferedInput.close();
164+
165+
html = updateTexts(folderPath, html, index - '0');
166+
167+
return html;
168+
}
169+
170+
/**
171+
* generate the html file using the files available in the given folder<br>
172+
* The file "main.txt" is needed in the folder to indicate the no. of items<br>
173+
* The method then generates the html file based on the no. of individual
174+
* components of each item available
175+
*
176+
* @param folderPath
177+
* The path to the folder where the contents are
178+
* @param outputPath
179+
* The path to the folder to be created where the output file
180+
* will be written to
181+
* @param outputName
182+
* The name of the output file
183+
* @return the html string representing the expected html file
184+
*
185+
* @throws IOException
186+
* If the files are not readable
187+
*/
188+
public String generateHtml(String folderPath, String outputPath,
189+
String outputName, String emailType) throws IOException {
190+
String html = "";
191+
File files = new File(outputPath);
192+
files.mkdirs();
193+
files = new File(outputPath + "contents/");
194+
files.mkdirs();
195+
int urlStart = outputPath.indexOf("newsletters.nuscomputing.com");
196+
String indexUrl = "http://" + outputPath.substring(urlStart,
197+
outputPath.length()) + outputName;
198+
html += String.format(HtmlConstants.OPENING, indexUrl);
199+
html += getDate();
200+
if (emailType.equals(FLAG_EMAIL_BLAST)) {
201+
html += String.format(HtmlConstants.AFTER_DATE, CC_NEWSLETTER);
202+
} else if (emailType.equals(FLAG_ACAD_ADVISORY)) {
203+
html += String.format(HtmlConstants.AFTER_DATE, ACAD_ADVISORY);
204+
html += HtmlConstants.CONTENT_START;
205+
html += HtmlConstants.ACAD_LOGO;
206+
html += HtmlConstants.CONTENT_END;
207+
}
208+
html += generateContent(folderPath, outputPath, emailType);
209+
html += HtmlConstants.ENDING;
210+
211+
return html;
212+
}
213+
214+
/**
215+
* Replaces all inline images code to the relative variables and write the
216+
* html file
217+
*
218+
* @param outputPath
219+
* The path to the folder to be created where the output file
220+
* will be written to
221+
* @param outputName
222+
* The name of the output file
223+
* @param html
224+
* The generated html file
225+
* @throws FileNotFoundException
226+
* @throws IOException
227+
*/
228+
public void writeHtml(String outputPath, String outputName, String html)
229+
throws IOException {
230+
bufferedOutput =
231+
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
232+
outputPath + outputName)));
233+
bufferedOutput.write(html);
234+
bufferedOutput.close();
235+
int urlStart = outputPath.indexOf("newsletters.nuscomputing.com");
236+
bufferedOutput =
237+
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
238+
outputPath.substring(0, urlStart
239+
+ "newsletters.nuscomputing.com/".length())
240+
+ outputName)));
241+
bufferedOutput.write(html);
242+
bufferedOutput.close();
243+
}
244+
245+
/**
246+
* Assumes that generateHtml ran successfully
247+
*
248+
* @return String of titles from the items
249+
*/
250+
public String getTitles() {
251+
return titles;
252+
}
253+
254+
public static void main(String[] args) {
255+
HtmlGenerator htmlGenerator = new HtmlGenerator();
256+
try {
257+
String generatedHTML =
258+
htmlGenerator.generateHtml("sample/", "sampleOut/",
259+
"out.html", "emailBlast");
260+
System.out.println(generatedHTML);
261+
} catch (IOException e) {
262+
e.printStackTrace();
263+
}
264+
}
265+
266+
}

0 commit comments

Comments
 (0)
Please sign in to comment.