X-Git-Url: http://git.hcoop.net/hcoop/portal.git/blobdiff_plain/208e2cbc6b64811eba6c762795022c042bc48e33..aaba877afe8e8ce438a63ba764897fbfdbf2d760:/util.sml diff --git a/util.sml b/util.sml index 6f067ac..9c269c1 100644 --- a/util.sml +++ b/util.sml @@ -1,6 +1,12 @@ structure Util :> UTIL = struct +datatype 'a flat_element = + BEGIN + | END + | ITEM of 'a +type 'a flat_tree = 'a flat_element list + fun printInt n = Web.print (if n < 0 then "-" ^ Int.toString (~n) @@ -21,4 +27,86 @@ fun makeSet f items = | [usr] => "(" ^ f usr ^ ")" | usr::rest => foldl (fn (usr, s) => s ^ ", " ^ f usr) ("(" ^ f usr) rest ^ ")" -end \ No newline at end of file +fun neg (r : real) = ~r +fun add (r1 : real, r2) = r1 + r2 +fun sub (r1 : real, r2) = r1 - r2 +fun mult (r1, r2) = real r1 * r2 + +fun lt (r1 : real, r2) = r1 < r2 +fun ge (r1 : real, r2) = r1 >= r2 + +fun isIdent ch = Char.isLower ch orelse Char.isDigit ch orelse ch = #"-" + +fun validHost s = + size s > 0 andalso size s < 40 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 validUser s = + size s > 0 andalso size s < 50 andalso List.all + (fn ch => isIdent ch orelse ch = #"." orelse ch = #"_" orelse ch = #"-" orelse ch = #"+") + (String.explode 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 whoisUrl dom = String.concat ["http://reports.internic.net/cgi/whois?whois_nic=", dom, "&type=domain"] + +val rnd = ref (Random.rand (0, 0)) + +fun init () = rnd := Random.rand (SysWord.toInt (Posix.Process.pidToWord (Posix.ProcEnv.getpid ())), + SysWord.toInt (Posix.Process.pidToWord (Posix.ProcEnv.getpid ()))) + +fun randomPassword () = Int.toString (Int.abs (Random.randInt (!rnd))) + +fun domainDir dom = + String.concatWith "/" ("/afs/hcoop.net/common/etc/domtool/nodes/deleuze" :: List.rev (String.fields (fn ch => ch = #".") dom)) + +fun readFile fname = + let + val inf = TextIO.openIn fname + + fun readLines lines = + case TextIO.inputLine inf of + NONE => String.concat (List.rev lines) + | SOME line => readLines (line :: lines) + in + readLines [] + before TextIO.closeIn inf + end + +fun mem (x, ls) = List.exists (fn y => y = x) ls + +val allLower = CharVector.map Char.toLower + +fun normEmail s = case String.tokens Char.isSpace (allLower s) of + s :: _ => s + | [] => "" + +val s_cutoff = LargeInt.fromInt 60 +val m_cutoff = LargeInt.fromInt (60 * 60) +val h_cutoff = LargeInt.fromInt (60 * 60 * 24) + +fun diffFromNow t = + let + val secs = Time.toSeconds (Time.- (Time.now (), t)) + in + if LargeInt.< (secs, s_cutoff) then + LargeInt.toString secs ^ " seconds" + else if LargeInt.< (secs, m_cutoff) then + LargeInt.toString (LargeInt.div (secs, s_cutoff)) ^ " minutes" + else if LargeInt.< (secs, h_cutoff) then + LargeInt.toString (LargeInt.div (secs, m_cutoff)) ^ " hours" + else + LargeInt.toString (LargeInt.div (secs, h_cutoff)) ^ " days" + end + +end