diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ics.ml | 7 | ||||
-rw-r--r-- | src/ics.mli | 1 | ||||
-rw-r--r-- | src/server.ml | 50 |
3 files changed, 48 insertions, 10 deletions
@@ -57,12 +57,19 @@ module Event = struct "END:VEVENT\n"] |> List.map ics_split_line |> String.concat "\n" + + let has_groups groups event = + List.fold_left (fun found group -> + found || List.exists ((=) group) groups) false event.groups end type t = Event.t list let make events = events +let filter_groups groups = + List.filter (Event.has_groups groups) + let gen_vtimezone tz = if tz <> "" then ["BEGIN:VTIMEZONE"; diff --git a/src/ics.mli b/src/ics.mli index ca09406..cdb00d8 100644 --- a/src/ics.mli +++ b/src/ics.mli @@ -26,4 +26,5 @@ end type t val make : Event.t list -> t +val filter_groups : string list -> t -> t val to_string : string -> t -> string diff --git a/src/server.ml b/src/server.ml index 7107fdf..389da95 100644 --- a/src/server.ml +++ b/src/server.ml @@ -26,7 +26,7 @@ let format_date = Printer.Date.sprint "%Y-%m-%d" and a_month = Date.Period.make 0 1 0 and a_year = Date.Period.make 1 0 0 -type [@warning "-37"] fetch_kind = +type fetch_kind = | Group | Module @@ -58,6 +58,8 @@ let respond ?(mime="text/html; charset=utf-8") ?(status=`OK) body = let headers = Header.init_with "Content-Type" mime in Server.respond_string ~status ~body ~headers () +let bad_request = Server.respond_string ~status:`Bad_request ~body:"Bad request\n" + let get_tz () = Lwt_unix.file_exists "/etc/timezone" >>= fun exists -> if exists then @@ -70,6 +72,35 @@ let get_tz () = else Lwt.return "" +let fetch_and_respond ?(groups=[]) tzname celcat_url file kind = + let skip_if predicate fn value = + if predicate then + value + else + fn value in + let id = String.(sub file 0 (length file - 4)) in + fetch celcat_url id kind >>= fun body -> + Course.decode body + |> skip_if (kind = Group || groups = []) (Ics.filter_groups groups) + |> Ics.to_string tzname + |> respond ~mime:"text/calendar; charset=utf-8" + +let check_ics = Astring.String.is_suffix ~affix:".ics" + +let get_link ?(args=[]) base_url kind id = + let kind_to_url = function + | Group -> "g" + | Module -> "m" in + let args = + if args = [] then "" + else "?" ^ Uri.encoded_of_query args in + base_url ^ "/ics/" ^ kind_to_url kind ^ "/" ^ id ^ ".ics" ^ args + +let respond_link ?(args=[]) base_url kind id = + get_link ~args base_url kind id + |> Pages.link + |> respond + let serve base_url celcat_url mode stop = get_tz () >>= fun tzname -> let callback _conn req _body = @@ -83,16 +114,15 @@ let serve base_url celcat_url mode stop = match meth, path, query with | `GET, ([] | ["index.html"]), [] -> respond Pages.main | `GET, ["lnk"], ["group", [group]] -> - let lnk = base_url ^ "/ics/" ^ group ^ ".ics" in - respond @@ Pages.link lnk + respond_link base_url Group group | `GET, ["lnk"], _ -> - Server.respond_string ~status:`Bad_request ~body:"Bad request\n" () - | `GET, ["ics"; file], [] when Astring.String.is_suffix ~affix:".ics" file -> - let group = String.(sub file 0 (length file - 4)) in - fetch celcat_url group Group >>= fun body -> - Course.decode body - |> Ics.to_string tzname - |> respond ~mime:"text/calendar; charset=utf-8" + bad_request () + | `GET, ["ics"; "g"; file], [] when check_ics file -> + fetch_and_respond tzname celcat_url file Group + | `GET, ["ics"; "m"; file], ([] as groups | ["groups", groups]) when check_ics file -> + fetch_and_respond ~groups tzname celcat_url file Module + | `GET, ["ics"; "g" | "m"; file], _ when check_ics file -> + bad_request () | `GET, _, _ -> Server.respond_string ~status:`Not_found ~body:"Not found\n" () | _ -> |