Compare commits
	
		
			6 Commits
		
	
	
		
			v0.11.0
			...
			bc4d8fa37e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bc4d8fa37e | |||
| 1368593c75 | |||
| e4bef7006c | |||
| afa1b65563 | |||
| a9bef63174 | |||
| 4d944ef65a | 
							
								
								
									
										28
									
								
								cmd/backend/files.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								cmd/backend/files.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| package backend | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| func CopyFile(src, dst string) error { | ||||
| 	srcFile, err := os.Open(src) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error opening source file: %v", err) | ||||
| 	} | ||||
| 	defer srcFile.Close() | ||||
|  | ||||
| 	dstFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error opening destination file: %v", err) | ||||
| 	} | ||||
| 	defer dstFile.Close() | ||||
|  | ||||
| 	_, err = io.Copy(dstFile, srcFile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error copying file: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	return dstFile.Sync() | ||||
| } | ||||
| @@ -10,7 +10,10 @@ import ( | ||||
| 	"github.com/gorilla/sessions" | ||||
| ) | ||||
|  | ||||
| type CookieStore struct{ sessions.CookieStore } | ||||
| type ( | ||||
| 	CookieStore struct{ sessions.CookieStore } | ||||
| 	Session     struct{ sessions.Session } | ||||
| ) | ||||
|  | ||||
| func NewKey() ([]byte, error) { | ||||
| 	key := make([]byte, 32) | ||||
|   | ||||
| @@ -33,27 +33,6 @@ type EditorHTMLData struct { | ||||
| 	Tags         []*b.Tag | ||||
| } | ||||
|  | ||||
| func copyFile(src, dst string) error { | ||||
| 	srcFile, err := os.Open(src) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error opening source file: %v", err) | ||||
| 	} | ||||
| 	defer srcFile.Close() | ||||
|  | ||||
| 	dstFile, err := os.Create(dst) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error opening destination file: %v", err) | ||||
| 	} | ||||
| 	defer dstFile.Close() | ||||
|  | ||||
| 	_, err = io.Copy(dstFile, srcFile) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error copying file: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	return dstFile.Sync() | ||||
| } | ||||
|  | ||||
| func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		session, err := getSession(w, r, c, s) | ||||
| @@ -61,14 +40,13 @@ func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		data := new(EditorHTMLData) | ||||
| 		data := &EditorHTMLData{Action: "submit"} | ||||
|  | ||||
| 		if session.Values["article"] == nil { | ||||
| 			data = &EditorHTMLData{Article: new(b.Article)} | ||||
| 		} else { | ||||
| 			data = session.Values["article"].(*EditorHTMLData) | ||||
| 		} | ||||
| 		// data.Mode = EditMode | ||||
|  | ||||
| 		data.Tags, err = db.GetTagList() | ||||
| 		if err != nil { | ||||
| @@ -77,8 +55,6 @@ func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		data.Action = "submit" | ||||
|  | ||||
| 		tmpl, err := template.ParseFiles(c.WebDir + "/templates/editor.html") | ||||
| 		template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data) | ||||
| 	} | ||||
| @@ -696,7 +672,7 @@ func AllowEditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if err = copyFile(fmt.Sprint(c.ArticleDir, "/", oldID, ".md"), fmt.Sprint(c.ArticleDir, "/", newID, ".md")); err != nil { | ||||
| 		if err = b.CopyFile(fmt.Sprint(c.ArticleDir, "/", oldID, ".md"), fmt.Sprint(c.ArticleDir, "/", newID, ".md")); err != nil { | ||||
| 			log.Println(err) | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 			return | ||||
| @@ -762,94 +738,3 @@ func EditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | ||||
| 		template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SaveArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		session, err := getSession(w, r, c, s) | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		session.Values["article"] = nil | ||||
| 		if err = session.Save(r, w); err != nil { | ||||
| 			log.Println(err) | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		article := &b.Article{ | ||||
| 			Title:         r.PostFormValue("article-title"), | ||||
| 			Description:   r.PostFormValue("article-description"), | ||||
| 			Published:     false, | ||||
| 			Rejected:      false, | ||||
| 			AuthorID:      session.Values["id"].(int64), | ||||
| 			IsInIssue:     r.PostFormValue("issue") == "on", | ||||
| 			AutoGenerated: false, | ||||
| 		} | ||||
|  | ||||
| 		oldID, err := strconv.ParseInt(r.PathValue("id"), 10, 64) | ||||
| 		if err != nil { | ||||
| 			log.Println(err) | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		fmt.Println(oldID) | ||||
| 		if oldID != 0 { | ||||
| 			if err = db.DeleteArticle(oldID); err != nil { | ||||
| 				log.Println(err) | ||||
| 				http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			if err = os.Remove(fmt.Sprint(c.ArticleDir, "/", oldID, ".md")); err != nil { | ||||
| 				log.Println(err) | ||||
| 				http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		article.ID, err = db.AddArticle(article) | ||||
| 		if err != nil { | ||||
| 			log.Println(err) | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		articleAbsName := fmt.Sprint(c.ArticleDir, "/", article.ID, ".md") | ||||
| 		if err = os.WriteFile(articleAbsName, []byte(r.PostFormValue("article-content")), 0644); err != nil { | ||||
| 			log.Println(err) | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		article.Link = fmt.Sprint(c.Domain, "/article/serve/", article.ID) | ||||
| 		if err = db.UpdateAttributes(&b.Attribute{Table: "articles", ID: article.ID, AttName: "link", Value: article.Link}); err != nil { | ||||
| 			log.Println(err) | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		r.ParseForm() | ||||
| 		tags := make([]int64, 0) | ||||
| 		for _, tag := range r.Form["tags"] { | ||||
| 			tagID, err := strconv.ParseInt(tag, 10, 64) | ||||
| 			if err != nil { | ||||
| 				log.Println(err) | ||||
| 				http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 				return | ||||
| 			} | ||||
| 			tags = append(tags, tagID) | ||||
| 		} | ||||
| 		if err = db.WriteArticleTags(article.ID, tags); err != nil { | ||||
| 			log.Println(err) | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html") | ||||
| 		tmpl = template.Must(tmpl, err) | ||||
| 		tmpl.ExecuteTemplate(w, "page-content", session.Values["role"]) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package frontend | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"html/template" | ||||
| 	"log" | ||||
| @@ -26,6 +27,26 @@ func saveSession(w http.ResponseWriter, r *http.Request, s *b.CookieStore, u *b. | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // getSession is used for verifying that the user is logged in and returns their session and an error. | ||||
| func getSession(w http.ResponseWriter, r *http.Request, c *b.Config, s *b.CookieStore) (*b.Session, error) { | ||||
| 	msg := "Keine gültige Session. Bitte erneut anmelden." | ||||
| 	tmpl, tmplErr := template.ParseFiles(c.WebDir+"/templates/index.html", c.WebDir+"/templates/login.html") | ||||
|  | ||||
| 	tmpSession, err := s.Get(r, "cookie") | ||||
| 	if err != nil { | ||||
| 		template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	session := &b.Session{Session: *tmpSession} | ||||
| 	if session.IsNew { | ||||
| 		template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg) | ||||
| 		return session, errors.New("error: no existing session") | ||||
| 	} | ||||
|  | ||||
| 	return session, nil | ||||
| } | ||||
|  | ||||
| func HomePage(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		numRows, err := db.CountEntries("users") | ||||
|   | ||||
| @@ -1,29 +0,0 @@ | ||||
| package frontend | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"html/template" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/gorilla/sessions" | ||||
| 	b "streifling.com/jason/cpolis/cmd/backend" | ||||
| ) | ||||
|  | ||||
| // getSession is used for verifying that the user is logged in and returns their session and an error. | ||||
| func getSession(w http.ResponseWriter, r *http.Request, c *b.Config, s *b.CookieStore) (*sessions.Session, error) { | ||||
| 	msg := "Keine gültige Session. Bitte erneut anmelden." | ||||
| 	tmpl, tmplErr := template.ParseFiles(c.WebDir+"/templates/index.html", c.WebDir+"/templates/login.html") | ||||
|  | ||||
| 	session, err := s.Get(r, "cookie") | ||||
| 	if err != nil { | ||||
| 		template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if session.IsNew { | ||||
| 		template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg) | ||||
| 		return session, errors.New("error: no existing session") | ||||
| 	} | ||||
|  | ||||
| 	return session, nil | ||||
| } | ||||
| @@ -62,7 +62,6 @@ func main() { | ||||
| 	mux.HandleFunc("GET /article/review-edit/{id}", f.ReviewArticle(config, db, store, "allow-edit", "Artikel bearbeiten", "Bearbeiten erlauben")) | ||||
| 	mux.HandleFunc("GET /article/review-rejected/{id}", f.ReviewRejectedArticle(config, db, store)) | ||||
| 	mux.HandleFunc("GET /article/review-unpublished/{id}", f.ReviewArticle(config, db, store, "publish", "Artikel veröffentlichen", "Veröffentlichen")) | ||||
| 	mux.HandleFunc("GET /article/save/{id}", f.SaveArticle(config, db, store)) | ||||
| 	mux.HandleFunc("GET /article/serve/{id}", c.ServeArticle(config, db)) | ||||
| 	mux.HandleFunc("GET /article/write", f.WriteArticle(config, db, store)) | ||||
| 	mux.HandleFunc("GET /hub", f.ShowHub(config, db, store)) | ||||
|   | ||||
| @@ -35,7 +35,7 @@ | ||||
|  | ||||
|     <footer class="text-center text-gray-500 my-8"> | ||||
|         <p>© 2024 Jason Streifling. Alle Rechte vorbehalten.</p> | ||||
|         <p>v0.11.0 - <strong>Alpha: Drastische Änderungen und Fehler vorbehalten.</strong></p> | ||||
|         <p>v0.11.1 - <strong>Alpha: Drastische Änderungen und Fehler vorbehalten.</strong></p> | ||||
|     </footer> | ||||
|  | ||||
|     <script src="https://unpkg.com/htmx.org@2.0.2"></script> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user