.cm
-CM
\ No newline at end of file
+CM
+out
struct
val baseUrl = "http://join.hcoop.net/join/"
-val portalUrl = "http://users.hcoop.net/portal/"
+val portalUrl = "https://members.hcoop.net/portal/"
open Sql
fun init () =
let
- val c = C.conn "dbname='hcoop'"
+ val c = C.conn "dbname='hcoop_hcoop'"
in
db := SOME c;
C.dml c "BEGIN";
before TextIO.closeIn inf
end
-fun readTosBody () = readFile "/var/www/home/html/tos.body.html"
-fun readTosAgree () = readFile "/var/www/home/html/tos.agree.html"
-fun readTosMinorAgree () = readFile "/var/www/home/html/tos.agree.minor.html"
+fun readTosBody () = readFile "/home/hcoop/public_html/tos.body.html"
+fun readTosAgree () = readFile "/home/hcoop/public_html/tos.agree.html"
+fun readTosMinorAgree () = readFile "/home/hcoop/public_html/tos.agree.minor.html"
fun sendMail (to, subj, intro, footer, id) =
let
| NONE => false
end
-end
\ No newline at end of file
+end
<input type="hidden" name="cmd" value="app">
<table>
<tr> <td align="right" valign="top"><b>Desired username</b>:</td> <td><input name="name"><br>
- You should follow usual UNIX conventions, and it's helpful to pick a name you wouldn't mind using to identify yourself to strangers.</td> </tr>
+ You should follow usual UNIX conventions, including limiting yourself to lowercase letters and at most 8 characters. It's helpful to pick a name you wouldn't mind using to identify yourself to both strangers and friends. Something based on your "real" name is a safe bet.</td> </tr>
<% if minor then %>
<tr> <td align="right"><b>New member's "real" name</b>:</td> <td><input name="rname"></td> </tr>
<tr> <td align="right"><b>Legal guardian's name</b>:</td> <td><input name="gname"></td> </tr>
<tr> <td align="right" valign="top"><b>Any other information about yourself</b></td> <td><textarea name="other" rows="5" cols="80" wrap="soft"></textarea></td> </tr>
</table>
+<br><hr><br>
+
+You must agree to the following terms to be considered for membership:
+
<h2><b>Terms of Service Agreement</b></h2>
<% App.readTosBody () %>
exn exn
out out
-pub /var/www/join.hcoop.net/cgi/join
+pub /home/hcoop/join/cgi
+cm $/smlnj-lib.cm
cm /usr/local/share/smlsql/smlsql.cm
cm /usr/local/share/smlsql/libpq/sources.cm
--- /dev/null
+*
\ No newline at end of file
val scratchDir = "/home/hcoop"
val urlPrefix = "https://members.hcoop.net/portal/"
-val emailSuffix = "@new.hcoop.net"
+val emailSuffix = "@hcoop.net"
val boardEmail = "board" ^ emailSuffix
fun conn () = C.conn "dbname='hcoop_hcoop'"
--- /dev/null
+*.x86-linux
+.cm
+CM
+listaddrs
--- /dev/null
+listaddrs.x86-linux: listaddrs.sml sources.cm
+ /usr/local/sml/bin/ml-build sources.cm Main.main listaddrs
--- /dev/null
+structure Main = struct
+
+structure C = PgClient
+
+fun main _ =
+ let
+ val db = C.conn "dbname='hcoop_hcoop'"
+
+ fun printOne [name] = print (C.stringFromSql name ^ "@hcoop.net\n")
+ in
+ C.app db printOne "SELECT name FROM WebUser";
+ C.close db;
+ OS.Process.success
+ end
+end
--- /dev/null
+Group is
+ $/basis.cm
+
+ /usr/local/share/smlsql/libpq/sources.cm
+ /usr/local/share/smlsql/smlsql.cm
+
+ listaddrs.sml
\ No newline at end of file
<h3><b>Vote Report</b></h3>
+<p>Voters:
+<% ref first = true;
+ foreach user in Poll.listPollVoters id do
+ if first then
+ first := false
+ else
+ %>, <%
+ end
+ %><a href="user?id=<% #id user %>"><% #name user %></a><%
+ end %></p>
+
<table>
<tr> <td align="right"><b>Poll#</b>:</td> <td><% id %></td> </tr>
<tr> <td align="right"><b>Title</b>:</td> <td><% Web.html (#title poll) %></td> </tr>
<h3><b>Choices<% if Poll.takingVotes poll then %><a href="poll?vote=<% id %>">(Vote!)</a><% end %></b></h3>
+<p><% Poll.countVoters (#id poll) %> people have voted.</p>
+
<% if Poll.takingVotes poll then %>
<table>
<tr> <td><b>You</b></td> <td><b>Total</b></td> </tr>
val noDupes : ''a list -> bool
val listVoters : int -> Init.user list
-end
\ No newline at end of file
+ (* This operates on choice IDs. *)
+
+ (* These operate on poll IDs. *)
+ val countVoters : int -> int
+ val listPollVoters : int -> Init.user list
+end
AND cho = ^(C.intToSql cho)
ORDER BY name`)
-end
\ No newline at end of file
+fun countVoters pol =
+ case C.oneRow (getDb ()) ($`SELECT COUNT(DISTINCT usr)
+ FROM Vote JOIN PollChoice ON id = cho AND pol = ^(C.intToSql pol)`) of
+ [count] => C.intFromSql count
+ | row => Init.rowError ("countVoters", row)
+
+fun listPollVoters pol =
+ C.map (getDb ()) mkUserRow ($`SELECT DISTINCT WebUser.id, name, rname, bal, joined, app
+ FROM WebUser, Vote JOIN PollChoice ON cho = PollChoice.id
+ WHERE pol = ^(C.intToSql pol)
+ AND usr = WebUser.id
+ ORDER BY name`)
+
+end
ignore (C.dml (getDb ()) ($`DELETE FROM DirectoryPref WHERE usr = ^(C.intToSql usr)`))
fun subscribed (list, address) = OS.Process.isSuccess (OS.Process.system (String.concat
- ["/usr/bin/sudo /usr/local/bin/portalsub ",
+ ["/usr/bin/sudo -u list /usr/local/bin/portalsub ",
list,
" check ",
address]))
fun subscribe (list, address) = OS.Process.isSuccess (OS.Process.system (String.concat
- ["/usr/bin/sudo /usr/local/bin/portalsub ",
+ ["/usr/bin/sudo -u list /usr/local/bin/portalsub ",
list,
" add ",
address]))
fun unsubscribe (list, address) = OS.Process.isSuccess (OS.Process.system (String.concat
- ["/usr/bin/sudo /usr/local/bin/portalsub ",
+ ["/usr/bin/sudo -u list /usr/local/bin/portalsub ",
list,
" rm ",
address]))
-end
\ No newline at end of file
+end