directive @isAdmin on FIELD_DEFINITION scalar Time enum OrderDirection { ASC DESC } input Filter { order_by: String order_direction: OrderDirection limit: Int offset: Int } type Query { siteInfo: SiteInfo! "List of registered users, must be admin to call" user(filter: Filter): [User!]! @isAdmin "Information about the currently logged in user" myUser: User! "List of albums owned by the logged in user." myAlbums( filter: Filter "Return only albums from the root directory of the user" onlyRoot: Boolean "Return also albums with no media directly in them" showEmpty: Boolean ): [Album!]! "Get album by id, user must own the album or be admin" album(id: Int!): Album! "List of media owned by the logged in user" myMedia(filter: Filter): [Media!]! "Get media by id, user must own the media or be admin" media(id: Int!): Media! shareToken(token: String!, password: String): ShareToken! shareTokenValidatePassword(token: String!, password: String): Boolean! search(query: String!, limitMedia: Int, limitAlbums: Int): SearchResult! } type Mutation { authorizeUser(username: String!, password: String!): AuthorizeResult! "Registers a new user, must be admin to call" registerUser( username: String! password: String! rootPath: String! ): AuthorizeResult! "Registers the initial user, can only be called if initialSetup from SiteInfo is true" initialSetupWizard( username: String! password: String! rootPath: String! ): AuthorizeResult "Scan all users for new media" scanAll: ScannerResult! @isAdmin "Scan a single user for new media" scanUser(userId: Int!): ScannerResult! "Generate share token for album" shareAlbum(albumId: Int!, expire: Time, password: String): ShareToken "Generate share token for media" shareMedia(mediaId: Int!, expire: Time, password: String): ShareToken "Delete a share token by it's token value" deleteShareToken(token: String!): ShareToken "Set a password for a token, if null is passed for the password argument, the password will be cleared" protectShareToken(token: String!, password: String): ShareToken "Mark or unmark a media as being a favorite" favoriteMedia(mediaId: Int!, favorite: Boolean!): Media updateUser( id: Int! username: String rootPath: String password: String admin: Boolean ): User @isAdmin createUser( username: String! rootPath: String! password: String admin: Boolean! ): User @isAdmin deleteUser(id: Int!): User @isAdmin """ Set how often, in seconds, the server should automatically scan for new media, a value of 0 will disable periodic scans """ setPeriodicScanInterval(interval: Int!): Int! } type Subscription { notification: Notification! } enum NotificationType { Message Progress "Close a notification with a given key" Close } type Notification { key: String! type: NotificationType! header: String! content: String! progress: Float positive: Boolean! negative: Boolean! "Time in milliseconds before the notification will close" timeout: Int } type AuthorizeResult { success: Boolean! status: String! token: String } type ScannerResult { finished: Boolean! success: Boolean! progress: Float message: String } "A token used to publicly access an album or media" type ShareToken { id: Int! token: String! "The user who created the token" owner: User! "Optional expire date" expire: Time "Whether or not a password is needed to access the share" hasPassword: Boolean! "The album this token shares" album: Album "The media this token shares" media: Media } "General information about the site" type SiteInfo { initialSetup: Boolean! "How often automatic scans should be initiated in seconds" periodicScanInterval: Int! @isAdmin } type User { id: Int! username: String! #albums: [Album] "Local filepath for the user's photos" rootPath: String! @isAdmin admin: Boolean! #shareTokens: [ShareToken] } type Album { id: Int! title: String! "The media inside this album" media(filter: Filter): [Media!]! "The albums contained in this album" subAlbums(filter: Filter): [Album!]! "The album witch contains this album" parentAlbum: Album "The user who owns this album" owner: User! "The path on the filesystem of the server, where this album is located" filePath: String! "An image in this album used for previewing this album" thumbnail: Media path: [Album!]! shares: [ShareToken] } type MediaURL { "URL for previewing the image" url: String! "Width of the image in pixels" width: Int! "Height of the image in pixels" height: Int! "The file size of the resource in bytes" fileSize: Int! } type MediaDownload { title: String! mediaUrl: MediaURL! } enum MediaType { photo video } type Media { id: Int! title: String! "Local filepath for the media" path: String! "URL to display the media in a smaller resolution" thumbnail: MediaURL! "URL to display the photo in full resolution, will be null for videos" highRes: MediaURL "URL to get the video in a web format that can be played in the browser, will be null for photos" videoWeb: MediaURL "The album that holds the media" album: Album! exif: MediaEXIF videoMetadata: VideoMetadata favorite: Boolean! type: MediaType! shares: [ShareToken!]! downloads: [MediaDownload!]! } "EXIF metadata from the camera" type MediaEXIF { id: Int! media: Media! "The model name of the camera" camera: String "The maker of the camera" maker: String "The name of the lens" lens: String dateShot: Time "The exposure time of the image" exposure: String "The aperature stops of the image" aperture: Float "The ISO setting of the image" iso: Int "The focal length of the lens, when the image was taken" focalLength: Float "A formatted description of the flash settings, when the image was taken" flash: String "An index describing the mode for adjusting the exposure of the image" exposureProgram: Int } type VideoMetadata { id: Int! media: Media! width: Int! height: Int! duration: Float! codec: String framerate: Float bitrate: Int colorProfile: String audio: String } type SearchResult { query: String! albums: [Album!]! media: [Media!]! }