summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavy wybiral <davy.wybiral@gmail.com>2019-08-08 06:04:39 -0500
committerGitHub <noreply@github.com>2019-08-08 06:04:39 -0500
commit6b09ccd9d885a3230a197f7d42fa1fcc760a25ef (patch)
tree39bbbb55e489989c0c89ed9af2e45d7eaf6d1fd1
parent02762c812ccd692d61328bc76029b9cc01ed8bb4 (diff)
cache rss feed (#19)v0.2.0
-rw-r--r--pkg/app/app.go65
-rw-r--r--pkg/app/feed.go77
-rw-r--r--pkg/app/watcher.go4
3 files changed, 84 insertions, 62 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 1f6b769..0efd22a 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -8,14 +8,9 @@ import (
"log"
"net"
"net/http"
- "net/url"
- "os"
"path"
- "strconv"
- "time"
"github.com/fsnotify/fsnotify"
- "github.com/gorilla/feeds"
"github.com/gorilla/mux"
"github.com/wybiral/tube/pkg/media"
"github.com/wybiral/tube/pkg/onionkey"
@@ -27,6 +22,7 @@ type App struct {
Library *media.Library
Watcher *fsnotify.Watcher
Templates *template.Template
+ Feed []byte
Tor *tor
Listener net.Listener
Router *mux.Router
@@ -123,6 +119,7 @@ func (a *App) Run() error {
}
a.Watcher.Add(p.Path)
}
+ buildFeed(a)
go startWatcher(a)
return http.Serve(a.Listener, a.Router)
}
@@ -219,63 +216,7 @@ func (a *App) thumbHandler(w http.ResponseWriter, r *http.Request) {
// HTTP handler for /feed.xml
func (a *App) rssHandler(w http.ResponseWriter, r *http.Request) {
- cfg := a.Config.Feed
- now := time.Now()
- f := &feeds.Feed{
- Title: cfg.Title,
- Link: &feeds.Link{Href: cfg.Link},
- Description: cfg.Description,
- Author: &feeds.Author{
- Name: cfg.Author.Name,
- Email: cfg.Author.Email,
- },
- Created: now,
- Copyright: cfg.Copyright,
- }
- var externalURL string
- if len(cfg.ExternalURL) > 0 {
- externalURL = cfg.ExternalURL
- } else if a.Tor != nil {
- onion, err := a.Tor.OnionKey.Onion()
- if err != nil {
- return
- }
- externalURL = fmt.Sprintf("http://%s.onion", onion.ServiceID)
- } else {
- hostname, err := os.Hostname()
- if err != nil {
- host := a.Config.Server.Host
- port := a.Config.Server.Port
- externalURL = fmt.Sprintf("http://%s:%d", host, port)
- } else {
- externalURL = fmt.Sprintf("http://%s", hostname)
- }
- }
- for _, v := range a.Library.Playlist() {
- u, err := url.Parse(externalURL)
- if err != nil {
- return
- }
- u.Path = path.Join(u.Path, "v", v.ID)
- id := u.String()
- f.Items = append(f.Items, &feeds.Item{
- Id: id,
- Title: v.Title,
- Link: &feeds.Link{Href: id},
- Description: v.Description,
- Enclosure: &feeds.Enclosure{
- Url: id + ".mp4",
- Length: strconv.FormatInt(v.Size, 10),
- Type: "video/mp4",
- },
- Author: &feeds.Author{
- Name: cfg.Author.Name,
- Email: cfg.Author.Email,
- },
- Created: v.Timestamp,
- })
- }
w.Header().Set("Cache-Control", "public, max-age=7776000")
w.Header().Set("Content-Type", "text/xml")
- f.WriteRss(w)
+ w.Write(a.Feed)
}
diff --git a/pkg/app/feed.go b/pkg/app/feed.go
new file mode 100644
index 0000000..e4c1ce2
--- /dev/null
+++ b/pkg/app/feed.go
@@ -0,0 +1,77 @@
+package app
+
+import (
+ "fmt"
+ "net/url"
+ "os"
+ "path"
+ "strconv"
+ "time"
+
+ "github.com/wybiral/feeds"
+)
+
+// buildFeed creates RSS feed attribute for App based on Library contents.
+func buildFeed(a *App) {
+ cfg := a.Config.Feed
+ now := time.Now()
+ f := &feeds.Feed{
+ Title: cfg.Title,
+ Link: &feeds.Link{Href: cfg.Link},
+ Description: cfg.Description,
+ Author: &feeds.Author{
+ Name: cfg.Author.Name,
+ Email: cfg.Author.Email,
+ },
+ Created: now,
+ Copyright: cfg.Copyright,
+ }
+ var externalURL string
+ if len(cfg.ExternalURL) > 0 {
+ externalURL = cfg.ExternalURL
+ } else if a.Tor != nil {
+ onion, err := a.Tor.OnionKey.Onion()
+ if err != nil {
+ return
+ }
+ externalURL = fmt.Sprintf("http://%s.onion", onion.ServiceID)
+ } else {
+ hostname, err := os.Hostname()
+ if err != nil {
+ host := a.Config.Server.Host
+ port := a.Config.Server.Port
+ externalURL = fmt.Sprintf("http://%s:%d", host, port)
+ } else {
+ externalURL = fmt.Sprintf("http://%s", hostname)
+ }
+ }
+ for _, v := range a.Library.Playlist() {
+ u, err := url.Parse(externalURL)
+ if err != nil {
+ return
+ }
+ u.Path = path.Join(u.Path, "v", v.ID)
+ id := u.String()
+ f.Items = append(f.Items, &feeds.Item{
+ Id: id,
+ Title: v.Title,
+ Link: &feeds.Link{Href: id},
+ Description: v.Description,
+ Enclosure: &feeds.Enclosure{
+ Url: id + ".mp4",
+ Length: strconv.FormatInt(v.Size, 10),
+ Type: "video/mp4",
+ },
+ Author: &feeds.Author{
+ Name: cfg.Author.Name,
+ Email: cfg.Author.Email,
+ },
+ Created: v.Timestamp,
+ })
+ }
+ feed, err := f.ToRss()
+ if err != nil {
+ return
+ }
+ a.Feed = []byte(feed)
+}
diff --git a/pkg/app/watcher.go b/pkg/app/watcher.go
index 2d7a761..624e470 100644
--- a/pkg/app/watcher.go
+++ b/pkg/app/watcher.go
@@ -36,6 +36,7 @@ func startWatcher(a *App) {
// reset timer
timer.Reset(debounceTimeout)
case <-timer.C:
+ eventCount := len(removeEvents) + len(addEvents)
// handle remove events first
if len(removeEvents) > 0 {
for p := range removeEvents {
@@ -52,6 +53,9 @@ func startWatcher(a *App) {
// clear map
addEvents = make(map[string]struct{})
}
+ if eventCount > 0 {
+ buildFeed(a)
+ }
// reset timer
timer.Reset(debounceTimeout)
}