texmailer 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +339 -0
- data/README +24 -0
- data/bin/texmailer +70 -0
- data/lib/texmailer/ca-bundle.crt +4599 -0
- data/lib/texmailer/config.rb +75 -0
- data/lib/texmailer/drafts.rb +172 -0
- data/lib/texmailer/rhtml/blankprev.html +4 -0
- data/lib/texmailer/rhtml/drafts.html +82 -0
- data/lib/texmailer/rhtml/header.html +24 -0
- data/lib/texmailer/rhtml/index.html +125 -0
- data/lib/texmailer/rhtml/send.html +50 -0
- data/lib/texmailer/rhtml/settings.html +62 -0
- data/lib/texmailer/send.rb +150 -0
- data/lib/texmailer/wapp.rb +38 -0
- metadata +104 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
module Texmailer
|
2
|
+
|
3
|
+
def loadparams
|
4
|
+
p = Hash.new
|
5
|
+
params = [['from',0],['mailfrom', 0],['host', 0],['port', 0],['ssl', 1],['igcert', 1],['auth', 1],['user', 0],['pass', 0]]
|
6
|
+
fnm = $userdir + '/smtp.cfg'
|
7
|
+
|
8
|
+
if File.readable? fnm
|
9
|
+
lns = IO.readlines(fnm)
|
10
|
+
(1..((lns.length < params.length) ? lns.length : params.length)).each {|i|
|
11
|
+
p[params[i-1][0]] = lns[i-1].sub(/\n/m,'')
|
12
|
+
}
|
13
|
+
end
|
14
|
+
p.inspect
|
15
|
+
params.each { |x| p[x[0]] ||= '' }
|
16
|
+
params.each { |x| p[x[0]] == 'false' if x[1] == 1 && p[x[0]] != 'true' }
|
17
|
+
return p
|
18
|
+
end
|
19
|
+
|
20
|
+
def saveparams req
|
21
|
+
fnm = $userdir + '/smtp.cfg'
|
22
|
+
params = [['from',0],['mailfrom', 0],['host', 0],['port', 0],['ssl', 1],['igcert', 1],['auth', 1],['user', 0],['pass', 0]]
|
23
|
+
|
24
|
+
File.open(fnm,'w',0600) { |f|
|
25
|
+
params.each { |x|
|
26
|
+
d = req[x[0]] if x[1] == 0 && req[x[0]]
|
27
|
+
d = 'true' if x[1] == 1 && req[x[0]]
|
28
|
+
d ||= '' if x[1] == 0
|
29
|
+
d ||= 'false'
|
30
|
+
f.write d+"\n"
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def makerc
|
36
|
+
p = loadparams
|
37
|
+
fnm = $userdir + '/msmtprc'
|
38
|
+
File.open(fnm,'w',0600) { |f|
|
39
|
+
f.write "account default\ntimeout 15\nauto_from off\n"
|
40
|
+
f.write "from \"#{p["mailfrom"]}\"\n"
|
41
|
+
f.write "host #{p["host"]}\n"
|
42
|
+
f.write "port #{p["port"]}\n"
|
43
|
+
f.write "auth on\nuser #{p["user"]}\npassword #{p["pass"]}\n" if p["auth"] == "true"
|
44
|
+
if p["ssl"] == "true" then
|
45
|
+
f.write "tls on\n"
|
46
|
+
if p["igcert"] == "true" then
|
47
|
+
f.write "tls_certcheck off\n"
|
48
|
+
else
|
49
|
+
f.write "tls_certcheck on\n"
|
50
|
+
f.write "tls_trust_file #{$basedir}/ca-bundle.crt\n"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
}
|
54
|
+
return fnm
|
55
|
+
end
|
56
|
+
|
57
|
+
def msmtp(req,message)
|
58
|
+
fnm = makerc
|
59
|
+
pr = loadparams
|
60
|
+
IO.popen("msmtp -C #{fnm} -t 2> #{$userdir}/msmtplog","w") { |p|
|
61
|
+
[ ["To:","mailto"],["CC:","mailcc"],["BCC:","mailbcc"],["Subject:","subject"] ].each { |x|
|
62
|
+
if req[x[1]] && req[x[1]].length > 0 then
|
63
|
+
p.write x[0] + " " + req[x[1]].gsub(/\n/m,'') + "\n"
|
64
|
+
end
|
65
|
+
}
|
66
|
+
if pr["from"].length > 0 then
|
67
|
+
p.write "From: #{pr["from"]} <#{pr["mailfrom"]}>\n"
|
68
|
+
end
|
69
|
+
p.write message
|
70
|
+
}
|
71
|
+
return true,"E-mail Sent" if $? == 0
|
72
|
+
return false, "<pre>\n"+File.read($userdir+'/msmtplog')+"\n</pre>" if File.readable? $userdir+'/msmtplog'
|
73
|
+
return false, 'Error running msmtp.'
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module Texmailer
|
4
|
+
|
5
|
+
def savedraft(mailid,req)
|
6
|
+
svdir = $userdir + '/drafts/'+mailid
|
7
|
+
if ! File.directory? svdir
|
8
|
+
Dir.mkdir(svdir)
|
9
|
+
end
|
10
|
+
["mailto","mailcc","mailbcc","subject","body"].each { |s|
|
11
|
+
File.open(svdir+'/'+s,"w") { |f| f.write req[s] }
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def getpvloc(mailid)
|
16
|
+
pvlnk = '/preview/' + mailid + '/t.html'
|
17
|
+
return pvlnk if File.readable? $userdir+pvlnk
|
18
|
+
return '/blankprev.html'
|
19
|
+
end
|
20
|
+
|
21
|
+
def preview(mailid,req)
|
22
|
+
pvdir = $userdir + '/preview/' + mailid
|
23
|
+
if ! File.directory? pvdir
|
24
|
+
Dir.mkdir(pvdir)
|
25
|
+
end
|
26
|
+
|
27
|
+
s = <<EOF
|
28
|
+
\\documentclass{article}
|
29
|
+
\\usepackage{amsmath,amssymb}
|
30
|
+
\\setlength{\\parindent}{0in}
|
31
|
+
\\begin{document}
|
32
|
+
#{req["body"]}
|
33
|
+
\\end{document}
|
34
|
+
EOF
|
35
|
+
File.open(pvdir + '/t.tex','w') { |f| f.write s}
|
36
|
+
Dir.chdir(pvdir);
|
37
|
+
|
38
|
+
if system('latex -interaction=nonstopmode t > ltxrun.txt 2>/dev/null')
|
39
|
+
system('htlatex t > /dev/null 2>/dev/null')
|
40
|
+
return true
|
41
|
+
else
|
42
|
+
emsg = File.read(pvdir+'/ltxrun.txt');
|
43
|
+
s = "<html><body><h1>Latex Error</h1><br><pre>\n" + emsg + "\n</pre></body></html>";
|
44
|
+
File.open(pvdir + '/t.html','w') {|f| f.write s}
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def loaddraft(mailid)
|
50
|
+
svdir = $userdir + '/drafts/'+mailid
|
51
|
+
a = Array.new
|
52
|
+
["mailto","mailcc","mailbcc","subject","body"].each { |s|
|
53
|
+
fname = svdir+'/'+s
|
54
|
+
a.push File.readable?(fname) ? File.read(fname) : ""
|
55
|
+
}
|
56
|
+
return a[0],a[1],a[2],a[3],a[4]
|
57
|
+
end
|
58
|
+
|
59
|
+
def discarddraft(mailid)
|
60
|
+
svdir = $userdir + '/drafts/'+mailid
|
61
|
+
if File.directory? svdir
|
62
|
+
lst = Dir[svdir+'/*'];
|
63
|
+
lst.each {|f| File.delete(f)}
|
64
|
+
Dir.rmdir(svdir)
|
65
|
+
end
|
66
|
+
svdir = $userdir + '/preview/'+mailid
|
67
|
+
if File.directory? svdir
|
68
|
+
lst = Dir[svdir+'/*'];
|
69
|
+
lst.each {|f| File.delete(f)}
|
70
|
+
Dir.rmdir(svdir)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def getdrafts
|
76
|
+
ids = Dir.glob($userdir + '/drafts/*',File::FNM_PATHNAME)
|
77
|
+
s = ids.collect { |i|
|
78
|
+
if ! File.directory? i
|
79
|
+
nil
|
80
|
+
else
|
81
|
+
mid = File.basename i
|
82
|
+
|
83
|
+
mailto = File.read(i + '/mailto') if File.readable? i + '/mailto'
|
84
|
+
drtime = File.mtime(i + '/mailto') if File.readable? i + '/mailto'
|
85
|
+
mailto ||= ''
|
86
|
+
mailto = '(No Recipient)' if mailto.length == 0
|
87
|
+
drtime ||= File.mtime(i)
|
88
|
+
|
89
|
+
subject = File.read(i + '/subject') if File.readable? i + '/subject'
|
90
|
+
subject ||= ''
|
91
|
+
subject = '(No Subject)' if subject.length == 0
|
92
|
+
|
93
|
+
[mid,CGI.escapeHTML(mailto),CGI.escapeHTML(subject),drtime]
|
94
|
+
end
|
95
|
+
}
|
96
|
+
s.compact!
|
97
|
+
s.sort! {|a,b| b[3] <=> a[3]}
|
98
|
+
return s
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
## Borrowed from sup
|
103
|
+
class Time
|
104
|
+
def to_indexable_s
|
105
|
+
sprintf "%012d", self
|
106
|
+
end
|
107
|
+
|
108
|
+
def nearest_hour
|
109
|
+
if min < 30
|
110
|
+
self
|
111
|
+
else
|
112
|
+
self + (60 - min) * 60
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def midnight # within a second
|
117
|
+
self - (hour * 60 * 60) - (min * 60) - sec
|
118
|
+
end
|
119
|
+
|
120
|
+
def is_the_same_day? other
|
121
|
+
(midnight - other.midnight).abs < 1
|
122
|
+
end
|
123
|
+
|
124
|
+
def is_the_day_before? other
|
125
|
+
other.midnight - midnight <= 24 * 60 * 60 + 1
|
126
|
+
end
|
127
|
+
|
128
|
+
def to_nice_distance_s from=Time.now
|
129
|
+
later_than = (self < from)
|
130
|
+
diff = (self.to_i - from.to_i).abs.to_f
|
131
|
+
text =
|
132
|
+
[ ["second", 60],
|
133
|
+
["minute", 60],
|
134
|
+
["hour", 24],
|
135
|
+
["day", 7],
|
136
|
+
["week", 4.345], # heh heh
|
137
|
+
["month", 12],
|
138
|
+
["year", nil],
|
139
|
+
].argfind do |unit, size|
|
140
|
+
if diff.round <= 1
|
141
|
+
"one #{unit}"
|
142
|
+
elsif size.nil? || diff.round < size
|
143
|
+
"#{diff.round} #{unit}s"
|
144
|
+
else
|
145
|
+
diff /= size.to_f
|
146
|
+
false
|
147
|
+
end
|
148
|
+
end
|
149
|
+
if later_than
|
150
|
+
text + " ago"
|
151
|
+
else
|
152
|
+
"in " + text
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
TO_NICE_S_MAX_LEN = 9 # e.g. "Yest.10am"
|
157
|
+
def to_nice_s from=Time.now
|
158
|
+
if year != from.year
|
159
|
+
strftime "%b %Y"
|
160
|
+
elsif month != from.month
|
161
|
+
strftime "%b %e"
|
162
|
+
else
|
163
|
+
if is_the_same_day? from
|
164
|
+
strftime("%l:%M%p").downcase # emulate %P (missing on ruby 1.8 darwin)
|
165
|
+
elsif is_the_day_before? from
|
166
|
+
"Yest." + nearest_hour.strftime("%l%p").downcase # emulate %P
|
167
|
+
else
|
168
|
+
strftime "%b %e"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
<%
|
2
|
+
if req["discard"] then
|
3
|
+
req["discard"].each { |x| discarddraft(x) }
|
4
|
+
end
|
5
|
+
%>
|
6
|
+
<html>
|
7
|
+
|
8
|
+
<head>
|
9
|
+
<title>TeXMailer</title>
|
10
|
+
<style type="text/css">
|
11
|
+
input {
|
12
|
+
border: 1px solid;
|
13
|
+
}
|
14
|
+
a.drft {
|
15
|
+
font-size: 15px;
|
16
|
+
color: black;
|
17
|
+
text-decoration: none;
|
18
|
+
}
|
19
|
+
a.drft:hover {
|
20
|
+
color: #a00000;
|
21
|
+
}
|
22
|
+
</style>
|
23
|
+
<script type="text/javascript">
|
24
|
+
function selectall(me)
|
25
|
+
{
|
26
|
+
l = document.getElementsByName("discard[]");
|
27
|
+
for(i = 0; i < l.length;i++)
|
28
|
+
l[i].checked = me.checked;
|
29
|
+
}
|
30
|
+
</script>
|
31
|
+
</head>
|
32
|
+
|
33
|
+
<body style="background-color:#dedede">
|
34
|
+
<%= File.read($basedir+"/rhtml/header.html")%>
|
35
|
+
<center>
|
36
|
+
<form method="POST" name="draftform" action="drafts.html">
|
37
|
+
<table style="width:98%; font-size:15px; border-width:2px; background-color:#badaba; border-color:#1aaa1a; border-style:solid">
|
38
|
+
<tr>
|
39
|
+
<td style="width:100%">
|
40
|
+
<input type="checkbox" onChange="selectall(this)"> <input type="submit" value="Delete Drafts">
|
41
|
+
</td>
|
42
|
+
</tr>
|
43
|
+
</table>
|
44
|
+
<table style="width:98%; font-size:15px; border-width:0px; border-spacing:0px 2px; padding:2px; font-size:15px">
|
45
|
+
<%
|
46
|
+
s = getdrafts
|
47
|
+
if s.length == 0 then
|
48
|
+
%>
|
49
|
+
<tr style="background-color:#fefefe">
|
50
|
+
<td style="width:100%; text-align:center">
|
51
|
+
<br>
|
52
|
+
You have no saved drafts.
|
53
|
+
<br>
|
54
|
+
</br>
|
55
|
+
</td>
|
56
|
+
</tr>
|
57
|
+
<%
|
58
|
+
else
|
59
|
+
s.each do |x|
|
60
|
+
mlink = "index.html?mailid="+x[0]
|
61
|
+
%>
|
62
|
+
<tr style="background-color:#fefefe">
|
63
|
+
<td style="width:30%">
|
64
|
+
<input type="checkbox" name="discard[]" value="<%= x[0] %>">
|
65
|
+
<a class="drft" href="<%= mlink %>"><%= x[1] %></a>
|
66
|
+
</td>
|
67
|
+
<td style="width:55%">
|
68
|
+
<a class="drft" href="<%= mlink %>"><%= x[2] %></a>
|
69
|
+
</td>
|
70
|
+
<td style="width:15%; text-align:right">
|
71
|
+
<a class="drft" href="<%= mlink %>"><%= x[3].to_nice_s %></a>
|
72
|
+
</td>
|
73
|
+
</tr>
|
74
|
+
<%
|
75
|
+
end
|
76
|
+
end
|
77
|
+
%>
|
78
|
+
</table>
|
79
|
+
</form>
|
80
|
+
</center>
|
81
|
+
</body>
|
82
|
+
</html>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<style type="text/css">
|
2
|
+
a.toplink {
|
3
|
+
border: 1px outset;
|
4
|
+
padding: 2px;
|
5
|
+
text-decoration: none;
|
6
|
+
font-size:15px;
|
7
|
+
background-color: #f5f5e5;
|
8
|
+
color: #000000
|
9
|
+
}
|
10
|
+
a.toplink:hover {
|
11
|
+
background-color: #aaffaa
|
12
|
+
}
|
13
|
+
</style>
|
14
|
+
<table style="width:100%;">
|
15
|
+
<tr><td width=75%>
|
16
|
+
<a href="index.html" class="toplink">New Mail</a>
|
17
|
+
<a href="drafts.html" class="toplink">Drafts</a>
|
18
|
+
<a href="settings.html" class="toplink">Settings</a>
|
19
|
+
<a href="die" class="toplink">Exit</a>
|
20
|
+
</td>
|
21
|
+
<td width=25% style="text-align:right; vertical-align:bottom">
|
22
|
+
<span style="font-size:25px">TeXMailer </span>
|
23
|
+
</td>
|
24
|
+
</tr></table>
|
@@ -0,0 +1,125 @@
|
|
1
|
+
<%
|
2
|
+
mailto,mailcc,mailbcc,subject,body = "","","","",""
|
3
|
+
|
4
|
+
# Does the draft exist
|
5
|
+
if req["mailid"] then
|
6
|
+
mailid = req["mailid"]
|
7
|
+
if req["stype"] then
|
8
|
+
savedraft(mailid,req) if req["stype"] == "save" || req["stype"] == "preview"
|
9
|
+
preview(mailid,req) if req["stype"] == "preview"
|
10
|
+
discarddraft(mailid) if req["stype"] == "discard"
|
11
|
+
end
|
12
|
+
else # Create new draft
|
13
|
+
mailid = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join;
|
14
|
+
end
|
15
|
+
|
16
|
+
mailto,mailcc,mailbcc,subject,body = loaddraft(mailid)
|
17
|
+
posturl = 'index.html?mailid='+mailid
|
18
|
+
sendurl = 'send.html?mailid='+mailid
|
19
|
+
%>
|
20
|
+
|
21
|
+
<html>
|
22
|
+
|
23
|
+
<head>
|
24
|
+
<title>TeXMailer</title>
|
25
|
+
|
26
|
+
<style type="text/css">
|
27
|
+
input {
|
28
|
+
border: 1px solid;
|
29
|
+
}
|
30
|
+
textarea {
|
31
|
+
border: 1px solid;
|
32
|
+
}
|
33
|
+
|
34
|
+
</style>
|
35
|
+
<script type="text/javascript">
|
36
|
+
function send()
|
37
|
+
{
|
38
|
+
document.getElementById("mailform").stype.value = "send";
|
39
|
+
document.getElementById("mailform").action = "<%= sendurl %>";
|
40
|
+
document.getElementById("mailform").submit();
|
41
|
+
}
|
42
|
+
function save()
|
43
|
+
{
|
44
|
+
document.getElementById("mailform").stype.value = "save";
|
45
|
+
document.getElementById("mailform").action = "<%= posturl %>";
|
46
|
+
document.getElementById("mailform").submit();
|
47
|
+
}
|
48
|
+
function preview()
|
49
|
+
{
|
50
|
+
document.getElementById("mailform").stype.value = "preview";
|
51
|
+
document.getElementById("mailform").action = "<%= posturl %>";
|
52
|
+
document.getElementById("mailform").submit();
|
53
|
+
}
|
54
|
+
function discard()
|
55
|
+
{
|
56
|
+
document.getElementById("mailform").stype.value = "discard";
|
57
|
+
document.getElementById("mailform").action = "<%= posturl %>";
|
58
|
+
document.getElementById("mailform").submit();
|
59
|
+
}
|
60
|
+
</script>
|
61
|
+
</head>
|
62
|
+
|
63
|
+
<body style="background-color:#dedede">
|
64
|
+
<%= File.read($basedir+"/rhtml/header.html")%>
|
65
|
+
<center>
|
66
|
+
<table style="width:100%; border-width:0px">
|
67
|
+
<tr style="width:100%; vertical-align: top">
|
68
|
+
|
69
|
+
<td style="width:45%">
|
70
|
+
<table style="width:100%; border-width:2px; background-color:#badaba; border-color:#1aaa1a; border-style:solid">
|
71
|
+
<tr><td style="text-align:left">
|
72
|
+
<input type="submit" value="Send" onClick="send();">
|
73
|
+
<input type="submit" value="Preview" onClick="preview();">
|
74
|
+
<input type="submit" value="Save" onClick="save();">
|
75
|
+
<input type="submit" value="Discard" onClick="discard();">
|
76
|
+
</td></tr>
|
77
|
+
<tr><td style="text-align:center">
|
78
|
+
<form method="POST" id="mailform" action="<%= posturl %>">
|
79
|
+
<input name="stype" id="stype" type="hidden" value="save">
|
80
|
+
<table style="width:99%;">
|
81
|
+
<tr>
|
82
|
+
<td style="text-align:right; width:10%; text-align:right; vertical-align:top">To:</td>
|
83
|
+
<td style="text-align:left; width:90%">
|
84
|
+
<input name="mailto" style="width:100%" value="<%= mailto %>">
|
85
|
+
</td>
|
86
|
+
</tr>
|
87
|
+
<tr>
|
88
|
+
<td style="text-align:right; width:10%; text-align:right; vertical-align:top">CC:</td>
|
89
|
+
<td style="text-align:left; width:90%">
|
90
|
+
<input name="mailcc" style="width:100%" value="<%= mailcc %>">
|
91
|
+
</td>
|
92
|
+
</tr>
|
93
|
+
<tr>
|
94
|
+
<td style="text-align:right; width:10%; text-align:right; vertical-align:top">BCC:</td>
|
95
|
+
<td style="text-align:left; width:90%">
|
96
|
+
<input name="mailbcc" style="width:100%" value="<%= mailbcc %>">
|
97
|
+
</td>
|
98
|
+
</tr>
|
99
|
+
<tr>
|
100
|
+
<td style="text-align:right; width:10%; text-align:right; vertical-align:top">Subject:</td>
|
101
|
+
<td style="text-align:left; width:90%">
|
102
|
+
<input name="subject" style="width:100%" value="<%= subject %>">
|
103
|
+
</td>
|
104
|
+
</tr>
|
105
|
+
</table>
|
106
|
+
<br>
|
107
|
+
<textarea name="body" style="width:99%;" rows=60><%= body %></textarea>
|
108
|
+
</form>
|
109
|
+
</td></tr>
|
110
|
+
<tr><td style="text-align:left">
|
111
|
+
<input type="submit" value="Send" onClick="send();">
|
112
|
+
<input type="submit" value="Preview" onClick="preview();">
|
113
|
+
<input type="submit" value="Save" onClick="save();">
|
114
|
+
<input type="submit" value="Discard" onClick="discard();">
|
115
|
+
</td></tr>
|
116
|
+
</table>
|
117
|
+
</td>
|
118
|
+
<td style="width:55%; height:99%; background-color:#faf4f4">
|
119
|
+
<iframe src="<%= getpvloc(mailid) %>" style="height:100%; width:100%; border:1px solid" scrolling="auto"></iframe>
|
120
|
+
</td>
|
121
|
+
</tr>
|
122
|
+
</table>
|
123
|
+
</center>
|
124
|
+
</body>
|
125
|
+
</html>
|