Expose media_type to graphql
- Make video thumbnail accessible from graphql
This commit is contained in:
parent
9e5480188b
commit
990a592fcc
|
@ -81,6 +81,7 @@ type ComplexityRoot struct {
|
||||||
Shares func(childComplexity int) int
|
Shares func(childComplexity int) int
|
||||||
Thumbnail func(childComplexity int) int
|
Thumbnail func(childComplexity int) int
|
||||||
Title func(childComplexity int) int
|
Title func(childComplexity int) int
|
||||||
|
Type func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaDownload struct {
|
MediaDownload struct {
|
||||||
|
@ -433,6 +434,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Media.Title(childComplexity), true
|
return e.complexity.Media.Title(childComplexity), true
|
||||||
|
|
||||||
|
case "Media.type":
|
||||||
|
if e.complexity.Media.Type == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Media.Type(childComplexity), true
|
||||||
|
|
||||||
case "MediaDownload.height":
|
case "MediaDownload.height":
|
||||||
if e.complexity.MediaDownload.Height == nil {
|
if e.complexity.MediaDownload.Height == nil {
|
||||||
break
|
break
|
||||||
|
@ -1304,6 +1312,11 @@ type MediaDownload {
|
||||||
url: String!
|
url: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MediaType {
|
||||||
|
photo
|
||||||
|
video
|
||||||
|
}
|
||||||
|
|
||||||
type Media {
|
type Media {
|
||||||
id: Int!
|
id: Int!
|
||||||
title: String!
|
title: String!
|
||||||
|
@ -1317,6 +1330,7 @@ type Media {
|
||||||
album: Album!
|
album: Album!
|
||||||
exif: MediaEXIF
|
exif: MediaEXIF
|
||||||
favorite: Boolean!
|
favorite: Boolean!
|
||||||
|
type: MediaType!
|
||||||
|
|
||||||
shares: [ShareToken!]!
|
shares: [ShareToken!]!
|
||||||
downloads: [MediaDownload!]!
|
downloads: [MediaDownload!]!
|
||||||
|
@ -2620,6 +2634,40 @@ func (ec *executionContext) _Media_favorite(ctx context.Context, field graphql.C
|
||||||
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
|
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Media_type(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
fc := &graphql.FieldContext{
|
||||||
|
Object: "Media",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.Type, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
if !graphql.HasFieldError(ctx, fc) {
|
||||||
|
ec.Errorf(ctx, "must not be null")
|
||||||
|
}
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(models.MediaType)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNMediaType2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaType(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Media_shares(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Media_shares(ctx context.Context, field graphql.CollectedField, obj *models.Media) (ret graphql.Marshaler) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
@ -6669,6 +6717,11 @@ func (ec *executionContext) _Media(ctx context.Context, sel ast.SelectionSet, ob
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
atomic.AddUint32(&invalids, 1)
|
atomic.AddUint32(&invalids, 1)
|
||||||
}
|
}
|
||||||
|
case "type":
|
||||||
|
out.Values[i] = ec._Media_type(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
atomic.AddUint32(&invalids, 1)
|
||||||
|
}
|
||||||
case "shares":
|
case "shares":
|
||||||
field := field
|
field := field
|
||||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
|
@ -7815,6 +7868,15 @@ func (ec *executionContext) marshalNMediaDownload2ᚖgithubᚗcomᚋviktorstrate
|
||||||
return ec._MediaDownload(ctx, sel, v)
|
return ec._MediaDownload(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNMediaType2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaType(ctx context.Context, v interface{}) (models.MediaType, error) {
|
||||||
|
var res models.MediaType
|
||||||
|
return res, res.UnmarshalGQL(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNMediaType2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaType(ctx context.Context, sel ast.SelectionSet, v models.MediaType) graphql.Marshaler {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNMediaURL2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx context.Context, sel ast.SelectionSet, v models.MediaURL) graphql.Marshaler {
|
func (ec *executionContext) marshalNMediaURL2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐMediaURL(ctx context.Context, sel ast.SelectionSet, v models.MediaURL) graphql.Marshaler {
|
||||||
return ec._MediaURL(ctx, sel, &v)
|
return ec._MediaURL(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,47 @@ type SiteInfo struct {
|
||||||
InitialSetup bool `json:"initialSetup"`
|
InitialSetup bool `json:"initialSetup"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MediaType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
MediaTypePhoto MediaType = "photo"
|
||||||
|
MediaTypeVideo MediaType = "video"
|
||||||
|
)
|
||||||
|
|
||||||
|
var AllMediaType = []MediaType{
|
||||||
|
MediaTypePhoto,
|
||||||
|
MediaTypeVideo,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e MediaType) IsValid() bool {
|
||||||
|
switch e {
|
||||||
|
case MediaTypePhoto, MediaTypeVideo:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e MediaType) String() string {
|
||||||
|
return string(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *MediaType) UnmarshalGQL(v interface{}) error {
|
||||||
|
str, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("enums must be strings")
|
||||||
|
}
|
||||||
|
|
||||||
|
*e = MediaType(str)
|
||||||
|
if !e.IsValid() {
|
||||||
|
return fmt.Errorf("%s is not a valid MediaType", str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e MediaType) MarshalGQL(w io.Writer) {
|
||||||
|
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||||
|
}
|
||||||
|
|
||||||
type NotificationType string
|
type NotificationType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -7,13 +7,6 @@ import (
|
||||||
"github.com/viktorstrate/photoview/api/utils"
|
"github.com/viktorstrate/photoview/api/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MediaType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
MediaTypePhoto MediaType = "photo"
|
|
||||||
MediaTypeVide MediaType = "video"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Media struct {
|
type Media struct {
|
||||||
MediaID int
|
MediaID int
|
||||||
Title string
|
Title string
|
||||||
|
@ -64,7 +57,7 @@ func NewMediaFromRows(rows *sql.Rows) ([]*Media, error) {
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var media Media
|
var media Media
|
||||||
if err := rows.Scan(&media.MediaID, &media.Title, &media.Path, &media.PathHash, &media.AlbumId, &media.ExifId, &media.Favorite); err != nil {
|
if err := rows.Scan(&media.MediaID, &media.Title, &media.Path, &media.PathHash, &media.AlbumId, &media.ExifId, &media.Favorite, &media.Type); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
medias = append(medias, &media)
|
medias = append(medias, &media)
|
||||||
|
|
|
@ -132,14 +132,18 @@ func (r *mediaResolver) HighRes(ctx context.Context, obj *models.Media) (*models
|
||||||
|
|
||||||
url, err := models.NewMediaURLFromRow(row)
|
url, err := models.NewMediaURLFromRow(row)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
} else {
|
||||||
return nil, errors.Wrapf(err, "could not query high-res (%s)", obj.Path)
|
return nil, errors.Wrapf(err, "could not query high-res (%s)", obj.Path)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return url, nil
|
return url, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mediaResolver) Thumbnail(ctx context.Context, obj *models.Media) (*models.MediaURL, error) {
|
func (r *mediaResolver) Thumbnail(ctx context.Context, obj *models.Media) (*models.MediaURL, error) {
|
||||||
row := r.Database.QueryRow("SELECT * FROM media_url WHERE media_id = ? AND purpose = ?", obj.MediaID, models.PhotoThumbnail)
|
row := r.Database.QueryRow("SELECT * FROM media_url WHERE media_id = ? AND (purpose = ? OR purpose = ?)", obj.MediaID, models.PhotoThumbnail, models.VideoThumbnail)
|
||||||
|
|
||||||
url, err := models.NewMediaURLFromRow(row)
|
url, err := models.NewMediaURLFromRow(row)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -198,6 +198,11 @@ type MediaDownload {
|
||||||
url: String!
|
url: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MediaType {
|
||||||
|
photo
|
||||||
|
video
|
||||||
|
}
|
||||||
|
|
||||||
type Media {
|
type Media {
|
||||||
id: Int!
|
id: Int!
|
||||||
title: String!
|
title: String!
|
||||||
|
@ -211,6 +216,7 @@ type Media {
|
||||||
album: Album!
|
album: Album!
|
||||||
exif: MediaEXIF
|
exif: MediaEXIF
|
||||||
favorite: Boolean!
|
favorite: Boolean!
|
||||||
|
type: MediaType!
|
||||||
|
|
||||||
shares: [ShareToken!]!
|
shares: [ShareToken!]!
|
||||||
downloads: [MediaDownload!]!
|
downloads: [MediaDownload!]!
|
||||||
|
|
|
@ -132,7 +132,7 @@ func RegisterPhotoRoutes(db *sql.DB, router *mux.Router) {
|
||||||
var cachedPath string
|
var cachedPath string
|
||||||
var file *os.File = nil
|
var file *os.File = nil
|
||||||
|
|
||||||
if purpose == models.PhotoThumbnail || purpose == models.PhotoHighRes {
|
if purpose == models.PhotoThumbnail || purpose == models.PhotoHighRes || purpose == models.VideoThumbnail {
|
||||||
cachedPath = path.Join(scanner.PhotoCache(), strconv.Itoa(media.AlbumId), strconv.Itoa(media_id), media_name)
|
cachedPath = path.Join(scanner.PhotoCache(), strconv.Itoa(media.AlbumId), strconv.Itoa(media_id), media_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ func (queue *ScannerQueue) startBackgroundWorker() {
|
||||||
notification.BroadcastNotification(&models.Notification{
|
notification.BroadcastNotification(&models.Notification{
|
||||||
Key: "global-scanner-progress",
|
Key: "global-scanner-progress",
|
||||||
Type: models.NotificationTypeMessage,
|
Type: models.NotificationTypeMessage,
|
||||||
Header: fmt.Sprintf("Scanning photos"),
|
Header: fmt.Sprintf("Scanning media"),
|
||||||
Content: fmt.Sprintf("%d jobs in progress\n%d jobs waiting", in_progress_length, up_next_length),
|
Content: fmt.Sprintf("%d jobs in progress\n%d jobs waiting", in_progress_length, up_next_length),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,14 +25,14 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *sql.DB) {
|
||||||
notification.BroadcastNotification(&models.Notification{
|
notification.BroadcastNotification(&models.Notification{
|
||||||
Key: album_notify_key,
|
Key: album_notify_key,
|
||||||
Type: models.NotificationTypeMessage,
|
Type: models.NotificationTypeMessage,
|
||||||
Header: fmt.Sprintf("Found new photos in album '%s'", album.Title),
|
Header: fmt.Sprintf("Found new media in album '%s'", album.Title),
|
||||||
Content: fmt.Sprintf("Found photo %s", photo.Path),
|
Content: fmt.Sprintf("Found %s", photo.Path),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ScannerError("Failed to find photos for album (%s): %s", album.Path, err)
|
ScannerError("Failed to find media for album (%s): %s", album.Path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
album_has_changes := false
|
album_has_changes := false
|
||||||
|
@ -55,8 +55,8 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *sql.DB) {
|
||||||
notification.BroadcastNotification(&models.Notification{
|
notification.BroadcastNotification(&models.Notification{
|
||||||
Key: album_notify_key,
|
Key: album_notify_key,
|
||||||
Type: models.NotificationTypeProgress,
|
Type: models.NotificationTypeProgress,
|
||||||
Header: fmt.Sprintf("Processing photo for album '%s'", album.Title),
|
Header: fmt.Sprintf("Processing media for album '%s'", album.Title),
|
||||||
Content: fmt.Sprintf("Processed photo at %s", photo.Path),
|
Content: fmt.Sprintf("Processed media at %s", photo.Path),
|
||||||
Progress: &progress,
|
Progress: &progress,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,8 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *sql.DB) {
|
||||||
Key: album_notify_key,
|
Key: album_notify_key,
|
||||||
Type: models.NotificationTypeMessage,
|
Type: models.NotificationTypeMessage,
|
||||||
Positive: true,
|
Positive: true,
|
||||||
Header: fmt.Sprintf("Done processing photos for album '%s'", album.Title),
|
Header: fmt.Sprintf("Done processing media for album '%s'", album.Title),
|
||||||
Content: fmt.Sprintf("All photos have been processed"),
|
Content: fmt.Sprintf("All media have been processed"),
|
||||||
Timeout: &timeoutDelay,
|
Timeout: &timeoutDelay,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ func ScanMedia(tx *sql.Tx, mediaPath string, albumId int, cache *AlbumScannerCac
|
||||||
photo, err := models.NewMediaFromRow(row)
|
photo, err := models.NewMediaFromRow(row)
|
||||||
if err != sql.ErrNoRows {
|
if err != sql.ErrNoRows {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Printf("Image already scanned: %s\n", mediaPath)
|
log.Printf("Media already scanned: %s\n", mediaPath)
|
||||||
return photo, false, nil
|
return photo, false, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, false, errors.Wrap(err, "scan media fetch from database")
|
return nil, false, errors.Wrap(err, "scan media fetch from database")
|
||||||
|
|
Loading…
Reference in New Issue