## Csharp SDK Changes Detected:

* `PlexApi.Butler.StartTask()`: 
  *  `request` **Changed** **Breaking** ⚠️
  *  `error` **Changed** **Breaking** ⚠️
* `PlexApi.Butler.StopTask()`: 
  *  `request` **Changed** **Breaking** ⚠️
  *  `error` **Changed** **Breaking** ⚠️
* `PlexApi.Updater.ApplyUpdates()`: 
  *  `request` **Changed** **Breaking** ⚠️
  *  `error` **Changed** **Breaking** ⚠️
* `PlexApi.General.GetServerInfo()`: **Added**
* `PlexApi.General.GetIdentity()`: **Added**
* `PlexApi.General.GetSourceConnectionInformation()`: **Added**
* `PlexApi.General.GetTransientToken()`: **Added**
* `PlexApi.Events.GetNotifications()`: **Added**
* `PlexApi.Events.ConnectWebSocket()`: **Added**
* `PlexApi.Preferences.GetAllPreferences()`: **Added**
* `PlexApi.Preferences.SetPreferences()`: **Added**
* `PlexApi.Preferences.GetPreference()`: **Added**
* `PlexApi.Rate.SetRating()`: **Added**
* `PlexApi.Timeline.MarkPlayed()`: **Added**
* `PlexApi.Timeline.Report()`: **Added**
* `PlexApi.Timeline.Unscrobble()`: **Added**
* `PlexApi.Activities.ListActivities()`: **Added**
* `PlexApi.Activities.CancelActivity()`: **Added**
* `PlexApi.Butler.StopTasks()`: **Added**
* `PlexApi.Butler.GetTasks()`: **Added**
* `PlexApi.Butler.StartTasks()`: **Added**
* `PlexApi.DownloadQueue.CreateDownloadQueue()`: **Added**
* `PlexApi.DownloadQueue.GetDownloadQueue()`: **Added**
* `PlexApi.DownloadQueue.AddDownloadQueueItems()`: **Added**
* `PlexApi.DownloadQueue.ListDownloadQueueItems()`: **Added**
* `PlexApi.DownloadQueue.GetItemDecision()`: **Added**
* `PlexApi.DownloadQueue.GetDownloadQueueMedia()`: **Added**
* `PlexApi.DownloadQueue.RemoveDownloadQueueItems()`: **Added**
* `PlexApi.DownloadQueue.GetDownloadQueueItems()`: **Added**
* `PlexApi.DownloadQueue.RestartProcessingDownloadQueueItems()`: **Added**
* `PlexApi.Hubs.GetAllHubs()`: **Added**
* `PlexApi.Hubs.GetContinueWatching()`: **Added**
* `PlexApi.Hubs.GetHubItems()`: **Added**
* `PlexApi.Hubs.GetPromotedHubs()`: **Added**
* `PlexApi.Hubs.GetMetadataHubs()`: **Added**
* `PlexApi.Hubs.GetPostplayHubs()`: **Added**
* `PlexApi.Hubs.GetRelatedHubs()`: **Added**
* `PlexApi.Hubs.GetSectionHubs()`: **Added**
* `PlexApi.Hubs.ResetSectionDefaults()`: **Added**
* `PlexApi.Hubs.ListHubs()`: **Added**
* `PlexApi.Hubs.CreateCustomHub()`: **Added**
* `PlexApi.Hubs.MoveHub()`: **Added**
* `PlexApi.Hubs.DeleteCustomHub()`: **Added**
* `PlexApi.Hubs.UpdateHubVisibility()`: **Added**
* `PlexApi.Search.SearchHubs()`: **Added**
* `PlexApi.Search.VoiceSearchHubs()`: **Added**
* `PlexApi.Library.GetLibraryItems()`: **Added**
* `PlexApi.Library.DeleteCaches()`: **Added**
* `PlexApi.Library.CleanBundles()`: **Added**
* `PlexApi.Library.IngestTransientItem()`: **Added**
* `PlexApi.Library.GetLibraryMatches()`: **Added**
* `PlexApi.Library.OptimizeDatabase()`: **Added**
* `PlexApi.Library.GetRandomArtwork()`: **Added**
* `PlexApi.Library.GetSections()`: **Added**
* `PlexApi.Library.AddSection()`: **Added**
* `PlexApi.Library.StopAllRefreshes()`: **Added**
* `PlexApi.Library.GetSectionsPrefs()`: **Added**
* `PlexApi.Library.RefreshSectionsMetadata()`: **Added**
* `PlexApi.Library.GetTags()`: **Added**
* `PlexApi.Library.DeleteMetadataItem()`: **Added**
* `PlexApi.Library.EditMetadataItem()`: **Added**
* `PlexApi.Library.DetectAds()`: **Added**
* `PlexApi.Library.GetAllItemLeaves()`: **Added**
* `PlexApi.Library.AnalyzeMetadata()`: **Added**
* `PlexApi.Library.GenerateThumbs()`: **Added**
* `PlexApi.Library.DetectCredits()`: **Added**
* `PlexApi.Library.GetExtras()`: **Added**
* `PlexApi.Library.AddExtras()`: **Added**
* `PlexApi.Library.GetFile()`: **Added**
* `PlexApi.Library.StartBifGeneration()`: **Added**
* `PlexApi.Library.DetectIntros()`: **Added**
* `PlexApi.Library.CreateMarker()`: **Added**
* `PlexApi.Library.MatchItem()`: **Added**
* `PlexApi.Library.ListMatches()`: **Added**
* `PlexApi.Library.MergeItems()`: **Added**
* `PlexApi.Library.ListSonicallySimilar()`: **Added**
* `PlexApi.Library.SetItemPreferences()`: **Added**
* `PlexApi.Library.RefreshItemsMetadata()`: **Added**
* `PlexApi.Library.GetRelatedItems()`: **Added**
* `PlexApi.Library.ListSimilar()`: **Added**
* `PlexApi.Library.SplitItem()`: **Added**
* `PlexApi.Library.AddSubtitles()`: **Added**
* `PlexApi.Library.GetItemTree()`: **Added**
* `PlexApi.Library.Unmatch()`: **Added**
* `PlexApi.Library.ListTopUsers()`: **Added**
* `PlexApi.Library.DetectVoiceActivity()`: **Added**
* `PlexApi.Library.GetAugmentationStatus()`: **Added**
* `PlexApi.Library.SetStreamSelection()`: **Added**
* `PlexApi.Library.GetPerson()`: **Added**
* `PlexApi.Library.ListPersonMedia()`: **Added**
* `PlexApi.Library.DeleteLibrarySection()`: **Added**
* `PlexApi.Library.GetLibraryDetails()`: **Added**
* `PlexApi.Library.EditSection()`: **Added**
* `PlexApi.Library.UpdateItems()`: **Added**
* `PlexApi.Library.StartAnalysis()`: **Added**
* `PlexApi.Library.Autocomplete()`: **Added**
* `PlexApi.Library.GetCollections()`: **Added**
* `PlexApi.Library.GetCommon()`: **Added**
* `PlexApi.Library.EmptyTrash()`: **Added**
* `PlexApi.Library.GetSectionFilters()`: **Added**
* `PlexApi.Library.GetFirstCharacters()`: **Added**
* `PlexApi.Library.DeleteIndexes()`: **Added**
* `PlexApi.Library.DeleteIntros()`: **Added**
* `PlexApi.Library.GetSectionPreferences()`: **Added**
* `PlexApi.Library.SetSectionPreferences()`: **Added**
* `PlexApi.Library.CancelRefresh()`: **Added**
* `PlexApi.Library.RefreshSection()`: **Added**
* `PlexApi.Library.GetAvailableSorts()`: **Added**
* `PlexApi.Library.GetStreamLevels()`: **Added**
* `PlexApi.Library.GetStreamLoudness()`: **Added**
* `PlexApi.Library.GetChapterImage()`: **Added**
* `PlexApi.Library.SetItemArtwork()`: **Added**
* `PlexApi.Library.UpdateItemArtwork()`: **Added**
* `PlexApi.Library.DeleteMarker()`: **Added**
* `PlexApi.Library.EditMarker()`: **Added**
* `PlexApi.Library.DeleteMediaItem()`: **Added**
* `PlexApi.Library.GetPartIndex()`: **Added**
* `PlexApi.Library.DeleteCollection()`: **Added**
* `PlexApi.Library.GetSectionImage()`: **Added**
* `PlexApi.Library.DeleteStream()`: **Added**
* `PlexApi.Library.GetStream()`: **Added**
* `PlexApi.Library.SetStreamOffset()`: **Added**
* `PlexApi.Library.GetItemArtwork()`: **Added**
* `PlexApi.Library.GetMediaPart()`: **Added**
* `PlexApi.Library.GetImageFromBif()`: **Added**
* `PlexApi.Collections.CreateCollection()`: **Added**
* `PlexApi.DvRs.ListDvRs()`: **Added**
* `PlexApi.DvRs.CreateDvr()`: **Added**
* `PlexApi.DvRs.DeleteDvr()`: **Added**
* `PlexApi.DvRs.GetDvr()`: **Added**
* `PlexApi.DvRs.DeleteLineup()`: **Added**
* `PlexApi.DvRs.AddLineup()`: **Added**
* `PlexApi.DvRs.SetDvrPreferences()`: **Added**
* `PlexApi.DvRs.StopDvrReload()`: **Added**
* `PlexApi.DvRs.ReloadGuide()`: **Added**
* `PlexApi.DvRs.TuneChannel()`: **Added**
* `PlexApi.DvRs.RemoveDeviceFromDvr()`: **Added**
* `PlexApi.DvRs.AddDeviceToDvr()`: **Added**
* `PlexApi.Epg.ComputeChannelMap()`: **Added**
* `PlexApi.Epg.GetChannels()`: **Added**
* `PlexApi.Epg.GetCountries()`: **Added**
* `PlexApi.Epg.GetAllLanguages()`: **Added**
* `PlexApi.Epg.GetLineup()`: **Added**
* `PlexApi.Epg.GetLineupChannels()`: **Added**
* `PlexApi.Epg.GetCountriesLineups()`: **Added**
* `PlexApi.Epg.GetCountryRegions()`: **Added**
* `PlexApi.Epg.ListLineups()`: **Added**
* `PlexApi.LiveTv.GetSessions()`: **Added**
* `PlexApi.LiveTv.GetLiveTvSession()`: **Added**
* `PlexApi.LiveTv.GetSessionPlaylistIndex()`: **Added**
* `PlexApi.LiveTv.GetSessionSegment()`: **Added**
* `PlexApi.Log.WriteLog()`: **Added**
* `PlexApi.Log.WriteMessage()`: **Added**
* `PlexApi.Log.EnablePapertrail()`: **Added**
* `PlexApi.Devices.GetAvailableGrabbers()`: **Added**
* `PlexApi.Devices.ListDevices()`: **Added**
* `PlexApi.Devices.AddDevice()`: **Added**
* `PlexApi.Devices.DiscoverDevices()`: **Added**
* `PlexApi.Devices.RemoveDevice()`: **Added**
* `PlexApi.Devices.GetDeviceDetails()`: **Added**
* `PlexApi.Devices.ModifyDevice()`: **Added**
* `PlexApi.Devices.SetChannelmap()`: **Added**
* `PlexApi.Devices.GetDevicesChannels()`: **Added**
* `PlexApi.Devices.SetDevicePreferences()`: **Added**
* `PlexApi.Devices.StopScan()`: **Added**
* `PlexApi.Devices.Scan()`: **Added**
* `PlexApi.Devices.GetThumb()`: **Added**
* `PlexApi.Provider.ListProviders()`: **Added**
* `PlexApi.Provider.AddProvider()`: **Added**
* `PlexApi.Provider.RefreshProviders()`: **Added**
* `PlexApi.Provider.DeleteMediaProvider()`: **Added**
* `PlexApi.Subscriptions.GetAllSubscriptions()`: **Added**
* `PlexApi.Subscriptions.CreateSubscription()`: **Added**
* `PlexApi.Subscriptions.ProcessSubscriptions()`: **Added**
* `PlexApi.Subscriptions.GetScheduledRecordings()`: **Added**
* `PlexApi.Subscriptions.GetTemplate()`: **Added**
* `PlexApi.Subscriptions.CancelGrab()`: **Added**
* `PlexApi.Subscriptions.DeleteSubscription()`: **Added**
* `PlexApi.Subscriptions.GetSubscription()`: **Added**
* `PlexApi.Subscriptions.EditSubscriptionPreferences()`: **Added**
* `PlexApi.Subscriptions.ReorderSubscription()`: **Added**
* `PlexApi.Transcoder.TranscodeImage()`: **Added**
* `PlexApi.Transcoder.MakeDecision()`: **Added**
* `PlexApi.Transcoder.TriggerFallback()`: **Added**
* `PlexApi.Transcoder.TranscodeSubtitles()`: **Added**
* `PlexApi.Transcoder.StartTranscodeSession()`: **Added**
* `PlexApi.Playlist.ListPlaylists()`: **Added**
* `PlexApi.Playlist.GetPlaylist()`: **Added**
* `PlexApi.Playlist.GetPlaylistItems()`: **Added**
* `PlexApi.LibraryPlaylists.CreatePlaylist()`: **Added**
* `PlexApi.LibraryPlaylists.UploadPlaylist()`: **Added**
* `PlexApi.LibraryPlaylists.DeletePlaylist()`: **Added**
* `PlexApi.LibraryPlaylists.UpdatePlaylist()`: **Added**
* `PlexApi.LibraryPlaylists.GetPlaylistGenerators()`: **Added**
* `PlexApi.LibraryPlaylists.ClearPlaylistItems()`: **Added**
* `PlexApi.LibraryPlaylists.AddPlaylistItems()`: **Added**
* `PlexApi.LibraryPlaylists.DeletePlaylistItem()`: **Added**
* `PlexApi.LibraryPlaylists.GetPlaylistGenerator()`: **Added**
* `PlexApi.LibraryPlaylists.GetPlaylistGeneratorItems()`: **Added**
* `PlexApi.LibraryPlaylists.MovePlaylistItem()`: **Added**
* `PlexApi.LibraryPlaylists.RefreshPlaylist()`: **Added**
* `PlexApi.PlayQueue.CreatePlayQueue()`: **Added**
* `PlexApi.PlayQueue.GetPlayQueue()`: **Added**
* `PlexApi.PlayQueue.AddToPlayQueue()`: **Added**
* `PlexApi.PlayQueue.ClearPlayQueue()`: **Added**
* `PlexApi.PlayQueue.ResetPlayQueue()`: **Added**
* `PlexApi.PlayQueue.Shuffle()`: **Added**
* `PlexApi.PlayQueue.Unshuffle()`: **Added**
* `PlexApi.PlayQueue.DeletePlayQueueItem()`: **Added**
* `PlexApi.PlayQueue.MovePlayQueueItem()`: **Added**
* `PlexApi.UltraBlur.GetColors()`: **Added**
* `PlexApi.UltraBlur.GetImage()`: **Added**
* `PlexApi.Status.ListSessions()`: **Added**
* `PlexApi.Status.GetBackgroundTasks()`: **Added**
* `PlexApi.Status.ListPlaybackHistory()`: **Added**
* `PlexApi.Status.TerminateSession()`: **Added**
* `PlexApi.Status.DeleteHistory()`: **Added**
* `PlexApi.Status.GetHistoryItem()`: **Added**
* `PlexApi.Updater.CheckUpdates()`: **Added**
* `PlexApi.Updater.GetUpdatesStatus()`: **Added**
* `PlexApi.Content.GetCollectionItems()`: **Added**
* `PlexApi.Content.GetMetadataItem()`: **Added**
* `PlexApi.Content.GetAlbums()`: **Added**
* `PlexApi.Content.ListContent()`: **Added**
* `PlexApi.Content.GetAllLeaves()`: **Added**
* `PlexApi.Content.GetArts()`: **Added**
* `PlexApi.Content.GetCategories()`: **Added**
* `PlexApi.Content.GetCluster()`: **Added**
* `PlexApi.Content.GetSonicPath()`: **Added**
* `PlexApi.Content.GetFolders()`: **Added**
* `PlexApi.Content.ListMoments()`: **Added**
* `PlexApi.Content.GetSonicallySimilar()`: **Added**
* `PlexApi.Content.GetCollectionImage()`: **Added**
* `PlexApi.LibraryCollections.AddCollectionItems()`: **Added**
* `PlexApi.LibraryCollections.DeleteCollectionItem()`: **Added**
* `PlexApi.LibraryCollections.MoveCollectionItem()`: **Added**
* `PlexApi.Server.GetServerCapabilities()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.GetServerPreferences()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.GetAvailableClients()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.GetDevices()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.Get-Server-Identity()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.GetMyPlexAccount()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.GetResizedPhoto()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.Get-Media-Providers()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Server.GetServerList()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Media.MarkPlayed()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Media.MarkUnplayed()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Media.UpdatePlayProgress()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Media.Get-Banner-Image()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Media.Get-Thumb-Image()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Video.GetTimeline()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Video.StartUniversalTranscode()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Activities.GetServerActivities()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Activities.CancelServerActivities()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Butler.GetButlerTasks()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Butler.StartAllTasks()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Butler.StopAllTasks()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Plex.GetCompanionsData()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Plex.GetUserFriends()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Plex.GetGeoData()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Plex.GetHomeData()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Plex.Get-Server-Resources()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Plex.GetPin()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Plex.GetTokenByPinId()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Hubs.GetGlobalHubs()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Hubs.Get-Recently-Added()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Hubs.GetLibraryHubs()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Search.PerformSearch()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Search.PerformVoiceSearch()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Search.GetSearchResults()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.GetFileHash()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Recently-Added-Library()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-All-Libraries()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Library-Details()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.DeleteLibrary()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Library-Items()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Library-Sections-All()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Refresh-Library-Metadata()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Search-Library()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Genres-Library()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Countries-Library()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Actors-Library()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Search-All-Libraries()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Media-Meta-Data()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Media-Arts()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Post-Media-Arts()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Get-Media-Posters()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.Post-Media-Poster()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.GetMetadataChildren()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Library.GetTopWatchedContent()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Watchlist.Get-Watch-List()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Log.LogLine()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Log.LogMultiLine()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Log.EnablePaperTrail()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.CreatePlaylist()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.GetPlaylists()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.GetPlaylist()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.DeletePlaylist()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.UpdatePlaylist()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.GetPlaylistContents()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.ClearPlaylistContents()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.AddPlaylistContents()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Playlists.UploadPlaylist()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Authentication.GetTransientToken()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Authentication.GetSourceConnectionInformation()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Authentication.GetTokenDetails()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Authentication.Post-Users-Sign-In-Data()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Statistics.GetStatistics()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Statistics.GetResourcesStatistics()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Statistics.GetBandwidthStatistics()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Sessions.GetSessions()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Sessions.GetSessionHistory()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Sessions.GetTranscodeSessions()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Sessions.StopTranscodeSession()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Updater.GetUpdateStatus()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Updater.CheckForUpdates()`: **Deleted** **Breaking** ⚠️
* `PlexApi.Users.Get-Users()`: **Deleted** **Breaking** ⚠️
This commit is contained in:
speakeasybot
2025-10-26 10:42:55 +00:00
parent 8c02f6a6ae
commit 835a7430fa
3366 changed files with 111145 additions and 71251 deletions

View File

@@ -23,19 +23,17 @@ namespace LukeHagar.PlexAPI.SDK
using System.Threading.Tasks;
/// <summary>
/// API Calls that perform search operations with Plex Media Server<br/>
///
/// <remarks>
///
/// </remarks>
/// The search feature within a media provider
/// </summary>
public interface ISearch
{
/// <summary>
/// Perform a search
/// Search Hub
///
/// <remarks>
/// Perform a search and get the result as hubs<br/>
/// <br/>
/// This endpoint performs a search across all library sections, or a single section, and returns matches as hubs, split up by type. It performs spell checking, looks for partial matches, and orders the hubs based on quality of results. In addition, based on matches, it will return other related matches (e.g. for a genre match, it may return movies in that genre, or for an actor match, movies with that actor).<br/>
/// <br/>
/// In the response&apos;s items, the following extra attributes are returned to further describe or disambiguate the result:<br/>
@@ -51,71 +49,70 @@ namespace LukeHagar.PlexAPI.SDK
///
/// </remarks>
/// </summary>
Task<PerformSearchResponse> PerformSearchAsync(string query, double? sectionId = null, double? limit = 3D);
Task<SearchHubsResponse> SearchHubsAsync(SearchHubsRequest request);
/// <summary>
/// Perform a voice search
/// Voice Search Hub
///
/// <remarks>
/// This endpoint performs a search specifically tailored towards voice or other imprecise input which may work badly with the substring and spell-checking heuristics used by the `/hubs/search` endpoint. <br/>
/// It uses a <a href="https://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein distance</a> heuristic to search titles, and as such is much slower than the other search endpoint. <br/>
/// Whenever possible, clients should limit the search to the appropriate type. <br/>
/// Perform a search tailored to voice input and get the result as hubs<br/>
/// <br/>
/// This endpoint performs a search specifically tailored towards voice or other imprecise input which may work badly with the substring and spell-checking heuristics used by the `/hubs/search` endpoint. It uses a <a href="https://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein distance</a> heuristic to search titles, and as such is much slower than the other search endpoint. Whenever possible, clients should limit the search to the appropriate type.<br/>
/// <br/>
/// Results, as well as their containing per-type hubs, contain a `distance` attribute which can be used to judge result quality.<br/>
///
/// </remarks>
/// </summary>
Task<PerformVoiceSearchResponse> PerformVoiceSearchAsync(string query, double? sectionId = null, double? limit = 3D);
/// <summary>
/// Get Search Results
///
/// <remarks>
/// This will search the database for the string provided.
/// </remarks>
/// </summary>
Task<GetSearchResultsResponse> GetSearchResultsAsync(string query);
Task<VoiceSearchHubsResponse> VoiceSearchHubsAsync(VoiceSearchHubsRequest request);
}
/// <summary>
/// API Calls that perform search operations with Plex Media Server<br/>
///
/// <remarks>
///
/// </remarks>
/// The search feature within a media provider
/// </summary>
public class Search: ISearch
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = "csharp";
private const string _sdkVersion = "0.17.0";
private const string _sdkGenVersion = "2.698.4";
private const string _openapiDocVersion = "0.0.3";
private const string _sdkVersion = "0.18.0";
private const string _sdkGenVersion = "2.730.5";
private const string _openapiDocVersion = "1.1.1";
public Search(SDKConfig config)
{
SDKConfiguration = config;
}
public async Task<PerformSearchResponse> PerformSearchAsync(string query, double? sectionId = null, double? limit = 3D)
public async Task<SearchHubsResponse> SearchHubsAsync(SearchHubsRequest request)
{
var request = new PerformSearchRequest()
if (request == null)
{
Query = query,
SectionId = sectionId,
Limit = limit,
};
request = new SearchHubsRequest();
}
request.Accepts ??= SDKConfiguration.Accepts;
request.ClientIdentifier ??= SDKConfiguration.ClientIdentifier;
request.Product ??= SDKConfiguration.Product;
request.Version ??= SDKConfiguration.Version;
request.Platform ??= SDKConfiguration.Platform;
request.PlatformVersion ??= SDKConfiguration.PlatformVersion;
request.Device ??= SDKConfiguration.Device;
request.Model ??= SDKConfiguration.Model;
request.DeviceVendor ??= SDKConfiguration.DeviceVendor;
request.DeviceName ??= SDKConfiguration.DeviceName;
request.Marketplace ??= SDKConfiguration.Marketplace;
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/hubs/search", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "performSearch", new List<string> { }, SDKConfiguration.SecuritySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "searchHubs", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
@@ -125,241 +122,7 @@ namespace LukeHagar.PlexAPI.SDK
httpResponse = await SDKConfiguration.Client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode == 401 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
{
httpResponse = _httpResponse;
}
}
}
catch (Exception error)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), null, error);
if (_httpResponse != null)
{
httpResponse = _httpResponse;
}
else
{
throw;
}
}
httpResponse = await this.SDKConfiguration.Hooks.AfterSuccessAsync(new AfterSuccessContext(hookCtx), httpResponse);
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
return new PerformSearchResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
PerformSearchBadRequestPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<PerformSearchBadRequestPayload>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into PerformSearchBadRequestPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new PerformSearchBadRequest(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
PerformSearchUnauthorizedPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<PerformSearchUnauthorizedPayload>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into PerformSearchUnauthorizedPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new PerformSearchUnauthorized(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<PerformVoiceSearchResponse> PerformVoiceSearchAsync(string query, double? sectionId = null, double? limit = 3D)
{
var request = new PerformVoiceSearchRequest()
{
Query = query,
SectionId = sectionId,
Limit = limit,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/hubs/search/voice", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "performVoiceSearch", new List<string> { }, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await SDKConfiguration.Client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode == 401 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
{
httpResponse = _httpResponse;
}
}
}
catch (Exception error)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), null, error);
if (_httpResponse != null)
{
httpResponse = _httpResponse;
}
else
{
throw;
}
}
httpResponse = await this.SDKConfiguration.Hooks.AfterSuccessAsync(new AfterSuccessContext(hookCtx), httpResponse);
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
return new PerformVoiceSearchResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
PerformVoiceSearchBadRequestPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<PerformVoiceSearchBadRequestPayload>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into PerformVoiceSearchBadRequestPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new PerformVoiceSearchBadRequest(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
PerformVoiceSearchUnauthorizedPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<PerformVoiceSearchUnauthorizedPayload>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into PerformVoiceSearchUnauthorizedPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new PerformVoiceSearchUnauthorized(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<GetSearchResultsResponse> GetSearchResultsAsync(string query)
{
var request = new GetSearchResultsRequest()
{
Query = query,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/search", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "getSearchResults", new List<string> { }, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await SDKConfiguration.Client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode == 401 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
if (_statusCode == 400 || _statusCode == 404 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -390,17 +153,17 @@ namespace LukeHagar.PlexAPI.SDK
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
GetSearchResultsResponseBody obj;
SearchHubsResponseBody obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<GetSearchResultsResponseBody>(httpResponseBody, NullValueHandling.Ignore);
obj = ResponseBodyDeserializer.DeserializeNotNull<SearchHubsResponseBody>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetSearchResultsResponseBody.", httpResponse, httpResponseBody, ex);
throw new ResponseValidationException("Failed to deserialize response body into SearchHubsResponseBody.", httpResponse, httpResponseBody, ex);
}
var response = new GetSearchResultsResponse()
var response = new SearchHubsResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
@@ -412,49 +175,112 @@ namespace LukeHagar.PlexAPI.SDK
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 400)
else if(responseStatusCode == 400 || responseStatusCode == 404 || responseStatusCode >= 400 && responseStatusCode < 500)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<VoiceSearchHubsResponse> VoiceSearchHubsAsync(VoiceSearchHubsRequest request)
{
if (request == null)
{
request = new VoiceSearchHubsRequest();
}
request.Accepts ??= SDKConfiguration.Accepts;
request.ClientIdentifier ??= SDKConfiguration.ClientIdentifier;
request.Product ??= SDKConfiguration.Product;
request.Version ??= SDKConfiguration.Version;
request.Platform ??= SDKConfiguration.Platform;
request.PlatformVersion ??= SDKConfiguration.PlatformVersion;
request.Device ??= SDKConfiguration.Device;
request.Model ??= SDKConfiguration.Model;
request.DeviceVendor ??= SDKConfiguration.DeviceVendor;
request.DeviceName ??= SDKConfiguration.DeviceName;
request.Marketplace ??= SDKConfiguration.Marketplace;
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/hubs/search/voice", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "voiceSearchHubs", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await SDKConfiguration.Client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
{
httpResponse = _httpResponse;
}
}
}
catch (Exception error)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), null, error);
if (_httpResponse != null)
{
httpResponse = _httpResponse;
}
else
{
throw;
}
}
httpResponse = await this.SDKConfiguration.Hooks.AfterSuccessAsync(new AfterSuccessContext(hookCtx), httpResponse);
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
GetSearchResultsBadRequestPayload payload;
VoiceSearchHubsResponseBody obj;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<GetSearchResultsBadRequestPayload>(httpResponseBody, NullValueHandling.Ignore);
obj = ResponseBodyDeserializer.DeserializeNotNull<VoiceSearchHubsResponseBody>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetSearchResultsBadRequestPayload.", httpResponse, httpResponseBody, ex);
throw new ResponseValidationException("Failed to deserialize response body into VoiceSearchHubsResponseBody.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new GetSearchResultsBadRequest(payload, httpResponse, httpResponseBody);
var response = new VoiceSearchHubsResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.Object = obj;
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
GetSearchResultsUnauthorizedPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<GetSearchResultsUnauthorizedPayload>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetSearchResultsUnauthorizedPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new GetSearchResultsUnauthorized(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 400 && responseStatusCode < 500)
else if(responseStatusCode == 400 || responseStatusCode >= 400 && responseStatusCode < 500)
{
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}