Skip to content
Snippets Groups Projects
Commit 8f0c0870 authored by Abdulsamad Sheikh's avatar Abdulsamad Sheikh :cat2:
Browse files

Updated all files

parent f31c73bb
Branches
No related tags found
No related merge requests found
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)
}
......@@ -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"`
}
......@@ -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())
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment