Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
O
oblig1
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Steffen Sæther
oblig1
Commits
78dbf6d3
Commit
78dbf6d3
authored
1 year ago
by
Steffen Sæther
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
c2a21d19
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
oblig1/endpoints/bookcount.go
+153
-0
153 additions, 0 deletions
oblig1/endpoints/bookcount.go
with
153 additions
and
0 deletions
oblig1/endpoints/bookcount.go
0 → 100644
+
153
−
0
View file @
78dbf6d3
package
endpoints
import
(
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)
// BookCountResponse represents the structure of the response for book count endpoint.
type
BookCountResponse
struct
{
Language
string
`json:"language"`
Books
int
`json:"books"`
Authors
int
`json:"authors"`
Fraction
float64
`json:"fraction"`
}
type
Books
struct
{
Count
int
`json:"count"`
Next
string
`json:"next"`
Previous
string
`json:"previous"`
Results
[]
Result
`json:"results"`
}
type
Result
struct
{
Authors
[]
Author
`json:"authors"`
}
type
Author
struct
{
Name
string
`json:"name"`
}
// BookCountHandler handles requests to the /librarystats/v1/bookcount/ endpoint.
func
BookCountHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
languages
:=
r
.
URL
.
Query
()
.
Get
(
"language"
)
// Split the language codes into a slice.
languageCodes
:=
strings
.
Split
(
languages
,
","
)
// Placeholder values for books, authors, and total books.
var
totalBooks
int
var
uniqueAuthors
=
make
(
map
[
string
]
struct
{})
// Use a map as a set for unique authors
var
allBooks
int
// Create a slice to store results for each language.
var
response
[]
BookCountResponse
// Iterate through each language code.
for
_
,
language
:=
range
languageCodes
{
// Placeholder for the URL of the first page of results.
gutendexAPIURL
:=
fmt
.
Sprintf
(
"http://129.241.150.113:8000/books/?languages=%v"
,
language
)
// Fetch all pages of results.
for
gutendexAPIURL
!=
""
{
req
,
err
:=
http
.
NewRequest
(
"GET"
,
gutendexAPIURL
,
nil
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to create a new request"
,
http
.
StatusInternalServerError
)
return
}
req
.
Header
.
Add
(
"Content-Type"
,
"application/json"
)
client
:=
&
http
.
Client
{}
res
,
err
:=
client
.
Do
(
req
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to send a request to Gutendex API"
,
http
.
StatusInternalServerError
)
return
}
defer
res
.
Body
.
Close
()
// Decode the response.
body
,
err
:=
io
.
ReadAll
(
res
.
Body
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to read Gutendex API response"
,
http
.
StatusInternalServerError
)
return
}
var
books
Books
err
=
json
.
Unmarshal
(
body
,
&
books
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to decode Gutendex API response"
,
http
.
StatusInternalServerError
)
return
}
// Increment total books and unique authors for each language.
totalBooks
=
books
.
Count
for
_
,
book
:=
range
books
.
Results
{
for
_
,
author
:=
range
book
.
Authors
{
uniqueAuthors
[
author
.
Name
]
=
struct
{}{}
}
}
// Update total books for the first page only.
if
allBooks
==
0
{
allBooks
=
getBooksCount
(
w
)
}
// Update the URL to the next page of results.
gutendexAPIURL
=
books
.
Next
}
// Calculate fraction.
var
fraction
float64
if
allBooks
>
0
{
fraction
=
float64
(
totalBooks
)
/
float64
(
allBooks
)
}
// Append results for the current language to the response slice.
response
=
append
(
response
,
BookCountResponse
{
Language
:
language
,
Books
:
totalBooks
,
Authors
:
len
(
uniqueAuthors
),
Fraction
:
fraction
,
})
// Clear the set of unique authors for the next language.
uniqueAuthors
=
make
(
map
[
string
]
struct
{})
}
// Send the response.
sendJSONResponse
(
w
,
response
)
}
func
getBooksCount
(
w
http
.
ResponseWriter
)
int
{
gutendexCount
:=
"http://129.241.150.113:8000/books/"
req
,
err
:=
http
.
NewRequest
(
"GET"
,
gutendexCount
,
nil
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to create a new request"
,
http
.
StatusInternalServerError
)
return
1
}
req
.
Header
.
Add
(
"Content-Type"
,
"application/json"
)
client
:=
&
http
.
Client
{}
res
,
err
:=
client
.
Do
(
req
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to send a request to Gutendex API"
,
http
.
StatusInternalServerError
)
return
1
}
defer
res
.
Body
.
Close
()
// Decode the response.
body
,
err
:=
io
.
ReadAll
(
res
.
Body
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to read Gutendex API response"
,
http
.
StatusInternalServerError
)
return
1
}
var
books
Books
err
=
json
.
Unmarshal
(
body
,
&
books
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to decode Gutendex API response"
,
http
.
StatusInternalServerError
)
return
1
}
return
books
.
Count
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment