contact: fix build
[hcoop/portal.git] / apt.sml
diff --git a/apt.sml b/apt.sml
dissimilarity index 99%
index e5c8f80..7aef214 100644 (file)
--- a/apt.sml
+++ b/apt.sml
-structure Apt :> APT =
-struct
-
-open Util Sql Init
-
-datatype status =
-        NEW
-       | INSTALLED
-       | REJECTED
-
-type request = { id : int, usr : int, pkgs : string, msg : string, status : status, stamp : C.timestamp }
-
-val statusFromInt =
-    fn 0 => NEW
-     | 1 => INSTALLED
-     | 2 => REJECTED
-     | _ => raise C.Sql "Bad APT request status"
-
-val statusToInt =
-    fn NEW => 0
-     | INSTALLED => 1
-     | REJECTED => 2
-
-fun statusFromSql v = statusFromInt (C.intFromSql v)
-fun statusToSql s = C.intToSql (statusToInt s)
-
-fun mkRequestRow [id, usr, pkgs, msg, status, stamp] =
-    {id = C.intFromSql id, usr = C.intFromSql usr, pkgs = C.stringFromSql pkgs,
-     msg = C.stringFromSql msg, status = statusFromSql status, stamp = C.timestampFromSql stamp}
-  | mkRequestRow r = rowError ("APT request", r)
-
-fun addRequest (usr, pkgs, msg) =
-    let
-       val db = getDb ()
-       val id = nextSeq (db, "AptSeq")
-    in
-       C.dml db ($`INSERT INTO Apt (id, usr, pkgs, msg, status, stamp)
-                   VALUES (^(C.intToSql id), ^(C.intToSql usr), ^(C.stringToSql pkgs), ^(C.stringToSql msg),
-                           0, CURRENT_TIMESTAMP)`);
-       id
-    end
-
-fun modRequest (req : request) =
-    let
-       val db = getDb ()
-    in
-       ignore (C.dml db ($`UPDATE Apt SET
-                           usr = ^(C.intToSql (#usr req)), pkgs = ^(C.stringToSql (#pkgs req)),
-                              msg = ^(C.stringToSql (#msg req)), status = ^(statusToSql (#status req))
-                           WHERE id = ^(C.intToSql (#id req))`))
-    end
-
-fun deleteRequest id =
-    ignore (C.dml (getDb ()) ($`DELETE FROM Apt WHERE id = ^(C.intToSql id)`))
-
-fun lookupRequest id =
-    case C.oneOrNoRows (getDb ()) ($`SELECT id, usr, pkgs, msg, status, stamp
-                                    FROM Apt
-                                    WHERE id = ^(C.intToSql id)`) of
-       SOME row => mkRequestRow row
-      | NONE => raise Fail "APT request not found"
-
-fun mkRequestRow' (name :: rest) = (C.stringFromSql name, mkRequestRow rest)
-  | mkRequestRow' r = rowError ("Apt.request'", r)
-
-fun listRequests () =
-    C.map (getDb ()) mkRequestRow' ($`SELECT name, Apt.id, usr, pkgs, msg, status, stamp
-                                     FROM Apt JOIN WebUser ON usr = WebUser.id
-                                     ORDER BY stamp DESC`)
-
-fun listOpenRequests () =
-    C.map (getDb ()) mkRequestRow' ($`SELECT name, Apt.id, usr, pkgs, msg, status, stamp
-                                     FROM Apt JOIN WebUser ON usr = WebUser.id
-                                     WHERE status = 0
-                                     ORDER BY stamp DESC`)
-
-fun notify f req =
-    let
-       val grp =
-           case Group.groupNameToId "server" of
-               NONE => 0
-             | SOME grp => grp
-
-       val req = lookupRequest req
-       val user = Init.lookupUser (#usr req)
-
-       val mail = Mail.mopen ()
-
-       fun doOne [name] =
-           let
-               val name = C.stringFromSql name
-           in
-               if name = #name user then
-                   ()
-               else
-                   (Mail.mwrite (mail, name);
-                    Mail.mwrite (mail, ","))
-           end
-         | doOne r = rowError ("apt.doOne", r)
-
-       fun rightJustify (n, s) =
-           let
-               fun pad n =
-                   if n <= 0 then
-                       ()
-                   else
-                       (Mail.mwrite (mail, " ");
-                        pad (n-1))
-           in
-               pad (n - size s);
-               Mail.mwrite (mail, s)
-           end
-
-       val pkgs = String.tokens Char.isSpace (#pkgs req)
-       val infos = map (valOf o AptQuery.query) pkgs
-    in
-       Mail.mwrite (mail, "From: Hcoop Portal <portal@hcoop.net>\nTo: ");
-       Mail.mwrite (mail, #name user);
-       Mail.mwrite (mail, "@hcoop.net\n");
-       Mail.mwrite (mail, "Bcc: ");
-       C.app (getDb ()) doOne ($`SELECT name
-                                 FROM WebUser JOIN Membership ON (usr = id AND grp = ^(C.intToSql grp))`);
-       Mail.mwrite (mail, "\nSubject: Apt package installation request\n\n");
-
-       f (user, mail);
-
-       app (fn info =>
-               (rightJustify (10, #name info);
-                Mail.mwrite (mail, "  ");
-                Mail.mwrite (mail, #descr info);
-                Mail.mwrite (mail, "\n"))) infos;
-
-       Mail.mwrite (mail, "\n");
-       Mail.mwrite (mail, #msg req);
-
-       Mail.mwrite (mail, "\n\nOpen requests: ");
-       Mail.mwrite (mail, urlPrefix);
-       Mail.mwrite (mail, "apt?cmd=open\n");
-
-       OS.Process.isSuccess (Mail.mclose mail)
-    end
-
-val notifyNew = notify (fn (user, mail) =>
-                          (Mail.mwrite (mail, #name user);
-                           Mail.mwrite (mail, " has requested the following packages:\n\n")))
-
-val statusToString =
-    fn NEW => "New"
-     | INSTALLED => "Installed"
-     | REJECTED => "Rejected"
-
-fun notifyMod (oldStatus, newStatus, changer, req) =
-    notify (fn (_, mail) =>
-              (Mail.mwrite (mail, changer);
-               Mail.mwrite (mail, " has changed the status of this request from ");
-               Mail.mwrite (mail, statusToString oldStatus);
-               Mail.mwrite (mail, " to ");
-               Mail.mwrite (mail, statusToString newStatus);
-               Mail.mwrite (mail, ".\n\n"))) req
-               
-end
\ No newline at end of file
+structure Apt = RequestH(struct
+                        val table = "Apt"
+                        val adminGroup = "server"
+                        fun subject _ = "Apt package installation request"
+                        val template = "apt"
+                        val descr = "packages"
+
+                        fun body {node, mail, data = pkgs} =
+                            let
+                                val pkgs = String.tokens Char.isSpace pkgs
+                                val infos = map (valOf o (fn x => AptQuery.query {node = node, pkg = x})) pkgs
+
+                                fun rightJustify (n, s) =
+                                    let
+                                        fun pad n =
+                                            if n <= 0 then
+                                                ()
+                                            else
+                                                (Mail.mwrite (mail, " ");
+                                                 pad (n-1))
+                                    in
+                                        pad (n - size s);
+                                        Mail.mwrite (mail, s)
+                                    end
+                            in
+                                app (fn info =>
+                                        (rightJustify (10, #name info);
+                                         Mail.mwrite (mail, "  ");
+                                         Mail.mwrite (mail, #descr info);
+                                         Mail.mwrite (mail, "\n"))) infos
+                            end
+                        end)