Progress
This commit is contained in:
parent
e0f25b8529
commit
8cc411b89d
127
assets.go
127
assets.go
@ -222,6 +222,94 @@ nC1WAvxNMB27f2/7AjTg5s54BOwNTttvIBe0ubuEzo83ocq/bONcqwz1BCL/BAAA///ACu/RdBMAAA==
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"/assets/img/favicon.png": {
|
||||||
|
local: "assets/img/favicon.png",
|
||||||
|
size: 4752,
|
||||||
|
modtime: 1547232209,
|
||||||
|
compressed: `
|
||||||
|
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
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
"/assets/vendor/css/grids-responsive-min.css": {
|
"/assets/vendor/css/grids-responsive-min.css": {
|
||||||
local: "assets/vendor/css/grids-responsive-min.css",
|
local: "assets/vendor/css/grids-responsive-min.css",
|
||||||
size: 8032,
|
size: 8032,
|
||||||
@ -389,10 +477,38 @@ ZfY39XJelrPeb2dTP1e8O5VLPwIAAP//0xnP9ywDAAA=
|
|||||||
|
|
||||||
"/templates/user_dashboard.html": {
|
"/templates/user_dashboard.html": {
|
||||||
local: "templates/user_dashboard.html",
|
local: "templates/user_dashboard.html",
|
||||||
size: 0,
|
size: 45,
|
||||||
modtime: 1547138339,
|
modtime: 1547160534,
|
||||||
compressed: `
|
compressed: `
|
||||||
H4sIAAAAAAAC/wEAAP//AAAAAAAAAAA=
|
H4sIAAAAAAAC/7JJVMgoSk2zVdIvLU4t0k9LTU0pVrJzTcksUQguTSpOLsosKMnMzyu20U+04wIEAAD/
|
||||||
|
/2HSavctAAAA
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
|
"/templates/user_feeds.html": {
|
||||||
|
local: "templates/user_feeds.html",
|
||||||
|
size: 3588,
|
||||||
|
modtime: 1547234296,
|
||||||
|
compressed: `
|
||||||
|
H4sIAAAAAAAC/5xXXY/aOBe+z6+wrLkIGia0t4UgtdP3lSpVu9JC92aEkIkPiTXGjmwHZjTiv69sJ9ih
|
||||||
|
IWL3ApT4POf7wycLyo6I0RwTzrdaNqoAvS2kMIQJUHi5mFF2XCaLvVQHJMgBcrwHoFvd7HShWG2YFBoj
|
||||||
|
UtiHHM8aDWrW1JQY6EOWCUILJurGOHUWt7WSNEbmvYYcV4xSELhVEtOPhDeQY4xmTsiuMUaKlks3uwMz
|
||||||
|
eLkiR1jMPGmZLGbW3mWy8AYskyNRKIhEOXpJPj6QIqIE9MCm6OGIvuQoW8Oh5sTAd2JI9kuDylbNbsWb
|
||||||
|
UqPzOUEIf3w8HM9nPLXcIKg93cwTJ94G8F9I/z8AXfl4e9mB4+hY9pbn4eiALQShD/ePELZRwl+8Qfvs
|
||||||
|
D3IAZ1ZLJY2ppAr0r+49RmjelIFuXexRnWER3b3HCAq6CPTvoIuYyok2W18FAfSTaPPLnZ3P2CHPU+93
|
||||||
|
G8l+TPeNcEWFmGAmnTjXbZzbIn3uahTliMqiOYAwWQnmfxzs47f3HzS9UdSTeV+UTdjGnu2lSu05Qzn6
|
||||||
|
NEcMLUJWMw6iNNUcscfHSZsHtk9bERkTFN7+3KcX/AvbZJ44QQv0aXJJXcdRN7oahPvQJP43YFInYMCg
|
||||||
|
69hkpK5B0OeKcZoWCoiBUHdrsuPQOfDCNhMXl3NyjmI/xnOdksGMeAFtUlJM2fE6/GtmOIywVJ89R4TO
|
||||||
|
mBCg1vBmUN6eB8Sw8xH3Rb+xzoxodnSv3D1mBSda/2TaZITSFNeNgicPmkYvTzupKCigeIoLEAbUE+E8
|
||||||
|
uG0qIHRMraXHcDMWUaNi6HP1Oio5xoo7kKYSvWBjO2lwkEHukkH6Mvw0iqTwu6TwvhQ7TpCfJ9gDTD/l
|
||||||
|
YxIn/7HdB/oV5V0Nhh735TLcfK6F/pKnnixvUGj7sVJ2wh1egWmUuAbPb3TwRbFV+sPAITSwkqc7S6yo
|
||||||
|
Xp+BjyaM9tDf5NsI2C0EHu+xmQbz1RjFdo2BFNtLHk8RLiooXnfybQRKiSFP7lqbos7Dl+4m2zziOX6M
|
||||||
|
ji1uEwuTouCssN3ThS7t8mlkWXJYRetMaiqm7W0zqL8bpK5iwtZxuSPutQ4t83BxtGa6QIAdH0Y10Olp
|
||||||
|
s9KWSeqxvkTkKTq1oEty7ApxZy47aK8Dg71uGdlcqet4LvrsUnKnvg56Q1+73lxr7LguGpua3qmwRd7Q
|
||||||
|
F68z10pbzrgflTz1e3CggGyKfWoLKbTkkHFZpnhtkUyUCD86xM0a8vxxgUQgXXNWwE22KfrsKxQB1/A7
|
||||||
|
u9tMHLKrL+977MDfdidPJ30/SzCrZmdHTHCvjcnNFU3J09Y7mymoOSkgxXM8xVvXRucg/Hcb/DLi1QzM
|
||||||
|
8sijgWEexl6wOnDYkTzvhr6SpzDabeqDD/rb+5qU9lK8zLKXT5uBLu1Gexyum1F1ym5GLPo0mmTu2wjl
|
||||||
|
kbMuJX5nnic3gzZPFrPu4+ifAAAA//9hEtQ2BA4AAA==
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -411,6 +527,11 @@ H4sIAAAAAAAC/wEAAP//AAAAAAAAAAA=
|
|||||||
local: "assets/css",
|
local: "assets/css",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"/assets/img": {
|
||||||
|
isDir: true,
|
||||||
|
local: "assets/img",
|
||||||
|
},
|
||||||
|
|
||||||
"/assets/vendor": {
|
"/assets/vendor": {
|
||||||
isDir: true,
|
isDir: true,
|
||||||
local: "assets/vendor",
|
local: "assets/vendor",
|
||||||
|
BIN
assets/img/favicon.png
Normal file
BIN
assets/img/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
@ -36,3 +36,7 @@ func handleRssFeed(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
fmt.Fprint(w, v)
|
fmt.Fprint(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildRssFeed(uid string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
@ -21,16 +21,22 @@ func handleUserRequest(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
if !page.LoggedIn {
|
if !page.LoggedIn {
|
||||||
page.SubTitle = "ribbit login"
|
page.SubTitle = "ribbit login"
|
||||||
page.show("login.html", w)
|
page.show("login.html")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
page.SubTitle = "dashboard"
|
switch f {
|
||||||
page.show("user_dashboard.html", w)
|
case "feeds":
|
||||||
|
handleUserFeeds(page)
|
||||||
|
case "updatesubscriptions":
|
||||||
|
handleUpdateUserSubs(page)
|
||||||
|
default:
|
||||||
|
handleUserDashboard(page)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleUserLoginForm(page *pageData) {
|
func handleUserLoginForm(page *pageData) {
|
||||||
page.SubTitle = "ribbit login"
|
page.SubTitle = "ribbit login"
|
||||||
page.show("login.html", page.session.w)
|
page.show("login.html")
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleUserLogin(page *pageData) {
|
func handleUserLogin(page *pageData) {
|
||||||
@ -61,9 +67,59 @@ func handleUserLogin(page *pageData) {
|
|||||||
// doLogin attempts to log in with the given email/password
|
// doLogin attempts to log in with the given email/password
|
||||||
// If it can't, it returns an error
|
// If it can't, it returns an error
|
||||||
func doLogin(uid, password string) error {
|
func doLogin(uid, password string) error {
|
||||||
fmt.Println("Doing Login", uid, password)
|
|
||||||
if strings.TrimSpace(uid) != "" && strings.TrimSpace(password) != "" {
|
if strings.TrimSpace(uid) != "" && strings.TrimSpace(password) != "" {
|
||||||
return m.checkCredentials(uid, password)
|
return m.checkCredentials(uid, password)
|
||||||
}
|
}
|
||||||
return errors.New("Invalid Credentials")
|
return errors.New("Invalid Credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleUserDashboard(page *pageData) {
|
||||||
|
page.SubTitle = "dashboard"
|
||||||
|
page.show("user_dashboard.html")
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleUserFeeds(page *pageData) {
|
||||||
|
page.SubTitle = "feeds"
|
||||||
|
type feedsPageData struct {
|
||||||
|
User *User
|
||||||
|
FeedSources []FeedSource
|
||||||
|
}
|
||||||
|
fpd := new(feedsPageData)
|
||||||
|
fpd.FeedSources = m.FeedSources
|
||||||
|
id, err := page.session.getStringValue("id")
|
||||||
|
if err != nil {
|
||||||
|
userError(page.session.w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fpd.User, err = m.GetUser(id)
|
||||||
|
if err != nil {
|
||||||
|
userError(page.session.w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
page.TemplateData = fpd
|
||||||
|
page.show("user_feeds.html")
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleUpdateUserSubs(page *pageData) {
|
||||||
|
subs := page.session.req.FormValue("user_feeds")
|
||||||
|
fmt.Println(subs)
|
||||||
|
subPts := strings.Split(subs, ",")
|
||||||
|
var userSubs []string
|
||||||
|
for i := range subPts {
|
||||||
|
subPts[i] = strings.TrimSpace(subPts[i])
|
||||||
|
if subPts[i] != "" {
|
||||||
|
userSubs = append(userSubs, subPts[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
id, err := page.session.getStringValue("id")
|
||||||
|
if err != nil {
|
||||||
|
userError(page.session.w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var u *User
|
||||||
|
u, err = m.GetUser(id)
|
||||||
|
u.SubSlugs = userSubs
|
||||||
|
m.SaveUser(u)
|
||||||
|
|
||||||
|
redirect("/user/dashboard", page.session.w, page.session.req)
|
||||||
|
}
|
||||||
|
61
main.go
61
main.go
@ -6,10 +6,12 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"plugin"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -24,25 +26,6 @@ import (
|
|||||||
const AppName = "ribbit"
|
const AppName = "ribbit"
|
||||||
const DbName = AppName + ".db"
|
const DbName = AppName + ".db"
|
||||||
|
|
||||||
// pageData is stuff that changes per request
|
|
||||||
type pageData struct {
|
|
||||||
Site *SiteData
|
|
||||||
Title string
|
|
||||||
SubTitle string
|
|
||||||
Stylesheets []string
|
|
||||||
HeaderScripts []string
|
|
||||||
Scripts []string
|
|
||||||
FlashMessage string
|
|
||||||
FlashClass string
|
|
||||||
LoggedIn bool
|
|
||||||
IsAdmin bool
|
|
||||||
Menu []menuItem
|
|
||||||
BottomMenu []menuItem
|
|
||||||
session *pageSession
|
|
||||||
|
|
||||||
TemplateData interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type menuItem struct {
|
type menuItem struct {
|
||||||
Label string
|
Label string
|
||||||
Location string
|
Location string
|
||||||
@ -130,10 +113,6 @@ func main() {
|
|||||||
log.Fatal(http.ListenAndServe("127.0.0.1:"+strconv.Itoa(m.Site.Port), chain))
|
log.Fatal(http.ListenAndServe("127.0.0.1:"+strconv.Itoa(m.Site.Port), chain))
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildRssFeed(uid string) (string, error) {
|
|
||||||
return uid, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loggingHandler(h http.Handler) http.Handler {
|
func loggingHandler(h http.Handler) http.Handler {
|
||||||
return handlers.LoggingHandler(os.Stdout, h)
|
return handlers.LoggingHandler(os.Stdout, h)
|
||||||
}
|
}
|
||||||
@ -193,22 +172,6 @@ func initPageData(w http.ResponseWriter, req *http.Request) *pageData {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pageData) show(tmplName string, w http.ResponseWriter) error {
|
|
||||||
for _, tmpl := range []string{
|
|
||||||
"htmlheader.html",
|
|
||||||
"header.html",
|
|
||||||
tmplName,
|
|
||||||
"footer.html",
|
|
||||||
"htmlfooter.html",
|
|
||||||
} {
|
|
||||||
if err := outputTemplate(tmpl, p, w); err != nil {
|
|
||||||
fmt.Printf("%s\n", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func outputTemplate(tmplName string, tmplData interface{}, w http.ResponseWriter) error {
|
func outputTemplate(tmplName string, tmplData interface{}, w http.ResponseWriter) error {
|
||||||
n := "/templates/" + tmplName
|
n := "/templates/" + tmplName
|
||||||
l := template.Must(template.New("layout").Parse(FSMustString(m.Site.DevMode, n)))
|
l := template.Must(template.New("layout").Parse(FSMustString(m.Site.DevMode, n)))
|
||||||
@ -272,4 +235,24 @@ func initialize() {
|
|||||||
m.Site.sessionSecret = sessSc
|
m.Site.sessionSecret = sessSc
|
||||||
assertError(m.Site.SaveToDB())
|
assertError(m.Site.SaveToDB())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load Feed Sources from Plugins
|
||||||
|
files, err := ioutil.ReadDir("./plugins/")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
for _, f := range files {
|
||||||
|
fmt.Print("Loading plugin ", f.Name(), "...")
|
||||||
|
p, err := plugin.Open("./plugins/" + f.Name())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var feedSource *FeedSource
|
||||||
|
if feedSource, err = LoadFeedPlugin(p); err != nil {
|
||||||
|
fmt.Println(" ", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.FeedSources = append(m.FeedSources, *feedSource)
|
||||||
|
fmt.Printf("Done. (%d feeds)\n", len(feedSource.Feeds))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1
model.go
1
model.go
@ -14,6 +14,7 @@ type model struct {
|
|||||||
dbFileName string
|
dbFileName string
|
||||||
|
|
||||||
Users []User
|
Users []User
|
||||||
|
FeedSources []FeedSource
|
||||||
Feeds []Feed
|
Feeds []Feed
|
||||||
|
|
||||||
Site *SiteData
|
Site *SiteData
|
||||||
|
@ -1,9 +1,77 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"plugin"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FeedSource struct {
|
||||||
|
Feeds []*Feed
|
||||||
|
|
||||||
|
// Plugin Functions
|
||||||
|
getSourceName func() string
|
||||||
|
refreshFeedList func() []map[string]string
|
||||||
|
getFeedUrl func(string, time.Time) (string, error)
|
||||||
|
getFeedDesc func(string, time.Time) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadFeedPlugin(p *plugin.Plugin) (*FeedSource, error) {
|
||||||
|
ret := new(FeedSource)
|
||||||
|
feedSourceSymbol, err := p.Lookup("GetSourceName")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret.getSourceName = feedSourceSymbol.(func() string)
|
||||||
|
|
||||||
|
feedListSymbol, err := p.Lookup("GetFeedList")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret.refreshFeedList = feedListSymbol.(func() []map[string]string)
|
||||||
|
feeds := ret.refreshFeedList()
|
||||||
|
// `feeds` is a []map, each map should contain keys: `slug`, `name`, `author`, `source`
|
||||||
|
for _, f := range feeds {
|
||||||
|
var slug, name, author, source string
|
||||||
|
var ok bool
|
||||||
|
if slug, ok = f["slug"]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if name, ok = f["name"]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if author, ok = f["author"]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if source, ok = f["source"]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret.Feeds = append(ret.Feeds, NewFeed(slug, name, author, source))
|
||||||
|
}
|
||||||
|
|
||||||
|
feedUrlSymbol, err := p.Lookup("GetFeedUrl")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret.getFeedUrl = feedUrlSymbol.(func(string, time.Time) (string, error))
|
||||||
|
|
||||||
|
feedDescSymbol, err := p.Lookup("GetFeedDesc")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret.getFeedDesc = feedDescSymbol.(func(string, time.Time) (string, error))
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FeedSource) getFeed(slug string) *Feed {
|
||||||
|
for i := range f.Feeds {
|
||||||
|
if f.Feeds[i].Slug == slug {
|
||||||
|
return f.Feeds[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Feed struct {
|
type Feed struct {
|
||||||
Name string
|
Name string
|
||||||
Author string
|
Author string
|
||||||
|
40
page_data.go
Normal file
40
page_data.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// pageData is stuff that changes per request
|
||||||
|
type pageData struct {
|
||||||
|
Site *SiteData
|
||||||
|
Title string
|
||||||
|
SubTitle string
|
||||||
|
Stylesheets []string
|
||||||
|
HeaderScripts []string
|
||||||
|
Scripts []string
|
||||||
|
FlashMessage string
|
||||||
|
FlashClass string
|
||||||
|
LoggedIn bool
|
||||||
|
IsAdmin bool
|
||||||
|
Menu []menuItem
|
||||||
|
BottomMenu []menuItem
|
||||||
|
session *pageSession
|
||||||
|
|
||||||
|
TemplateData interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pageData) show(tmplName string) error {
|
||||||
|
for _, tmpl := range []string{
|
||||||
|
"htmlheader.html",
|
||||||
|
"header.html",
|
||||||
|
tmplName,
|
||||||
|
"footer.html",
|
||||||
|
"htmlfooter.html",
|
||||||
|
} {
|
||||||
|
if err := outputTemplate(tmpl, p, p.session.w); err != nil {
|
||||||
|
fmt.Printf("%s\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -2,8 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"C"
|
"C"
|
||||||
)
|
|
||||||
import (
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -12,43 +10,36 @@ import (
|
|||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getFeedList() []Feed {
|
func GetSourceName() string {
|
||||||
var ret []Feed
|
return "dilbert"
|
||||||
ret = append(ret, *NewFeed("dilbert", "Dilbert", "Scott Adams", "dilbert"))
|
}
|
||||||
|
|
||||||
|
func GetFeedList() []map[string]string {
|
||||||
|
var ret []map[string]string
|
||||||
|
feedMap := make(map[string]string)
|
||||||
|
feedMap["slug"] = "dilbert"
|
||||||
|
feedMap["name"] = "Dilbert"
|
||||||
|
feedMap["author"] = "Scott Adams"
|
||||||
|
feedMap["source"] = GetSourceName()
|
||||||
|
ret = append(ret, feedMap)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRssItem(slug string) (string, error) {
|
func GetFeedUrl(slug string, date time.Time) (string, error) {
|
||||||
desc, err := getFeedDesc(time.Now())
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
feed, err := m.GetFeed(SRC_DILBERT, slug)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
desc = "<![CDATA[" + desc + "]]>"
|
|
||||||
ret := " <item>\n"
|
|
||||||
ret += " <title>" + feed.Name + "</title>\n"
|
|
||||||
ret += " <pubDate>" + feed.LastUpdate.Format(time.RFC1123Z) + "</pubDate>\n"
|
|
||||||
ret += " <guid>dilbert;" + slug + ";" + feed.LastUpdate.Format(time.RFC1123Z) + "</guid>\n"
|
|
||||||
ret += " <link>" + getFeedUrl(time.Now()) + "</link>\n"
|
|
||||||
ret += " <description>" + desc + "</description>\n"
|
|
||||||
ret += " </item>\n"
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFeedUrl(date time.Time) string {
|
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"http://dilbert.com/strip/%4d-%02d-%02d",
|
"http://dilbert.com/strip/%4d-%02d-%02d",
|
||||||
date.Year(),
|
date.Year(),
|
||||||
date.Month(),
|
date.Month(),
|
||||||
date.Day(),
|
date.Day(),
|
||||||
)
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFeedDesc(date time.Time) (string, error) {
|
func GetFeedDesc(slug string, date time.Time) (string, error) {
|
||||||
res, err := http.Get(getFeedUrl(date))
|
url, err := GetFeedUrl(slug, date)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
res, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,12 @@ import (
|
|||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
)
|
)
|
||||||
|
|
||||||
func downloadList() {
|
func GetSourceName() string {
|
||||||
var ret []Feed
|
return "gocomics"
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFeedList() []map[string]string {
|
||||||
|
var ret []map[string]string
|
||||||
lstUrl := "http://www.gocomics.com/comics/a-to-z"
|
lstUrl := "http://www.gocomics.com/comics/a-to-z"
|
||||||
res, err := http.Get(lstUrl)
|
res, err := http.Get(lstUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -48,44 +52,33 @@ func downloadList() {
|
|||||||
}
|
}
|
||||||
author = strings.TrimPrefix(author, "By ")
|
author = strings.TrimPrefix(author, "By ")
|
||||||
author = strings.Replace(author, "\u0026", "&", -1)
|
author = strings.Replace(author, "\u0026", "&", -1)
|
||||||
ret = append(ret, *NewFeed(slug, name, author, "gocomics"))
|
feedMap := make(map[string]string)
|
||||||
|
feedMap["slug"] = slug
|
||||||
|
feedMap["name"] = name
|
||||||
|
feedMap["author"] = author
|
||||||
|
feedMap["source"] = GetSourceName()
|
||||||
|
ret = append(ret, feedMap)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRssItem(slug string) (string, error) {
|
func GetFeedUrl(slug string, date time.Time) (string, error) {
|
||||||
desc, err := getFeedDesc(slug, time.Now())
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
comic, err := m.GetComic(SRC_GOCOMICS, slug)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
desc = "<![CDATA[" + desc + "]]>"
|
|
||||||
ret := " <item>\n"
|
|
||||||
ret += " <title>" + comic.Name + "</title>\n"
|
|
||||||
ret += " <pubDate>" + comic.LastUpdate.Format(time.RFC1123Z) + "</pubDate>\n"
|
|
||||||
ret += " <guid>gocomics;" + slug + ";" + comic.LastUpdate.Format(time.RFC1123Z) + "</guid>\n"
|
|
||||||
ret += " <link>" + getGoComicsComicUrl(slug, time.Now()) + "</link>\n"
|
|
||||||
ret += " <description>" + desc + "</description>\n"
|
|
||||||
ret += " </item>\n"
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFeedUrl(slug string, date time.Time) string {
|
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"http://www.gocomics.com/%s/%04d/%02d/%02d",
|
"http://www.gocomics.com/%s/%04d/%02d/%02d",
|
||||||
slug,
|
slug,
|
||||||
date.Year(),
|
date.Year(),
|
||||||
date.Month(),
|
date.Month(),
|
||||||
date.Day(),
|
date.Day(),
|
||||||
)
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFeedDesc(slug string, date time.Time) (string, error) {
|
func GetFeedDesc(slug string, date time.Time) (string, error) {
|
||||||
res, err := http.Get(getFeedUrl(slug, date))
|
url, err := GetFeedUrl(slug, date)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
res, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,22 @@ import (
|
|||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getFeedList() []Feed {
|
func GetSourceName() string {
|
||||||
var ret []Feed
|
return "xkcd"
|
||||||
ret = append(ret, *NewFeed("xkcd", "XKCD", "Randall Munroe", "xkcd"))
|
}
|
||||||
|
|
||||||
|
func GetFeedList() []map[string]string {
|
||||||
|
var ret []map[string]string
|
||||||
|
feedMap := make(map[string]string)
|
||||||
|
feedMap["slug"] = "xkcd"
|
||||||
|
feedMap["name"] = "XKCD"
|
||||||
|
feedMap["author"] = "Randall Munroe"
|
||||||
|
feedMap["source"] = GetSourceName()
|
||||||
|
ret = append(ret, feedMap)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func getRssItem(slug string) (string, error) {
|
func getRssItem(slug string) (string, error) {
|
||||||
desc, err := getFeedDesc(time.Now())
|
desc, err := getFeedDesc(time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,8 +45,9 @@ func getRssItem(slug string) (string, error) {
|
|||||||
ret += " </item>\n"
|
ret += " </item>\n"
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func getFeedUrl(date time.Time) (string, error) {
|
func GetFeedUrl(slug string, dt time.Time) (string, error) {
|
||||||
var isComicDay = func(dt time.Time) bool {
|
var isComicDay = func(dt time.Time) bool {
|
||||||
return dt.Weekday() == time.Monday || dt.Weekday() == time.Wednesday || dt.Weekday() == time.Friday
|
return dt.Weekday() == time.Monday || dt.Weekday() == time.Wednesday || dt.Weekday() == time.Friday
|
||||||
}
|
}
|
||||||
@ -54,8 +65,13 @@ func getFeedUrl(date time.Time) (string, error) {
|
|||||||
return fmt.Sprintf("https://xkcd.com/%d", num), nil
|
return fmt.Sprintf("https://xkcd.com/%d", num), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFeedDesc(date time.Time) (string, error) {
|
func GetFeedDesc(slug string, dt time.Time) (string, error) {
|
||||||
res, err := http.Get(getUrl(date))
|
var url string
|
||||||
|
var err error
|
||||||
|
if url, err = GetFeedUrl(slug, dt); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
res, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
BIN
plugins/plugin_dilbert.so
Normal file
BIN
plugins/plugin_dilbert.so
Normal file
Binary file not shown.
BIN
plugins/plugin_gocomics.so
Normal file
BIN
plugins/plugin_gocomics.so
Normal file
Binary file not shown.
BIN
plugins/plugin_xkcd.so
Normal file
BIN
plugins/plugin_xkcd.so
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
<a href="/user/feeds">Edit Subscriptions</a>
|
135
templates/user_feeds.html
Normal file
135
templates/user_feeds.html
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<div id="all_sources_container"></div>
|
||||||
|
<form name="feed_subscriptions" action="/user/updatesubscriptions" onsubmit="updateSubscriptionValue()">
|
||||||
|
<input id="user_feeds" type="hidden" name="user_feeds" value="" />
|
||||||
|
<button type="submit">Save</button>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
var user_feeds = [
|
||||||
|
{{ range $i, $v := .TemplateData.User.SubSlugs }}
|
||||||
|
"{{$v}}",
|
||||||
|
{{ end }}
|
||||||
|
];
|
||||||
|
|
||||||
|
var all_feeds = [
|
||||||
|
{{ range $i, $v := .TemplateData.FeedSources }}
|
||||||
|
{{ range $vi, $vf := $v.Feeds }}
|
||||||
|
{
|
||||||
|
"name": "{{$vf.Name}}",
|
||||||
|
"author": "{{$vf.Author}}",
|
||||||
|
"slug": "{{$vf.Slug}}",
|
||||||
|
"source": "{{$vf.Source}}",
|
||||||
|
"desc": "{{$vf.Desc}}",
|
||||||
|
"last_update": "{{$vf.LastUpdate}}"
|
||||||
|
},
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
];
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
var sourcesContainer = document.getElementById("all_sources_container");
|
||||||
|
var sources = [];
|
||||||
|
for(var i = 0; i < all_feeds.length; i++) {
|
||||||
|
if(sources.indexOf(all_feeds[i].source) < 0) {
|
||||||
|
sources.push(all_feeds[i].source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(var i = 0; i < sources.length; i++) {
|
||||||
|
sourcesContainer.appendChild(createFeedSourceTable(sources[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFeedSourceTable(source) {
|
||||||
|
var sourceContainer = document.createElement("div");
|
||||||
|
var sourceTitle = document.createElement("h1");
|
||||||
|
sourceTitle.innerText = source+" ";
|
||||||
|
sourceContainer.appendChild(sourceTitle);
|
||||||
|
var table = document.createElement("table");
|
||||||
|
table.classList.add("pure-table","pure-table-bordered","center-all","hidden");
|
||||||
|
var thead = document.createElement("thead");
|
||||||
|
var thtr = document.createElement("tr");
|
||||||
|
var thChk = document.createElement("th");
|
||||||
|
var thn = document.createElement("th");
|
||||||
|
thn.innerText = "Name";
|
||||||
|
var tha = document.createElement("th");
|
||||||
|
tha.innerText = "Author";
|
||||||
|
var thl = document.createElement("th");
|
||||||
|
thl.innerText = "Last Update";
|
||||||
|
thtr.appendChild(document.createElement("th"));
|
||||||
|
for(var i = 0; i < all_feeds.length; i++) {
|
||||||
|
if(all_feeds[i].source == source) {
|
||||||
|
table.appendChild(createFeedTableRow(all_feeds[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceContainer.appendChild(table);
|
||||||
|
var sourceShow = document.createElement("a");
|
||||||
|
sourceShow.style["color"] = "blue";
|
||||||
|
sourceShow.style["cursor"] = "pointer";
|
||||||
|
sourceShow.innerText = "v";
|
||||||
|
sourceShow.onclick = function() {
|
||||||
|
if(table.classList.contains("hidden")) {
|
||||||
|
sourceShow.innerText = "^";
|
||||||
|
} else {
|
||||||
|
sourceShow.innerText = "v";
|
||||||
|
}
|
||||||
|
table.classList.toggle("hidden");
|
||||||
|
}
|
||||||
|
sourceTitle.appendChild(sourceShow);
|
||||||
|
sourceContainer.style["margin-bottom"] = "2em";
|
||||||
|
|
||||||
|
return sourceContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFeedTableRow(feedItem) {
|
||||||
|
var row = document.createElement("tr");
|
||||||
|
var chkCell = document.createElement("td");
|
||||||
|
var chkBox = document.createElement("input");
|
||||||
|
chkBox.setAttribute("type", "checkbox");
|
||||||
|
chkBox.setAttribute("data-slug", feedItem["source"]+";"+feedItem["slug"]);
|
||||||
|
chkBox.onclick = function() {
|
||||||
|
toggleSubscription(this.getAttribute("data-slug"));
|
||||||
|
}
|
||||||
|
if(user_feeds.indexOf(feedItem["source"]+";"+feedItem["slug"]) >= 0) {
|
||||||
|
chkBox.checked = true;
|
||||||
|
}
|
||||||
|
chkCell.append(chkBox);
|
||||||
|
row.append(chkCell);
|
||||||
|
var nameCell = document.createElement("td");
|
||||||
|
nameCell.innerText = feedItem["name"];
|
||||||
|
row.append(nameCell);
|
||||||
|
var authCell = document.createElement("td");
|
||||||
|
authCell.innerText = feedItem["author"];
|
||||||
|
row.append(authCell);
|
||||||
|
var updCell = document.createElement("td");
|
||||||
|
updCell.innerText = feedItem["last_update"];
|
||||||
|
row.append(updCell);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSubscription(slug) {
|
||||||
|
if(user_feeds.indexOf(slug) >= 0) {
|
||||||
|
user_feeds.splice(user_feeds.indexOf(slug), 1);
|
||||||
|
} else {
|
||||||
|
user_feeds.push(slug);
|
||||||
|
}
|
||||||
|
updateSubscriptionValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubRow(slug) {
|
||||||
|
return document.getElementById("row_"+slug.replace(";","_"));
|
||||||
|
}
|
||||||
|
function updateSubscriptionTable() {
|
||||||
|
for(var i = 0; i < user_feeds.length; i++) {
|
||||||
|
var row = getSubRow(user_feeds[i]);
|
||||||
|
if(row) {
|
||||||
|
row.getElementsByTagName("input")[0].checked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSubscriptionValue() {
|
||||||
|
document.getElementById("user_feeds").value = user_feeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
updateSubscriptionTable();
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user