158 lines
3.5 KiB
Go
158 lines
3.5 KiB
Go
package rssapi
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"write-server/internal/config"
|
|
)
|
|
|
|
type Feed struct {
|
|
URL string `json:"url"`
|
|
FeedTitle string `json:"feedTitle"`
|
|
SiteURL string `json:"siteUrl,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
type FeedHealth struct {
|
|
URL string `json:"url"`
|
|
Status int `json:"status"`
|
|
OK bool `json:"ok"`
|
|
Latency int `json:"latency,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
type Link struct {
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
Description string `json:"description,omitempty"`
|
|
Image string `json:"image,omitempty"`
|
|
Hidden bool `json:"hidden,omitempty"`
|
|
RSS string `json:"rss,omitempty"`
|
|
AddedAt string `json:"addedAt,omitempty"`
|
|
}
|
|
|
|
func rssFetch(path string, method string, body interface{}) (map[string]interface{}, error) {
|
|
u := config.RSS_API_BASE + path
|
|
var req *http.Request
|
|
var err error
|
|
|
|
if body != nil && (method == "POST" || method == "PUT") {
|
|
data, _ := json.Marshal(body)
|
|
req, err = http.NewRequest(method, u, bytes.NewReader(data))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
} else {
|
|
req, err = http.NewRequest(method, u, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if config.RSS_API_TOKEN != "" {
|
|
q := req.URL.Query()
|
|
q.Set("token", config.RSS_API_TOKEN)
|
|
req.URL.RawQuery = q.Encode()
|
|
}
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
data, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := json.Unmarshal(data, &result); err != nil {
|
|
return nil, fmt.Errorf("RSS API error: %d", resp.StatusCode)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func GetFeeds() ([]Feed, error) {
|
|
result, err := rssFetch("/api/rss/feeds", "GET", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var feeds []Feed
|
|
if raw, ok := result["feeds"]; ok {
|
|
data, _ := json.Marshal(raw)
|
|
json.Unmarshal(data, &feeds)
|
|
}
|
|
return feeds, nil
|
|
}
|
|
|
|
func AddFeed(feedURL, feedTitle string) error {
|
|
_, err := rssFetch("/api/rss/feeds", "POST", map[string]string{
|
|
"url": feedURL,
|
|
"feedTitle": feedTitle,
|
|
})
|
|
return err
|
|
}
|
|
|
|
func DeleteFeed(feedURL string) error {
|
|
_, err := rssFetch("/api/rss/feeds?url="+url.QueryEscape(feedURL), "DELETE", nil)
|
|
return err
|
|
}
|
|
|
|
func UpdateFeed(oldURL, newURL, feedTitle string) error {
|
|
_, err := rssFetch("/api/rss/feeds", "PUT", map[string]string{
|
|
"oldUrl": oldURL,
|
|
"url": newURL,
|
|
"feedTitle": feedTitle,
|
|
})
|
|
return err
|
|
}
|
|
|
|
func GetLinks(all bool) ([]Link, error) {
|
|
path := "/api/rss/links"
|
|
if all {
|
|
path += "?all=1"
|
|
}
|
|
result, err := rssFetch(path, "GET", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var links []Link
|
|
if raw, ok := result["links"]; ok {
|
|
data, _ := json.Marshal(raw)
|
|
json.Unmarshal(data, &links)
|
|
}
|
|
return links, nil
|
|
}
|
|
|
|
func AddLink(link Link) error {
|
|
_, err := rssFetch("/api/rss/links", "POST", link)
|
|
return err
|
|
}
|
|
|
|
func UpdateLink(oldURL string, data map[string]interface{}) error {
|
|
body := map[string]interface{}{"oldUrl": oldURL}
|
|
for k, v := range data {
|
|
if k != "oldUrl" {
|
|
body[k] = v
|
|
}
|
|
}
|
|
_, err := rssFetch("/api/rss/links", "PUT", body)
|
|
return err
|
|
}
|
|
|
|
func DeleteLink(linkURL string) error {
|
|
_, err := rssFetch("/api/rss/links?url="+url.QueryEscape(linkURL), "DELETE", nil)
|
|
return err
|
|
}
|
|
|
|
func CheckLinkHealth(targetURL string) (map[string]interface{}, error) {
|
|
return rssFetch("/api/rss/links?health="+url.QueryEscape(targetURL), "GET", nil)
|
|
}
|