diff --git a/main.go b/main.go index fcaa918..d778d89 100644 --- a/main.go +++ b/main.go @@ -1,75 +1,40 @@ package main import ( - "embed" "encoding/json" "html/template" - "io/ioutil" "log" "net/http" - "sync" + "rss-reader/globals" + "rss-reader/models" + + "rss-reader/utils" "time" "github.com/gorilla/websocket" - "github.com/mmcdole/gofeed" -) - -type Config struct { - Values []string `json:"values"` - ReFresh int `json:"refresh"` - AutoUpdatePush int `json:"autoUpdatePush"` -} - -var ( - dbMap map[string]feed - rssUrls Config - upgrader = websocket.Upgrader{} - lock sync.RWMutex - - //go:embed static - dirStatic embed.FS - //go:embed index.html - fileIndex embed.FS - - htmlContent []byte ) func init() { - // 读取配置文件 - data, err := ioutil.ReadFile("config.json") - if err != nil { - panic(err) - } - // 解析JSON数据到Config结构体 - err = json.Unmarshal(data, &rssUrls) - if err != nil { - panic(err) - } - // 读取 index.html 内容 - htmlContent, err = fileIndex.ReadFile("index.html") - if err != nil { - panic(err) - } - - dbMap = make(map[string]feed) + globals.Init() } func main() { - go updateFeeds() + go utils.UpdateFeeds() + go utils.WatchConfigFileChanges("config.json") http.HandleFunc("/feeds", getFeedsHandler) http.HandleFunc("/ws", wsHandler) // http.HandleFunc("/", serveHome) http.HandleFunc("/", tplHandler) //加载静态文件 - fs := http.FileServer(http.FS(dirStatic)) + fs := http.FileServer(http.FS(globals.DirStatic)) http.Handle("/static/", fs) log.Fatal(http.ListenAndServe(":8080", nil)) } func serveHome(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "text/html; charset=utf-8") - w.Write(htmlContent) + w.Write(globals.HtmlContent) } func tplHandler(w http.ResponseWriter, r *http.Request) { @@ -82,19 +47,30 @@ func tplHandler(w http.ResponseWriter, r *http.Request) { }, } // 加载模板文件 - tmpl, err := tmplInstance.Funcs(funcMap).ParseFS(fileIndex, "index.html") + tmpl, err := tmplInstance.Funcs(funcMap).ParseFS(globals.DirStatic, "static/index.html") if err != nil { log.Println("模板加载错误:", err) return } + //判断现在是否是夜间 + formattedTime := time.Now().Format("15:04:05") + darkMode := false + if globals.RssUrls.NightStartTime != "" && globals.RssUrls.NightEndTime != "" { + if globals.RssUrls.NightStartTime > formattedTime || formattedTime > globals.RssUrls.NightEndTime { + darkMode = true + } + } + // 定义一个数据对象 data := struct { Keywords string - RssDataList []feed + RssDataList []models.Feed + DarkMode bool }{ Keywords: getKeywords(), - RssDataList: getFeeds(), + RssDataList: utils.GetFeeds(), + DarkMode: darkMode, } // 渲染模板并将结果写入响应 @@ -105,7 +81,7 @@ func tplHandler(w http.ResponseWriter, r *http.Request) { } func wsHandler(w http.ResponseWriter, r *http.Request) { - conn, err := upgrader.Upgrade(w, r, nil) + conn, err := globals.Upgrader.Upgrade(w, r, nil) if err != nil { log.Printf("Upgrade failed: %v", err) return @@ -113,10 +89,10 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { defer conn.Close() for { - for _, url := range rssUrls.Values { - lock.RLock() - cache, ok := dbMap[url] - lock.RUnlock() + for _, url := range globals.RssUrls.Values { + globals.Lock.RLock() + cache, ok := globals.DbMap[url] + globals.Lock.RUnlock() if !ok { log.Printf("Error getting feed from db is null %v", url) continue @@ -135,83 +111,21 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { } } //如果未配置则不自动更新 - if rssUrls.AutoUpdatePush == 0 { + if globals.RssUrls.AutoUpdatePush == 0 { return } - time.Sleep(time.Duration(rssUrls.AutoUpdatePush) * time.Minute) + time.Sleep(time.Duration(globals.RssUrls.AutoUpdatePush) * time.Minute) } } -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 { - go updateFeed(fp, url, formattedTime) - } - <-tick - } -} - -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列表 -func getFeeds() []feed { - feeds := make([]feed, 0, len(rssUrls.Values)) - for _, url := range rssUrls.Values { - lock.RLock() - cache, ok := dbMap[url] - lock.RUnlock() - if !ok { - log.Printf("Error getting feed from db is null %v", url) - continue - } - - feeds = append(feeds, cache) - } - return feeds -} - //获取关键词也就是title //获取feeds列表 func getKeywords() string { words := "" - for _, url := range rssUrls.Values { - lock.RLock() - cache, ok := dbMap[url] - lock.RUnlock() + for _, url := range globals.RssUrls.Values { + globals.Lock.RLock() + cache, ok := globals.DbMap[url] + globals.Lock.RUnlock() if !ok { log.Printf("Error getting feed from db is null %v", url) continue @@ -224,7 +138,7 @@ func getKeywords() string { } func getFeedsHandler(w http.ResponseWriter, r *http.Request) { - feeds := getFeeds() + feeds := utils.GetFeeds() w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(feeds)