Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
assignment1
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
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
Abdulsamad Sheikh
assignment1
Commits
8f0c0870
Commit
8f0c0870
authored
1 year ago
by
Abdulsamad Sheikh
Browse files
Options
Downloads
Patches
Plain Diff
Updated all files
parent
f31c73bb
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
handlers/handlers.go
+57
-18
57 additions, 18 deletions
handlers/handlers.go
models/models.go
+16
-0
16 additions, 0 deletions
models/models.go
services/services.go
+68
-0
68 additions, 0 deletions
services/services.go
with
141 additions
and
18 deletions
handlers/handlers.go
+
57
−
18
View file @
8f0c0870
package
handlers
import
(
// ... other imports
"encoding/json"
"net/http"
"assignment1/models"
"assignment1/services"
"fmt"
)
func
BookCountHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// Parse query parameters for language
func
ReadershipHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// Extract the language code from the URL path
language
:=
r
.
URL
.
Path
[
len
(
"/librarystats/v1/readership/"
)
:
]
// Optional: Parse query parameters for limit if present
query
:=
r
.
URL
.
Query
()
language
:=
query
.
Get
(
"language"
)
limitParam
:=
query
.
Get
(
"limit"
)
var
limit
int
if
limitParam
!=
""
{
fmt
.
Sscanf
(
limitParam
,
"%d"
,
&
limit
)
}
// Fetch book data from the Gutendex API
books
,
err
:=
services
.
FetchBooksByLanguage
(
language
)
if
err
!=
nil
{
// Handle error
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
// Process the books to calculate the book count and author count
// ... (Implementation required)
// Fetch countries for the given language
countries
,
err
:=
services
.
FetchCountriesByLanguage
(
language
)
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
// Fetch population data for each country and calculate total readership
var
readershipDetails
[]
models
.
ReadershipDetail
var
totalReadership
int64
=
0
for
_
,
country
:=
range
countries
.
Countries
{
population
,
err
:=
services
.
FetchPopulationByCountryCode
(
country
.
ISOCode
)
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
totalReadership
+=
population
// Create a response object
response
:=
models
.
GutenbergBookCount
{
Language
:
language
,
// Books: Number of books (to be calculated),
// Authors: Number of unique authors (to be calculated),
// Fraction: Fraction of books in the language (to be calculated),
readershipDetail
:=
models
.
ReadershipDetail
{
Country
:
country
.
Name
,
ISOCode
:
country
.
ISOCode
,
Books
:
len
(
books
.
Results
),
Authors
:
services
.
CalculateUniqueAuthors
(
books
.
Results
),
Readership
:
population
,
}
readershipDetails
=
append
(
readershipDetails
,
readershipDetail
)
// Apply limit if specified
if
limit
>
0
&&
len
(
readershipDetails
)
>=
limit
{
break
}
}
//
Write the response back as JSON
//
Create and send the response
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
if
err
:=
json
.
NewEncoder
(
w
)
.
Encode
(
response
);
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
}
json
.
NewEncoder
(
w
)
.
Encode
(
readershipDetails
)
}
// ... Other handlers
func
StatusHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
status
:=
models
.
ServiceStatus
{
GutendexAPI
:
services
.
CheckServiceAvailability
(
"http://129.241.150.113:8000/books/"
),
LanguageAPI
:
services
.
CheckServiceAvailability
(
"http://129.241.150.113:3000/language2countries/"
),
CountriesAPI
:
services
.
CheckServiceAvailability
(
"http://129.241.150.113:8080/v3.1/"
),
Version
:
"v1"
,
Uptime
:
services
.
GetUptime
(),
// Implement GetUptime in your services package
}
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
json
.
NewEncoder
(
w
)
.
Encode
(
status
)
}
This diff is collapsed.
Click to expand it.
models/models.go
+
16
−
0
View file @
8f0c0870
...
...
@@ -31,3 +31,19 @@ type Person struct {
DeathYear
*
int
`json:"death_year"`
Name
string
`json:"name"`
}
// LanguageCountriesResponse represents the response structure from the Language2Countries API.
type
LanguageCountriesResponse
struct
{
Countries
[]
CountryInfo
`json:"countries"`
}
// CountryInfo represents country information in the LanguageCountriesResponse.
type
CountryInfo
struct
{
Name
string
`json:"name"`
ISOCode
string
`json:"isoCode"`
}
// CountryResponse represents the structure of a country response from the REST Countries API.
type
CountryResponse
struct
{
Population
int64
`json:"population"`
}
This diff is collapsed.
Click to expand it.
services/services.go
+
68
−
0
View file @
8f0c0870
...
...
@@ -23,3 +23,71 @@ func FetchBooksByLanguage(language string) (*models.GutenbergResponse, error) {
return
&
booksResponse
,
nil
}
// FetchCountriesByLanguage retrieves countries for a given language code.
func
FetchCountriesByLanguage
(
language
string
)
(
*
models
.
LanguageCountriesResponse
,
error
)
{
url
:=
"http://129.241.150.113:3000/language2countries/"
+
language
resp
,
err
:=
http
.
Get
(
url
)
if
err
!=
nil
{
return
nil
,
err
}
defer
resp
.
Body
.
Close
()
var
countriesResponse
models
.
LanguageCountriesResponse
if
err
:=
json
.
NewDecoder
(
resp
.
Body
)
.
Decode
(
&
countriesResponse
);
err
!=
nil
{
return
nil
,
err
}
return
&
countriesResponse
,
nil
}
// FetchPopulationByCountryCode retrieves population for a given country code.
func
FetchPopulationByCountryCode
(
isoCode
string
)
(
int64
,
error
)
{
url
:=
"http://129.241.150.113:8080/v3.1/alpha/"
+
isoCode
resp
,
err
:=
http
.
Get
(
url
)
if
err
!=
nil
{
return
0
,
err
}
defer
resp
.
Body
.
Close
()
var
countryResponse
[]
models
.
CountryResponse
// Assuming CountryResponse is an array
if
err
:=
json
.
NewDecoder
(
resp
.
Body
)
.
Decode
(
&
countryResponse
);
err
!=
nil
{
return
0
,
err
}
if
len
(
countryResponse
)
>
0
{
return
countryResponse
[
0
]
.
Population
,
nil
}
return
0
,
nil
// Or return an error if no country is found
}
// CalculateUniqueAuthors calculates the number of unique authors from a list of books.
func
CalculateUniqueAuthors
(
books
[]
models
.
GutenbergBook
)
int
{
authorsSet
:=
make
(
map
[
string
]
struct
{})
for
_
,
book
:=
range
books
{
for
_
,
author
:=
range
book
.
Authors
{
authorsSet
[
author
.
Name
]
=
struct
{}{}
}
}
return
len
(
authorsSet
)
}
// CheckServiceAvailability checks the availability of a given service URL.
func
CheckServiceAvailability
(
serviceURL
string
)
string
{
resp
,
err
:=
http
.
Get
(
serviceURL
)
if
err
!=
nil
{
return
"Unavailable"
}
defer
resp
.
Body
.
Close
()
return
http
.
StatusText
(
resp
.
StatusCode
)
}
// Assuming you have a global variable to track the start time of your service.
var
serviceStartTime
=
time
.
Now
()
// GetUptime calculates the uptime of the service in seconds.
func
GetUptime
()
int64
{
return
int64
(
time
.
Since
(
serviceStartTime
)
.
Seconds
())
}
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