luminate/Sources/LuminateCore/Models/JellyfinMediaQuery.swift

133 lines
5.4 KiB
Swift

//
// JellyfinMediaQuery.swift
//
// Copyright 2026 Brendan Szymanski <hello@bscubed.dev>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
/// A browse or search query against a Jellyfin library.
///
/// The server's item endpoint accepts close to ninety query parameters. This type exposes only the
/// ones Luminate's browse, search, and filter surfaces actually drive, so a spec regeneration
/// cannot ripple into feature code. Every property is optional; a `nil` property is simply not sent
/// and the server applies its own default.
///
/// ```swift
/// var query = JellyfinMediaQuery()
/// query.parentID = library.id
/// query.includeItemKinds = [.movie]
/// query.sortBy = [.sortName]
/// query.limit = 60
/// let page = try await client.items(query)
/// ```
package struct JellyfinMediaQuery: Hashable, Sendable {
/// Restrict results to what this user may see, and populate their playback state.
package var userID: String?
/// Restrict results to descendants of this item, normally a library.
package var parentID: String?
/// Only return these kinds of item.
package var includeItemKinds: [JellyfinMediaKind]?
/// Never return these kinds of item.
package var excludeItemKinds: [JellyfinMediaKind]?
/// Fetch exactly these items, ignoring the other filters.
package var ids: [String]?
/// Match items against this free-text term.
package var searchTerm: String?
/// Order results by these fields, most significant first.
package var sortBy: [JellyfinSortField]?
/// The direction of each entry in ``sortBy``.
package var sortOrder: [JellyfinSortOrder]?
/// Optional metadata to populate on each returned item.
package var fields: [JellyfinItemField]?
/// Skip this many matching items before the first result.
package var startIndex: Int32?
/// Return at most this many items.
package var limit: Int32?
/// Search the whole subtree rather than only direct children.
package var recursive: Bool?
/// Only return items the user has, or has not, favourited.
package var isFavorite: Bool?
/// Only return items the user has, or has not, watched.
package var isPlayed: Bool?
/// Only return items carrying one of these genres.
package var genres: [String]?
/// Only return items produced in one of these years.
package var years: [Int32]?
/// Only return items with one of these parental rating certificates.
package var officialRatings: [String]?
/// Only return items whose sort title starts with this string, for the alphabet jump picker.
package var nameStartsWith: String?
/// Populate each item's playback and favourite state.
package var enableUserData: Bool?
/// Populate each item's artwork tags.
package var enableImages: Bool?
/// Return at most this many images per image type.
package var imageTypeLimit: Int32?
/// Only report artwork tags for these image types.
package var enableImageTypes: [JellyfinImageType]?
/// Creates an unfiltered query, leaving every parameter to the server's default.
///
/// Each parameter sets the property of the same name.
package init(
userID: String? = nil,
parentID: String? = nil,
includeItemKinds: [JellyfinMediaKind]? = nil,
excludeItemKinds: [JellyfinMediaKind]? = nil,
ids: [String]? = nil,
searchTerm: String? = nil,
sortBy: [JellyfinSortField]? = nil,
sortOrder: [JellyfinSortOrder]? = nil,
fields: [JellyfinItemField]? = nil,
startIndex: Int32? = nil,
limit: Int32? = nil,
recursive: Bool? = nil,
isFavorite: Bool? = nil,
isPlayed: Bool? = nil,
genres: [String]? = nil,
years: [Int32]? = nil,
officialRatings: [String]? = nil,
nameStartsWith: String? = nil,
enableUserData: Bool? = nil,
enableImages: Bool? = nil,
imageTypeLimit: Int32? = nil,
enableImageTypes: [JellyfinImageType]? = nil
) {
self.userID = userID
self.parentID = parentID
self.includeItemKinds = includeItemKinds
self.excludeItemKinds = excludeItemKinds
self.ids = ids
self.searchTerm = searchTerm
self.sortBy = sortBy
self.sortOrder = sortOrder
self.fields = fields
self.startIndex = startIndex
self.limit = limit
self.recursive = recursive
self.isFavorite = isFavorite
self.isPlayed = isPlayed
self.genres = genres
self.years = years
self.officialRatings = officialRatings
self.nameStartsWith = nameStartsWith
self.enableUserData = enableUserData
self.enableImages = enableImages
self.imageTypeLimit = imageTypeLimit
self.enableImageTypes = enableImageTypes
}
}