Converted articles and tags to DB base
This commit is contained in:
parent
052d36b01b
commit
582f25bec7
@ -1,206 +1,16 @@
|
|||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Article struct {
|
type Article struct {
|
||||||
Title string
|
Title string
|
||||||
Author string
|
Created time.Time
|
||||||
Created time.Time
|
Desc string
|
||||||
Desc string
|
Content string
|
||||||
Content string
|
Tags []string
|
||||||
Tags []string
|
Published bool
|
||||||
UUID uuid.UUID
|
ID int64
|
||||||
AuthorID int64
|
AuthorID int64
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: setCh
|
|
||||||
type ArticleList struct {
|
|
||||||
addCh chan *Article
|
|
||||||
delCh chan uuid.UUID
|
|
||||||
getCh chan []Article
|
|
||||||
retCh chan *Article
|
|
||||||
articles []*Article
|
|
||||||
wg sync.WaitGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: setCh
|
|
||||||
type TagList struct {
|
|
||||||
addCh chan string
|
|
||||||
getCh chan []string
|
|
||||||
tags []string
|
|
||||||
wg sync.WaitGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
func initArticleList() *ArticleList {
|
|
||||||
return &ArticleList{
|
|
||||||
addCh: make(chan *Article),
|
|
||||||
delCh: make(chan uuid.UUID),
|
|
||||||
getCh: make(chan []Article),
|
|
||||||
retCh: make(chan *Article),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func initTagList() *TagList {
|
|
||||||
return &TagList{
|
|
||||||
addCh: make(chan string),
|
|
||||||
getCh: make(chan []string),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (al *ArticleList) start() {
|
|
||||||
al.wg.Done()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case article := <-al.addCh:
|
|
||||||
al.articles = append(al.articles, article)
|
|
||||||
case uuid := <-al.delCh:
|
|
||||||
for i, article := range al.articles {
|
|
||||||
if article.UUID == uuid {
|
|
||||||
al.articles = append(al.articles[:i], al.articles[i+1:]...)
|
|
||||||
al.retCh <- article
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case al.getCh <- func() []Article {
|
|
||||||
var list []Article
|
|
||||||
for _, article := range al.articles {
|
|
||||||
list = append(list, *article)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}():
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tl *TagList) start() {
|
|
||||||
tl.wg.Done()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case tag := <-tl.addCh:
|
|
||||||
tl.tags = append(tl.tags, tag)
|
|
||||||
case tl.getCh <- tl.tags:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewArticleList() *ArticleList {
|
|
||||||
list := initArticleList()
|
|
||||||
list.articles = make([]*Article, 0)
|
|
||||||
|
|
||||||
list.wg.Add(1)
|
|
||||||
go list.start()
|
|
||||||
list.wg.Wait()
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func (al *ArticleList) Add(a *Article) {
|
|
||||||
al.addCh <- a
|
|
||||||
}
|
|
||||||
|
|
||||||
func (al *ArticleList) Release(uuid uuid.UUID) (*Article, bool) {
|
|
||||||
al.delCh <- uuid
|
|
||||||
article := <-al.retCh
|
|
||||||
|
|
||||||
if article == nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return article, true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (al *ArticleList) Get() []Article {
|
|
||||||
return <-al.getCh
|
|
||||||
}
|
|
||||||
|
|
||||||
func (al *ArticleList) Save(filename string) error {
|
|
||||||
file, err := os.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating key file: %v", err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
articles := al.Get()
|
|
||||||
if err = gob.NewEncoder(file).Encode(articles); err != nil {
|
|
||||||
return fmt.Errorf("error ecoding key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadArticleList(filename string) (*ArticleList, error) {
|
|
||||||
file, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error opening key file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
articleList := initArticleList()
|
|
||||||
if err = gob.NewDecoder(file).Decode(&articleList.articles); err != nil {
|
|
||||||
return nil, fmt.Errorf("error decoding key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
articleList.wg.Add(1)
|
|
||||||
go articleList.start()
|
|
||||||
articleList.wg.Wait()
|
|
||||||
|
|
||||||
return articleList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTagList() *TagList {
|
|
||||||
list := initTagList()
|
|
||||||
list.tags = make([]string, 0)
|
|
||||||
|
|
||||||
list.wg.Add(1)
|
|
||||||
go list.start()
|
|
||||||
list.wg.Wait()
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tl *TagList) Add(tag string) {
|
|
||||||
tl.addCh <- tag
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tl *TagList) Get() []string {
|
|
||||||
return <-tl.getCh
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tl *TagList) Save(filename string) error {
|
|
||||||
file, err := os.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating key file: %v", err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
tags := tl.Get()
|
|
||||||
if err = gob.NewEncoder(file).Encode(tags); err != nil {
|
|
||||||
return fmt.Errorf("error ecoding key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadTagList(filename string) (*TagList, error) {
|
|
||||||
file, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error opening key file: %v", err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
tagList := initTagList()
|
|
||||||
if err = gob.NewDecoder(file).Decode(&tagList.tags); err != nil {
|
|
||||||
return nil, fmt.Errorf("error decoding key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tagList.wg.Add(1)
|
|
||||||
go tagList.start()
|
|
||||||
tagList.wg.Wait()
|
|
||||||
|
|
||||||
return tagList, nil
|
|
||||||
}
|
}
|
||||||
|
@ -171,3 +171,97 @@ func (db *DB) GetUser(id int64) (*User, error) {
|
|||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) AddTag(tagName string) error {
|
||||||
|
query := "INSERT INTO tags name VALUES ?"
|
||||||
|
if _, err := db.Exec(query, tagName); err != nil {
|
||||||
|
return fmt.Errorf("error inserting tag into DB: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) GetTagList() ([]Tag, error) {
|
||||||
|
query := "SELECT id, name FROM tags"
|
||||||
|
rows, err := db.Query(query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error querying tags: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var tagList []Tag
|
||||||
|
for rows.Next() {
|
||||||
|
var tag Tag
|
||||||
|
if err = rows.Scan(&tag.ID, &tag.Name); err != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning tag row: %v", err)
|
||||||
|
}
|
||||||
|
tagList = append(tagList, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tagList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) AddArticle(a *Article) error {
|
||||||
|
query := `
|
||||||
|
INSERT INTO articles
|
||||||
|
(title, description, content, published, author_id)
|
||||||
|
VALUES
|
||||||
|
(?, ?, ?, ?)
|
||||||
|
`
|
||||||
|
if _, err := db.Exec(query, a.Title, a.Desc, a.Content, a.Published, a.AuthorID); err != nil {
|
||||||
|
return fmt.Errorf("error inserting article into DB: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) GetArticle(id int64) (*Article, error) {
|
||||||
|
query := `
|
||||||
|
SELECT title, created, description, content, published, author_id
|
||||||
|
FROM articles
|
||||||
|
WHERE id = ?
|
||||||
|
`
|
||||||
|
row := db.QueryRow(query, id)
|
||||||
|
|
||||||
|
article := new(Article)
|
||||||
|
if err := row.Scan(&article.Title, &article.Created, &article.Desc,
|
||||||
|
&article.Content, &article.Published, &article.AuthorID); err != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning article row: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return article, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) GetUnpublishedArticles() ([]Article, error) {
|
||||||
|
query := `
|
||||||
|
SELECT id, title, created, description, content, published, author_id
|
||||||
|
FROM articles
|
||||||
|
WHERE published = ?
|
||||||
|
`
|
||||||
|
rows, err := db.Query(query, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error querying articles: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var articleList []Article
|
||||||
|
for rows.Next() {
|
||||||
|
var article Article
|
||||||
|
if err = rows.Scan(&article.ID, &article.Title, &article.Created,
|
||||||
|
&article.Desc, &article.Content, &article.Published,
|
||||||
|
&article.AuthorID); err != nil {
|
||||||
|
return nil, fmt.Errorf("error scanning article row: %v", err)
|
||||||
|
}
|
||||||
|
articleList = append(articleList, article)
|
||||||
|
}
|
||||||
|
|
||||||
|
return articleList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) UpdateArticle(id int64, attribute string, val interface{}) error {
|
||||||
|
query := `
|
||||||
|
UPDATE articles
|
||||||
|
SET ? = ?
|
||||||
|
WHERE id = ?
|
||||||
|
`
|
||||||
|
if _, err := db.Exec(query, attribute, val, id); err != nil {
|
||||||
|
return fmt.Errorf("error updating article in DB: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
6
cmd/data/tags.go
Normal file
6
cmd/data/tags.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package data
|
||||||
|
|
||||||
|
type Tag struct {
|
||||||
|
ID int64
|
||||||
|
Name string
|
||||||
|
}
|
22
cmd/main.go
22
cmd/main.go
@ -47,16 +47,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
store := data.NewCookieStore(key)
|
store := data.NewCookieStore(key)
|
||||||
|
|
||||||
articleList, err := data.LoadArticleList("tmp/unpublished-articles.gob")
|
|
||||||
if err != nil {
|
|
||||||
articleList = data.NewArticleList()
|
|
||||||
}
|
|
||||||
|
|
||||||
tagList, err := data.LoadTagList("tmp/tags.gob")
|
|
||||||
if err != nil {
|
|
||||||
tagList = data.NewTagList()
|
|
||||||
}
|
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/web/static/", http.StripPrefix("/web/static/", http.FileServer(http.Dir("web/static/"))))
|
mux.Handle("/web/static/", http.StripPrefix("/web/static/", http.FileServer(http.Dir("web/static/"))))
|
||||||
mux.HandleFunc("/", ui.HomePage(db, store))
|
mux.HandleFunc("/", ui.HomePage(db, store))
|
||||||
@ -65,15 +55,15 @@ func main() {
|
|||||||
mux.HandleFunc("GET /create-user/", ui.CreateUser)
|
mux.HandleFunc("GET /create-user/", ui.CreateUser)
|
||||||
mux.HandleFunc("GET /hub/", ui.ShowHub(store))
|
mux.HandleFunc("GET /hub/", ui.ShowHub(store))
|
||||||
mux.HandleFunc("GET /rss/", ui.ShowRSS(feed))
|
mux.HandleFunc("GET /rss/", ui.ShowRSS(feed))
|
||||||
mux.HandleFunc("GET /unpublished-articles/", ui.ShowUnpublishedArticles(articleList))
|
mux.HandleFunc("GET /unpublished-articles/", ui.ShowUnpublishedArticles(db))
|
||||||
mux.HandleFunc("GET /write-article/", ui.WriteArticle(tagList))
|
mux.HandleFunc("GET /write-article/", ui.WriteArticle(db))
|
||||||
|
|
||||||
mux.HandleFunc("POST /add-tag/", ui.AddTag(tagList, store))
|
mux.HandleFunc("POST /add-tag/", ui.AddTag(db, store))
|
||||||
mux.HandleFunc("POST /add-user/", ui.AddUser(db, store))
|
mux.HandleFunc("POST /add-user/", ui.AddUser(db, store))
|
||||||
mux.HandleFunc("POST /finish-article/", ui.FinishArticle(articleList, store))
|
mux.HandleFunc("POST /finish-article/", ui.FinishArticle(db, store))
|
||||||
mux.HandleFunc("POST /login/", ui.Login(db, store))
|
mux.HandleFunc("POST /login/", ui.Login(db, store))
|
||||||
mux.HandleFunc("POST /review-article/", ui.ReviewArticle(articleList, store))
|
mux.HandleFunc("POST /review-article/", ui.ReviewArticle(db, store))
|
||||||
mux.HandleFunc("POST /publish-article/", ui.PublishArticle(feed, articleList, store))
|
mux.HandleFunc("POST /publish-article/", ui.PublishArticle(db, feed, store))
|
||||||
|
|
||||||
log.Fatalln(http.ListenAndServe(":8080", mux))
|
log.Fatalln(http.ListenAndServe(":8080", mux))
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.streifling.com/jason/rss"
|
"git.streifling.com/jason/rss"
|
||||||
"github.com/google/uuid"
|
|
||||||
"streifling.com/jason/cpolis/cmd/data"
|
"streifling.com/jason/cpolis/cmd/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,14 +25,21 @@ func ShowHub(s *data.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteArticle(tl *data.TagList) http.HandlerFunc {
|
func WriteArticle(db *data.DB) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
tags, err := db.GetTagList()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles("web/templates/editor.html")
|
tmpl, err := template.ParseFiles("web/templates/editor.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", tl.Get())
|
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", tags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func FinishArticle(al *data.ArticleList, s *data.CookieStore) http.HandlerFunc {
|
func FinishArticle(db *data.DB, s *data.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
article := new(data.Article)
|
article := new(data.Article)
|
||||||
var err error
|
var err error
|
||||||
@ -68,13 +75,8 @@ func FinishArticle(al *data.ArticleList, s *data.CookieStore) http.HandlerFunc {
|
|||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
|
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
article.UUID = uuid.New()
|
|
||||||
article.Author = session.Values["name"].(string)
|
|
||||||
article.Created = time.Now()
|
|
||||||
article.AuthorID = session.Values["id"].(int64)
|
article.AuthorID = session.Values["id"].(int64)
|
||||||
|
db.AddArticle(article)
|
||||||
al.Add(article)
|
|
||||||
al.Save("tmp/unpublished-articles.gob")
|
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles("web/templates/hub.html")
|
tmpl, err := template.ParseFiles("web/templates/hub.html")
|
||||||
tmpl = template.Must(tmpl, err)
|
tmpl = template.Must(tmpl, err)
|
||||||
@ -82,28 +84,33 @@ func FinishArticle(al *data.ArticleList, s *data.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShowUnpublishedArticles(al *data.ArticleList) http.HandlerFunc {
|
func ShowUnpublishedArticles(db *data.DB) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
articles, err := db.GetUnpublishedArticles()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
tmpl, err := template.ParseFiles("web/templates/unpublished-articles.html")
|
tmpl, err := template.ParseFiles("web/templates/unpublished-articles.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", al.Get())
|
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", articles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReviewArticle(al *data.ArticleList, s *data.CookieStore) http.HandlerFunc {
|
func ReviewArticle(db *data.DB, s *data.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
uuid, err := uuid.Parse(r.PostFormValue("uuid"))
|
id, err := strconv.ParseInt(r.PostFormValue("id"), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, article := range al.Get() {
|
article, err := db.GetArticle(id)
|
||||||
if article.UUID == uuid {
|
if err != nil {
|
||||||
tmpl, err := template.ParseFiles("web/templates/to-be-published.html")
|
tmpl, err := template.ParseFiles("web/templates/to-be-published.html")
|
||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", article)
|
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", article)
|
||||||
return
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session, err := s.Get(r, "cookie")
|
session, err := s.Get(r, "cookie")
|
||||||
@ -119,21 +126,24 @@ func ReviewArticle(al *data.ArticleList, s *data.CookieStore) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PublishArticle(c *data.Channel, al *data.ArticleList, s *data.CookieStore) http.HandlerFunc {
|
func PublishArticle(db *data.DB, c *data.Channel, s *data.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
uuid, err := uuid.Parse(r.PostFormValue("uuid"))
|
id, err := strconv.ParseInt(r.PostFormValue("id"), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
article, ok := al.Release(uuid)
|
if err = db.UpdateArticle(id, "published", true); err != nil {
|
||||||
if !ok {
|
log.Println(err)
|
||||||
// TODO: Warnung anzeigen
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
// msg = "Alle Felder müssen ausgefüllt werden."
|
return
|
||||||
// tmpl, err := template.ParseFiles("web/templates/add-user.html")
|
}
|
||||||
// template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
|
article, err := db.GetArticle(id)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,10 +12,9 @@ func CreateTag(w http.ResponseWriter, r *http.Request) {
|
|||||||
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
|
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddTag(tl *data.TagList, s *data.CookieStore) http.HandlerFunc {
|
func AddTag(db *data.DB, s *data.CookieStore) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
tl.Add(r.PostFormValue("tag"))
|
db.AddTag(r.PostFormValue("tag"))
|
||||||
tl.Save("tmp/tags.gob")
|
|
||||||
|
|
||||||
session, err := s.Get(r, "cookie")
|
session, err := s.Get(r, "cookie")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user