forked from sneak/hnblogs
initial
This commit is contained in:
102
hnblogs.go
Normal file
102
hnblogs.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package hnblogs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const BlogsURL = "https://raw.githubusercontent.com/surprisetalk/blogs.hn/main/blogs.json"
|
||||
|
||||
// Blog represents a single blog entry.
|
||||
type Blog struct {
|
||||
URL string `json:"url"`
|
||||
Title string `json:"title"`
|
||||
About string `json:"about"`
|
||||
Now string `json:"now"`
|
||||
Feed string `json:"feed"`
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
var (
|
||||
blogs []Blog
|
||||
fetchError error
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
// FetchBlogs fetches the list of blogs and memoizes it in RAM.
|
||||
func FetchBlogs() ([]Blog, error) {
|
||||
once.Do(func() {
|
||||
resp, err := http.Get(BlogsURL)
|
||||
if err != nil {
|
||||
fetchError = fmt.Errorf("failed to fetch blogs: %v", err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
fetchError = fmt.Errorf("failed to fetch blogs: status code %d", resp.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
var fetchedBlogs []Blog
|
||||
if err := json.NewDecoder(resp.Body).Decode(&fetchedBlogs); err != nil {
|
||||
fetchError = fmt.Errorf("failed to decode blogs JSON: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
blogs = fetchedBlogs
|
||||
})
|
||||
|
||||
return blogs, fetchError
|
||||
}
|
||||
|
||||
// GetBlogs returns the memoized list of blogs.
|
||||
func GetBlogs() ([]Blog, error) {
|
||||
return FetchBlogs()
|
||||
}
|
||||
|
||||
// RandomBlog returns a random blog from the list of blogs.
|
||||
func RandomBlog() (Blog, error) {
|
||||
blogs, err := GetBlogs()
|
||||
if err != nil {
|
||||
return Blog{}, err
|
||||
}
|
||||
|
||||
return blogs[rand.Intn(len(blogs))], nil
|
||||
}
|
||||
|
||||
// RandomBlogs returns n random blogs from the list of blogs.
|
||||
func RandomBlogs(n int) ([]Blog, error) {
|
||||
blogs, err := GetBlogs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if n <= 0 || n > len(blogs) {
|
||||
return nil, fmt.Errorf("invalid number of blogs requested")
|
||||
}
|
||||
|
||||
selected := make([]Blog, n)
|
||||
for i := range selected {
|
||||
selected[i] = blogs[rand.Intn(len(blogs))]
|
||||
}
|
||||
|
||||
return selected, nil
|
||||
}
|
||||
|
||||
// NthBlog returns the nth blog from the list of blogs.
|
||||
func NthBlog(n int) (Blog, error) {
|
||||
blogs, err := GetBlogs()
|
||||
if err != nil {
|
||||
return Blog{}, err
|
||||
}
|
||||
|
||||
if n < 0 || n >= len(blogs) {
|
||||
return Blog{}, fmt.Errorf("index out of range")
|
||||
}
|
||||
|
||||
return blogs[n], nil
|
||||
}
|
||||
Reference in New Issue
Block a user