aboutsummaryrefslogtreecommitdiff
path: root/cmd/web/handlers/rss.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/web/handlers/rss.go')
-rw-r--r--cmd/web/handlers/rss.go218
1 files changed, 218 insertions, 0 deletions
diff --git a/cmd/web/handlers/rss.go b/cmd/web/handlers/rss.go
new file mode 100644
index 0000000..3e3019d
--- /dev/null
+++ b/cmd/web/handlers/rss.go
@@ -0,0 +1,218 @@
+package handlers
+
+import (
+ "database/sql"
+ "html/template"
+ "log"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/mmcdole/gofeed"
+ "paterissa.net/mblog/internal/models"
+)
+
+type video struct {
+ Title string
+ Description string
+ Published string
+ Link string
+}
+
+type rssContext struct {
+ err *log.Logger
+ db *sql.DB
+
+ Feed models.Feed
+ Videos []video
+ Rows []models.Feed
+ IsAuth bool
+}
+
+func (ctx *rssContext) new(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "POST" {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ w.Write([]byte("Method Not Allowed"))
+ return
+ }
+
+ cookie, err := r.Cookie("paterissa_session_token")
+ if err != nil {
+ w.WriteHeader(http.StatusUnauthorized)
+ w.Write([]byte("Unauthorized"))
+ return
+ }
+
+ err = r.ParseForm()
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Server Error"))
+ return
+ }
+
+ name := r.Form.Get("name")
+ url := r.Form.Get("url")
+
+ stmt, err := ctx.db.Prepare("SELECT * FROM cookies WHERE content = $1;")
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not load cookies from DB: %v\n", err)
+ return
+ }
+ defer stmt.Close()
+
+ var id uint64
+ var content string
+ var userId uint64
+ var expiration time.Time
+
+ row := stmt.QueryRow(cookie.Value)
+ err = row.Scan(&id, &content, &userId, &expiration)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ return
+ }
+
+ insertStmt, err := ctx.db.Prepare("INSERT INTO feeds (name, user_id, url) VALUES ($1, $2, $3);")
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not prepare insert statement to DB: %v\n", err)
+ return
+ }
+ defer insertStmt.Close()
+
+ _, err = insertStmt.Exec(name, userId, url)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not execute feed into DB: %v\n", err)
+ return
+ }
+
+ http.Redirect(w, r, "/feeds", http.StatusFound)
+ return
+}
+
+func (ctx *rssContext) feed(w http.ResponseWriter, r *http.Request) {
+ ctx.Videos = []video{}
+ ctx.Feed = models.Feed{}
+
+ id := r.URL.Query().Get("id")
+
+ stmt, err := ctx.db.Prepare("SELECT * FROM feeds WHERE id = $1;")
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not load feeds from DB: %v\n", err)
+ return
+ }
+ defer stmt.Close()
+
+ var f models.Feed
+
+ row := stmt.QueryRow(id)
+ err = row.Scan(&f.Id, &f.Name, &f.User, &f.Url)
+
+ ctx.Feed = f
+
+ parser := gofeed.NewParser()
+ feed, err := parser.ParseURL(f.Url)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not parse RSS feed: %v\n", err)
+ return
+ }
+
+ for _, raw := range feed.Items {
+ var v video
+
+ v.Title = raw.Title
+ v.Description = raw.Extensions["media"]["group"][0].Children["description"][0].Value
+ v.Published = raw.Published
+ v.Link = strings.Replace(raw.Link, "watch?v=", "embed/", 1)
+
+ ctx.Videos = append(ctx.Videos, v)
+ }
+
+ files := []string{
+ "ui/html/base.tmpl.html",
+ "ui/html/music_player.tmpl.html",
+ "ui/html/pages/feed.tmpl.html",
+ }
+
+ compiled, err := template.ParseFiles(files...)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not parse template: %v\n", err)
+ return
+ }
+
+ err = compiled.ExecuteTemplate(w, "base", ctx)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not execute template: %v\n", err)
+ return
+ }
+
+ return
+}
+
+func (ctx *rssContext) index(w http.ResponseWriter, r *http.Request) {
+ ctx.Rows = []models.Feed{}
+ ctx.IsAuth = false
+
+ _, err := r.Cookie("paterissa_session_token")
+ if err == nil {
+ ctx.IsAuth = true
+ }
+
+ rows, err := ctx.db.Query("SELECT f.id, f.name, u.name, f.url FROM feeds f INNER JOIN logins u ON f.user_id = u.id ORDER BY f.name DESC;")
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not load posts from DB: %v\n", err)
+ return
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ var f models.Feed
+
+ if err = rows.Scan(&f.Id, &f.Name, &f.User, &f.Url); err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not load posts from DB: %v\n", err)
+ return
+ }
+
+ ctx.Rows = append(ctx.Rows, f)
+ }
+
+ files := []string{
+ "ui/html/base.tmpl.html",
+ "ui/html/music_player.tmpl.html",
+ "ui/html/pages/feed_index.tmpl.html",
+ }
+
+ compiled, err := template.ParseFiles(files...)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not parse template: %v\n", err)
+ return
+ }
+
+ err = compiled.ExecuteTemplate(w, "base", ctx)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not execute template: %v\n", err)
+ return
+ }
+}