diff --git a/cmd/data/articles.go b/cmd/data/articles.go new file mode 100644 index 0000000..42b4eca --- /dev/null +++ b/cmd/data/articles.go @@ -0,0 +1,58 @@ +package data + +import "time" + +type Article struct { + Title string + Created time.Time + Desc string + Content string +} + +type ArticleList struct { + addChan chan Article + releaseChan chan int + returnChan chan Article + List []Article +} + +func (l *ArticleList) start() { + for { + select { + case article := <-l.addChan: + l.List = append(l.List, article) + case i := <-l.releaseChan: + l.returnChan <- l.List[i] + l.List = append(l.List[:i], l.List[i+1:]...) + } + } +} + +func NewArticleList() *ArticleList { + list := &ArticleList{ + List: []Article{}, + addChan: make(chan Article), + releaseChan: make(chan int), + returnChan: make(chan Article), + } + list.start() + return list +} + +func (l *ArticleList) Close() { + close(l.addChan) + close(l.releaseChan) + close(l.returnChan) +} + +func (l *ArticleList) Add(a Article) { + l.addChan <- a +} + +func (l *ArticleList) Release(i int) (Article, bool) { + if i < 0 || i > len(l.List) { + return Article{}, false + } + l.releaseChan <- i + return <-l.returnChan, true +} diff --git a/cmd/data/rss.go b/cmd/data/rss.go index 52f58a7..78d7509 100644 --- a/cmd/data/rss.go +++ b/cmd/data/rss.go @@ -10,16 +10,30 @@ import ( type Feed struct { feeds.Feed + addChan chan *feeds.Item +} + +func (f *Feed) start() { + for item := range f.addChan { + f.Items = append(f.Items, item) + } } func NewFeed(title, link, desc string) *Feed { - return &Feed{ + feed := &Feed{ Feed: feeds.Feed{ Title: title, Link: &feeds.Link{Href: link}, Description: desc, }, + addChan: make(chan *feeds.Item), } + feed.start() + return feed +} + +func (f *Feed) Close() { + close(f.addChan) } func OpenFeed(filename string) (*Feed, error) { @@ -29,17 +43,19 @@ func OpenFeed(filename string) (*Feed, error) { } defer file.Close() - feed := &Feed{} + feed := new(Feed) decoder := gob.NewDecoder(file) - err = decoder.Decode(feed) + err = decoder.Decode(&feed.Feed) if err != nil { return nil, fmt.Errorf("error decoding file %v: %v", filename, err) } + feed.addChan = make(chan *feeds.Item) + feed.start() return feed, nil } -func (feed *Feed) Save(filename string) error { +func (f *Feed) Save(filename string) error { file, err := os.Create(filename) if err != nil { return fmt.Errorf("error creating file %v: %v", filename, err) @@ -47,10 +63,14 @@ func (feed *Feed) Save(filename string) error { defer file.Close() encoder := gob.NewEncoder(file) - err = encoder.Encode(feed) + err = encoder.Encode(f.Feed) if err != nil { return fmt.Errorf("error encoding file %v: %v", filename, err) } return nil } + +func (f *Feed) Add(i *feeds.Item) { + f.addChan <- i +} diff --git a/cmd/ui/articles.go b/cmd/ui/articles.go new file mode 100644 index 0000000..95f65ee --- /dev/null +++ b/cmd/ui/articles.go @@ -0,0 +1,72 @@ +package ui + +import ( + "html/template" + "log" + "net/http" + "time" + + "github.com/gorilla/feeds" + "streifling.com/jason/cpolis/cmd/data" +) + +func WriteArticle() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + template.Must(template.ParseFiles("web/templates/editor.html")).ExecuteTemplate(w, "page-content", nil) + } +} + +func FinishArticle(l *data.ArticleList) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + article := data.Article{} + var err error + + article.Title, err = data.ConvertToPlain(r.PostFormValue("editor-title")) + if err != nil { + log.Println(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + article.Desc, err = data.ConvertToPlain(r.PostFormValue("editor-desc")) + if err != nil { + log.Println(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + article.Content, err = data.ConvertToHTML(r.PostFormValue("editor-text")) + if err != nil { + log.Println(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + article.Created = time.Now() + l.Add(article) + + template.Must(template.ParseFiles("web/templates/hub.html")).ExecuteTemplate(w, "page-content", nil) + } +} + +func PublishArticle(f *data.Feed, l *data.ArticleList, i int) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + article, ok := l.Release(i) + if !ok { + // TODO: Warnung anzeigen + // data.Msg = "Alle Felder müssen ausgefüllt werden." + // template.Must(template.ParseFiles("web/templates/add-user.html")).ExecuteTemplate(w, "page-content", data) + return + } + + f.Add(&feeds.Item{ + Title: article.Title, + Created: article.Created, + Description: article.Desc, + Content: article.Content, + }) + f.Save("rss.gob") + + template.Must(template.ParseFiles("web/templates/hub.html")).ExecuteTemplate(w, "page-content", nil) + } +} diff --git a/cmd/ui/editor.go b/cmd/ui/editor.go deleted file mode 100644 index d96c41e..0000000 --- a/cmd/ui/editor.go +++ /dev/null @@ -1,52 +0,0 @@ -package ui - -import ( - "html/template" - "log" - "net/http" - "time" - - "github.com/gorilla/feeds" - "streifling.com/jason/cpolis/cmd/data" -) - -func WriteArticle() http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - template.Must(template.ParseFiles("web/templates/editor.html")).ExecuteTemplate(w, "page-content", nil) - } -} - -func FinishEdit(feed *data.Feed) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - title, err := data.ConvertToPlain(r.PostFormValue("editor-title")) - if err != nil { - log.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - desc, err := data.ConvertToPlain(r.PostFormValue("editor-desc")) - if err != nil { - log.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - content, err := data.ConvertToHTML(r.PostFormValue("editor-text")) - if err != nil { - log.Println(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - feed.Add(&feeds.Item{ - Title: title, - Created: time.Now(), - Description: desc, - Content: content, - }) - feed.Save("tmp/rss.gob") - - template.Must(template.ParseFiles("web/templates/hub.html")).ExecuteTemplate(w, "page-content", nil) - } -} diff --git a/main.go b/main.go index 7c9c72c..9faa660 100644 --- a/main.go +++ b/main.go @@ -31,6 +31,10 @@ func main() { "https://distrikt-ni-st.de", "Freiheit, Gleichheit, Brüderlichkeit, Toleranz und Humanität") } + defer feed.Close() + + articleList := data.NewArticleList() + defer articleList.Close() mux := http.NewServeMux() mux.Handle("/web/static/", http.StripPrefix("/web/static/", http.FileServer(http.Dir("web/static/")))) @@ -51,9 +55,9 @@ func main() { mux.HandleFunc("POST /add-user/", ui.AddUser(db)) mux.HandleFunc("POST /create-user/", ui.CreateUser()) - mux.HandleFunc("POST /write-article/", ui.WriteArticle()) - mux.HandleFunc("POST /finish-edit/", ui.FinishEdit(feed)) + mux.HandleFunc("POST /finish-article/", ui.FinishArticle(articleList)) mux.HandleFunc("POST /login/", ui.Login(db)) + mux.HandleFunc("POST /write-article/", ui.WriteArticle()) mux.HandleFunc("/rss/", ui.ShowRSS(feed)) log.Fatalln(http.ListenAndServe(":8080", mux)) diff --git a/web/templates/editor.html b/web/templates/editor.html index c3aab1b..e5f203a 100644 --- a/web/templates/editor.html +++ b/web/templates/editor.html @@ -4,7 +4,7 @@ - + {{end}}