Current section
Files
Jump to
Current section
Files
lib/webuntis.ex
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