diff options
| author | Bobby <[email protected]> | 2025-07-17 10:47:08 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2025-07-17 10:47:08 +0530 |
| commit | b0ba363696a758a8d0637107bd29a0a9ac1382d4 (patch) | |
| tree | f11acd0ebc5a4b3d633a6a596deee92b575f8f1c /models | |
| parent | 94cca506f6d1461bf38afa5b0e38d778391b8d39 (diff) | |
| download | imageboard-b0ba363696a758a8d0637107bd29a0a9ac1382d4.tar.xz imageboard-b0ba363696a758a8d0637107bd29a0a9ac1382d4.zip | |
refactor and fake upload
Diffstat (limited to 'models')
| -rw-r--r-- | models/enums.go | 120 | ||||
| -rw-r--r-- | models/image.go | 68 | ||||
| -rw-r--r-- | models/tags.go | 21 | ||||
| -rw-r--r-- | models/tokens.go | 13 | ||||
| -rw-r--r-- | models/user.go | 64 |
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 |
