Files
ClubLogos/backend/facr_client.go
T
Tomáš Dvořák cdb8bcd3e9 fff
2025-10-03 16:26:44 +02:00

169 lines
4.4 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"
)
const FACR_API_BASE = "https://facr.tdvorak.dev"
type FACRClient struct {
httpClient *http.Client
}
func NewFACRClient() *FACRClient {
return &FACRClient{
httpClient: &http.Client{
Timeout: 10 * time.Second,
},
}
}
// Club represents a club from the FAČR API
type Club struct {
ID string `json:"id"`
Name string `json:"name"`
City string `json:"city,omitempty"`
Type string `json:"type,omitempty"`
Website string `json:"website,omitempty"`
LogoURL string `json:"logo_url,omitempty"`
}
// FACRSearchResponse represents the search response from FAČR API
type FACRSearchResponse struct {
Query string `json:"query"`
Count int `json:"count"`
Results []FACRSearchResult `json:"results"`
}
// FACRSearchResult represents a single search result from FAČR API
type FACRSearchResult struct {
Name string `json:"name"`
ClubID string `json:"club_id"`
ClubType string `json:"club_type"`
URL string `json:"url"`
LogoURL string `json:"logo_url"`
Category string `json:"category"`
Address string `json:"address"`
}
// FACRClubResponse represents the club details response from FAČR API
type FACRClubResponse struct {
Name string `json:"name"`
ClubID string `json:"club_id"`
ClubType string `json:"club_type"`
ClubInternalID string `json:"club_internal_id"`
URL string `json:"url"`
LogoURL string `json:"logo_url"`
Address string `json:"address"`
Category string `json:"category"`
}
// SearchClubs searches for clubs by query
func (c *FACRClient) SearchClubs(query string) ([]Club, error) {
url := fmt.Sprintf("%s/club/search?q=%s", FACR_API_BASE, query)
resp, err := c.httpClient.Get(url)
if err != nil {
return nil, fmt.Errorf("failed to fetch from FAČR API: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("FAČR API returned status %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
var searchResp FACRSearchResponse
if err := json.Unmarshal(body, &searchResp); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
// Convert FACR results to our Club format
clubs := make([]Club, 0, len(searchResp.Results))
for _, result := range searchResp.Results {
// Extract city from address if available
city := extractCityFromAddress(result.Address)
clubs = append(clubs, Club{
ID: result.ClubID,
Name: result.Name,
City: city,
Type: result.ClubType,
Website: "", // Not provided in search results
LogoURL: result.LogoURL,
})
}
return clubs, nil
}
// extractCityFromAddress extracts city name from address string
// Address format: "Street, PostalCode City"
func extractCityFromAddress(address string) string {
if address == "" {
return ""
}
// Try to extract city after postal code (format: "Street, 12345 City")
parts := strings.Split(address, ",")
if len(parts) < 2 {
return ""
}
// Get the part after comma and split by space
lastPart := strings.TrimSpace(parts[len(parts)-1])
words := strings.Fields(lastPart)
if len(words) >= 2 {
// Skip postal code (first word) and return the rest as city
return strings.Join(words[1:], " ")
}
return ""
}
// GetClub gets a club by ID
func (c *FACRClient) GetClub(id string) (*Club, error) {
// Try football first, then futsal
url := fmt.Sprintf("%s/club/football/%s", FACR_API_BASE, id)
resp, err := c.httpClient.Get(url)
if err != nil {
return nil, fmt.Errorf("failed to fetch from FAČR API: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("FAČR API returned status %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
var clubResp FACRClubResponse
if err := json.Unmarshal(body, &clubResp); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
// Extract city from address
city := extractCityFromAddress(clubResp.Address)
club := &Club{
ID: clubResp.ClubID,
Name: clubResp.Name,
City: city,
Type: clubResp.ClubType,
Website: "", // Not provided in FACR API
LogoURL: clubResp.LogoURL,
}
return club, nil
}