1
Fork 0
photoview/api/graphql/models/media.go

131 lines
3.5 KiB
Go
Raw Normal View History

package models
import (
2021-02-15 17:35:28 +01:00
"fmt"
"path"
2021-02-15 17:35:28 +01:00
"strconv"
"strings"
"time"
2020-12-17 22:51:43 +01:00
"github.com/photoview/photoview/api/utils"
2021-02-15 17:35:28 +01:00
"github.com/pkg/errors"
2020-11-30 21:29:49 +01:00
"gorm.io/gorm"
)
type Media struct {
Model
Title string `gorm:"not null"`
Path string `gorm:"not null"`
PathHash string `gorm:"not null;unique"`
AlbumID int `gorm:"not null;index"`
Album Album `gorm:"constraint:OnDelete:CASCADE;"`
ExifID *int `gorm:"index"`
Exif *MediaEXIF `gorm:"constraint:OnDelete:CASCADE;"`
MediaURL []MediaURL `gorm:"constraint:OnDelete:CASCADE;"`
DateShot time.Time `gorm:"not null"`
Type MediaType `gorm:"not null;index"`
VideoMetadataID *int `gorm:"index"`
VideoMetadata *VideoMetadata `gorm:"constraint:OnDelete:CASCADE;"`
2020-11-16 21:57:34 +01:00
SideCarPath *string
2021-02-16 17:13:08 +01:00
SideCarHash *string `gorm:"unique"`
Faces []*ImageFace `gorm:"constraint:OnDelete:CASCADE;"`
// Only used internally
2021-01-19 18:35:19 +01:00
CounterpartPath *string `gorm:"-"`
}
2020-11-28 17:31:19 +01:00
func (Media) TableName() string {
return "media"
}
2020-11-30 21:29:49 +01:00
func (m *Media) BeforeSave(tx *gorm.DB) error {
2021-04-03 22:52:53 +02:00
// Update path hash
2021-01-17 12:45:23 +01:00
m.PathHash = MD5Hash(m.Path)
2020-11-30 21:29:49 +01:00
// Save media type as lowercase for better compatibility
m.Type = MediaType(strings.ToLower(string(m.Type)))
return nil
}
func (m *Media) AfterFind(tx *gorm.DB) error {
// Convert lowercased media type back
lowercasedType := strings.ToLower(string(m.Type))
foundType := false
for _, t := range AllMediaType {
if strings.ToLower(string(t)) == lowercasedType {
m.Type = t
foundType = true
break
}
}
if foundType == false {
return errors.New(fmt.Sprintf("Failed to parse media from DB: Invalid media type: %s", m.Type))
}
2020-11-30 21:29:49 +01:00
return nil
}
type MediaPurpose string
const (
PhotoThumbnail MediaPurpose = "thumbnail"
PhotoHighRes MediaPurpose = "high-res"
MediaOriginal MediaPurpose = "original"
VideoWeb MediaPurpose = "video-web"
2020-07-11 13:39:11 +02:00
VideoThumbnail MediaPurpose = "video-thumbnail"
)
type MediaURL struct {
Model
MediaID int `gorm:"not null;index"`
2021-02-15 17:35:28 +01:00
Media *Media `gorm:"constraint:OnDelete:CASCADE;"`
MediaName string `gorm:"not null"`
Width int `gorm:"not null"`
Height int `gorm:"not null"`
Purpose MediaPurpose `gorm:"not null;index"`
ContentType string `gorm:"not null"`
FileSize int64 `gorm:"not null"`
}
func (p *MediaURL) URL() string {
imageURL := utils.ApiEndpointUrl()
2020-07-11 15:57:58 +02:00
if p.Purpose != VideoWeb {
imageURL.Path = path.Join(imageURL.Path, "photo", p.MediaName)
2020-07-11 15:57:58 +02:00
} else {
imageURL.Path = path.Join(imageURL.Path, "video", p.MediaName)
2020-07-11 15:57:58 +02:00
}
return imageURL.String()
}
2021-02-15 17:35:28 +01:00
func (p *MediaURL) CachedPath() (string, error) {
var cachedPath string
if p.Media == nil {
return "", errors.New("mediaURL.Media is nil")
}
if p.Purpose == PhotoThumbnail || p.Purpose == PhotoHighRes || p.Purpose == VideoThumbnail {
cachedPath = path.Join(utils.MediaCachePath(), strconv.Itoa(int(p.Media.AlbumID)), strconv.Itoa(int(p.MediaID)), p.MediaName)
} else if p.Purpose == MediaOriginal {
cachedPath = p.Media.Path
} else {
return "", errors.New(fmt.Sprintf("cannot determine cache path for purpose (%s)", p.Purpose))
}
return cachedPath, nil
}
func SanitizeMediaName(mediaName string) string {
result := mediaName
result = strings.ReplaceAll(result, "/", "")
result = strings.ReplaceAll(result, "\\", "")
result = strings.ReplaceAll(result, " ", "_")
result = strings.ReplaceAll(result, ".", "_")
return result
}