diff --git a/.gitignore b/.gitignore index 25541a7..1733003 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /build *.db .vscode +*.local diff --git a/go.mod b/go.mod index 23edc3a..5ef2f21 100644 --- a/go.mod +++ b/go.mod @@ -92,6 +92,7 @@ require ( github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/mattn/go-colorable v0.1.13 // indirect diff --git a/go.sum b/go.sum index 6eebb55..e1e5edb 100644 --- a/go.sum +++ b/go.sum @@ -215,6 +215,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= diff --git a/internal/bootstrap/config.go b/internal/bootstrap/config.go index 7988bf3..df53549 100644 --- a/internal/bootstrap/config.go +++ b/internal/bootstrap/config.go @@ -3,9 +3,12 @@ package bootstrap import ( "context" "errors" + "os" "path/filepath" + "strings" "github.com/caarlos0/env/v9" + "github.com/joho/godotenv" log "github.com/sirupsen/logrus" "github.com/synctv-org/synctv/cmd/flags" @@ -84,7 +87,46 @@ func restoreConfig(filePath string, conf *conf.Config) error { } func confFromEnv(prefix string, conf *conf.Config) error { + s, err := getEnvFiles(flags.DataDir) + if err != nil { + return err + } + if flags.Dev { + ss, err := getEnvFiles(".") + if err != nil { + return err + } + s = append(s, ss...) + } + if len(s) != 0 { + err = godotenv.Overload(s...) + if err != nil { + return err + } + } return env.ParseWithOptions(conf, env.Options{ Prefix: prefix, }) } + +func getEnvFiles(root string) ([]string, error) { + var files []string + + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !info.IsDir() && strings.HasPrefix(info.Name(), ".env") { + files = append(files, path) + } + + return nil + }) + + if err != nil { + return nil, err + } + + return files, nil +} diff --git a/internal/bootstrap/db.go b/internal/bootstrap/db.go index fa01cd1..88f1e75 100644 --- a/internal/bootstrap/db.go +++ b/internal/bootstrap/db.go @@ -60,7 +60,7 @@ func createDialector(dbConf conf.DatabaseConfig) (dialector gorm.Dialector, err conf.Conf.Database.Name, conf.Conf.Database.SslMode, ) - log.Infof("mysql database unix socket: %s", conf.Conf.Database.Host) + log.Infof("mysql database: %s", conf.Conf.Database.Host) } else { dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local&interpolateParams=true&tls=%s", conf.Conf.Database.User, @@ -109,7 +109,7 @@ func createDialector(dbConf conf.DatabaseConfig) (dialector gorm.Dialector, err conf.Conf.Database.Name, conf.Conf.Database.SslMode, ) - log.Infof("postgres database unix socket: %s", conf.Conf.Database.Host) + log.Infof("postgres database: %s", conf.Conf.Database.Host) } else { dsn = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", conf.Conf.Database.Host, diff --git a/internal/model/movie.go b/internal/model/movie.go index c358159..c938bd5 100644 --- a/internal/model/movie.go +++ b/internal/model/movie.go @@ -9,12 +9,12 @@ import ( ) type Movie struct { - ID string `gorm:"primaryKey;type:varchar(32)" json:"id"` + ID string `gorm:"primaryKey;type:char(32)" json:"id"` CreatedAt time.Time `json:"-"` UpdatedAt time.Time `json:"-"` Position uint `gorm:"not null" json:"-"` - RoomID string `gorm:"not null;index" json:"-"` - CreatorID string `gorm:"index" json:"creatorId"` + RoomID string `gorm:"not null;index;type:char(32)" json:"-"` + CreatorID string `gorm:"index;type:char(32)" json:"creatorId"` Base BaseMovie `gorm:"embedded;embeddedPrefix:base_" json:"base"` } @@ -26,14 +26,14 @@ func (m *Movie) BeforeCreate(tx *gorm.DB) error { } type BaseMovie struct { - Url string `json:"url"` - Name string `gorm:"not null" json:"name"` + Url string `gorm:"type:varchar(8192)" json:"url"` + Name string `gorm:"not null;type:varchar(128)" json:"name"` Live bool `json:"live"` Proxy bool `json:"proxy"` RtmpSource bool `json:"rtmpSource"` Type string `json:"type"` - Headers map[string]string `gorm:"serializer:fastjson" json:"headers"` - Subtitles map[string]*Subtitle `gorm:"serializer:fastjson" json:"subtitles"` + Headers map[string]string `gorm:"serializer:fastjson;type:text" json:"headers"` + Subtitles map[string]*Subtitle `gorm:"serializer:fastjson;type:text" json:"subtitles"` VendorInfo VendorInfo `gorm:"embedded;embeddedPrefix:vendor_info_" json:"vendorInfo,omitempty"` } @@ -51,8 +51,8 @@ const ( ) type VendorInfo struct { - Vendor VendorName `json:"vendor"` - Backend string `json:"backend"` + Vendor VendorName `gorm:"type:varchar(32)" json:"vendor"` + Backend string `gorm:"type:varchar(64)" json:"backend"` Bilibili *BilibiliStreamingInfo `gorm:"embedded;embeddedPrefix:bilibili_" json:"bilibili,omitempty"` Alist *AlistStreamingInfo `gorm:"embedded;embeddedPrefix:alist_" json:"alist,omitempty"` Emby *EmbyStreamingInfo `gorm:"embedded;embeddedPrefix:emby_" json:"emby,omitempty"` @@ -85,8 +85,8 @@ func (b *BilibiliStreamingInfo) Validate() error { } type AlistStreamingInfo struct { - Path string `json:"path,omitempty"` - Password string `json:"password,omitempty"` + Path string `gorm:"type:varchar(4096)" json:"path,omitempty"` + Password string `gorm:"type:varchar(256)" json:"password,omitempty"` } func (a *AlistStreamingInfo) BeforeSave(tx *gorm.DB) error { @@ -116,5 +116,5 @@ func (a *AlistStreamingInfo) AfterFind(tx *gorm.DB) error { } type EmbyStreamingInfo struct { - Path string `json:"path,omitempty"` + Path string `gorm:"type:varchar(20)" json:"path,omitempty"` } diff --git a/internal/model/oauth2.go b/internal/model/oauth2.go index 3d185a3..b109b67 100644 --- a/internal/model/oauth2.go +++ b/internal/model/oauth2.go @@ -7,9 +7,9 @@ import ( ) type UserProvider struct { - Provider provider.OAuth2Provider `gorm:"not null;primarykey;uniqueIndex:idx_provider_user_id"` - ProviderUserID string `gorm:"not null;primarykey"` + Provider provider.OAuth2Provider `gorm:"primarykey;type:varchar(32);uniqueIndex:idx_provider_user_id"` + ProviderUserID string `gorm:"primarykey;type:varchar(64)"` CreatedAt time.Time UpdatedAt time.Time - UserID string `gorm:"not null;uniqueIndex:idx_provider_user_id"` + UserID string `gorm:"not null;type:char(32);uniqueIndex:idx_provider_user_id"` } diff --git a/internal/model/relation.go b/internal/model/relation.go index 0e8de53..2763935 100644 --- a/internal/model/relation.go +++ b/internal/model/relation.go @@ -48,8 +48,8 @@ func (p RoomUserPermission) Has(permission RoomUserPermission) bool { type RoomUserRelation struct { CreatedAt time.Time UpdatedAt time.Time - UserID string `gorm:"not null;primarykey"` - RoomID string `gorm:"not null;primarykey"` + UserID string `gorm:"primarykey;type:char(32)"` + RoomID string `gorm:"primarykey;type:char(32)"` Status RoomUserStatus `gorm:"not null;default:2"` Permissions RoomUserPermission } diff --git a/internal/model/room.go b/internal/model/room.go index c403d56..b98fef8 100644 --- a/internal/model/room.go +++ b/internal/model/room.go @@ -31,13 +31,13 @@ func (r RoomStatus) String() string { } type Room struct { - ID string `gorm:"not null;primaryKey;type:varchar(32)" json:"id"` + ID string `gorm:"primaryKey;type:char(32)" json:"id"` CreatedAt time.Time UpdatedAt time.Time Status RoomStatus `gorm:"not null;default:2"` - Name string `gorm:"not null;uniqueIndex"` + Name string `gorm:"not null;uniqueIndex;type:varchar(32)"` Settings RoomSettings `gorm:"embedded;embeddedPrefix:settings_"` - CreatorID string `gorm:"index"` + CreatorID string `gorm:"index;type:char(32)"` HashedPassword []byte GroupUserRelations []RoomUserRelation `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` Movies []Movie `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` diff --git a/internal/model/setting.go b/internal/model/setting.go index 34a02a0..e71e6b0 100644 --- a/internal/model/setting.go +++ b/internal/model/setting.go @@ -26,8 +26,8 @@ const ( ) type Setting struct { - Name string `gorm:"primaryKey"` - Value string + Name string `gorm:"primaryKey;type:varchar(256)"` + Value string `gorm:"not null;type:text"` Type SettingType `gorm:"not null;default:string"` Group SettingGroup `gorm:"not null"` } diff --git a/internal/model/user.go b/internal/model/user.go index f18b0ca..3d8185f 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -39,12 +39,12 @@ func (r Role) String() string { } type User struct { - ID string `gorm:"primaryKey;type:varchar(32)" json:"id"` + ID string `gorm:"primaryKey;type:char(32)" json:"id"` CreatedAt time.Time UpdatedAt time.Time RegisteredByProvider bool `gorm:"not null;default:false"` UserProviders []UserProvider `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` - Username string `gorm:"not null;uniqueIndex"` + Username string `gorm:"not null;uniqueIndex;type:varchar(32)"` HashedPassword []byte `gorm:"not null"` Role Role `gorm:"not null;default:2"` RoomUserRelations []RoomUserRelation `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` diff --git a/internal/model/vendorBackend.go b/internal/model/vendorBackend.go index a695b05..1c92362 100644 --- a/internal/model/vendorBackend.go +++ b/internal/model/vendorBackend.go @@ -9,24 +9,24 @@ import ( ) type Consul struct { - ServiceName string `json:"serviceName"` - Token string `json:"token"` - PathPrefix string `json:"pathPrefix"` - Namespace string `json:"namespace"` - Partition string `json:"partition"` + ServiceName string `gorm:"type:varchar(64)" json:"serviceName"` + Token string `gorm:"type:varchar(256)" json:"token"` + PathPrefix string `gorm:"type:varchar(64)" json:"pathPrefix"` + Namespace string `gorm:"type:varchar(64)" json:"namespace"` + Partition string `gorm:"type:varchar(64)" json:"partition"` } type Etcd struct { - ServiceName string `json:"serviceName"` - Username string `json:"username"` - Password string `json:"password"` + ServiceName string `gorm:"type:varchar(64)" json:"serviceName"` + Username string `gorm:"type:varchar(64)" json:"username"` + Password string `gorm:"type:varchar(256)" json:"password"` } type Backend struct { - Endpoint string `gorm:"primaryKey" json:"endpoint"` + Endpoint string `gorm:"primaryKey;type:varchar(512)" json:"endpoint"` Comment string `gorm:"type:text" json:"comment"` Tls bool `gorm:"default:false" json:"tls"` - JwtSecret string `json:"jwtSecret"` + JwtSecret string `gorm:"type:varchar(256)" json:"jwtSecret"` CustomCA string `gorm:"type:text" json:"customCA"` TimeOut string `gorm:"default:10s" json:"timeOut"` @@ -57,11 +57,11 @@ type VendorBackend struct { type BackendUsedBy struct { Bilibili bool `gorm:"default:false" json:"bilibili"` - BilibiliBackendName string `json:"bilibiliBackendName"` + BilibiliBackendName string `gorm:"type:varchar(64)" json:"bilibiliBackendName"` Alist bool `gorm:"default:false" json:"alist"` - AlistBackendName string `json:"alistBackendName"` + AlistBackendName string `gorm:"type:varchar(64)" json:"alistBackendName"` Emby bool `gorm:"default:false" json:"emby"` - EmbyBackendName string `json:"embyBackendName"` + EmbyBackendName string `gorm:"type:varchar(64)" json:"embyBackendName"` } func (v *VendorBackend) BeforeSave(tx *gorm.DB) error { diff --git a/internal/model/vendorRecord.go b/internal/model/vendorRecord.go index b7e1e08..93b4103 100644 --- a/internal/model/vendorRecord.go +++ b/internal/model/vendorRecord.go @@ -6,9 +6,9 @@ import ( ) type BilibiliVendor struct { - UserID string `gorm:"primaryKey"` - Backend string - Cookies map[string]string `gorm:"serializer:fastjson"` + UserID string `gorm:"primaryKey;type:char(32)"` + Backend string `gorm:"type:varchar(64)"` + Cookies map[string]string `gorm:"serializer:fastjson;type:text"` } func (b *BilibiliVendor) BeforeSave(tx *gorm.DB) error { @@ -40,10 +40,10 @@ func (b *BilibiliVendor) AfterFind(tx *gorm.DB) error { } type AlistVendor struct { - UserID string `gorm:"primaryKey"` - Backend string - Host string - Username string + UserID string `gorm:"primaryKey;type:char(32)"` + Backend string `gorm:"type:varchar(64)"` + Host string `gorm:"type:varchar(256)"` + Username string `gorm:"type:varchar(256)"` HashedPassword []byte } @@ -87,10 +87,10 @@ func (a *AlistVendor) AfterFind(tx *gorm.DB) error { } type EmbyVendor struct { - UserID string `gorm:"primaryKey"` - Backend string - Host string - ApiKey string + UserID string `gorm:"primaryKey;type:char(32)"` + Backend string `gorm:"type:varchar(64)"` + Host string `gorm:"type:varchar(256)"` + ApiKey string `gorm:"type:varchar(256)"` } func (e *EmbyVendor) BeforeSave(tx *gorm.DB) error { diff --git a/server/model/movie.go b/server/model/movie.go index a821835..7bde86d 100644 --- a/server/model/movie.go +++ b/server/model/movie.go @@ -33,7 +33,7 @@ func (p *PushMovieReq) Validate() error { if p.Name == "" { return ErrEmptyName - } else if len(p.Name) > 512 { + } else if len(p.Name) > 128 { return ErrNameTooLong }