🚚 Expose the models to public

This commit is contained in:
2025-03-29 22:17:22 +08:00
parent 8f91649d25
commit 820d7a9f42
33 changed files with 28 additions and 28 deletions

View File

@ -0,0 +1,140 @@
package models
import (
"time"
"git.solsynth.dev/hypernet/nexus/pkg/nex/cachekit"
"git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
"git.solsynth.dev/hypernet/paperclip/pkg/internal/gap"
"gorm.io/datatypes"
"gorm.io/gorm"
)
const (
AttachmentDstTemporary = 0 // The destination 0 is a reserved config for pre-upload processing
)
const (
AttachmentTypeNormal = iota
AttachmentTypeThumbnail
AttachmentTypeCompressed
)
type Attachment struct {
cruda.BaseModel
// Random ID is for accessing (appear in URL)
Rid string `json:"rid" gorm:"uniqueIndex"`
// Unique ID is for storing (appear in local file name or object name)
Uuid string `json:"uuid"`
Size int64 `json:"size"`
Name string `json:"name"`
Alternative string `json:"alt"`
MimeType string `json:"mimetype"`
HashCode string `json:"hash"`
Destination int `json:"destination"`
RefCount int `json:"ref_count"`
Type uint `json:"type"`
CleanedAt *time.Time `json:"cleaned_at"`
Metadata datatypes.JSONMap `json:"metadata"` // This field is analyzer auto generated metadata
Usermeta datatypes.JSONMap `json:"usermeta"` // This field is user set metadata
ContentRating int `json:"content_rating"` // This field use to filter mature content or not
QualityRating int `json:"quality_rating"` // This field use to filter good content or not
IsAnalyzed bool `json:"is_analyzed"`
IsSelfRef bool `json:"is_self_ref"`
IsIndexable bool `json:"is_indexable"` // Show this attachment in the public directory api or not
// Count the usage of this attachment across all services
// If this number remain 0, it will be deleted during the maintenance
UsedCount int `json:"used_count"`
Thumbnail *Attachment `json:"thumbnail"`
ThumbnailID *uint `json:"thumbnail_id"`
Compressed *Attachment `json:"compressed"`
CompressedID *uint `json:"compressed_id"`
Ref *Attachment `json:"ref"`
RefID *uint `json:"ref_id"`
Pool *AttachmentPool `json:"pool"`
PoolID *uint `json:"pool_id"`
Boosts []AttachmentBoost `json:"boosts"`
AccountID uint `json:"account_id"`
// Outdated fields, just for backward compatibility
FileChunks datatypes.JSONMap `json:"file_chunks" gorm:"-"`
IsUploaded bool `json:"is_uploaded" gorm:"-"`
IsMature bool `json:"is_mature" gorm:"-"`
}
func (v *Attachment) AfterUpdate(tx *gorm.DB) error {
cachekit.FKey(cachekit.DAAttachment, v.Rid)
return nil
}
// Data model for in progress multipart attachments
type AttachmentFragment struct {
cruda.BaseModel
// Random ID is for accessing (appear in URL)
Rid string `json:"rid" gorm:"uniqueIndex"`
// Unique ID is for storing (appear in local file name or object name)
Uuid string `json:"uuid"`
Size int64 `json:"size"`
Name string `json:"name"`
Alternative string `json:"alt"`
MimeType string `json:"mimetype"`
HashCode string `json:"hash"`
Fingerprint *string `json:"fingerprint"` // Client side generated hash, for continue uploading
FileChunks datatypes.JSONMap `json:"file_chunks"`
Metadata datatypes.JSONMap `json:"metadata"` // This field is analyzer auto generated metadata
Usermeta datatypes.JSONMap `json:"usermeta"` // This field is user set metadata
Pool *AttachmentPool `json:"pool"`
PoolID *uint `json:"pool_id"`
AccountID uint `json:"account_id"`
FileChunksMissing []string `json:"file_chunks_missing" gorm:"-"` // This field use to prompt client which chunks is pending upload, do not store it
}
func (v *AttachmentFragment) AfterUpdate(tx *gorm.DB) error {
cachekit.Delete(
gap.Ca,
cachekit.FKey("attachment-fragment", v.Rid),
)
return nil
}
func (v AttachmentFragment) ToAttachment() Attachment {
return Attachment{
Rid: v.Rid,
Uuid: v.Uuid,
Size: v.Size,
Name: v.Name,
Alternative: v.Alternative,
MimeType: v.MimeType,
HashCode: v.HashCode,
Metadata: v.Metadata,
Usermeta: v.Usermeta,
Destination: AttachmentDstTemporary,
Type: AttachmentTypeNormal,
Pool: v.Pool,
PoolID: v.PoolID,
AccountID: v.AccountID,
}
}

View File

@ -0,0 +1,24 @@
package models
import "git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
const (
BoostStatusPending = iota
BoostStatusActive
BoostStatusSuspended
BoostStatusError
)
// AttachmentBoost is made for speed up attachment loading by copy the original attachments
// to others faster CDN or storage destinations.
type AttachmentBoost struct {
cruda.BaseModel
Status int `json:"status"`
Destination int `json:"destination"`
AttachmentID uint `json:"attachment_id"`
Attachment Attachment `json:"attachment"`
AccountID uint `json:"account"`
}

View File

@ -0,0 +1,53 @@
package models
import (
pkg "git.solsynth.dev/hypernet/paperclip/pkg/internal"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
const (
DestinationTypeLocal = "local"
DestinationTypeS3 = "s3"
)
type BaseDestination struct {
ID int `json:"id,omitempty"` // Auto filled with index, only for user
Type string `json:"type"`
Label string `json:"label"`
Region string `json:"region"`
IsBoost bool `json:"is_boost"`
}
type LocalDestination struct {
BaseDestination
Path string `json:"path"`
AccessBaseURL string `json:"access_baseurl"`
}
type S3Destination struct {
BaseDestination
Path string `json:"path"`
Bucket string `json:"bucket"`
Endpoint string `json:"endpoint"`
SecretID string `json:"secret_id"`
SecretKey string `json:"secret_key"`
AccessBaseURL string `json:"access_baseurl"`
EnableSSL bool `json:"enable_ssl"`
EnableSigned bool `json:"enable_signed"`
BucketLookup int `json:"bucket_lookup"`
}
func (v S3Destination) GetClient() (*minio.Client, error) {
client, err := minio.New(v.Endpoint, &minio.Options{
Creds: credentials.NewStaticV4(v.SecretID, v.SecretKey, ""),
Secure: v.EnableSSL,
BucketLookup: minio.BucketLookupType(v.BucketLookup),
})
if err == nil {
client.SetAppInfo("HyperNet.Paperclip", pkg.AppVersion)
}
return client, err
}

View File

@ -0,0 +1,27 @@
package models
import (
"git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
"gorm.io/datatypes"
)
type AttachmentPool struct {
cruda.BaseModel
Alias string `json:"alias"`
Name string `json:"name"`
Description string `json:"description"`
Config datatypes.JSONType[AttachmentPoolConfig] `json:"config"`
Attachments []Attachment `json:"attachments" gorm:"foreignKey:PoolID"`
AccountID *uint `json:"account_id"`
}
type AttachmentPoolConfig struct {
MaxFileSize *int64 `json:"max_file_size"`
ExistLifecycle *int64 `json:"exist_lifecycle"`
AllowCrossPoolIngress bool `json:"allow_cross_pool_ingress"`
AllowCrossPoolEgress bool `json:"allow_cross_pool_egress"`
PublicIndexable bool `json:"public_indexable"`
}

View File

@ -0,0 +1,32 @@
package models
import (
"git.solsynth.dev/hypernet/nexus/pkg/nex/cruda"
)
type Sticker struct {
cruda.BaseModel
Alias string `json:"alias"`
Name string `json:"name"`
AttachmentID uint `json:"attachment_id"`
Attachment Attachment `json:"attachment"`
PackID uint `json:"pack_id"`
Pack StickerPack `json:"pack"`
AccountID uint `json:"account_id"`
}
type StickerPack struct {
cruda.BaseModel
Prefix string `json:"prefix"`
Name string `json:"name"`
Description string `json:"description"`
Stickers []Sticker `json:"stickers" gorm:"foreignKey:PackID;constraint:OnDelete:CASCADE"`
AccountID uint `json:"account_id"`
}
type StickerPackOwnership struct {
PackID uint `json:"pack_id" gorm:"primaryKey"`
AccountID uint `json:"account_id" gorm:"primaryKey"`
}