diff options
Diffstat (limited to 'bin')
-rw-r--r-- | bin/dune | 4 | ||||
-rw-r--r-- | bin/main.ml | 41 | ||||
-rw-r--r-- | bin/utils.ml | 51 |
3 files changed, 96 insertions, 0 deletions
diff --git a/bin/dune b/bin/dune new file mode 100644 index 0000000..7f1bcd1 --- /dev/null +++ b/bin/dune @@ -0,0 +1,4 @@ +(executable + (public_name aoc) + (name main) + (libraries cohttp-lwt-unix lwt_ssl aoc)) diff --git a/bin/main.ml b/bin/main.ml new file mode 100644 index 0000000..8e36c28 --- /dev/null +++ b/bin/main.ml @@ -0,0 +1,41 @@ +open Aoc +open Utils + +let () = + let args = Sys.argv in + let day = args.(1) in + let input_file = Printf.sprintf "inputs/%s.in" day in + if not @@ Caml.Sys.file_exists input_file then + download_input day input_file ; + let file = In_channel.open_text input_file in + let inputs = In_channel.input_all file in + let (module Day : Day.S) = + match day with + | "1" -> (module Day1) + | "2" -> (module Day2) + | "3" -> (module Day3) + | "4" -> (module Day4) + | "5" -> (module Day5) + | "6" -> (module Day6) + | "7" -> (module Day7) + | "8" -> (module Day8) + | "9" -> (module Day9) + | "10" -> (module Day10) + | "11" -> (module Day11) + | "12" -> (module Day12) + | "13" -> (module Day13) + | "14" -> (module Day14) + | "15" -> (module Day15) + | "16" -> (module Day16) + | "17" -> (module Day17) + | "18" -> (module Day18) + | "19" -> (module Day19) + | "20" -> (module Day20) + | "21" -> (module Day21) + | "22" -> (module Day22) + | "23" -> (module Day23) + | "24" -> (module Day24) + | "25" -> (module Day25) + | _ -> failwith "invalid day" + in + Day.run inputs ; In_channel.close file diff --git a/bin/utils.ml b/bin/utils.ml new file mode 100644 index 0000000..4f488f4 --- /dev/null +++ b/bin/utils.ml @@ -0,0 +1,51 @@ +open Unix +open Lwt +open Cohttp +open Cohttp_lwt_unix + +let session_file = ".session" + +let year_file = ".year" + +let get_token () = + let file = In_channel.open_text session_file in + let token = In_channel.input_all file in + In_channel.close file ; String.trim token + +let get_year () = + if Caml.Sys.file_exists year_file then ( + let file = In_channel.open_text year_file in + let year = In_channel.input_all file in + In_channel.close file ; + int_of_string (String.trim year) ) + else + let time = time () in + let time = gmtime time in + time.tm_year + 1900 + +let download_input day fn = + let year = get_year () in + let url = + Printf.sprintf "https://adventofcode.com/%d/day/%s/input" year day + in + let token = get_token () in + let headers = Header.init () in + let headers = Header.add headers "Cookie" ("session=" ^ token) in + let headers = + Header.add headers "User-Agent" + "github.com/fangyi-zhou/advent-of-code-ocaml-starter by \ + me+aoc@fangyi.io" + in + let uri = Uri.of_string url in + let body = + Client.get ~headers uri + >>= fun (resp, body) -> + let code = resp |> Response.status |> Code.code_of_status in + if code = 200 then body |> Cohttp_lwt.Body.to_string + else failwith ("Unable to get data, status " ^ Int.to_string code) + in + let body = Lwt_main.run body in + let body = String.trim body in + let file = Out_channel.open_text fn in + Out_channel.output_string file body ; + Out_channel.close file |