11defmodule Cadet.Accounts.IVLE do
22 @ moduledoc """
3- Helper functions to IVLE calls. All helper functions are prefixed with fetch
4- to differentiate them from database helpers, or other 'getters'.
3+ This module provides abstractions for various IVLE API calls.
54
65 This module relies on the environment variable `IVLE_KEY` being set.
76 `IVLE_KEY` should contain the IVLE Lapi key. Obtain the key from
@@ -30,7 +29,7 @@ defmodule Cadet.Accounts.IVLE do
3029 {:ok, "e012345"}
3130
3231 """
33- def fetch_nusnet_id ( token ) , do: api_fetch ( "UserID_Get" , Token: token )
32+ def fetch_nusnet_id ( token ) , do: api_call ( "UserID_Get" , Token: token )
3433
3534 @ doc """
3635 Get the full name of the user corresponding to this token.
@@ -51,7 +50,7 @@ defmodule Cadet.Accounts.IVLE do
5150 {:ok, "LEE NING YUAN"}
5251
5352 """
54- def fetch_name ( token ) , do: api_fetch ( "UserName_Get" , Token: token )
53+ def fetch_name ( token ) , do: api_call ( "UserName_Get" , Token: token )
5554
5655 @ doc """
5756 Get the role of the user corresponding to this token.
@@ -64,6 +63,10 @@ defmodule Cadet.Accounts.IVLE do
6463 - {:error, :bad_request} - invalid token, or not taking the module
6564 - {:error, :internal_server_error} - the ivle_key is invalid
6665
66+ ## Parameters
67+
68+ - token: String, the IVLE authentication token
69+
6770 This function assumes that inactive modules have an ID of
6871 `"00000000-0000-0000-0000-000000000000"`, and that there is only one active
6972 module with the course code `"CS1101S"`. (So far, these assumptions have been
@@ -82,15 +85,14 @@ defmodule Cadet.Accounts.IVLE do
8285
8386 """
8487 def fetch_role ( token ) do
85- { :ok , modules } = api_fetch ( "Modules" , AuthToken: token , CourseID: "CS1101S" )
88+ { :ok , modules } = api_call ( "Modules" , AuthToken: token , CourseID: "CS1101S" )
8689
8790 cs1101s =
8891 modules [ "Results" ]
89- |> Enum . filter ( fn module ->
92+ |> Enum . find ( fn module ->
9093 module [ "CourseCode" ] == "CS1101S" and
9194 module [ "ID" ] != "00000000-0000-0000-0000-000000000000"
9295 end )
93- |> List . first ( )
9496
9597 case cs1101s do
9698 % { "Permission" => "S" } ->
@@ -107,7 +109,60 @@ defmodule Cadet.Accounts.IVLE do
107109 end
108110 end
109111
110- defp api_fetch ( method , queries ) do
112+ @ doc """
113+ Make an API call to IVLE LAPI.
114+
115+ returns...
116+
117+ - {:ok, body} - valid token
118+ - {:error, :internal_server_error} - Invalid API key
119+ - {:error, :bad_request} - Invalid token
120+
121+ ## Parameters
122+
123+ - method: String, the HTTP request method to use
124+ - queries: [Keyword], key-value pair of parameters to send
125+
126+ This method is valid for methods that return with a string "Invalid login!"
127+ in a JSON nested in the body. Refer to the next method `api_call/2` for
128+ methods that return a 200 with an empty string body on invalid tokens.
129+ """
130+ def api_call ( method , queries ) when method in [ "Announcements" ] do
131+ with { :ok , % { status_code: 200 , body: body } } <- HTTPoison . get ( api_url ( method , queries ) ) ,
132+ body = Poison . decode! ( body ) ,
133+ % { "Comments" => "Valid login!" } <- body do
134+ { :ok , body [ "Results" ] }
135+ else
136+ { :ok , % { status_code: 500 } } ->
137+ # IVLE responds with 500 if APIKey is invalid
138+ { :error , :internal_server_error }
139+
140+ % { "Comments" => "Invalid login!" } ->
141+ # IVLE response if AuthToken is invalid
142+ { :error , :bad_request }
143+ end
144+ end
145+
146+ @ doc """
147+ Make an API call to IVLE LAPI.
148+
149+ returns...
150+
151+ - {:ok, body} - valid token
152+ - {:error, :internal_server_error} - Invalid API key
153+ - {:error, :bad_request} - Invalid token
154+
155+ ## Parameters
156+
157+ - method: String, the HTTP request method to use
158+ - queries: [Keyword], key-value pair of parameters to send
159+
160+ This method is valid for methods that return a 200 with an empty string body
161+ on invalid tokens. For methods that return with string "Invalid login!" in a
162+ JSON nested in the body, refer to the previous method api_call/2 with guard
163+ clause.
164+ """
165+ def api_call ( method , queries ) do
111166 case HTTPoison . get ( api_url ( method , queries ) ) do
112167 { :ok , % { body: body , status_code: 200 } } when body != ~s( "") ->
113168 { :ok , Poison . decode! ( body ) }
@@ -117,14 +172,15 @@ defmodule Cadet.Accounts.IVLE do
117172 { :error , :internal_server_error }
118173
119174 { :ok , % { body: ~s( "") , status_code: 200 } } ->
120- # IVLE responsed 200 with body == ~s("") if token is invalid
175+ # IVLE responds 200 with body == ~s("") if token is invalid
121176 { :error , :bad_request }
122177 end
123178 end
124179
125180 # Construct a valid URL with the module attributes, and given params
126- # token_param_key is specified as some api calls use ...&Token={token},
127- # but other calls use ...&AuthToken={token}
181+ # The authentication token parameter must be provided explicitly rather than
182+ # provided implicitly by this function as some API calls use ...&Token={token},
183+ # while others use ...&AuthToken={token}
128184 defp api_url ( method , queries ) do
129185 queries = [ APIKey: @ api_key ] ++ queries
130186
0 commit comments