Przeglądaj źródła

made image store creation and verification functions and added categories to image upload. Allows for adding assets that can be added to blog posts

aeth 2 tygodni temu
rodzic
commit
d5edffb43d

+ 5 - 1
cmd/keiji/keiji.go

@@ -94,7 +94,11 @@ func main() {
 	if err != nil {
 		log.Fatal(err)
 	}
-	webserverDb := storage.NewSQLiteRepo(db, storage.FilesystemImageIO{RootDir: os.Getenv(env.IMAGE_STORE)})
+	path := os.Getenv(env.IMAGE_STORE)
+	if path == "" {
+		log.Fatalf("Environment variable: '%s' resolved to a null value: '%s'", env.IMAGE_STORE, path)
+	}
+	webserverDb := storage.NewSQLiteRepo(db, storage.MustNewFilesystemImageIO(path))
 	err = webserverDb.Migrate(storage.RequiredTables)
 	if err != nil {
 		log.Fatal(err)

+ 3 - 1
pkg/controller/admin_handlers.go

@@ -398,6 +398,8 @@ func (c *Controller) ServeFileUpload(ctx *gin.Context) {
 			"menu":    c.database.GetDropdownElements(),
 			"headers": c.database.GetNavBarLinks(),
 		},
+		"Topics":       storage.ImageCategories,
+		"DefaultTopic": storage.DIGITAL_ART,
 	})
 }
 
@@ -433,7 +435,7 @@ func (c *Controller) SaveFile(ctx *gin.Context) {
 		}
 		output.Write(fb[:n])
 	}
-	_, err = c.database.AddImage(fb, img.Title, img.Desc)
+	_, err = c.database.AddImage(fb, img.Title, img.Desc, img.Category)
 	if err != nil {
 		ctx.HTML(500, "upload_status", gin.H{"UpdateMessage": err, "Color": "red"})
 		return

+ 1 - 1
pkg/controller/html_handlers.go

@@ -108,7 +108,7 @@ func (c *Controller) ServeCreative(ctx *gin.Context) {
 // @Tags webpages
 // @Router /digital [get]
 func (c *Controller) ServeDigitalArt(ctx *gin.Context) {
-	images := c.database.GetAllImages()
+	images := c.database.GetImagesByCategory(storage.DIGITAL_ART)
 	ctx.HTML(http.StatusOK, "digital_art", gin.H{
 		"navigation": gin.H{
 			"headers": c.database.GetNavBarLinks(),

+ 2 - 1
pkg/storage/queries.go

@@ -17,7 +17,8 @@ const imagesTable = `
 		id TEXT NOT NULL,
 		title TEXT NOT NULL,
 		desc TEXT NOT NULL,
-		created TEXT NOT NULL
+		created TEXT NOT NULL,
+		category TEXT NOT NULL
 	);
 	`
 const menuItemsTable = `

+ 55 - 9
pkg/storage/storage.go

@@ -21,6 +21,7 @@ const CONFIGURATION = "configuration"
 const BLOG = "blog"
 const CREATIVE = "creative"
 const DIGITAL_ART = "digital_art"
+const MISC_ASSET = "misc_asset"
 const HOMEPAGE = "homepage"
 
 var Topics = []string{
@@ -30,6 +31,11 @@ var Topics = []string{
 	HOMEPAGE,
 }
 
+var ImageCategories = []string{
+	MISC_ASSET,
+	DIGITAL_ART,
+}
+
 type DatabaseSchema struct {
 	// Gotta figure out what this looks like
 	// so that the ExtractAll() function gets
@@ -104,7 +110,7 @@ type Image struct {
 	File     *multipart.FileHeader `form:"file"`
 	Desc     string                `json:"description" form:"description"`
 	Created  string
-	Category string
+	Category string `json:"category" form:"category"`
 	Data     []byte
 }
 
@@ -112,11 +118,12 @@ type DocumentIO interface {
 	GetDocument(id Identifier) (Document, error)
 	GetImage(id Identifier) (Image, error)
 	GetAllImages() []Image
+	GetImagesByCategory(category string) []Image
 	UpdateDocument(doc Document) error
 	DeleteDocument(id Identifier) error
 	DeleteNavbarItem(id Identifier) error
 	AddDocument(doc Document) (Identifier, error)
-	AddImage(data []byte, title, desc string) (Identifier, error)
+	AddImage(data []byte, title, desc, category string) (Identifier, error)
 	AddAsset(name string, data []byte) error
 	AddAdminTableEntry(TableData, string) error
 	AddNavbarItem(NavBarItem) error
@@ -150,6 +157,19 @@ type FilesystemImageIO struct {
 	RootDir string
 }
 
+/*
+create a new FilesystemImageIO struct
+*/
+func MustNewFilesystemImageIO(path string) FilesystemImageIO {
+	var filemode os.FileMode
+	filemode = 0775
+	err := os.MkdirAll(path, filemode)
+	if err != nil {
+		log.Fatalf("Error creating path: '%s' with permissions: '%d'. Error: %s\n", path, filemode, err.Error())
+	}
+	return FilesystemImageIO{RootDir: path}
+}
+
 /*
 Put a data blob on the filesystem
 
@@ -408,8 +428,8 @@ get image data from the images table
 func (s *SQLiteRepo) GetImage(id Identifier) (Image, error) {
 	row := s.db.QueryRow("SELECT * FROM images WHERE id = ?", id)
 	var rowNum int
-	var title, desc, created string
-	if err := row.Scan(&rowNum, &id, &title, &desc, &created); err != nil {
+	var title, desc, created, category string
+	if err := row.Scan(&rowNum, &id, &title, &desc, &created, &category); err != nil {
 		if errors.Is(err, sql.ErrNoRows) {
 			return Image{}, ErrNotExists
 		}
@@ -419,7 +439,7 @@ func (s *SQLiteRepo) GetImage(id Identifier) (Image, error) {
 	if err != nil {
 		return Image{}, err
 	}
-	return Image{Ident: id, Title: title, Desc: desc, Data: data, Created: created}, nil
+	return Image{Ident: id, Title: title, Desc: desc, Data: data, Created: created, Category: category}, nil
 }
 
 /*
@@ -434,7 +454,33 @@ func (s *SQLiteRepo) GetAllImages() []Image {
 	for rows.Next() {
 		var img Image
 		var rowNum int
-		err := rows.Scan(&rowNum, &img.Ident, &img.Title, &img.Desc, &img.Created)
+		err := rows.Scan(&rowNum, &img.Ident, &img.Title, &img.Desc, &img.Created, &img.Category)
+		if err != nil {
+			log.Fatal(err)
+		}
+		b, err := s.imageIO.Get(img.Ident)
+		if err != nil {
+			log.Fatal(err)
+		}
+		imgs = append(imgs, Image{Ident: img.Ident, Title: img.Title, Desc: img.Desc, Data: b, Created: img.Created, Category: img.Category})
+	}
+	err = rows.Err()
+	if err != nil {
+		log.Fatal(err)
+	}
+	return imgs
+}
+
+func (s *SQLiteRepo) GetImagesByCategory(category string) []Image {
+	rows, err := s.db.Query("SELECT * FROM images WHERE category = ?", category)
+	if err != nil {
+		log.Fatal(err)
+	}
+	imgs := []Image{}
+	for rows.Next() {
+		var img Image
+		var rowNum int
+		err := rows.Scan(&rowNum, &img.Ident, &img.Title, &img.Desc, &img.Created, &img.Category)
 		if err != nil {
 			log.Fatal(err)
 		}
@@ -442,7 +488,7 @@ func (s *SQLiteRepo) GetAllImages() []Image {
 		if err != nil {
 			log.Fatal(err)
 		}
-		imgs = append(imgs, Image{Ident: img.Ident, Title: img.Title, Desc: img.Desc, Data: b, Created: img.Created})
+		imgs = append(imgs, Image{Ident: img.Ident, Title: img.Title, Desc: img.Desc, Data: b, Created: img.Created, Category: img.Category})
 	}
 	err = rows.Err()
 	if err != nil {
@@ -459,13 +505,13 @@ Add an image to the database
 	:param desc: the description of the image, if any
 	:param data: the binary data for the image
 */
-func (s *SQLiteRepo) AddImage(data []byte, title string, desc string) (Identifier, error) {
+func (s *SQLiteRepo) AddImage(data []byte, title string, desc string, category string) (Identifier, error) {
 	id := newIdentifier()
 	err := s.imageIO.Put(data, id)
 	if err != nil {
 		return Identifier(""), err
 	}
-	_, err = s.db.Exec("INSERT INTO images (id, title, desc, created) VALUES (?,?,?,?)", string(id), title, desc, time.Now().String())
+	_, err = s.db.Exec("INSERT INTO images (id, title, desc, created, category) VALUES (?,?,?,?,?)", string(id), title, desc, time.Now().String(), category)
 	if err != nil {
 		return Identifier(""), err
 	}

+ 11 - 0
pkg/webpages/html/upload.html

@@ -9,6 +9,17 @@
                     <div class="row container p-2 m-2">
                         <input type='file' name='file'>
                     </div>
+                    <div class="row"
+                        style="background-color: rgb(22, 22, 22); color: white; height: fit-content; font-size: larger; font-family: monospace;">
+                        <a>Category:</a>
+                        <select name="category" class="form-select"
+                            style="background-color: rgb(73, 73, 73); color: white; height: fit-content; font-size: larger; font-family: monospace;">
+                            <option selected>{{ .DefaultTopic }}</option>
+                            {{ range .Topics }}
+                            <option value="{{ . }}">{{ . }}</option>
+                            {{ end }}
+                        </select>
+                    </div>
                     <div class="row container p-2 m-2">
                         <textarea name="title" wrap="soft" required="required" placeholder="Name of the piece?"></textarea>
                     </div>