From 56c0e176f1d18f18899e0552c7896c782b7439e7 Mon Sep 17 00:00:00 2001 From: adamch Date: Tue, 26 Apr 2005 19:33:11 +0000 Subject: [PATCH] Mailing list subscription management (discuss and misc) --- TODO | 5 ---- mailman/.cvsignore | 1 + mailman/Makefile | 2 ++ mailman/portalsub.sml | 59 +++++++++++++++++++++++++++++++++++++++++++ pref.mlt | 22 ++++++++++++++-- pref.sig | 4 +++ pref.sml | 18 +++++++++++++ 7 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 mailman/.cvsignore create mode 100644 mailman/Makefile create mode 100644 mailman/portalsub.sml diff --git a/TODO b/TODO index c1fc465..b4d7664 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,2 @@ -Member data - - Summarize these with publicly accessible static pages - Specific requests - Join, with display of pending applications for all members to read - -Manage mailing list subscriptions \ No newline at end of file diff --git a/mailman/.cvsignore b/mailman/.cvsignore new file mode 100644 index 0000000..7ed5368 --- /dev/null +++ b/mailman/.cvsignore @@ -0,0 +1 @@ +portalsub \ No newline at end of file diff --git a/mailman/Makefile b/mailman/Makefile new file mode 100644 index 0000000..e99f98d --- /dev/null +++ b/mailman/Makefile @@ -0,0 +1,2 @@ +portalsub: + mlton portalsub.sml \ No newline at end of file diff --git a/mailman/portalsub.sml b/mailman/portalsub.sml new file mode 100644 index 0000000..f781964 --- /dev/null +++ b/mailman/portalsub.sml @@ -0,0 +1,59 @@ +fun isMember (list, addr) = + let + val proc = Unix.execute ("/usr/sbin/find_member", ["-l", list, addr]) + in + (case TextIO.inputLine (Unix.textInstreamOf proc) of + NONE => false + | _ => true) + before ignore (Unix.reap proc) + end + +fun isIdent ch = Char.isLower ch orelse Char.isDigit ch + +fun validHost s = + size s > 0 andalso size s < 20 andalso List.all isIdent (String.explode s) + +fun validDomain s = + size s > 0 andalso size s < 100 andalso List.all validHost (String.fields (fn ch => ch = #".") s) + +fun validEmailUser s = + size s > 0 andalso size s < 50 andalso List.all + (fn ch => Char.isAlphaNum ch orelse ch = #"." orelse ch = #"_" orelse ch = #"-" orelse ch = #"+") + (String.explode s) + +fun validEmail s = + (case String.fields (fn ch => ch = #"@") s of + [user, host] => validEmailUser user andalso validDomain host + | _ => false) + +fun main () = + case CommandLine.arguments () of + [list, cmd, addr] => + if list <> "hcoop-discuss" andalso list <> "hcoop-misc" then + (print "Bad mailing list name\n"; + OS.Process.failure) + else if not (validEmail addr) then + (print "Invalid e-mail address\n"; + OS.Process.failure) + else (case cmd of + "check" => + if isMember (list, addr) then + OS.Process.success + else + OS.Process.failure + | "add" => + if isMember (list, addr) then + OS.Process.success + else + OS.Process.system (String.concat ["echo ", addr, " | /usr/sbin/add_members -r - ", list]) + | "rm" => + if isMember (list, addr) then + OS.Process.system (String.concat ["/usr/sbin/remove_members ", list, " ", addr]) + else + OS.Process.success + | _ => (print ("Invalid command " ^ cmd ^ "\n"); + OS.Process.failure)) + | _ => (print "Bad command-line arguments\n"; + OS.Process.failure) + +val _ = OS.Process.exit (main ()) \ No newline at end of file diff --git a/pref.mlt b/pref.mlt index f4ba6fb..0f908d6 100644 --- a/pref.mlt +++ b/pref.mlt @@ -1,4 +1,6 @@ <% val you = Init.getUserId (); +val yourname = Init.getUserName (); +val youremail = yourname ^ "@hcoop.net"; @header [("title", ["Member preferences"])]; @@ -7,7 +9,21 @@ if $"cmd" = "mod" then Pref.setDirectory you else Pref.unsetDirectory you - end + end; + + if not (iff $"discuss" = "on" then + Pref.subscribe ("hcoop-discuss", youremail) + else + Pref.unsubscribe ("hcoop-discuss", youremail)) then + %>

Error setting hcoop-discuss status

<% + end; + + if not (iff $"misc" = "on" then + Pref.subscribe ("hcoop-misc", youremail) + else + Pref.unsubscribe ("hcoop-misc", youremail)) then + %>

Error setting hcoop-misc status

<% + end; %>

Preferences updated

<% end %> @@ -15,7 +31,9 @@ end %>
- + + +
checked<% end %>> Include me in the public member directory
checked<% end %>> Include me in the public member directory.
checked<% end %>> Include me on the hcoop-discuss mailing list. (On-topic discussion and sporadically high volume)
checked<% end %>> Include me on the hcoop-misc mailing list. (Off-topic)
diff --git a/pref.sig b/pref.sig index 1bf518a..e3cb7d7 100644 --- a/pref.sig +++ b/pref.sig @@ -3,4 +3,8 @@ sig val hasDirectory : int -> bool val setDirectory : int -> unit val unsetDirectory : int -> unit + + val subscribed : string * string -> bool + val subscribe : string * string -> bool + val unsubscribe : string * string -> bool end \ No newline at end of file diff --git a/pref.sml b/pref.sml index 9deb6fe..8476410 100644 --- a/pref.sml +++ b/pref.sml @@ -17,4 +17,22 @@ fun setDirectory usr = fun unsetDirectory usr = 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 ", + list, + " check ", + address])) + +fun subscribe (list, address) = OS.Process.isSuccess (OS.Process.system (String.concat + ["/usr/bin/sudo /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 ", + list, + " rm ", + address])) + end \ No newline at end of file -- 2.20.1