aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
authorBobby <[email protected]>2025-07-17 10:47:08 +0530
committerBobby <[email protected]>2025-07-17 10:47:08 +0530
commitb0ba363696a758a8d0637107bd29a0a9ac1382d4 (patch)
treef11acd0ebc5a4b3d633a6a596deee92b575f8f1c /models
parent94cca506f6d1461bf38afa5b0e38d778391b8d39 (diff)
downloadimageboard-b0ba363696a758a8d0637107bd29a0a9ac1382d4.tar.xz
imageboard-b0ba363696a758a8d0637107bd29a0a9ac1382d4.zip
refactor and fake upload
Diffstat (limited to 'models')
-rw-r--r--models/enums.go120
-rw-r--r--models/image.go68
-rw-r--r--models/tags.go21
-rw-r--r--models/tokens.go13
-rw-r--r--models/user.go64
5 files changed, 84 insertions, 202 deletions
diff --git a/models/enums.go b/models/enums.go
deleted file mode 100644
index 3334141..0000000
--- a/models/enums.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package models
-
-type UserLevel int
-
-const (
- UserLevelMember UserLevel = iota
- UserLevelContributor
- UserLevelJanitor
- UserLevelModerator
- UserLevelAdmin
- UserLevelSuperAdmin
-)
-
-func (l UserLevel) String() string {
- switch l {
- case UserLevelMember:
- return "Member"
- case UserLevelContributor:
- return "Contributor"
- case UserLevelJanitor:
- return "Janitor"
- case UserLevelModerator:
- return "Moderator"
- case UserLevelAdmin:
- return "Admin"
- default:
- return "Unknown"
- }
-}
-
-func (l UserLevel) Color() string {
- switch l {
- case UserLevelMember:
- return "#8B9DC3" // Soft periwinkle blue
- case UserLevelContributor:
- return "#7FCDAE" // Mint green
- case UserLevelJanitor:
- return "#9BB5FF" // Light electric blue
- case UserLevelModerator:
- return "#FF9F9B" // Coral pink
- case UserLevelAdmin:
- return "#C39BD3" // Lavender purple
- case UserLevelSuperAdmin:
- return "#FFD93D" // Electric yellow
- default:
- return "#B0B0B0" // Neutral gray
- }
-}
-
-type Rating string
-
-const (
- RatingSafe Rating = "Safe"
- RatingQuestionable Rating = "Questionable"
- RatingSensitive Rating = "Sensitive"
- RatingExplicit Rating = "Explicit"
-)
-
-type ImageContentType string
-
-const (
- ImageContentTypeJPEG ImageContentType = "image/jpeg"
- ImageContentTypePNG ImageContentType = "image/png"
- ImageContentTypeGIF ImageContentType = "image/gif"
- ImageContentTypeWebP ImageContentType = "image/webp"
- ImageContentTypeAVIF ImageContentType = "image/avif"
- ImageContentTypeSVG ImageContentType = "image/svg+xml"
- ImageContentTypeBMP ImageContentType = "image/bmp"
- ImageContentTypeTIFF ImageContentType = "image/tiff"
- ImageContentTypeICO ImageContentType = "image/x-icon"
- ImageContentTypeHEIC ImageContentType = "image/heic"
- ImageContentTypeHEIF ImageContentType = "image/heif"
- ImageContentTypeUnknown ImageContentType = "application/octet-stream"
-)
-
-type ImageSizeType string
-
-const (
- ImageSizeTypeIcon ImageSizeType = "icon"
- ImageSizeTypeThumbnail ImageSizeType = "thumbnail"
- ImageSizeTypeSmall ImageSizeType = "small"
- ImageSizeTypeMedium ImageSizeType = "medium"
- ImageSizeTypeLarge ImageSizeType = "large"
- ImageSizeTypeOriginal ImageSizeType = "original"
-)
-
-type TagType string
-
-const (
- TagTypeGeneral TagType = "general"
- TagTypeArtist TagType = "artist"
- TagTypeCopyright TagType = "copyright"
- TagTypeCharacter TagType = "character"
- TagTypeMeta TagType = "meta"
-)
-
-func (t TagType) Color() string {
- switch t {
- case TagTypeGeneral:
- return "#4ECDC4" // Turquoise cyan
- case TagTypeArtist:
- return "#FF6B9D" // Hot pink
- case TagTypeCopyright:
- return "#A8E6CF" // Mint green
- case TagTypeCharacter:
- return "#FFB347" // Peach orange
- case TagTypeMeta:
- return "#DDA0DD" // Plum purple
- default:
- return "#E6E6FA" // Light lavender
- }
-}
-
-type EmailTokenType string
-
-const (
- EmailTokenTypeVerification EmailTokenType = "verification"
- EmailTokenTypePasswordReset EmailTokenType = "password_reset"
- EmailTokenTypeChangeEmail EmailTokenType = "change_email"
-)
diff --git a/models/image.go b/models/image.go
index 03d4c38..5feed5b 100644
--- a/models/image.go
+++ b/models/image.go
@@ -12,12 +12,12 @@ import (
type ImageSize struct {
gorm.Model
- ImageID uint `gorm:"not null;index" json:"-"`
- Image Image `gorm:"foreignKey:ImageID" json:"image"`
- SizeType ImageSizeType `gorm:"not null;size:50" json:"size_type"`
- Width int `gorm:"not null" json:"width"`
- Height int `gorm:"not null" json:"height"`
- FileSize int64 `gorm:"not null" json:"file_size"`
+ ImageID uint `gorm:"not null;index" json:"-"`
+ Image Image `gorm:"foreignKey:ImageID" json:"image"`
+ SizeType config.ImageSizeType `gorm:"not null;size:50" json:"size_type"`
+ Width int `gorm:"not null" json:"width"`
+ Height int `gorm:"not null" json:"height"`
+ FileSize int64 `gorm:"not null" json:"file_size"`
}
func (s *ImageSize) BeforeCreate(tx *gorm.DB) error {
@@ -56,29 +56,29 @@ func (s *ImageSize) GetFileSizeFormatted() string {
type Image struct {
gorm.Model
- FileName string `gorm:"not null;size:255" json:"file_name"`
- OriginalName string `gorm:"not null;size:255" json:"original_name"`
- ContentType ImageContentType `gorm:"not null;size:100" json:"content_type"`
- MD5Hash string `gorm:"not null;size:32" json:"md5_hash"`
- Title string `gorm:"default:'';size:255" json:"title"`
- Description string `gorm:"default:'';type:text" json:"description"`
- SourceURL string `gorm:"default:'';size:500" json:"source_url"`
- Rating Rating `gorm:"not null;default:'safe';size:10" json:"rating"`
- IsApproved bool `gorm:"not null;default:true" json:"is_approved"`
- IsDeleted bool `gorm:"not null;default:false" json:"is_deleted"`
- ThreadLocked bool `gorm:"not null;default:false" json:"thread_locked"`
- UploaderID uint `gorm:"not null;index" json:"-"`
- Uploader User `gorm:"foreignKey:UploaderID" json:"uploader"`
- ApproverID *uint `gorm:"index" json:"-"`
- Approver *User `gorm:"foreignKey:ApproverID" json:"approver,omitempty"`
- RelatedImages []Image `gorm:"many2many:image_relationships;joinForeignKey:image_id;joinReferences:related_image_id" json:"related_images,omitempty"`
- ViewCount int64 `gorm:"not null;default:0" json:"view_count"`
- FavouriteCount int64 `gorm:"not null;default:0" json:"favorite_count"`
- CommentCount int64 `gorm:"not null;default:0" json:"comment_count"`
- Sizes []ImageSize `gorm:"foreignKey:ImageID" json:"sizes,omitempty"`
- Tags []Tag `gorm:"many2many:image_tags" json:"tags,omitempty"`
- FavoritedBy []User `gorm:"many2many:user_favorites" json:"favorited_by,omitempty"`
- Comments []Comment `gorm:"foreignKey:ImageID" json:"comments,omitempty"`
+ FileName string `gorm:"not null;size:255" json:"file_name"`
+ OriginalName string `gorm:"not null;size:255" json:"original_name"`
+ ContentType config.ImageContentType `gorm:"not null;size:100" json:"content_type"`
+ MD5Hash string `gorm:"not null;size:32" json:"md5_hash"`
+ Title string `gorm:"default:'';size:255" json:"title"`
+ Description string `gorm:"default:'';type:text" json:"description"`
+ SourceURL string `gorm:"default:'';size:500" json:"source_url"`
+ Rating config.Rating `gorm:"not null;default:'safe';size:10" json:"rating"`
+ IsApproved bool `gorm:"not null;default:true" json:"is_approved"`
+ IsDeleted bool `gorm:"not null;default:false" json:"is_deleted"`
+ ThreadLocked bool `gorm:"not null;default:false" json:"thread_locked"`
+ UploaderID uint `gorm:"not null;index" json:"-"`
+ Uploader User `gorm:"foreignKey:UploaderID" json:"uploader"`
+ ApproverID *uint `gorm:"index" json:"-"`
+ Approver *User `gorm:"foreignKey:ApproverID" json:"approver,omitempty"`
+ RelatedImages []Image `gorm:"many2many:image_relationships;joinForeignKey:image_id;joinReferences:related_image_id" json:"related_images,omitempty"`
+ ViewCount int64 `gorm:"not null;default:0" json:"view_count"`
+ FavouriteCount int64 `gorm:"not null;default:0" json:"favorite_count"`
+ CommentCount int64 `gorm:"not null;default:0" json:"comment_count"`
+ Sizes []ImageSize `gorm:"foreignKey:ImageID" json:"sizes,omitempty"`
+ Tags []Tag `gorm:"many2many:image_tags" json:"tags,omitempty"`
+ FavoritedBy []User `gorm:"many2many:user_favorites" json:"favorited_by,omitempty"`
+ Comments []Comment `gorm:"foreignKey:ImageID" json:"comments,omitempty"`
}
func (i *Image) BeforeCreate(tx *gorm.DB) error {
@@ -104,7 +104,7 @@ func (i *Image) BeforeDelete(tx *gorm.DB) error {
) AND count > 0`, i.ID).Error
}
-func (i *Image) GetURL(sizeType ImageSizeType) string {
+func (i *Image) GetURL(sizeType config.ImageSizeType) string {
for _, size := range i.Sizes {
if size.SizeType == sizeType {
return size.GetURL()
@@ -114,7 +114,7 @@ func (i *Image) GetURL(sizeType ImageSizeType) string {
return ""
}
-func (i *Image) GetSize(sizeType ImageSizeType) *ImageSize {
+func (i *Image) GetSize(sizeType config.ImageSizeType) *ImageSize {
for _, size := range i.Sizes {
if size.SizeType == sizeType {
return &size
@@ -124,14 +124,14 @@ func (i *Image) GetSize(sizeType ImageSizeType) *ImageSize {
}
func (i *Image) GetOriginalDimensions() string {
- if fullSize := i.GetSize(ImageSizeTypeOriginal); fullSize != nil {
+ if fullSize := i.GetSize(config.ImageSizeTypeOriginal); fullSize != nil {
return fullSize.GetDimensions()
}
return "Unknown"
}
func (i *Image) GetAspectRatio() string {
- if fullSize := i.GetSize(ImageSizeTypeOriginal); fullSize != nil {
+ if fullSize := i.GetSize(config.ImageSizeTypeOriginal); fullSize != nil {
if fullSize.Height == 0 {
return "Unknown"
}
@@ -148,7 +148,7 @@ func (i *Image) GetAspectRatio() string {
return "Unknown"
}
-func (i *Image) AddSize(tx *gorm.DB, sizeType ImageSizeType, width, height int, fileSize int64) (*ImageSize, error) {
+func (i *Image) AddSize(tx *gorm.DB, sizeType config.ImageSizeType, width, height int, fileSize int64) (*ImageSize, error) {
if width <= 0 || height <= 0 {
return nil, fmt.Errorf("image dimensions must be greater than zero")
}
diff --git a/models/tags.go b/models/tags.go
index 61f7013..83f0735 100644
--- a/models/tags.go
+++ b/models/tags.go
@@ -2,6 +2,7 @@ package models
import (
"fmt"
+ "imageboard/config"
"imageboard/utils/validators"
"strings"
@@ -10,15 +11,15 @@ import (
type Tag struct {
gorm.Model
- Name string `gorm:"not null;uniqueIndex;size:100" json:"name"`
- Type TagType `gorm:"not null;default:'general';size:20" json:"type"`
- Description string `gorm:"default:'';type:text" json:"description"`
- Count int `gorm:"not null;default:0" json:"count"`
- IsDeleted bool `gorm:"not null;default:false" json:"is_deleted"`
- ParentID *uint `gorm:"index" json:"-"`
- Parent *Tag `gorm:"foreignKey:ParentID" json:"parent,omitempty"`
- Children []Tag `gorm:"foreignKey:ParentID" json:"children,omitempty"`
- Images []Image `gorm:"many2many:image_tags" json:"images,omitempty"`
+ Name string `gorm:"not null;uniqueIndex;size:100" json:"name"`
+ Type config.TagType `gorm:"not null;default:'general';size:20" json:"type"`
+ Description string `gorm:"default:'';type:text" json:"description"`
+ Count int `gorm:"not null;default:0" json:"count"`
+ IsDeleted bool `gorm:"not null;default:false" json:"is_deleted"`
+ ParentID *uint `gorm:"index" json:"-"`
+ Parent *Tag `gorm:"foreignKey:ParentID" json:"parent,omitempty"`
+ Children []Tag `gorm:"foreignKey:ParentID" json:"children,omitempty"`
+ Images []Image `gorm:"many2many:image_tags" json:"images,omitempty"`
}
func (t *Tag) BeforeCreate(tx *gorm.DB) error {
@@ -80,7 +81,7 @@ func SearchTagsExcluding(tx *gorm.DB, query string, imageID uint, limit int) ([]
return tags, err
}
-func FindOrCreateTag(tx *gorm.DB, name string, tagType TagType) (*Tag, error) {
+func FindOrCreateTag(tx *gorm.DB, name string, tagType config.TagType) (*Tag, error) {
name = strings.TrimSpace(strings.ToLower(name))
// First check for active tag
diff --git a/models/tokens.go b/models/tokens.go
index c53ea2e..c635c4e 100644
--- a/models/tokens.go
+++ b/models/tokens.go
@@ -1,6 +1,7 @@
package models
import (
+ "imageboard/config"
"time"
"gorm.io/gorm"
@@ -8,12 +9,12 @@ import (
type EmailToken struct {
gorm.Model
- UserID uint `gorm:"not null;index" json:"user_id"`
- Token string `gorm:"uniqueIndex;not null;size:64" json:"token"`
- Type EmailTokenType `gorm:"not null;size:20" json:"type"`
- ExpiresAt time.Time `gorm:"not null" json:"expires_at"`
- UsedAt *time.Time `gorm:"default:null" json:"used_at"`
- User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
+ UserID uint `gorm:"not null;index" json:"user_id"`
+ Token string `gorm:"uniqueIndex;not null;size:64" json:"token"`
+ Type config.EmailTokenType `gorm:"not null;size:20" json:"type"`
+ ExpiresAt time.Time `gorm:"not null" json:"expires_at"`
+ UsedAt *time.Time `gorm:"default:null" json:"used_at"`
+ User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
}
func (et *EmailToken) IsExpired() bool {
diff --git a/models/user.go b/models/user.go
index 546f600..ecb139f 100644
--- a/models/user.go
+++ b/models/user.go
@@ -13,23 +13,23 @@ import (
type User struct {
gorm.Model
- Username string `gorm:"uniqueIndex;not null;size:255" json:"username"`
- Email string `gorm:"not null;size:255" json:"email"`
- Password string `gorm:"not null;size:255" json:"-"`
- Level UserLevel `gorm:"not null;default:0" json:"level"`
- EmailVerified bool `gorm:"not null;default:false" json:"email_verified"`
- Bio string `gorm:"default:'';size:500" json:"bio"`
- AvatarURL string `gorm:"default:'';size:255" json:"avatar_url"`
- WebsiteURL string `gorm:"default:'';size:255" json:"website_url"`
- Location string `gorm:"default:'';size:255" json:"location"`
- Timezone string `gorm:"default:'UTC';size:50" json:"timezone"`
- AccountDisabled bool `gorm:"not null;default:false" json:"-"`
- AccountBanned bool `gorm:"not null;default:false" json:"-"`
- PostsRequireApproval bool `gorm:"not null;default:false" json:"-"`
- IsDeleted bool `gorm:"not null;default:false" json:"-"`
- LastLoginAt *time.Time `gorm:"default:null" json:"last_login_at"`
- LastActivityAt *time.Time `gorm:"default:null" json:"last_activity_at"`
- Images []Image `gorm:"foreignKey:UploaderID" json:"images,omitempty"`
+ Username string `gorm:"uniqueIndex;not null;size:255" json:"username"`
+ Email string `gorm:"not null;size:255" json:"email"`
+ Password string `gorm:"not null;size:255" json:"-"`
+ Level config.UserLevel `gorm:"not null;default:0" json:"level"`
+ EmailVerified bool `gorm:"not null;default:false" json:"email_verified"`
+ Bio string `gorm:"default:'';size:500" json:"bio"`
+ AvatarURL string `gorm:"default:'';size:255" json:"avatar_url"`
+ WebsiteURL string `gorm:"default:'';size:255" json:"website_url"`
+ Location string `gorm:"default:'';size:255" json:"location"`
+ Timezone string `gorm:"default:'UTC';size:50" json:"timezone"`
+ AccountDisabled bool `gorm:"not null;default:false" json:"-"`
+ AccountBanned bool `gorm:"not null;default:false" json:"-"`
+ PostsRequireApproval bool `gorm:"not null;default:false" json:"-"`
+ IsDeleted bool `gorm:"not null;default:false" json:"-"`
+ LastLoginAt *time.Time `gorm:"default:null" json:"last_login_at"`
+ LastActivityAt *time.Time `gorm:"default:null" json:"last_activity_at"`
+ Images []Image `gorm:"foreignKey:UploaderID" json:"images,omitempty"`
}
func (u *User) BeforeCreate(tx *gorm.DB) error {
@@ -76,7 +76,7 @@ func (u *User) BeforeCreate(tx *gorm.DB) error {
}
if userCount == 0 {
- u.Level = UserLevelSuperAdmin // First user becomes Super Admin
+ u.Level = config.UserLevelSuperAdmin // First user becomes Super Admin
}
if len(u.Password) < config.Server.MinPasswordLength {
@@ -143,23 +143,23 @@ func (u *User) CanLogin() bool {
}
func (u *User) IsAdmin() bool {
- return u.Level >= UserLevelAdmin
+ return u.Level >= config.UserLevelAdmin
}
func (u *User) IsModerator() bool {
- return u.IsActive() && u.Level >= UserLevelModerator
+ return u.IsActive() && u.Level >= config.UserLevelModerator
}
func (u *User) IsJanitor() bool {
- return u.IsActive() && u.Level >= UserLevelJanitor
+ return u.IsActive() && u.Level >= config.UserLevelJanitor
}
func (u *User) IsContributor() bool {
- return u.IsActive() && u.Level >= UserLevelContributor
+ return u.IsActive() && u.Level >= config.UserLevelContributor
}
func (u *User) IsMember() bool {
- return u.IsActive() && u.Level >= UserLevelMember
+ return u.IsActive() && u.Level >= config.UserLevelMember
}
func (u *User) CanUpload() bool {
@@ -206,28 +206,28 @@ func (u *User) CanEditUser(targetUser *User) bool {
return (u.IsAdmin() || u.IsModerator()) && targetUser.Level < u.Level
}
-func (u *User) CanPromoteUser(targetUser *User, newLevel UserLevel) bool {
+func (u *User) CanPromoteUser(targetUser *User, newLevel config.UserLevel) bool {
if u.ID == targetUser.ID || targetUser.IsDeleted {
return false
}
- if u.Level <= UserLevelContributor {
+ if u.Level <= config.UserLevelContributor {
return false
}
- return newLevel > UserLevelMember && newLevel <= u.Level && newLevel <= UserLevelAdmin
+ return newLevel > config.UserLevelMember && newLevel <= u.Level && newLevel <= config.UserLevelAdmin
}
-func (u *User) CanDemoteUser(targetUser *User, newLevel UserLevel) bool {
+func (u *User) CanDemoteUser(targetUser *User, newLevel config.UserLevel) bool {
if u.ID == targetUser.ID || targetUser.IsDeleted {
return false
}
- if u.Level <= UserLevelContributor {
+ if u.Level <= config.UserLevelContributor {
return false
}
- return newLevel >= UserLevelMember && newLevel < u.Level && newLevel <= UserLevelAdmin
+ return newLevel >= config.UserLevelMember && newLevel < u.Level && newLevel <= config.UserLevelAdmin
}
func (u *User) CanDisableUser(targetUser *User) bool {
@@ -255,7 +255,7 @@ func (u *User) CanDeleteUser(targetUser *User) bool {
return true // Users can delete their own account
}
- if u.Level <= UserLevelContributor {
+ if u.Level <= config.UserLevelContributor {
return false
}
@@ -272,9 +272,9 @@ func (u *User) CanMakeUserPostsRequireApproval(targetUser *User) bool {
func (u *User) GetDailyPostLimit() int {
switch u.Level {
- case UserLevelMember:
+ case config.UserLevelMember:
return 10
- case UserLevelContributor:
+ case config.UserLevelContributor:
return 25
default:
return -1 // No limit for Janitors, Moderators, and Admins