@@ -2,36 +2,43 @@ defmodule CodeCorps.GitHub.API do
22 alias CodeCorps . {
33 GithubAppInstallation ,
44 GitHub ,
5+ GitHub.API.Errors.PaginationError ,
56 GitHub.API.Pagination ,
67 GitHub.APIError ,
78 GitHub.HTTPClientError ,
9+ GitHub.Utils.ResultAggregator ,
810 User
911 }
1012
1113 alias HTTPoison . { Error , Response }
1214
1315 def gateway ( ) , do: Application . get_env ( :code_corps , :github )
1416
15- @ spec request ( GitHub . method , String . t , GitHub . headers , GitHub . body , list ) :: GitHub . response
17+ @ typep raw_body :: String . t
18+ @ typep raw_headers :: list ( { String . t , String . t } )
19+ @ typep raw_options :: Keyword . t
20+
21+ @ spec request ( GitHub . method , String . t , raw_body , raw_headers , raw_options ) :: GitHub . response
1622 def request ( method , url , body , headers , options ) do
1723 gateway ( ) . request ( method , url , body , headers , options )
1824 |> marshall_response ( )
1925 end
2026
21- @ spec get_all ( String . t , GitHub . headers , list ) :: GitHub . response
27+ @ spec get_all ( String . t , raw_headers , raw_options ) :: { :ok , list ( map ) } | { :error , PaginationError . t } | { :error , GitHub . api_error_struct }
2228 def get_all ( url , headers , options ) do
23- { :ok , % Response { request_url: request_url , headers: response_headers } } =
24- gateway ( ) . request ( :head , url , "" , headers , options )
25-
26- response_headers
27- |> Pagination . retrieve_total_pages ( )
28- |> Pagination . to_page_numbers ( )
29- |> Enum . map ( & Pagination . add_page_param ( options , & 1 ) )
30- |> Enum . map ( & gateway ( ) . request ( :get , url , "" , headers , & 1 ) )
31- |> Enum . map ( & marshall_response / 1 )
32- |> Enum . map ( & Tuple . to_list / 1 )
33- |> Enum . map ( & List . last / 1 )
34- |> List . flatten
29+ case gateway ( ) . request ( :head , url , "" , headers , options ) do
30+ { :ok , % Response { headers: response_headers , status_code: code } } when code in 200 .. 399 ->
31+ response_headers
32+ |> Pagination . retrieve_total_pages ( )
33+ |> Pagination . to_page_numbers ( )
34+ |> Enum . map ( & Pagination . add_page_param ( options , & 1 ) )
35+ |> Enum . map ( & gateway ( ) . request ( :get , url , "" , headers , & 1 ) )
36+ |> Enum . map ( & marshall_response / 1 )
37+ |> ResultAggregator . aggregate
38+ |> marshall_paginated_response ( )
39+ other
40+ -> other |> marshall_response ( )
41+ end
3542 end
3643
3744 @ doc """
@@ -69,6 +76,9 @@ defmodule CodeCorps.GitHub.API do
6976 @ typep http_failure :: { :error , term }
7077
7178 @ spec marshall_response ( http_success | http_failure ) :: GitHub . response
79+ defp marshall_response ( { :ok , % Response { body: "" , status_code: status } } ) when status in 200 .. 299 do
80+ { :ok , % { } }
81+ end
7282 defp marshall_response ( { :ok , % Response { body: body , status_code: status } } ) when status in 200 .. 299 do
7383 case body |> Poison . decode do
7484 { :ok , json } ->
@@ -80,6 +90,9 @@ defmodule CodeCorps.GitHub.API do
8090 defp marshall_response ( { :ok , % Response { body: body , status_code: 404 } } ) do
8191 { :error , APIError . new ( { 404 , % { "message" => body } } ) }
8292 end
93+ defp marshall_response ( { :ok , % Response { body: "" , status_code: status } } ) when status in 400 .. 599 do
94+ { :error , APIError . new ( { status , % { "message" => "API Error during HEAD request" } } ) }
95+ end
8396 defp marshall_response ( { :ok , % Response { body: body , status_code: status } } ) when status in 400 .. 599 do
8497 case body |> Poison . decode do
8598 { :ok , json } ->
@@ -94,4 +107,8 @@ defmodule CodeCorps.GitHub.API do
94107 defp marshall_response ( { :error , reason } ) do
95108 { :error , HTTPClientError . new ( reason: reason ) }
96109 end
110+
111+ @ spec marshall_paginated_response ( tuple ) :: tuple
112+ defp marshall_paginated_response ( { :ok , pages } ) , do: { :ok , pages |> List . flatten }
113+ defp marshall_paginated_response ( { :error , responses } ) , do: { :error , responses |> PaginationError . new }
97114end
0 commit comments