Add 404 page, add Deleted page, fix errors
This commit is contained in:
@@ -30,6 +30,9 @@ func uploadHandler(c *gin.Context) {
|
||||
id := uuid.New().String()
|
||||
delID := uuid.New().String()
|
||||
cleanName := filepath.Base(header.Filename)
|
||||
if len(cleanName) > 255 {
|
||||
cleanName = cleanName[:255]
|
||||
}
|
||||
|
||||
folderPath := filepath.Join("uploads", id)
|
||||
os.MkdirAll(folderPath, 0755)
|
||||
@@ -65,6 +68,7 @@ func uploadHandler(c *gin.Context) {
|
||||
Filename: cleanName,
|
||||
Path: storagePath,
|
||||
ExpiresAt: expiry,
|
||||
Size: written,
|
||||
DeleteAfterDownload: c.PostForm("once") == "true",
|
||||
}
|
||||
|
||||
@@ -79,14 +83,21 @@ func uploadHandler(c *gin.Context) {
|
||||
|
||||
func downloadHandler(c *gin.Context) {
|
||||
var record FileRecord
|
||||
if err := db.First(&record, "id = ? AND deleted = ?", c.Param("id"), false).Error; err != nil {
|
||||
c.String(404, "File not found or expired")
|
||||
var err = db.First(&record, "id = ? AND deleted = ?", c.Param("id"), false).Error
|
||||
if err != nil {
|
||||
c.HTML(200, "fileNotFound.html", gin.H{
|
||||
"message": "File not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if time.Now().After(record.ExpiresAt) {
|
||||
performDeletion(&record)
|
||||
c.String(410, "File has expired")
|
||||
|
||||
//c.String(410, "File has expired")
|
||||
c.HTML(404, "fileNotFound.html", gin.H{
|
||||
"message": "File not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -107,7 +118,8 @@ func deleteHandler(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
performDeletion(&record)
|
||||
c.JSON(200, gin.H{"message": "Deleted successfully"})
|
||||
//c.JSON(200, gin.H{"message": "Deleted successfully"})
|
||||
c.HTML(200, "deleted.html", nil)
|
||||
}
|
||||
|
||||
func loginHandler(c *gin.Context) {
|
||||
@@ -145,3 +157,30 @@ func loginHandler(c *gin.Context) {
|
||||
|
||||
c.Redirect(302, "/admin")
|
||||
}
|
||||
|
||||
func adminIndexHandler(c *gin.Context) {
|
||||
var files []FileRecord
|
||||
|
||||
// Pagination parameters
|
||||
perPage := 20
|
||||
page := 1
|
||||
if p := c.Query("page"); p != "" {
|
||||
if v, err := strconv.Atoi(p); err == nil && v > 0 {
|
||||
page = v
|
||||
}
|
||||
}
|
||||
|
||||
var total int64
|
||||
db.Model(&FileRecord{}).Count(&total)
|
||||
|
||||
totalPages := int((total + int64(perPage) - 1) / int64(perPage)) // ceiling division
|
||||
|
||||
offset := (page - 1) * perPage
|
||||
db.Order("created_at desc").Limit(perPage).Offset(offset).Find(&files)
|
||||
|
||||
c.HTML(200, "admin.html", gin.H{
|
||||
"Files": files,
|
||||
"Page": page,
|
||||
"TotalPages": totalPages,
|
||||
})
|
||||
}
|
||||
|
||||
41
src/main.go
41
src/main.go
@@ -6,7 +6,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
@@ -34,8 +33,9 @@ func main() {
|
||||
router := gin.Default()
|
||||
router.MaxMultipartMemory = 10 << 30
|
||||
router.SetFuncMap(template.FuncMap{
|
||||
"add": func(a, b int) int { return a + b },
|
||||
"sub": func(a, b int) int { return a - b },
|
||||
"add": func(a, b int) int { return a + b },
|
||||
"sub": func(a, b int) int { return a - b },
|
||||
"humanSize": humanSize,
|
||||
})
|
||||
router.LoadHTMLGlob("templates/*")
|
||||
var staticPath = gin.Dir("./static", false)
|
||||
@@ -43,6 +43,9 @@ func main() {
|
||||
|
||||
router.StaticFS("/static", staticPath)
|
||||
|
||||
router.NoRoute(func(c *gin.Context) {
|
||||
c.HTML(404, "error.html", nil)
|
||||
})
|
||||
// Public Routes
|
||||
router.GET("/", func(c *gin.Context) { c.HTML(200, "index.html", nil) })
|
||||
router.GET("/f/:id", downloadHandler)
|
||||
@@ -53,34 +56,16 @@ func main() {
|
||||
admin := router.Group("/admin")
|
||||
admin.Use(authMiddleware())
|
||||
|
||||
admin.GET("/", func(c *gin.Context) {
|
||||
var files []FileRecord
|
||||
|
||||
// Pagination parameters
|
||||
perPage := 20
|
||||
page := 1
|
||||
if p := c.Query("page"); p != "" {
|
||||
if v, err := strconv.Atoi(p); err == nil && v > 0 {
|
||||
page = v
|
||||
}
|
||||
admin.GET("/", adminIndexHandler)
|
||||
admin.GET("/delete/fr/:id", func(c *gin.Context) {
|
||||
var record FileRecord
|
||||
if err := db.First(&record, "id = ?", c.Param("id")).Error; err == nil {
|
||||
performActualDeletion(&record)
|
||||
}
|
||||
|
||||
var total int64
|
||||
db.Model(&FileRecord{}).Count(&total)
|
||||
|
||||
totalPages := int((total + int64(perPage) - 1) / int64(perPage)) // ceiling division
|
||||
|
||||
offset := (page - 1) * perPage
|
||||
db.Order("created_at desc").Limit(perPage).Offset(offset).Find(&files)
|
||||
|
||||
c.HTML(200, "admin.html", gin.H{
|
||||
"Files": files,
|
||||
"Page": page,
|
||||
"TotalPages": totalPages,
|
||||
})
|
||||
c.Redirect(301, "/admin")
|
||||
})
|
||||
|
||||
admin.POST("/delete/:id", func(c *gin.Context) {
|
||||
admin.GET("/delete/:id", func(c *gin.Context) {
|
||||
var record FileRecord
|
||||
if err := db.First(&record, "id = ?", c.Param("id")).Error; err == nil {
|
||||
performDeletion(&record)
|
||||
|
||||
@@ -9,6 +9,7 @@ type FileRecord struct {
|
||||
Path string `json:"-"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
DeleteAfterDownload bool `json:"delete_after_download"`
|
||||
Size int64 `json:"size"`
|
||||
DownloadCount int `json:"download_count"`
|
||||
Deleted bool `json:"deleted"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
||||
36
src/utils.go
36
src/utils.go
@@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -12,6 +15,19 @@ func performDeletion(r *FileRecord) {
|
||||
db.Save(r)
|
||||
}
|
||||
|
||||
func performActualDeletion(r *FileRecord) {
|
||||
|
||||
folderPath := filepath.Join("uploads", r.ID)
|
||||
err := os.RemoveAll(folderPath)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Error deleting file:", err)
|
||||
return
|
||||
}
|
||||
db.Delete(r)
|
||||
fmt.Println("Deleted file:", r.Filename)
|
||||
}
|
||||
|
||||
func cleanupWorker() {
|
||||
for {
|
||||
time.Sleep(10 * time.Minute)
|
||||
@@ -38,7 +54,7 @@ func authMiddleware() gin.HandlerFunc {
|
||||
|
||||
tokenStr, err := c.Cookie("auth")
|
||||
if err != nil {
|
||||
c.Redirect(302, "/")
|
||||
c.Redirect(302, "/login")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
@@ -48,7 +64,7 @@ func authMiddleware() gin.HandlerFunc {
|
||||
})
|
||||
|
||||
if err != nil || !token.Valid {
|
||||
c.Redirect(302, "/")
|
||||
c.Redirect(302, "/login")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
@@ -56,3 +72,19 @@ func authMiddleware() gin.HandlerFunc {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func humanSize(size int64) string {
|
||||
const unit = 1024
|
||||
if size < unit {
|
||||
return fmt.Sprintf("%d B", size)
|
||||
}
|
||||
div, exp := int64(unit), 0
|
||||
for n := size / unit; n >= unit; n /= unit {
|
||||
div *= unit
|
||||
exp++
|
||||
}
|
||||
return fmt.Sprintf("%.1f %cB",
|
||||
float64(size)/float64(div),
|
||||
"KMGTPE"[exp],
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user