commit
6160450fcf
14
feed.go
Normal file
14
feed.go
Normal file
@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
type feed struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
Link string `json:"link"`
|
||||
Custom map[string]string `json:"custom,omitempty"`
|
||||
Items []item `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
type item struct {
|
||||
Title string `json:"title"`
|
||||
Link string `json:"link"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
88
main.go
88
main.go
@ -20,9 +20,10 @@ type Config struct {
|
||||
}
|
||||
|
||||
var (
|
||||
dbMap sync.Map
|
||||
dbMap map[string]feed
|
||||
rssUrls Config
|
||||
upgrader = websocket.Upgrader{}
|
||||
lock sync.RWMutex
|
||||
|
||||
//go:embed static
|
||||
dirStatic embed.FS
|
||||
@ -48,6 +49,8 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
dbMap = make(map[string]feed)
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -73,15 +76,24 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("Upgrade failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
for {
|
||||
for _, url := range rssUrls.Values {
|
||||
feedJSON, ok := dbMap.Load(url)
|
||||
lock.RLock()
|
||||
cache, ok := dbMap[url]
|
||||
lock.RUnlock()
|
||||
if !ok {
|
||||
log.Printf("Error getting feed from db is null %v", url)
|
||||
continue
|
||||
}
|
||||
err = conn.WriteMessage(websocket.TextMessage, []byte(feedJSON.(string)))
|
||||
data, err := json.Marshal(cache)
|
||||
if err != nil {
|
||||
log.Printf("json marshal failure: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
err = conn.WriteMessage(websocket.TextMessage, data)
|
||||
//错误直接关闭更新
|
||||
if err != nil {
|
||||
log.Printf("Error sending message or Connection closed: %v", err)
|
||||
@ -97,46 +109,62 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func updateFeeds() {
|
||||
var (
|
||||
tick = time.Tick(time.Duration(rssUrls.ReFresh) * time.Minute)
|
||||
fp = gofeed.NewParser()
|
||||
)
|
||||
for {
|
||||
formattedTime := time.Now().Format("2006-01-02 15:04:05")
|
||||
for _, url := range rssUrls.Values {
|
||||
fp := gofeed.NewParser()
|
||||
feed, err := fp.ParseURL(url)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching feed: %v | %v", url, err)
|
||||
continue
|
||||
}
|
||||
currentTime := time.Now()
|
||||
formattedTime := currentTime.Format("2006-01-02 15:04:05")
|
||||
feed.Custom = map[string]string{"lastupdate": formattedTime}
|
||||
|
||||
feedJSON, err := json.Marshal(feed)
|
||||
if err != nil {
|
||||
log.Printf("Error marshaling feed: %v", err)
|
||||
continue
|
||||
}
|
||||
dbMap.Store(url, string(feedJSON))
|
||||
go updateFeed(fp, url, formattedTime)
|
||||
}
|
||||
time.Sleep(time.Duration(rssUrls.ReFresh) * time.Minute)
|
||||
<-tick
|
||||
}
|
||||
}
|
||||
|
||||
func getFeedsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func updateFeed(fp *gofeed.Parser, url, formattedTime string) {
|
||||
result, err := fp.ParseURL(url)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching feed: %v | %v", url, err)
|
||||
return
|
||||
}
|
||||
//feed内容无更新时无需更新缓存
|
||||
if cache, ok := dbMap[url]; ok &&
|
||||
len(result.Items) > 0 &&
|
||||
len(cache.Items) > 0 &&
|
||||
result.Items[0].Link == cache.Items[0].Link {
|
||||
return
|
||||
}
|
||||
customFeed := feed{
|
||||
Title: result.Title,
|
||||
Link: result.Link,
|
||||
Custom: map[string]string{"lastupdate": formattedTime},
|
||||
Items: make([]item, 0, len(result.Items)),
|
||||
}
|
||||
for _, v := range result.Items {
|
||||
customFeed.Items = append(customFeed.Items, item{
|
||||
Link: v.Link,
|
||||
Title: v.Title,
|
||||
Description: v.Description,
|
||||
})
|
||||
}
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
dbMap[url] = customFeed
|
||||
}
|
||||
|
||||
feeds := make([]gofeed.Feed, 0, len(rssUrls.Values))
|
||||
func getFeedsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
feeds := make([]feed, 0, len(rssUrls.Values))
|
||||
for _, url := range rssUrls.Values {
|
||||
feedJSON, ok := dbMap.Load(url)
|
||||
lock.RLock()
|
||||
cache, ok := dbMap[url]
|
||||
lock.RUnlock()
|
||||
if !ok {
|
||||
log.Printf("Error getting feed from db is null %v", url)
|
||||
continue
|
||||
}
|
||||
|
||||
var feed gofeed.Feed
|
||||
if err := json.Unmarshal([]byte(feedJSON.(string)), &feed); err != nil {
|
||||
log.Printf("Error unmarshaling feed: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
feeds = append(feeds, feed)
|
||||
feeds = append(feeds, cache)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user