aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Johnson <[email protected]>2025-11-26 01:55:22 -0500
committerSamuel Johnson <[email protected]>2025-11-26 01:55:22 -0500
commitd740821200f3bb89112ed08af84decf608d91732 (patch)
tree8b12316d31983bad71a629a29bd320e41eae3fb5
parentc72dfab37fd6f0d739ea70d42779b2a8c85e9915 (diff)
Add text RSS parser as well
-rw-r--r--cmd/web/handlers/rss.go76
-rw-r--r--internal/dbmigrations.go2
-rw-r--r--internal/models/feed.go14
-rw-r--r--static/app.css6
-rw-r--r--ui/html/pages/feed.tmpl.html10
-rw-r--r--ui/html/pages/feed_index.tmpl.html9
-rw-r--r--ui/html/pages/video_feed.tmpl.html15
7 files changed, 98 insertions, 34 deletions
diff --git a/cmd/web/handlers/rss.go b/cmd/web/handlers/rss.go
index 3e3019d..a1bfa92 100644
--- a/cmd/web/handlers/rss.go
+++ b/cmd/web/handlers/rss.go
@@ -12,6 +12,12 @@ import (
"paterissa.net/mblog/internal/models"
)
+type written struct {
+ Title string
+ Published string
+ Link string
+}
+
type video struct {
Title string
Description string
@@ -23,10 +29,11 @@ type rssContext struct {
err *log.Logger
db *sql.DB
- Feed models.Feed
- Videos []video
- Rows []models.Feed
- IsAuth bool
+ Feed models.Feed
+ Written []written
+ Videos []video
+ Rows []models.Feed
+ IsAuth bool
}
func (ctx *rssContext) new(w http.ResponseWriter, r *http.Request) {
@@ -52,6 +59,7 @@ func (ctx *rssContext) new(w http.ResponseWriter, r *http.Request) {
name := r.Form.Get("name")
url := r.Form.Get("url")
+ category := r.Form.Get("category")
stmt, err := ctx.db.Prepare("SELECT * FROM cookies WHERE content = $1;")
if err != nil {
@@ -75,7 +83,7 @@ func (ctx *rssContext) new(w http.ResponseWriter, r *http.Request) {
return
}
- insertStmt, err := ctx.db.Prepare("INSERT INTO feeds (name, user_id, url) VALUES ($1, $2, $3);")
+ insertStmt, err := ctx.db.Prepare("INSERT INTO feeds (name, user_id, url, category) VALUES ($1, $2, $3, $4);")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Internal Error"))
@@ -84,7 +92,17 @@ func (ctx *rssContext) new(w http.ResponseWriter, r *http.Request) {
}
defer insertStmt.Close()
- _, err = insertStmt.Exec(name, userId, url)
+ var categoryInt int
+ switch category {
+ case "YouTube":
+ categoryInt = models.YoutubeFeed
+ case "Text":
+ fallthrough
+ default:
+ categoryInt = models.TextFeed
+ }
+
+ _, err = insertStmt.Exec(name, userId, url, categoryInt)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Internal Error"))
@@ -114,7 +132,7 @@ func (ctx *rssContext) feed(w http.ResponseWriter, r *http.Request) {
var f models.Feed
row := stmt.QueryRow(id)
- err = row.Scan(&f.Id, &f.Name, &f.User, &f.Url)
+ err = row.Scan(&f.Id, &f.Name, &f.User, &f.Url, &f.Category)
ctx.Feed = f
@@ -127,21 +145,39 @@ func (ctx *rssContext) feed(w http.ResponseWriter, r *http.Request) {
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",
+ }
+
+ switch f.Category {
+ case models.YoutubeFeed:
+ files = append(files, "ui/html/pages/video_feed.tmpl.html")
+
+ 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)
+ }
+ case models.TextFeed:
+ fallthrough
+ default:
+ files = append(files, "ui/html/pages/feed.tmpl.html")
+
+ for _, raw := range feed.Items {
+ var t written
+
+ t.Title = raw.Title
+ t.Published = raw.Published
+ t.Link = raw.Link
+
+ ctx.Written = append(ctx.Written, t)
+ }
}
compiled, err := template.ParseFiles(files...)
@@ -172,7 +208,7 @@ func (ctx *rssContext) index(w http.ResponseWriter, r *http.Request) {
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;")
+ 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 ASC;")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Internal Error"))
diff --git a/internal/dbmigrations.go b/internal/dbmigrations.go
index 7d520ba..fcbaaaf 100644
--- a/internal/dbmigrations.go
+++ b/internal/dbmigrations.go
@@ -42,7 +42,7 @@ func Migrate(db *sql.DB, webmaster string, passOne string, passTwo string) {
_, table_check = db.Query("SELECT * FROM feeds;")
if table_check != nil {
- _, err := db.Exec("CREATE TABLE feeds (id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, user_id INTEGER REFERENCES logins(id), url VARCHAR(255) NOT NULL);")
+ _, err := db.Exec("CREATE TABLE feeds (id SERIAL PRIMARY KEY, name VARCHAR(50) NOT NULL, user_id INTEGER REFERENCES logins(id), url VARCHAR(255) NOT NULL, category INTEGER);")
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to create feeds table: %v\n", err)
os.Exit(1)
diff --git a/internal/models/feed.go b/internal/models/feed.go
index 9c68adb..289b1e6 100644
--- a/internal/models/feed.go
+++ b/internal/models/feed.go
@@ -1,8 +1,14 @@
package models
+const (
+ TextFeed = iota
+ YoutubeFeed
+)
+
type Feed struct {
- Id int
- Name string
- User string
- Url string
+ Id int
+ Name string
+ User string
+ Url string
+ Category int
}
diff --git a/static/app.css b/static/app.css
index 254cbc4..2b2c069 100644
--- a/static/app.css
+++ b/static/app.css
@@ -82,12 +82,16 @@ a:hover::after {
width: 75%;
background-color: rgba(0, 0, 0, 0.8);
- color: white;
+ color: #dcccd5;
border-radius: 20px;
box-shadow: 0px 0px 15px 2px #410f5e;
}
+input {
+ background-color: rgba(255, 255, 255, 0.8);
+}
+
.video {
background-color: rgba(0, 0, 0, 1.0);
}
diff --git a/ui/html/pages/feed.tmpl.html b/ui/html/pages/feed.tmpl.html
index 83332f2..bcf0033 100644
--- a/ui/html/pages/feed.tmpl.html
+++ b/ui/html/pages/feed.tmpl.html
@@ -1,15 +1,13 @@
{{define "title"}}{{.Feed.Name}}{{end}}
-{{define "description"}}"Recent videos from {{.Feed.Name}}"{{end}}
+{{define "description"}}"Recent content from {{.Feed.Name}}"{{end}}
{{define "main"}}
- {{range .Videos}}
+ {{range .Written}}
<div class="card">
- <div class="header">
+ <div class="flex_between">
<h4><b>{{.Title}} - {{.Published}}</b></h4>
- <iframe class="video" src="{{.Link}}"></iframe>
+ <a href="{{.Link}}" class="nav_tag right">Read</a>
</div>
- <p>{{.Description}}</p>
</div>
{{end}}
{{end}}
-
diff --git a/ui/html/pages/feed_index.tmpl.html b/ui/html/pages/feed_index.tmpl.html
index 59b37d4..2450240 100644
--- a/ui/html/pages/feed_index.tmpl.html
+++ b/ui/html/pages/feed_index.tmpl.html
@@ -1,11 +1,11 @@
{{define "title"}}RSS Feeds{{end}}
-{{define "description"}}"alternative to social media platforms"{{end}}
+{{define "description"}}"where I aggregate all the stuff I follow"{{end}}
{{define "main"}}
<div class="flex_between">
<div class="topline">
<h2>Feeds</h2>
- <p>Alternative to social media platforms</p>
+ <p>Where I aggregate all the stuff I follow</p>
</div>
<div class="spacer"></div>
{{if .IsAuth}}
@@ -21,6 +21,11 @@
<input type="text" id="name" name="name">
<label for="url">URL:</label>
<input type="text" id="url" name="url">
+ <label for="category">Category:</label>
+ <select id="category" name="category">
+ <option value="Text">Text</option>
+ <option value="YouTube">YouTube</option>
+ </select>
<div class="right">
<input type="submit" value="Submit">
</div>
diff --git a/ui/html/pages/video_feed.tmpl.html b/ui/html/pages/video_feed.tmpl.html
new file mode 100644
index 0000000..83332f2
--- /dev/null
+++ b/ui/html/pages/video_feed.tmpl.html
@@ -0,0 +1,15 @@
+{{define "title"}}{{.Feed.Name}}{{end}}
+{{define "description"}}"Recent videos from {{.Feed.Name}}"{{end}}
+
+{{define "main"}}
+ {{range .Videos}}
+ <div class="card">
+ <div class="header">
+ <h4><b>{{.Title}} - {{.Published}}</b></h4>
+ <iframe class="video" src="{{.Link}}"></iframe>
+ </div>
+ <p>{{.Description}}</p>
+ </div>
+ {{end}}
+{{end}}
+