From 98d69d440cb5ce1eb3bf106fb0d262f9de1733cd Mon Sep 17 00:00:00 2001 From: legitnull Date: Wed, 12 Apr 2023 06:32:18 -0600 Subject: [PATCH] fixed comments, added documentation --- comments.go | 79 ----------------------------------------- git.go | 73 -------------------------------------- main.go | 61 -------------------------------- render.go | 100 ---------------------------------------------------- 4 files changed, 313 deletions(-) delete mode 100644 comments.go delete mode 100644 git.go delete mode 100644 main.go delete mode 100644 render.go diff --git a/comments.go b/comments.go deleted file mode 100644 index 0895ae5..0000000 --- a/comments.go +++ /dev/null @@ -1,79 +0,0 @@ -package main - -import ( - "encoding/json" - "net/http" - "time" - - "github.com/prologic/bitcask" -) - -type Comment struct { - Author string - Content string - Date time.Time -} - -func getComments(db *bitcask.Bitcask, key string) ([]Comment, error) { - data, err := db.Get([]byte(key)) - if err != nil { - return nil, err - } - - var comments []Comment - err = json.Unmarshal(data, &comments) - if err != nil { - return nil, err - } - - return comments, nil -} - -func saveComment(db *bitcask.Bitcask, key string, comment Comment) error { - comments, err := getComments(db, key) - if err != nil && err != bitcask.ErrKeyNotFound { - return err - } - - comment.Date = time.Now() - comments = append(comments, comment) - - data, err := json.Marshal(comments) - if err != nil { - return err - } - - return db.Put([]byte(key), data) -} - -func submitCommentHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPost { - http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) - return - } - - err := r.ParseForm() - if err != nil { - http.Error(w, "Failed to parse form", http.StatusBadRequest) - return - } - - pagePath := r.FormValue("path") - if pagePath == "" { - http.Error(w, "Path is required", http.StatusBadRequest) - return - } - - comment := Comment{ - Author: r.FormValue("author"), - Content: r.FormValue("content"), - } - - err = saveComment(commentsDB, pagePath, comment) - if err != nil { - http.Error(w, "Failed to save comment", http.StatusInternalServerError) - return - } - - http.Redirect(w, r, pagePath, http.StatusSeeOther) -} diff --git a/git.go b/git.go deleted file mode 100644 index 1fa0326..0000000 --- a/git.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - //"fmt" - - "os" - - git "github.com/go-git/go-git/v5" -) - -func cloneRepository(repoURL, localPath string) error { - _, err := git.PlainClone(localPath, false, &git.CloneOptions{ - URL: repoURL, - Progress: os.Stdout, - }) - return err -} - -func pullRepository(localPath string) error { - repo, err := git.PlainOpen(localPath) - if err != nil { - return err - } - - worktree, err := repo.Worktree() - if err != nil { - return err - } - - err = worktree.Pull(&git.PullOptions{RemoteName: "origin"}) - if err != nil && err != git.NoErrAlreadyUpToDate { - return err - } - return nil -} - -func readFileFromRepo(localPath string, filePath string) ([]byte, error) { - // Open the local repository - repo, err := git.PlainOpen(localPath) - if err != nil { - return nil, err - } - - // Get the head reference - ref, err := repo.Head() - if err != nil { - return nil, err - } - - // Get the commit object - commit, err := repo.CommitObject(ref.Hash()) - if err != nil { - return nil, err - } - - // Get the file contents from the commit tree - tree, err := commit.Tree() - if err != nil { - return nil, err - } - - file, err := tree.File(filePath) - if err != nil { - return nil, err - } - - content, err := file.Contents() - if err != nil { - return nil, err - } - - return []byte(content), nil -} diff --git a/main.go b/main.go deleted file mode 100644 index 430c374..0000000 --- a/main.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "log" - "net/http" - "strings" - - "github.com/go-git/go-git/v5" - "github.com/prologic/bitcask" -) - -const repoURL = "https://git.tcp.direct/S4D/tcp-wiki.git" -const localPath = "data" - -var commentsDB *bitcask.Bitcask - -func main() { - err := cloneRepository(repoURL, localPath) - if err != nil && err != git.ErrRepositoryAlreadyExists { - log.Fatalf("Failed to clone repository: %v", err) - } - - commentsDB, err = bitcask.Open("./comments.db") - if err != nil { - log.Fatalf("Failed to open comments database: %v", err) - } - defer commentsDB.Close() - - http.HandleFunc("/", handler) - http.HandleFunc("/submit_comment", submitCommentHandler) - log.Fatal(http.ListenAndServe(":8080", nil)) -} - -func handler(w http.ResponseWriter, r *http.Request) { - //for debugging - log.Printf("LOCAL PATH: %q", localPath) - - //... - - if r.URL.Path == "/favicon.ico" { - return - } - - err := pullRepository(localPath) - if err != nil { - log.Printf("Failed to pull repository: %v", err) - } - - filePath := strings.TrimPrefix(r.URL.Path, "/") - if filePath == "" { - filePath = "README.md" - } - log.Printf("Rendering file %q from path %q", filePath, r.URL.Path) - - err = renderPage(w, r, localPath, filePath, commentsDB) - if err != nil { - log.Printf("Comment loading? %q", commentsDB.Path()) - - http.Error(w, "File not found", http.StatusNotFound) - } -} diff --git a/render.go b/render.go deleted file mode 100644 index 25d7e2b..0000000 --- a/render.go +++ /dev/null @@ -1,100 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "html/template" - "io/ioutil" - "log" - "net/http" - "path/filepath" - - "github.com/prologic/bitcask" - "github.com/yuin/goldmark" - highlighting "github.com/yuin/goldmark-highlighting" - "github.com/yuin/goldmark/extension" -) - -type Page struct { - Content template.HTML - Comments []Comment -} - -func renderPage(w http.ResponseWriter, r *http.Request, localPath, filePath string, commentsDB *bitcask.Bitcask) error { - content, err := readFileFromRepo(localPath, filePath) - if err != nil { - return err - } - - log.Printf("Read file content: %s", content) - - ext := filepath.Ext(filePath) - switch ext { - case ".md": - renderMarkdown(w, r, content, commentsDB) - case ".html", ".css": - renderStatic(w, content, ext) - default: - return fmt.Errorf("unsupported file format") - } - return nil -} - -func renderMarkdown(w http.ResponseWriter, r *http.Request, content []byte, commentsDB *bitcask.Bitcask) { - md := goldmark.New( - goldmark.WithExtensions( - extension.GFM, // GitHub Flavored Markdown - highlighting.NewHighlighting( - highlighting.WithStyle("monokai"), - ), - ), - ) - - var mdBuf bytes.Buffer - err := md.Convert(content, &mdBuf) - if err != nil { - http.Error(w, "Error converting Markdown", http.StatusInternalServerError) - return - } - - layout, err := ioutil.ReadFile(filepath.Join(localPath, "assets/_layout.html")) - if err != nil { - http.Error(w, "Layout not found", http.StatusInternalServerError) - return - } - - comments, err := getComments(commentsDB, r.URL.Path) - if err != nil && err != bitcask.ErrKeyNotFound { - http.Error(w, "Error fetching comments", http.StatusInternalServerError) - return - } - - page := &Page{Content: template.HTML(mdBuf.String()), Comments: comments} - t, err := template.New("layout").Parse(string(layout)) - if err != nil { - http.Error(w, "Error parsing layout", http.StatusInternalServerError) - return - } - - var buf bytes.Buffer - err = t.Execute(&buf, page) - if err != nil { - http.Error(w, "Error rendering layout", http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "text/html; charset=utf-8") - w.Write(buf.Bytes()) -} - -func renderStatic(w http.ResponseWriter, content []byte, ext string) { - contentType := "" - switch ext { - case ".html": - contentType = "text/html; charset=utf-8" - case ".css": - contentType = "text/css; charset=utf-8" - } - w.Header().Set("Content-Type", contentType) - w.Write(content) -}