forked from jason/cpolis
		
	Implement banner images in a more standard way
This commit is contained in:
		@@ -1,7 +1,6 @@
 | 
			
		||||
package backend
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"io"
 | 
			
		||||
@@ -43,20 +42,3 @@ func SaveImage(src io.Reader, maxHeight, maxWidth int, path string) (string, err
 | 
			
		||||
 | 
			
		||||
	return filename, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ServeBase64Image(c *Config, filename string) (string, error) {
 | 
			
		||||
	file := c.PicsDir + "/" + filename
 | 
			
		||||
 | 
			
		||||
	img, err := os.Open(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", fmt.Errorf("error opening file %v: %v", file, err)
 | 
			
		||||
	}
 | 
			
		||||
	defer img.Close()
 | 
			
		||||
 | 
			
		||||
	imgBytes, err := io.ReadAll(img)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", fmt.Errorf("error turning %v into bytes: %v", file, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return base64.StdEncoding.EncodeToString(imgBytes), nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
 | 
			
		||||
 | 
			
		||||
		article := &b.Article{
 | 
			
		||||
			Title:         r.PostFormValue("article-title"),
 | 
			
		||||
			BannerLink:    r.PostFormValue("article-banner-url"),
 | 
			
		||||
			BannerLink:    c.Domain + "/image/serve/" + r.PostFormValue("article-banner-url"),
 | 
			
		||||
			Summary:       r.PostFormValue("article-summary"),
 | 
			
		||||
			Published:     false,
 | 
			
		||||
			Rejected:      false,
 | 
			
		||||
@@ -181,6 +181,12 @@ func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bannerLink := c.Domain + "/image/serve/" + r.PostFormValue("article-banner-url")
 | 
			
		||||
		if len(bannerLink) == 0 {
 | 
			
		||||
			http.Error(w, "Bitte ein Titelbild einfügen.", http.StatusBadRequest)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		summary := r.PostFormValue("article-summary")
 | 
			
		||||
		if len(summary) == 0 {
 | 
			
		||||
			http.Error(w, "Bitte die Beschreibung eingeben.", http.StatusBadRequest)
 | 
			
		||||
@@ -202,6 +208,7 @@ func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
 | 
			
		||||
 | 
			
		||||
		if err = db.UpdateAttributes(
 | 
			
		||||
			&b.Attribute{Table: "articles", ID: id, AttName: "title", Value: title},
 | 
			
		||||
			&b.Attribute{Table: "articles", ID: id, AttName: "banner_link", Value: bannerLink},
 | 
			
		||||
			&b.Attribute{Table: "articles", ID: id, AttName: "summary", Value: summary},
 | 
			
		||||
			&b.Attribute{Table: "articles", ID: id, AttName: "rejected", Value: false},
 | 
			
		||||
			&b.Attribute{Table: "articles", ID: id, AttName: "is_in_issue", Value: r.PostFormValue("issue") == "on"},
 | 
			
		||||
@@ -347,13 +354,7 @@ func ReviewRejectedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.Handler
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		imgURL := strings.Split(data.Article.BannerLink, "/")
 | 
			
		||||
		imgFileName := imgURL[len(imgURL)-1]
 | 
			
		||||
		data.BannerImage, err = b.ServeBase64Image(c, imgFileName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		data.BannerImage = imgURL[len(imgURL)-1]
 | 
			
		||||
 | 
			
		||||
		articleAbsName := fmt.Sprint(c.ArticleDir, "/", data.Article.ID, ".md")
 | 
			
		||||
		content, err := os.ReadFile(articleAbsName)
 | 
			
		||||
@@ -624,13 +625,7 @@ func ReviewArticle(c *b.Config, db *b.DB, s *b.CookieStore, action, title, butto
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		imgURL := strings.Split(article.BannerLink, "/")
 | 
			
		||||
		imgFileName := imgURL[len(imgURL)-1]
 | 
			
		||||
		data.BannerImage, err = b.ServeBase64Image(c, imgFileName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		data.BannerImage = imgURL[len(imgURL)-1]
 | 
			
		||||
 | 
			
		||||
		data.Article.Summary, err = b.ConvertToPlain(article.Summary)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -807,13 +802,7 @@ func EditArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		imgURL := strings.Split(data.Article.BannerLink, "/")
 | 
			
		||||
		imgFileName := imgURL[len(imgURL)-1]
 | 
			
		||||
		data.BannerImage, err = b.ServeBase64Image(c, imgFileName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		data.BannerImage = imgURL[len(imgURL)-1]
 | 
			
		||||
 | 
			
		||||
		content, err := os.ReadFile(fmt.Sprint(c.ArticleDir, "/", data.Article.ID, ".md"))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"html/template"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	b "streifling.com/jason/cpolis/cmd/backend"
 | 
			
		||||
)
 | 
			
		||||
@@ -69,20 +70,8 @@ func UploadBanner(c *b.Config, s *b.CookieStore, fileKey, htmlFile, htmlTemplate
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		base64Img, err := b.ServeBase64Image(c, filename)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		data := new(struct {
 | 
			
		||||
			BannerImage string
 | 
			
		||||
			URL         string
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		data.BannerImage = base64Img
 | 
			
		||||
		data.URL = c.Domain + "/image/serve/" + filename
 | 
			
		||||
		data := new(struct{ BannerImage string })
 | 
			
		||||
		data.BannerImage = filename
 | 
			
		||||
 | 
			
		||||
		tmpl, err := template.ParseFiles(c.WebDir + "/templates/" + htmlFile)
 | 
			
		||||
		if err = template.Must(tmpl, err).ExecuteTemplate(w, htmlTemplate, data); err != nil {
 | 
			
		||||
@@ -92,3 +81,22 @@ func UploadBanner(c *b.Config, s *b.CookieStore, fileKey, htmlFile, htmlTemplate
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ServeImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		if _, err := getSession(w, r, c, s); err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		absFilepath, err := filepath.Abs(c.PicsDir)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println(err)
 | 
			
		||||
			http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		http.ServeFile(w, r, absFilepath+"/"+r.PathValue("img"))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,7 @@ func main() {
 | 
			
		||||
	mux.HandleFunc("GET /article/write", f.WriteArticle(config, db, store))
 | 
			
		||||
	mux.HandleFunc("GET /atom/serve", c.ServeAtomFeed(config))
 | 
			
		||||
	mux.HandleFunc("GET /hub", f.ShowHub(config, db, store))
 | 
			
		||||
	mux.HandleFunc("GET /image/{img}", f.ServeImage(config, store))
 | 
			
		||||
	mux.HandleFunc("GET /image/serve/{pic}", c.ServeImage(config))
 | 
			
		||||
	mux.HandleFunc("GET /issue/this", f.ShowCurrentIssue(config, db, store))
 | 
			
		||||
	mux.HandleFunc("GET /logout", f.Logout(config, store))
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,7 @@
 | 
			
		||||
 | 
			
		||||
<form id="edit-area" hx-encoding="multipart/form-data">
 | 
			
		||||
    <div class="flex flex-col gap-y-1">
 | 
			
		||||
        <div class="w-full" id="article-banner-container">
 | 
			
		||||
            <img src="data:image/webp;base64,{{.BannerImage}}" alt="Banner Image">
 | 
			
		||||
            <input id="article-banner-url" name="article-banner-url" type="hidden" value="{{.Article.BannerLink}}" />
 | 
			
		||||
        </div>
 | 
			
		||||
        {{template "article-banner-template" .}}
 | 
			
		||||
 | 
			
		||||
        <div class="grid grid-cols-2 gap-4 items-center">
 | 
			
		||||
            <div class="flex flex-col">
 | 
			
		||||
@@ -17,7 +14,7 @@
 | 
			
		||||
            <div class="grid grid-cols-1 items-center">
 | 
			
		||||
                <label class="btn text-center" for="article-banner">Titelbild</label>
 | 
			
		||||
                <input class="hidden" id="article-banner" name="article-banner" type="file" required
 | 
			
		||||
                    hx-post="/article/upload-banner" hx-target="#article-banner-container" />
 | 
			
		||||
                    hx-post="/article/upload-banner" hx-swap="outerHTML" hx-target="#article-banner-container" />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
@@ -92,8 +89,8 @@
 | 
			
		||||
{{end}}
 | 
			
		||||
 | 
			
		||||
{{define "article-banner-template"}}
 | 
			
		||||
<div class="w-full" id="article-banner-container">
 | 
			
		||||
    <img src="data:image/webp;base64,{{.BannerImage}}" alt="Banner Image">
 | 
			
		||||
    <input id="article-banner-url" name="article-banner-url" type="hidden" value="{{.URL}}" />
 | 
			
		||||
<div id="article-banner-container">
 | 
			
		||||
    <img src="/image/{{.BannerImage}}" alt="Banner Image">
 | 
			
		||||
    <input id="article-banner-url" name="article-banner-url" type="hidden" value="{{.BannerImage}}" />
 | 
			
		||||
</div>
 | 
			
		||||
{{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
<div>
 | 
			
		||||
    <div class="w-full" id="article-banner-container">
 | 
			
		||||
        <img src="data:image/webp;base64,{{.BannerImage}}" alt="Banner Image">
 | 
			
		||||
        <img src="/image/{{.BannerImage}}" alt="Banner Image">
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <span>Titel</span>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user