From 8a1517f86e4c9b6f92fdf8bc8abbcdece923f978 Mon Sep 17 00:00:00 2001 From: srcrs Date: Thu, 27 Jul 2023 10:59:35 -0400 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 17 ++++ docker-compose.yml | 16 ++-- go.mod | 22 +++++ go.sum | 49 +++++++++++ index.html | 202 ++++++++++++++++++++++----------------------- main.go | 105 +++++++++++++++++++++++ 6 files changed, 299 insertions(+), 112 deletions(-) create mode 100644 Dockerfile create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6931c89 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM golang:1.20.4-alpine3.18 AS builder + +COPY . /src +WORKDIR /src + +RUN go build -ldflags "-s -w" -o ./bin/ . + +FROM alpine + +COPY --from=builder /src/bin /app +COPY --from=builder /src/index.html /app/index.html + +WORKDIR /app + +EXPOSE 8080 + +ENTRYPOINT ["./ownrss"] diff --git a/docker-compose.yml b/docker-compose.yml index 973e7d6..5d1ca36 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,12 @@ version: "3" services: - ownrss: - image: nginx:alpine + server: + build: + context: . container_name: ownrss restart: always ports: - - 10016:80 + - "10060:8080" volumes: - - $PWD/index.html:/usr/share/nginx/html/index.html - - $PWD/config.json:/usr/share/nginx/html/config.json - cors: - image: chrissi2812/cors-anywhere - container_name: cors-anywhere - restart: always - ports: - - 10015:8080 + - "$PWD/index.html:/app/index.html" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..cf55e1d --- /dev/null +++ b/go.mod @@ -0,0 +1,22 @@ +module ownrss + +go 1.18 + +require ( + github.com/go-redis/redis/v8 v8.11.5 + github.com/mmcdole/gofeed v1.2.1 +) + +require ( + github.com/PuerkitoBio/goquery v1.8.0 // indirect + github.com/andybalholm/cascadia v1.3.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mmcdole/goxpp v1.1.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + golang.org/x/net v0.4.0 // indirect + golang.org/x/text v0.5.0 // indirect +) + diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c60e3c1 --- /dev/null +++ b/go.sum @@ -0,0 +1,49 @@ +github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= +github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= +github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= +github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/mmcdole/gofeed v1.2.1 h1:tPbFN+mfOLcM1kDF1x2c/N68ChbdBatkppdzf/vDe1s= +github.com/mmcdole/gofeed v1.2.1/go.mod h1:2wVInNpgmC85q16QTTuwbuKxtKkHLCDDtf0dCmnrNr4= +github.com/mmcdole/goxpp v1.1.0 h1:WwslZNF7KNAXTFuzRtn/OKZxFLJAAyOA9w82mDz2ZGI= +github.com/mmcdole/goxpp v1.1.0/go.mod h1:v+25+lT2ViuQ7mVxcncQ8ch1URund48oH+jhjiwEgS8= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +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/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.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +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.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= + diff --git a/index.html b/index.html index 6a8e462..223d1c7 100644 --- a/index.html +++ b/index.html @@ -1,111 +1,111 @@ - - - - ownrss + + + + RSS Reader + + + + +
+ + +

RSS Reader

+
+ + + + +
+ {{ feed.title }} +
+ + + + {{ item.title }} + + + +
+
+
+
+
+
- addToFeed (entry, tag) { - this.feed.push({ - tag: tag, - title: (entry.title).substring(0,30), - link: entry.link, - date: (("isoDate" in entry) ? new Date(entry.isoDate) : new Date("1970-01-01")), - }) - if (!this.tags.includes(tag)) { - this.tags.push(tag) - } - }, + + + - + app.use(ElementPlus); + app.mount("#app"); + + diff --git a/main.go b/main.go new file mode 100644 index 0000000..0439242 --- /dev/null +++ b/main.go @@ -0,0 +1,105 @@ +package main + +import ( + "context" + "encoding/json" + "log" + "net/http" + "time" + + "github.com/go-redis/redis/v8" + "github.com/mmcdole/gofeed" +) + +var ctx = context.Background() +var rdb *redis.Client + +func init() { + rdb = redis.NewClient(&redis.Options{ + Addr: "xx.xx.xx.xx:6399", + Password: "xxxxxx", + DB: 0, + }) +} + +func main() { + go updateFeeds() + http.HandleFunc("/feeds", getFeedsHandler) + http.HandleFunc("/", serveHome) + log.Fatal(http.ListenAndServe(":8080", nil)) +} + +func serveHome(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "index.html") +} + +func updateFeeds() { + rssUrls := []string{ + // 添加您的RSS订阅链接 + "https://www.zhihu.com/rss", + "https://tech.meituan.com/feed/", + "http://www.ruanyifeng.com/blog/atom.xml", + "https://cn.wsj.com/zh-hans/rss", + "https://feeds.appinn.com/appinns/", + "https://v2ex.com/feed/tab/tech.xml", + "https://hostloc.com/forum.php?mod=rss&fid=45&auth=389ec3vtQanmEuRoghE%2FpZPWnYCPmvwWgSa7RsfjbQ%2BJpA%2F6y6eHAx%2FKqtmPOg", + } + + for { + for _, url := range rssUrls { + fp := gofeed.NewParser() + feed, err := fp.ParseURL(url) + if err != nil { + log.Printf("Error fetching feed: %v", err) + continue + } + + feedJSON, err := json.Marshal(feed) + if err != nil { + log.Printf("Error marshaling feed: %v", err) + continue + } + + err = rdb.Set(ctx, url, feedJSON, 0).Err() + if err != nil { + log.Printf("Error saving feed to Redis: %v", err) + } + } + time.Sleep(10 * time.Minute) + } +} + +func getFeedsHandler(w http.ResponseWriter, r *http.Request) { + rssUrls := []string{ + // 添加您的RSS订阅链接 + "https://www.zhihu.com/rss", + "https://tech.meituan.com/feed/", + "http://www.ruanyifeng.com/blog/atom.xml", + "https://cn.wsj.com/zh-hans/rss", + "https://feeds.appinn.com/appinns/", + "https://v2ex.com/feed/tab/tech.xml", + "https://hostloc.com/forum.php?mod=rss&fid=45&auth=389ec3vtQanmEuRoghE%2FpZPWnYCPmvwWgSa7RsfjbQ%2BJpA%2F6y6eHAx%2FKqtmPOg", + } + + feeds := make([]gofeed.Feed, 0, len(rssUrls)) + for _, url := range rssUrls { + feedJSON, err := rdb.Get(ctx, url).Result() + if err != nil { + log.Printf("Error getting feed from Redis: %v", err) + continue + } + + var feed gofeed.Feed + err = json.Unmarshal([]byte(feedJSON), &feed) + if err != nil { + log.Printf("Error unmarshaling feed: %v", err) + continue + } + + feeds = append(feeds, feed) + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(feeds) +} +