fj/internal/api/client.go
2025-12-09 13:41:08 +01:00

122 lines
2.8 KiB
Go

package api
import (
"encoding/json"
"fmt"
"io"
"net/http"
"code.gitea.io/sdk/gitea"
"codeberg.org/romaintb/fgj/internal/config"
)
type Client struct {
*gitea.Client
hostname string
token string
}
func NewClient(hostname, token string) (*Client, error) {
if hostname == "" {
hostname = "codeberg.org"
}
client, err := gitea.NewClient("https://"+hostname, gitea.SetToken(token))
if err != nil {
return nil, err
}
return &Client{
Client: client,
hostname: hostname,
token: token,
}, nil
}
func NewClientFromConfig(cfg *config.Config, hostname string) (*Client, error) {
host, err := cfg.GetHost(hostname)
if err != nil {
return nil, err
}
return NewClient(host.Hostname, host.Token)
}
func (c *Client) Hostname() string {
return c.hostname
}
// GetJSON performs a GET request to the specified path and decodes the JSON response
func (c *Client) GetJSON(path string, result any) error {
baseURL := "https://" + c.hostname
url := baseURL + path
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
// Set authentication header
if c.token != "" {
req.Header.Set("Authorization", "token "+c.token)
}
req.Header.Set("Accept", "application/json")
httpClient := &http.Client{}
resp, err := httpClient.Do(req)
if err != nil {
return fmt.Errorf("failed to perform request: %w", err)
}
defer func() {
if closeErr := resp.Body.Close(); closeErr != nil && err == nil {
err = fmt.Errorf("failed to close response body: %w", closeErr)
}
}()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body))
}
if err := json.NewDecoder(resp.Body).Decode(result); err != nil {
return fmt.Errorf("failed to decode response: %w", err)
}
return nil
}
// GetRawLog performs a GET request and returns the raw response body as string
func (c *Client) GetRawLog(url string) (string, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return "", fmt.Errorf("failed to create request: %w", err)
}
// Set authentication header
if c.token != "" {
req.Header.Set("Authorization", "token "+c.token)
}
httpClient := &http.Client{}
resp, err := httpClient.Do(req)
if err != nil {
return "", fmt.Errorf("failed to perform request: %w", err)
}
defer func() {
if closeErr := resp.Body.Close(); closeErr != nil && err == nil {
err = fmt.Errorf("failed to close response body: %w", closeErr)
}
}()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return "", fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body))
}
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("failed to read response body: %w", err)
}
return string(bodyBytes), nil
}