Files
ArinDash/apis/newsapi/main.go
T

126 lines
2.7 KiB
Go

package news
import (
"ArinDash/config"
"encoding/json"
"io"
"log"
"net/http"
"strings"
"unicode"
)
const apiBaseURL = "https://newsapi.org/v2/top-headlines"
type configFile struct {
News newsConfig
}
type newsConfig struct {
ApiKey string
Sources string
}
type News struct {
Status string `json:"status"`
TotalResults int `json:"totalResults"`
Articles []Article `json:"articles"`
}
type Article struct {
Source Source `json:"source"`
Author string `json:"author"`
Title string `json:"title"`
Description string `json:"description"`
URL string `json:"url"`
URLToImage string `json:"urlToImage"`
PublishedAt string `json:"publishedAt"`
Content string `json:"content"`
}
type Source struct {
ID string `json:"id"`
Name string `json:"name"`
}
func FetchNews() News {
cfg := &configFile{}
config.LoadConfig(cfg)
client := &http.Client{}
if cfg.News.ApiKey == "" {
return News{
Status: "No API key provided",
}
}
req, err := http.NewRequest("GET", apiBaseURL+"?sources="+cfg.News.Sources+"&pageSize=100&apiKey="+cfg.News.ApiKey, nil)
if err != nil {
return News{
Status: err.Error(),
}
}
resp, err := client.Do(req)
if err != nil {
return News{
Status: err.Error(),
}
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
return
}
}(resp.Body)
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return News{
Status: err.Error(),
}
}
news := News{}
err = json.Unmarshal(respBody, &news)
if err != nil {
log.Fatal(err)
}
sanitizeNews(&news)
return news
}
func sanitizeNews(news *News) {
news.Status = removeInvisibleCharacters(news.Status)
for i := range news.Articles {
news.Articles[i].Author = removeInvisibleCharacters(news.Articles[i].Author)
news.Articles[i].Title = removeInvisibleCharacters(news.Articles[i].Title)
news.Articles[i].Description = removeInvisibleCharacters(news.Articles[i].Description)
news.Articles[i].URL = removeInvisibleCharacters(news.Articles[i].URL)
news.Articles[i].URLToImage = removeInvisibleCharacters(news.Articles[i].URLToImage)
news.Articles[i].PublishedAt = removeInvisibleCharacters(news.Articles[i].PublishedAt)
news.Articles[i].Content = removeInvisibleCharacters(news.Articles[i].Content)
news.Articles[i].Source.ID = removeInvisibleCharacters(news.Articles[i].Source.ID)
news.Articles[i].Source.Name = removeInvisibleCharacters(news.Articles[i].Source.Name)
}
}
func removeInvisibleCharacters(s string) string {
return strings.Map(func(r rune) rune {
switch r {
case '\u00A0':
return ' '
case '\r', '\u2028', '\u2029':
return ' '
}
if unicode.Is(unicode.Cf, r) {
return ' '
}
return r
}, s)
}