Compare commits
10 Commits
d0e4e09aab
...
129b3916ab
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
129b3916ab | ||
|
|
9f30853ded | ||
|
|
dcbeeebc20 | ||
|
|
3b2fb607a3 | ||
|
|
a9fdd31a4e | ||
|
|
8796bcc6c7 | ||
|
|
79ab3e511a | ||
|
|
3bf1dc961b | ||
|
|
837f187db7 | ||
|
|
4b968b7c81 |
10
README.md
10
README.md
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
- 简洁的页面布局,可以查看每个订阅链接最后更新时间
|
- 简洁的页面布局,可以查看每个订阅链接最后更新时间
|
||||||
|
|
||||||
|
- 支持夜间模式
|
||||||
|
|
||||||
|
- config.json配置文件支持热更新
|
||||||
|
|
||||||
2023年7月28日,进行了界面改版和升级
|
2023年7月28日,进行了界面改版和升级
|
||||||
|
|
||||||

|

|
||||||
@ -42,7 +46,9 @@
|
|||||||
"https://hostloc.com/forum.php?mod=rss&fid=45&auth=389ec3vtQanmEuRoghE%2FpZPWnYCPmvwWgSa7RsfjbQ%2BJpA%2F6y6eHAx%2FKqtmPOg"
|
"https://hostloc.com/forum.php?mod=rss&fid=45&auth=389ec3vtQanmEuRoghE%2FpZPWnYCPmvwWgSa7RsfjbQ%2BJpA%2F6y6eHAx%2FKqtmPOg"
|
||||||
],
|
],
|
||||||
"refresh": 6,
|
"refresh": 6,
|
||||||
"autoUpdatePush": 7
|
"autoUpdatePush": 7,
|
||||||
|
"nightStartTime": "06:30:00",
|
||||||
|
"nightEndTime": "19:30:00"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -51,6 +57,8 @@
|
|||||||
values | rss订阅链接(必填)
|
values | rss订阅链接(必填)
|
||||||
refresh | rss订阅更新时间间隔,单位分钟(必填)
|
refresh | rss订阅更新时间间隔,单位分钟(必填)
|
||||||
autoUpdatePush | 自动刷新间隔,默认为0,不开启。效果为前端每autoUpdatePush分钟自动更新页面信息,单位分钟(非必填)
|
autoUpdatePush | 自动刷新间隔,默认为0,不开启。效果为前端每autoUpdatePush分钟自动更新页面信息,单位分钟(非必填)
|
||||||
|
nightStartTime | 日间开始时间 ,如 06:30:00
|
||||||
|
nightEndTime | 日间结束时间,如 19:30:00
|
||||||
|
|
||||||
# 使用方式
|
# 使用方式
|
||||||
|
|
||||||
|
|||||||
0
config.json
Normal file → Executable file
0
config.json
Normal file → Executable file
@ -72,7 +72,12 @@
|
|||||||
<div id="app">
|
<div id="app">
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header>
|
<el-header>
|
||||||
<h1>RSS Reader</h1>
|
<h1>
|
||||||
|
RSS Reader
|
||||||
|
<< if gt .AutoUpdatePush 0 >>
|
||||||
|
<span v-show="isPc"><br/>{{ countdown }} s</span>
|
||||||
|
<< end >>
|
||||||
|
</h1>
|
||||||
</el-header>
|
</el-header>
|
||||||
<el-main v-loading.fullscreen.lock="fullscreenLoading" element-loading-text="拼命加载中">
|
<el-main v-loading.fullscreen.lock="fullscreenLoading" element-loading-text="拼命加载中">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@ -150,10 +155,15 @@
|
|||||||
feeds: [],
|
feeds: [],
|
||||||
showSEOFlag: true,
|
showSEOFlag: true,
|
||||||
fullscreenLoading: true,
|
fullscreenLoading: true,
|
||||||
|
countdown: 60,
|
||||||
|
isPc: true,
|
||||||
|
autoUpdatePush: << .AutoUpdatePush >>,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
this.fullscreenLoading = false;
|
this.fullscreenLoading = false;
|
||||||
|
// 使用媒体查询判断设备类型
|
||||||
|
this.isPc = !window.matchMedia('(max-width: 767px)').matches;
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||||
@ -169,17 +179,39 @@
|
|||||||
}
|
}
|
||||||
this.showSEOFlag = false;
|
this.showSEOFlag = false;
|
||||||
};
|
};
|
||||||
|
const reloadHtml = () => {
|
||||||
|
if (socket.readyState === WebSocket.CLOSED || socket.readyState === WebSocket.CLOSING) {
|
||||||
|
if (document.visibilityState === 'visible') {
|
||||||
|
// 刷新网页
|
||||||
|
console.log("reload...")
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
socket.onclose = event => {
|
socket.onclose = event => {
|
||||||
|
if (this.isPc && this.autoUpdatePush > 0) {
|
||||||
console.log("WebSocket closed. Reconnecting...");
|
console.log("WebSocket closed. Reconnecting...");
|
||||||
setTimeout(connect, 300000);
|
setInterval(reloadHtml, 3000);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Send heartbeat message every 120 seconds
|
// Send heartbeat message every 60 seconds
|
||||||
const sendHeartbeat = () => {
|
const sendHeartbeat = () => {
|
||||||
if (socket.readyState === WebSocket.OPEN) {
|
if (socket.readyState === WebSocket.OPEN) {
|
||||||
socket.send("heartbeat");
|
socket.send("heartbeat");
|
||||||
|
} else if (socket.readyState === WebSocket.CLOSED || socket.readyState === WebSocket.CLOSING) {
|
||||||
|
reloadHtml()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setInterval(sendHeartbeat, 120000);
|
if (this.isPc && this.autoUpdatePush > 0) {
|
||||||
|
setInterval(sendHeartbeat, 60000);
|
||||||
|
setInterval(() => {
|
||||||
|
if (this.countdown > 0) {
|
||||||
|
this.countdown--;
|
||||||
|
} else {
|
||||||
|
this.countdown = 60;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
connect();
|
connect();
|
||||||
},
|
},
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -3,6 +3,7 @@ module rss-reader
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/mmcdole/gofeed v1.2.1
|
github.com/mmcdole/gofeed v1.2.1
|
||||||
)
|
)
|
||||||
@ -15,5 +16,6 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
golang.org/x/net v0.4.0 // indirect
|
golang.org/x/net v0.4.0 // indirect
|
||||||
|
golang.org/x/sys v0.3.0 // indirect
|
||||||
golang.org/x/text v0.5.0 // indirect
|
golang.org/x/text v0.5.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
5
go.sum
5
go.sum
@ -5,6 +5,8 @@ github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEq
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
@ -29,6 +31,9 @@ golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
|||||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||||
|
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||||
|
|||||||
2
main.go
2
main.go
@ -67,10 +67,12 @@ func tplHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
Keywords string
|
Keywords string
|
||||||
RssDataList []models.Feed
|
RssDataList []models.Feed
|
||||||
DarkMode bool
|
DarkMode bool
|
||||||
|
AutoUpdatePush int
|
||||||
}{
|
}{
|
||||||
Keywords: getKeywords(),
|
Keywords: getKeywords(),
|
||||||
RssDataList: utils.GetFeeds(),
|
RssDataList: utils.GetFeeds(),
|
||||||
DarkMode: darkMode,
|
DarkMode: darkMode,
|
||||||
|
AutoUpdatePush: globals.RssUrls.AutoUpdatePush,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染模板并将结果写入响应
|
// 渲染模板并将结果写入响应
|
||||||
|
|||||||
@ -2,10 +2,11 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"rss-reader/globals"
|
"rss-reader/globals"
|
||||||
"rss-reader/models"
|
"rss-reader/models"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fsnotify/fsnotify"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UpdateFeeds() {
|
func UpdateFeeds() {
|
||||||
@ -70,33 +71,47 @@ func GetFeeds() []models.Feed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WatchConfigFileChanges(filePath string) {
|
func WatchConfigFileChanges(filePath string) {
|
||||||
// 获取初始文件信息
|
// 创建一个新的监控器
|
||||||
initialFileInfo, err := os.Stat(filePath)
|
watcher, err := fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("无法获取文件信息:", err)
|
log.Fatal(err)
|
||||||
return
|
}
|
||||||
|
defer watcher.Close()
|
||||||
|
|
||||||
|
// 添加要监控的文件
|
||||||
|
err = watcher.Add(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 启动一个 goroutine 来处理文件变化事件
|
||||||
|
go func() {
|
||||||
for {
|
for {
|
||||||
// 每隔一段时间检查文件是否有变化
|
|
||||||
time.Sleep(7 * time.Second)
|
time.Sleep(7 * time.Second)
|
||||||
|
select {
|
||||||
// 获取最新的文件信息
|
case event, ok := <-watcher.Events:
|
||||||
currentFileInfo, err := os.Stat(filePath)
|
if !ok {
|
||||||
if err != nil {
|
log.Println("通道关闭1")
|
||||||
log.Println("无法获取文件信息:", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||||
// 检查文件的修改时间是否有变化
|
|
||||||
if currentFileInfo.ModTime() != initialFileInfo.ModTime() {
|
|
||||||
log.Println("文件已修改")
|
log.Println("文件已修改")
|
||||||
initialFileInfo = currentFileInfo
|
|
||||||
globals.Init()
|
globals.Init()
|
||||||
formattedTime := time.Now().Format("2006-01-02 15:04:05")
|
formattedTime := time.Now().Format("2006-01-02 15:04:05")
|
||||||
for _, url := range globals.RssUrls.Values {
|
for _, url := range globals.RssUrls.Values {
|
||||||
go UpdateFeed(url, formattedTime)
|
go UpdateFeed(url, formattedTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case err, ok := <-watcher.Errors:
|
||||||
|
if !ok {
|
||||||
|
log.Println("通道关闭2")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
log.Println("错误:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user