defmodule Webuntis do @moduledoc """ Documentation for Webuntis. """ @doc """ Returns the internal id of the student. Example: 889 > Requires authentication """ def student_id do fetch_data("public/timetable/weekly/pageconfig?type=5&date=" <> current_date()) |> decode |> Map.fetch!("elements") |> List.first() |> Map.fetch!("id") end @doc """ Returns the internal id of the student's class. Example: 237 > Requires authentication """ def klasse_id do fetch_data("public/timetable/weekly/pageconfig?type=5&date=" <> current_date()) |> decode |> Map.fetch!("elements") |> List.first() |> Map.fetch!("klasse_id") end @doc """ Returns the last update of the timetable in NaiveDateTime. > Requires authentication """ def last_update do webuntis_date = fetch_data("public/info/infoWidgetData") |> decode |> Map.fetch!("lastImportDate") |> to_string |> String.codepoints() {year, _} = webuntis_date |> Enum.slice(0, 4) |> Enum.join() |> Integer.parse() {month, _} = webuntis_date |> Enum.slice(4, 2) |> Enum.join() |> Integer.parse() {day, _} = webuntis_date |> Enum.slice(6, 2) |> Enum.join() |> Integer.parse() {hour, _} = webuntis_date |> Enum.slice(8, 2) |> Enum.join() |> Integer.parse() {minute, _} = webuntis_date |> Enum.slice(10, 2) |> Enum.join() |> Integer.parse() {:ok, date} = NaiveDateTime.new(year, month, day, hour, minute, 0) date end @doc """ Returns the timetable of the student for the current week. Same as: ```elixir Webuntis.timetable_student(Webuntis.student_id(), Webuntis.current_date()) ``` > Requires authentication """ def timetable_student do timetable(5, student_id(), current_date()) end @doc """ Returns an ics file for the current week. Example: Webuntis.timetable_ics(5, Webuntis.student_id(), Webuntis.current_date()) > Requires authentication """ def timetable_ics(type, id, date, base_url \\ "mese.webuntis.com") do url = "https://" <> base_url <> "/WebUntis/Ical.do?" <> "elemType=" <> to_string(type) <> "&elemId=" <> to_string(id) <> "&rpt_sd=" <> date state = Webuntis.Auth.current_state() HTTPoison.get!(url, [{"Cookie", state.cookies}]).body end @doc """ Returns the timetable for the week which starting at the given date. > Requires authentication """ def timetable(type, id, date) do data = timetable_raw(type, id, date) |> decode elements = data |> Map.fetch!("result") |> Map.fetch!("data") |> Map.fetch!("elements") |> Enum.map(fn json_element -> %Webuntis.Struct.Element{ type: Map.get(json_element, "type"), id: Map.get(json_element, "id", 0), name: Map.get(json_element, "name", ""), long_name: Map.get(json_element, "longName", ""), displayname: Map.get(json_element, "displayname", ""), alternatename: Map.get(json_element, "alternatename", ""), fore_color: Map.get(json_element, "foreColor", ""), back_color: Map.get(json_element, "backColor", ""), can_view_timetable: Map.get(json_element, "canViewTimetable", false), extern_key: Map.get(json_element, "externKey", ""), room_capacity: Map.get(json_element, "roomCapacity", 0) } end) periods = data |> Map.fetch!("result") |> Map.fetch!("data") |> Map.fetch!("elementPeriods") |> Map.fetch!(to_string(id)) %{elements: elements, periods: periods} end @doc """ Returns the raw json response. Don't use it if you don't know what you're doing! > Requires authentication """ @doc since: "0.1.1" def timetable_raw(type, id, date) do fetch_data( "public/timetable/weekly/data?elementType=" <> to_string(type) <> "&elementId=" <> to_string(id) <> "&date=" <> date <> "&formatId=5" ) end @doc """ Returns news for the current day. """ def news do date = current_date() |> String.replace("-", "") fetch_data("public/news/newsWidgetData?date=" <> date) |> decode end @doc """ Returns the date of the current day. """ def current_date do Date.utc_today() |> to_string end # -= private stuff =- defp fetch_data(url) do state = Webuntis.Auth.current_state() {:ok, response} = HTTPoison.get("https://" <> state.base_url <> "/WebUntis/api/" <> url, [ {"Accept", "application/json"}, {"Cookie", state.cookies} ]) response.body end defp decode(reponse_body) do Jason.decode!(reponse_body)["data"] end end