Added article list for written but non-published articles
This commit is contained in:
		
							
								
								
									
										58
									
								
								cmd/data/articles.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								cmd/data/articles.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| } | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
							
								
								
									
										72
									
								
								cmd/ui/articles.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								cmd/ui/articles.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
| 	} | ||||
| } | ||||
| @@ -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) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										8
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								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)) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     <input name="editor-title" placeholder="Titel" type="text" /> | ||||
|     <textarea name="editor-desc" placeholder="Beschreibung"></textarea> | ||||
|     <textarea name="editor-text" placeholder="Artikel"></textarea> | ||||
|     <input type="submit" value="Senden" hx-post="/finish-edit/" hx-target="#page-content" /> | ||||
|     <input type="submit" value="Senden" hx-post="/finish-article/" hx-target="#page-content" /> | ||||
| </form> | ||||
| {{end}} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user