Commiting changes long overdue

This commit is contained in:
Brian Buller 2020-09-28 13:03:57 -05:00
parent 8cc411b89d
commit 3fbcfdcb5d
12 changed files with 229 additions and 88 deletions

View File

@ -475,40 +475,57 @@ ZfY39XJelrPeb2dTP1e8O5VLPwIAAP//0xnP9ywDAAA=
`,
},
"/templates/rss_feed.xml": {
local: "templates/rss_feed.xml",
size: 700,
modtime: 1547486966,
compressed: `
H4sIAAAAAAAC/2xSTY+bMBC951dMEbdt7bTqaev1alvUU9VDlZyiHAyeEivGIH/QShb/fQUG8qGcsGfe
e543D/b6v9HQo3WqNS/ZZ7LNXvmGWecuxS9km/ENAKtOwhjU4xmAeeU18j+qLJWHn4iS0VRKba3MmZ+8
754ptROIlEFrtFUr8V9rz45UbUNRKk9jJDtsOi08FsILsndoyT4oOQyMTkJJU6KrrOq8ag0fX4S/rYXH
ZIfWiAZHgWvWPJswdRA1cjSfgmN0vS9t578HpWUhPPJ7/bUzDXcDnRfjNf+6ZXT8TpUYwQpTI+TqI+Q9
PL/AreToxcEwJP6Hw4/ibfd2yOAJ8p4Ul/HhCbLjkWcJpzw26YE1jRjznvyefV+lAcC6UM528p78Es7v
OzmbWFoLtA5KJpxrg61wGL6lmw71cr5VmBgLfQrsOre75Cb+6OpxOPTiK0ZAI9NiGF1/P0atc3zzHgAA
//+UZXAKvAIAAA==
`,
},
"/templates/user_dashboard.html": {
local: "templates/user_dashboard.html",
size: 45,
modtime: 1547160534,
size: 97,
modtime: 1547486320,
compressed: `
H4sIAAAAAAAC/7JJVMgoSk2zVdIvLU4t0k9LTU0pVrJzTcksUQguTSpOLsosKMnMzyu20U+04wIEAAD/
/2HSavctAAAA
H4sIAAAAAAAC/7JJVMgoSk2zVdIvLU4t0k9LTU0pVrJzTcksUQguTSpOLsosKMnMzyu20U+04+JCqC4q
LtavrtYLSc0tyEksSXVJLEnUCy3NTKmtVbILCg5WcEtNTQHrAQQAAP//EcPbEmEAAAA=
`,
},
"/templates/user_feeds.html": {
local: "templates/user_feeds.html",
size: 3588,
modtime: 1547234296,
size: 4065,
modtime: 1547235825,
compressed: `
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
UuK/debJVdLmyWLWftT+EwAA///sH8RP4Q8AAA==
`,
},

View File

@ -1,10 +1,7 @@
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func handleRequest(w http.ResponseWriter, req *http.Request) {
@ -19,24 +16,3 @@ func handleRequest(w http.ResponseWriter, req *http.Request) {
handleUserLoginForm(page)
}
}
func handleRssFeed(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
var uid string
var uidOk bool
if uid, uidOk = vars["uid"]; !uidOk {
userError(w)
return
}
w.Header().Set("Content-Type", "application/xml")
v, err := buildRssFeed(uid)
if err != nil {
userError(w)
return
}
fmt.Fprint(w, v)
}
func buildRssFeed(uid string) (string, error) {
return "", nil
}

73
endpoints_rss.go Normal file
View File

@ -0,0 +1,73 @@
package main
import (
"net/http"
"strings"
"time"
"github.com/gorilla/mux"
)
func handleRssFeed(w http.ResponseWriter, req *http.Request) {
page := initPageData(w, req)
vars := mux.Vars(req)
var uid string
var uidOk bool
if uid, uidOk = vars["uid"]; !uidOk {
userError(w)
return
}
w.Header().Set("Content-Type", "application/xml")
var slug string
var slugOk bool
slug, slugOk = vars["slug"]
if !slugOk {
// Print the user's entire feed
buildUserRssFeed(page, uid)
} else {
// Print the feed for a specific slug
buildSlugRssFeed(page, uid, slug)
}
}
type rssPageData struct {
User *User
Feeds []Feed
BuildDate time.Time
}
func buildUserRssFeed(page *pageData, uid string) {
var err error
rpd := new(rssPageData)
rpd.BuildDate = time.Now()
rpd.User, err = m.GetUser(uid)
if err != nil {
userError(page.session.w)
return
}
for _, v := range rpd.User.SubSlugs {
pts := strings.Split(v, ";")
fd, err := m.GetFeed(pts[0], pts[1])
if err != nil {
userError(page.session.w)
return
}
rpd.Feeds = append(rpd.Feeds, *fd)
}
page.TemplateData = rpd
page.showRss()
}
func buildSlugRssFeed(page *pageData, uid, slug string) {
var err error
rpd := new(rssPageData)
rpd.BuildDate = time.Now()
rpd.User, err = m.GetUser(uid)
if err != nil {
userError(page.session.w)
return
}
page.TemplateData = rpd
page.showRss()
}

View File

@ -75,6 +75,17 @@ func doLogin(uid, password string) error {
func handleUserDashboard(page *pageData) {
page.SubTitle = "dashboard"
var err error
id, err := page.session.getStringValue("id")
if err != nil {
userError(page.session.w)
return
}
page.TemplateData, err = m.GetUser(id)
if err != nil {
userError(page.session.w)
return
}
page.show("user_dashboard.html")
}
@ -120,6 +131,11 @@ func handleUpdateUserSubs(page *pageData) {
u, err = m.GetUser(id)
u.SubSlugs = userSubs
m.SaveUser(u)
for k := range m.Users {
if m.Users[k].Uuid == id {
m.Users[k].SubSlugs = userSubs
}
}
redirect("/user/dashboard", page.session.w, page.session.req)
}

View File

@ -72,6 +72,7 @@ func main() {
pub.HandleFunc("/api/comics/{cid}/{function}", handleApiComicsCall)
*/
pub.HandleFunc("/rss/{uid}", handleRssFeed)
pub.HandleFunc("/rss/{uid}/{slug}", handleRssFeed)
pub.HandleFunc("/user/{function}", handleUserRequest)
http.Handle("/", r)

View File

@ -10,8 +10,10 @@ import (
)
type model struct {
dbOpen int
bolt *boltease.DB
dbFileName string
dbChanged bool
Users []User
FeedSources []FeedSource
@ -48,10 +50,10 @@ func NewModel() (*model, error) {
func (m *model) initDB() error {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return err
}
defer m.bolt.CloseDB()
defer m.closeDB()
if err = m.bolt.MkBucketPath([]string{"site"}); err != nil {
return err
@ -65,9 +67,31 @@ func (m *model) initDB() error {
return nil
}
func (m *model) openDB() error {
m.dbOpen = m.dbOpen + 1
if m.dbOpen > 1 {
return nil
}
var err error
if err = m.openDB(); err != nil {
return err
}
return nil
}
func (m *model) closeDB() {
m.dbOpen = m.dbOpen - 1
if m.dbOpen == 0 {
m.closeDB()
}
}
func (m *model) saveChanges() {
fmt.Println("Saving Site to DB")
m.Site.SaveToDB()
//m.SaveAllFeeds(m.Feeds)
//fmt.Println("Saving Feeds to DB")
//m.SaveAllFeeds(m.FeedSources)
fmt.Println("Saving Users to DB")
m.SaveAllUsers(m.Users)
}

View File

@ -1,6 +1,7 @@
package main
import (
"fmt"
"plugin"
"time"
)
@ -91,7 +92,7 @@ func NewFeed(s, n, a, source string) *Feed {
}
func (f *Feed) GetBucket() []string {
return []string{"feed", f.Source, f.Slug}
return []string{"feeds", f.Source, f.Slug}
}
func (f *Feed) Update() error {
@ -146,10 +147,10 @@ func (f *Feed) GetRssItem() string {
// DB Function to save a feed
func (m *model) SaveFeed(f *Feed) error {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return err
}
defer m.bolt.CloseDB()
defer m.closeDB()
bkt := f.GetBucket()
if err = m.bolt.MkBucketPath(bkt); err != nil {
return err
@ -180,10 +181,10 @@ func (m *model) SaveFeed(f *Feed) error {
// DB Function to get a feed
func (m *model) GetFeed(source, slug string) (*Feed, error) {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return nil, err
}
defer m.bolt.CloseDB()
defer m.closeDB()
ret := new(Feed)
ret.Source = source
ret.Slug = slug
@ -210,14 +211,17 @@ func (m *model) LoadFeeds() error {
}
// Save all feeds to the DB
func (m *model) SaveAllFeeds(feeds []Feed) {
func (m *model) SaveAllFeeds(feedSources []FeedSource) {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return
}
defer m.bolt.CloseDB()
for i := range feeds {
m.SaveFeed(&feeds[i])
defer m.closeDB()
for _, v := range feedSources {
for j := range v.Feeds {
fmt.Printf("Saving Feed to DB (%s;%s)\n", v.Feeds[j].Source, v.Feeds[j].Slug)
m.SaveFeed(v.Feeds[j])
}
}
}
@ -225,10 +229,10 @@ func (m *model) SaveAllFeeds(feeds []Feed) {
func (m *model) GetAllFeeds() []Feed {
var ret []Feed
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return ret
}
defer m.bolt.CloseDB()
defer m.closeDB()
var srcs []string
bkt := []string{"feeds"}
if srcs, err = m.bolt.GetBucketList(bkt); err != nil {
@ -253,10 +257,10 @@ func (m *model) GetAllFeeds() []Feed {
// Delete a feed from the DB
func (m *model) DeleteFeed(slug string) error {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return err
}
defer m.bolt.CloseDB()
defer m.closeDB()
return m.bolt.DeleteBucket([]string{"feeds"}, slug)
}

View File

@ -42,10 +42,10 @@ func NewSiteData(m *model) *SiteData {
// load the site data out of the database
// If fields don't exist in the DB, don't clobber what is already in s
func (s *SiteData) LoadFromDB() error {
if err := s.m.bolt.OpenDB(); err != nil {
if err := s.m.openDB(); err != nil {
return err
}
defer s.m.bolt.CloseDB()
defer s.m.closeDB()
if title, _ := s.m.bolt.GetValue(s.mPath, "title"); strings.TrimSpace(title) != "" {
s.Title = title
@ -78,10 +78,10 @@ func (s *SiteData) NeedsSave() bool {
func (s *SiteData) SaveToDB() error {
s.lastSave = time.Now()
var err error
if err = s.m.bolt.OpenDB(); err != nil {
if err = s.m.openDB(); err != nil {
return err
}
defer s.m.bolt.CloseDB()
defer s.m.closeDB()
if err = s.m.bolt.SetValue(s.mPath, "title", s.Title); err != nil {
return err

View File

@ -40,10 +40,10 @@ func (u *User) UpdateFeed() error {
func (m *model) SaveUser(u *User) error {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return err
}
defer m.bolt.CloseDB()
defer m.closeDB()
bkt := []string{"users", u.Uuid}
if err = m.bolt.MkBucketPath(bkt); err != nil {
return err
@ -73,10 +73,10 @@ func (m *model) SaveUser(u *User) error {
func (m *model) isValidUser(uid string) bool {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return false
}
defer m.bolt.CloseDB()
defer m.closeDB()
ret := new(User)
bkt := []string{"users", uid}
ret.Uuid = uid
@ -105,10 +105,10 @@ func (m *model) GetUser(uid string) (*User, error) {
return nil, errors.New("No user id given")
}
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return nil, err
}
defer m.bolt.CloseDB()
defer m.closeDB()
ret := new(User)
bkt := []string{"users", uid}
ret.Uuid = uid
@ -128,10 +128,10 @@ func (m *model) GetUser(uid string) (*User, error) {
func (m *model) SaveAllUsers(users []User) {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return
}
defer m.bolt.CloseDB()
defer m.closeDB()
for i := range users {
m.SaveUser(&users[i])
}
@ -145,10 +145,10 @@ func (m *model) LoadUsers() error {
func (m *model) GetAllUsers() []User {
var err error
var ret []User
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return ret
}
defer m.bolt.CloseDB()
defer m.closeDB()
uids := m.GetUserIdList()
for _, uid := range uids {
@ -161,10 +161,10 @@ func (m *model) GetAllUsers() []User {
func (m *model) GetUserByName(nm string) (*User, error) {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return nil, err
}
defer m.bolt.CloseDB()
defer m.closeDB()
usrids := m.GetUserIdList()
for i := range usrids {
bkt := []string{"users", usrids[i]}
@ -180,10 +180,10 @@ func (m *model) GetUserByName(nm string) (*User, error) {
func (m *model) GetUserIdList() []string {
var ret []string
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return ret
}
defer m.bolt.CloseDB()
defer m.closeDB()
bkt := []string{"users"}
ret, _ = m.bolt.GetBucketList(bkt)
return ret
@ -201,10 +201,10 @@ func (m *model) updateUserPassword(uid, password string) error {
return err
}
if err := m.bolt.OpenDB(); err != nil {
if err := m.openDB(); err != nil {
return err
}
defer m.bolt.CloseDB()
defer m.closeDB()
usrPath := []string{"users", uid}
return m.bolt.SetValue(usrPath, "password", string(cryptPw))
@ -213,10 +213,10 @@ func (m *model) updateUserPassword(uid, password string) error {
// Is the uid and pw given valid?
func (m *model) checkCredentials(uid, pw string) error {
var err error
if err = m.bolt.OpenDB(); err != nil {
if err = m.openDB(); err != nil {
return err
}
defer m.bolt.CloseDB()
defer m.closeDB()
var uPw string
usrPath := []string{"users", uid}

View File

@ -38,3 +38,11 @@ func (p *pageData) show(tmplName string) error {
}
return nil
}
func (p *pageData) showRss() error {
if err := outputTemplate("rss_feed.xml", p, p.session.w); err != nil {
fmt.Printf("%s\n", err)
return err
}
return nil
}

20
templates/rss_feed.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>Ribbit Feed</title>
<link>http://ribbit.bullercodeworks.com/edit/{{.TemplateData.User.Uuid}}</link>
<description>Feed for {{.TemplateData.User.Username}}</description>
<language>en-us</language>
<lastBuildDate>{{.TemplateData.BuildDate}}</lastBuildDate>
<ttl>40</ttl>
{{ range $i, $v := .TemplateData.Feeds }}
<item>
<title>{{$v.Name}}</title>
<pubDate>{{$v.LastUpdate}}</pubDate>
<guid>{{$v.Source}};{{$v.Slug}};{{$v.LastUpdate}}</guid>
<link></link>
<description><![CDATA[{{$v.Desc}}]]></description>
</item>
{{ end }}
</channel>
</rss>

View File

@ -1 +1,3 @@
<a href="/user/feeds">Edit Subscriptions</a>
<a href="/rss/{{.TemplateData.Uuid}}">RSS Feed</a>