1
Fork 0

Expose media_type to graphql

- Make video thumbnail accessible from graphql
This commit is contained in:
viktorstrate 2020-07-11 14:21:10 +02:00
parent 9e5480188b
commit 990a592fcc
9 changed files with 126 additions and 20 deletions

View File

@ -81,6 +81,7 @@ type ComplexityRoot struct {
Shares func(childComplexity int) int
Thumbnail func(childComplexity int) int
Title func(childComplexity int) int
Type func(childComplexity int) int
}
MediaDownload struct {
@ -433,6 +434,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
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":
if e.complexity.MediaDownload.Height == nil {
break
@ -1304,6 +1312,11 @@ type MediaDownload {
url: String!
}
enum MediaType {
photo
video
}
type Media {
id: Int!
title: String!
@ -1317,6 +1330,7 @@ type Media {
album: Album!
exif: MediaEXIF
favorite: Boolean!
type: MediaType!
shares: [ShareToken!]!
downloads: [MediaDownload!]!
@ -2620,6 +2634,40 @@ func (ec *executionContext) _Media_favorite(ctx context.Context, field graphql.C
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) {
defer func() {
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 {
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":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
@ -7815,6 +7868,15 @@ func (ec *executionContext) marshalNMediaDownload2ᚖgithubᚗcomᚋviktorstrate
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 {
return ec._MediaURL(ctx, sel, &v)
}

View File

@ -58,6 +58,47 @@ type SiteInfo struct {
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
const (

View File

@ -7,13 +7,6 @@ import (
"github.com/viktorstrate/photoview/api/utils"
)
type MediaType string
const (
MediaTypePhoto MediaType = "photo"
MediaTypeVide MediaType = "video"
)
type Media struct {
MediaID int
Title string
@ -64,7 +57,7 @@ func NewMediaFromRows(rows *sql.Rows) ([]*Media, error) {
for rows.Next() {
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
}
medias = append(medias, &media)

View File

@ -132,14 +132,18 @@ func (r *mediaResolver) HighRes(ctx context.Context, obj *models.Media) (*models
url, err := models.NewMediaURLFromRow(row)
if err != nil {
return nil, errors.Wrapf(err, "could not query high-res (%s)", obj.Path)
if err == sql.ErrNoRows {
return nil, nil
} else {
return nil, errors.Wrapf(err, "could not query high-res (%s)", obj.Path)
}
}
return url, nil
}
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)
if err != nil {

View File

@ -198,6 +198,11 @@ type MediaDownload {
url: String!
}
enum MediaType {
photo
video
}
type Media {
id: Int!
title: String!
@ -211,6 +216,7 @@ type Media {
album: Album!
exif: MediaEXIF
favorite: Boolean!
type: MediaType!
shares: [ShareToken!]!
downloads: [MediaDownload!]!

View File

@ -132,7 +132,7 @@ func RegisterPhotoRoutes(db *sql.DB, router *mux.Router) {
var cachedPath string
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)
}

View File

@ -104,7 +104,7 @@ func (queue *ScannerQueue) startBackgroundWorker() {
notification.BroadcastNotification(&models.Notification{
Key: "global-scanner-progress",
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),
})
})

View File

@ -25,14 +25,14 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *sql.DB) {
notification.BroadcastNotification(&models.Notification{
Key: album_notify_key,
Type: models.NotificationTypeMessage,
Header: fmt.Sprintf("Found new photos in album '%s'", album.Title),
Content: fmt.Sprintf("Found photo %s", photo.Path),
Header: fmt.Sprintf("Found new media in album '%s'", album.Title),
Content: fmt.Sprintf("Found %s", photo.Path),
})
})
}
})
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
@ -55,8 +55,8 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *sql.DB) {
notification.BroadcastNotification(&models.Notification{
Key: album_notify_key,
Type: models.NotificationTypeProgress,
Header: fmt.Sprintf("Processing photo for album '%s'", album.Title),
Content: fmt.Sprintf("Processed photo at %s", photo.Path),
Header: fmt.Sprintf("Processing media for album '%s'", album.Title),
Content: fmt.Sprintf("Processed media at %s", photo.Path),
Progress: &progress,
})
}
@ -73,8 +73,8 @@ func scanAlbum(album *models.Album, cache *AlbumScannerCache, db *sql.DB) {
Key: album_notify_key,
Type: models.NotificationTypeMessage,
Positive: true,
Header: fmt.Sprintf("Done processing photos for album '%s'", album.Title),
Content: fmt.Sprintf("All photos have been processed"),
Header: fmt.Sprintf("Done processing media for album '%s'", album.Title),
Content: fmt.Sprintf("All media have been processed"),
Timeout: &timeoutDelay,
})
}

View File

@ -18,7 +18,7 @@ func ScanMedia(tx *sql.Tx, mediaPath string, albumId int, cache *AlbumScannerCac
photo, err := models.NewMediaFromRow(row)
if err != sql.ErrNoRows {
if err == nil {
log.Printf("Image already scanned: %s\n", mediaPath)
log.Printf("Media already scanned: %s\n", mediaPath)
return photo, false, nil
} else {
return nil, false, errors.Wrap(err, "scan media fetch from database")