Compare commits

..

43 Commits
v0.8.3 ... main

Author SHA1 Message Date
speakeasybot
c0836c3b34 ## Csharp SDK Changes:
* `PlexApi.LibraryPlaylists.AddPlaylistItems()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryPlaylists.ClearPlaylistItems()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryCollections.MoveCollectionItem()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryCollections.DeleteCollectionItem()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryCollections.AddCollectionItems()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Content.GetSonicallySimilar()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Butler.StopTask()`:  `request` **Changed** **Breaking** ⚠️
* `PlexApi.Butler.StartTask()`:  `request` **Changed** **Breaking** ⚠️
* `PlexApi.Content.GetSonicPath()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.DownloadQueue.GetItemDecision()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Hubs.GetAllHubs()`: 
  *  `request.OnlyTransient` **Changed**
  *  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Hubs.GetContinueWatching()`:  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Hubs.GetPromotedHubs()`:  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Hubs.GetMetadataHubs()`: 
  *  `request.OnlyTransient` **Changed**
  *  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Hubs.GetPostplayHubs()`: 
  *  `request.OnlyTransient` **Changed**
  *  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Hubs.GetRelatedHubs()`: 
  *  `request.OnlyTransient` **Changed**
  *  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Hubs.GetSectionHubs()`: 
  *  `request.OnlyTransient` **Changed**
  *  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Content.GetAllLeaves()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Content.ListContent()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Search.SearchHubs()`:  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Content.GetAlbums()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetLibraryItems()`: 
  *  `request.MediaQuery` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.IngestTransientItem()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetLibraryMatches()`: 
  *  `request` **Changed** **Breaking** ⚠️
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Content.GetMetadataItem()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetSections()`:  `response.mediaContainer.Directory.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.AddSection()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.Directory.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetTags()`: 
  *  `request.Type` **Changed** **Breaking** ⚠️
* `PlexApi.Content.GetCollectionItems()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetAllItemLeaves()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Status.ListSessions()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.MovePlayQueueItem()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetExtras()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.DeletePlayQueueItem()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.Unshuffle()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.ListMatches()`: 
  *  `request.Manual` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.ListSonicallySimilar()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.Shuffle()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetRelatedItems()`:  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.ListSimilar()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.ResetPlayQueue()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetItemTree()`:  `response.mediaContainer.MetadataItem.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.ClearPlayQueue()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.AddToPlayQueue()`: 
  *  `request.Next` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetCommon()`: 
  *  `request.MediaQuery` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetPerson()`:  `response.mediaContainer.Directory.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.ListPersonMedia()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.PlayQueue.GetPlayQueue()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetLibraryDetails()`: 
  *  `request.IncludeDetails` **Changed**
  *  `response.mediaContainer.Directory.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryPlaylists.MovePlaylistItem()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.Autocomplete()`: 
  *  `request.MediaQuery` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Library.GetCollections()`: 
  *  `request.MediaQuery` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryPlaylists.GetPlaylistGeneratorItems()`:  `response.mediaContainer.Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryPlaylists.DeletePlaylistItem()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Search.VoiceSearchHubs()`: 
  *  `request.Type` **Changed** **Breaking** ⚠️
  *  `response.mediaContainer.Hub.[].Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LibraryPlaylists.CreatePlaylist()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Playlist.GetPlaylistItems()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Playlist.GetPlaylist()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Playlist.ListPlaylists()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Collections.CreateCollection()`: 
  *  `request.Type` **Changed** **Breaking** ⚠️
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.DvRs.TuneChannel()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LiveTv.GetSessions()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.LiveTv.GetLiveTvSession()`:  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Transcoder.MakeDecision()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.Metadata.[]` **Changed** **Breaking** ⚠️
* `PlexApi.Subscriptions.GetAllSubscriptions()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.MediaSubscription.[].MediaGrabOperation.[].Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.Subscriptions.CreateSubscription()`:  `response.mediaContainer.MediaSubscription.[].MediaGrabOperation.[].Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.Subscriptions.GetScheduledRecordings()`:  `response.mediaContainer.MediaGrabOperation.[].Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.Subscriptions.GetTemplate()`:  `response.mediaContainer.SubscriptionTemplate.[].MediaSubscription.[].MediaGrabOperation.[].Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.Subscriptions.GetSubscription()`: 
  *  `request` **Changed**
  *  `response.mediaContainer.MediaSubscription.[].MediaGrabOperation.[].Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.Subscriptions.EditSubscriptionPreferences()`:  `response.mediaContainer.MediaSubscription.[].MediaGrabOperation.[].Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.Subscriptions.ReorderSubscription()`:  `response.mediaContainer.MediaSubscription.[].MediaGrabOperation.[].Metadata` **Changed** **Breaking** ⚠️
* `PlexApi.Library.AddSubtitles()`:  `request` **Changed**
* `PlexApi.LibraryPlaylists.UploadPlaylist()`: 
  *  `request.Force` **Changed**
* `PlexApi.Transcoder.TranscodeSubtitles()`:  `request` **Changed**
* `PlexApi.Transcoder.StartTranscodeSession()`:  `request` **Changed**
* `PlexApi.Library.GetMediaPart()`: 
  *  `request.Download` **Changed**
* `PlexApi.Library.DetectIntros()`: 
  *  `request.Force` **Changed**
* `PlexApi.Library.GetSectionImage()`: 
  *  `request.MediaQuery` **Changed**
* `PlexApi.Library.DeleteMediaItem()`: 
  *  `request.Proxy` **Changed**
* `PlexApi.Library.RefreshItemsMetadata()`: 
  *  `request.MarkUpdated` **Changed**
* `PlexApi.Authentication.Post-Users-Sign-In-Data()`: **Added**
* `PlexApi.Authentication.GetTokenDetails()`: **Added**
* `PlexApi.Library.DetectCredits()`:  `request` **Changed**
* `PlexApi.Library.SetStreamSelection()`: 
  *  `request.AllParts` **Changed**
* `PlexApi.Library.UpdateItems()`: 
  *  `request.Field.locked` **Changed**
* `PlexApi.PlayQueue.CreatePlayQueue()`:  `request` **Changed**
* `PlexApi.Library.DeleteLibrarySection()`: 
  *  `request.Async` **Changed**
* `PlexApi.Library.GetAugmentationStatus()`: 
  *  `request.Wait` **Changed**
* `PlexApi.Transcoder.TranscodeImage()`:  `request` **Changed**
* `PlexApi.Devices.ModifyDevice()`: 
  *  `request.Enabled` **Changed**
* `PlexApi.Library.DetectVoiceActivity()`:  `request` **Changed**
* `PlexApi.Library.GetStream()`: 
  *  `request.AutoAdjustSubtitle` **Changed**
* `PlexApi.Library.StartBifGeneration()`: 
  *  `request.Force` **Changed**
* `PlexApi.Library.GetFirstCharacters()`: 
  *  `request.MediaQuery` **Changed**
* `PlexApi.UltraBlur.GetImage()`: 
  *  `request.Noise` **Changed**
* `PlexApi.Library.GenerateThumbs()`: 
  *  `request.Force` **Changed**
* `PlexApi.Updater.ApplyUpdates()`:  `request` **Changed**
* `PlexApi.Updater.CheckUpdates()`: 
  *  `request.Download` **Changed**
* `PlexApi.Library.DeleteMetadataItem()`: 
  *  `request.Proxy` **Changed**
* `PlexApi.Library.OptimizeDatabase()`: 
  *  `request.Async` **Changed**
* `PlexApi.Library.RefreshSection()`: 
  *  `request.Force` **Changed**
* `PlexApi.Hubs.UpdateHubVisibility()`:  `request` **Changed**
* `PlexApi.Hubs.CreateCustomHub()`:  `request` **Changed**
* `PlexApi.DownloadQueue.AddDownloadQueueItems()`:  `request` **Changed**
* `PlexApi.Timeline.Report()`:  `request` **Changed**
* `PlexApi.General.GetSourceConnectionInformation()`: 
  *  `request.Refresh` **Changed**
* `PlexApi.Plex.Get-Server-Resources()`: **Added**
* `PlexApi.Users.Get-Users()`: **Added**
2025-12-01 00:32:52 +00:00
speakeasybot
70dbffa1d4 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.656.1 2025-11-13 00:26:46 +00:00
speakeasybot
c695dbace1 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.650.0 2025-11-06 22:25:44 +00:00
speakeasybot
835a7430fa ## 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** ⚠️
2025-10-26 10:42:55 +00:00
Luke Hagar
8c02f6a6ae Update plexapi source location in workflow.yaml 2025-10-12 01:49:24 -05:00
speakeasybot
8563e8fef2 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.615.2 2025-09-15 00:26:45 +00:00
speakeasybot
1f5d4ff03a ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.598.3 2025-08-07 00:28:41 +00:00
speakeasybot
d970db3b6f ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.598.0 2025-08-06 00:28:40 +00:00
speakeasybot
4197184f92 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.557.0 2025-06-09 00:28:07 +00:00
speakeasybot
bc02ecef34 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.555.2 2025-06-04 00:26:20 +00:00
speakeasybot
55b5c2b3dd ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.542.1 2025-05-05 00:26:49 +00:00
speakeasybot
67a53e72d5 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.541.2 2025-05-01 00:28:06 +00:00
speakeasybot
9ccab7b22d ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.529.1 2025-04-19 00:24:30 +00:00
speakeasybot
eb2f6e54a2 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.529.1 2025-04-14 00:26:56 +00:00
speakeasybot
4b798cbb85 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.529.1 2025-04-06 00:25:51 +00:00
speakeasybot
a89870d526 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.528.1 2025-04-03 00:23:53 +00:00
speakeasybot
01b116a71c ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.526.6 2025-03-31 17:08:42 +00:00
Luke Hagar
9831457f45 Update workflow.yaml 2025-03-31 12:06:13 -05:00
speakeasybot
653b23dab6 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.513.4 2025-03-09 00:21:37 +00:00
speakeasybot
86c36c72b7 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.513.2 2025-03-07 00:23:51 +00:00
speakeasybot
3e00ddc6b1 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.487.1 2025-02-10 00:23:35 +00:00
speakeasybot
d976a079a9 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.487.0 2025-02-07 00:22:51 +00:00
speakeasybot
b10d5f7023 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.484.1 2025-02-06 00:22:53 +00:00
speakeasybot
c431cee288 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.484.1 2025-02-05 00:22:30 +00:00
speakeasybot
5195de1dca ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.476.1 2025-01-27 00:23:03 +00:00
speakeasybot
43dc47a5a0 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.476.1 2025-01-26 17:23:56 +00:00
speakeasybot
53157408b3 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.476.1 2025-01-26 16:03:29 +00:00
speakeasybot
fe81f4dff0 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.474.0 2025-01-24 00:22:18 +00:00
speakeasybot
c9746b7ad8 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.459.2 2024-12-22 00:24:32 +00:00
speakeasybot
0ec48b6a1d ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.459.2 2024-12-21 00:22:05 +00:00
speakeasybot
14e54fa017 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.438.3 2024-11-14 00:22:09 +00:00
speakeasybot
61492e5dad ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.438.1 2024-11-12 00:21:43 +00:00
speakeasybot
f099c01940 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.406.0 2024-10-03 12:26:13 +00:00
speakeasybot
92be5b3a91 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.405.8 2024-10-02 11:11:07 +00:00
speakeasybot
a183f389bc ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.405.8 2024-10-02 10:46:38 +00:00
speakeasybot
4a443f6f2e ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.405.8 2024-10-02 09:49:57 +00:00
speakeasybot
b9b7cd1146 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.405.4 2024-09-30 17:36:49 +00:00
speakeasybot
81c55cb08b ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.405.4 2024-09-30 17:23:32 +00:00
speakeasybot
860991f2a0 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.404.5 2024-09-30 08:47:49 +00:00
Jason Landbridge
d25639db53 Added dotnet_version directly 2024-09-30 10:42:22 +02:00
speakeasybot
227e2351d5 ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.404.5 2024-09-30 00:23:16 +00:00
JasonLandbridge
3bd4f51297 Merge remote-tracking branch 'origin/main' 2024-09-29 09:09:51 +02:00
JasonLandbridge
2beb707ed5 make project intelij compatible 2024-09-28 10:01:25 +02:00
3163 changed files with 119076 additions and 50120 deletions

View File

@@ -24,6 +24,7 @@ jobs:
mode: direct
set_version: ${{ github.event.inputs.set_version }}
speakeasy_version: latest
dotnet_version: "8.x"
secrets:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
nuget_api_key: ${{ secrets.NUGET_API_KEY }}

5
.gitignore vendored
View File

@@ -1,3 +1,8 @@
.env
.env.local
.DS_Store
**/.speakeasy/temp/
**/.speakeasy/logs/
obj/
bin/
debug/

View File

@@ -0,0 +1 @@
LukeHagar.PlexAPI.SDK

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="vcsConfiguration" value="3" />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

File diff suppressed because one or more lines are too long

View File

@@ -4,22 +4,40 @@ generation:
maintainOpenAPIOrder: true
usageSnippets:
optionalPropertyRendering: withExample
sdkInitStyle: constructor
useClassNamesForArrayFields: true
fixes:
nameResolutionDec2023: true
nameResolutionFeb2025: false
parameterOrderingFeb2024: true
requestResponseComponentNamesFeb2024: true
securityFeb2025: false
sharedErrorComponentsApr2025: false
auth:
oAuth2ClientCredentialsEnabled: true
oAuth2PasswordEnabled: false
hoistGlobalSecurity: true
schemas:
allOfMergeStrategy: shallowMerge
requestBodyFieldName: ""
tests:
generateTests: true
generateNewTests: false
skipResponseBodyAssertions: false
csharp:
version: 0.8.3
version: 0.20.0
additionalDependencies: []
author: LukeHagar
baseErrorName: PlexAPIError
clientServerStatusCodesAsErrors: true
defaultErrorName: SDKException
disableNamespacePascalCasingApr2024: true
dotnetVersion: net8.0
enableCancellationToken: false
enableSourceLink: true
flattenGlobalSecurity: true
flatteningOrder: ""
httpClientPrefix: Speakeasy
imports:
option: openapi
paths:
@@ -29,10 +47,14 @@ csharp:
shared: Models/Components
webhooks: Models/Webhooks
includeDebugSymbols: true
inferUnionDiscriminators: false
inputModelSuffix: input
maxMethodParams: 4
methodArguments: infer-optional-args
multipartArrayFormat: legacy
outputModelSuffix: output
packageName: LukeHagar.PlexAPI.SDK
packageTags: Plex Media Server SDK
responseFormat: envelope
sourceDirectory: ""
useNodatime: true

View File

@@ -1,4 +1,4 @@
speakeasyVersion: 1.404.5
speakeasyVersion: 1.665.0
sources:
my-source:
sourceNamespace: my-source
@@ -16,26 +16,29 @@ sources:
- main
plexapi:
sourceNamespace: plexapi
sourceRevisionDigest: sha256:ed1af8e79d553cc0bf2f8f7975f445d80cb8bd58390bca18d1352577da5ec5ed
sourceBlobDigest: sha256:157db2a169209c18fdca786b671c5da8d2b14dc3005574d08c9d667320869093
sourceRevisionDigest: sha256:ace004a3b232e8ab9ca3d89f2da8e40470236e6d997073a16c3f8872d67a7383
sourceBlobDigest: sha256:993bfb796a3833b0a3b813ad12469ca34db94f23c2d15ae988a26b4d1ed80fbe
tags:
- latest
- main
- speakeasy-sdk-regen-1764549074
- 1.1.1
targets:
plexcsharp:
source: plexapi
sourceNamespace: plexapi
sourceRevisionDigest: sha256:ed1af8e79d553cc0bf2f8f7975f445d80cb8bd58390bca18d1352577da5ec5ed
sourceBlobDigest: sha256:157db2a169209c18fdca786b671c5da8d2b14dc3005574d08c9d667320869093
sourceRevisionDigest: sha256:ace004a3b232e8ab9ca3d89f2da8e40470236e6d997073a16c3f8872d67a7383
sourceBlobDigest: sha256:993bfb796a3833b0a3b813ad12469ca34db94f23c2d15ae988a26b4d1ed80fbe
codeSamplesNamespace: code-samples-csharp-plexcsharp
codeSamplesRevisionDigest: sha256:0711c7458cb5cacdabcd9e40a1121e20cb5e2d52e796814c15589d2b6d32d9da
codeSamplesRevisionDigest: sha256:1608b54b5bd352a497de07a555fe755ff438efc7fd0d0f42fb1021dda420e88f
workflow:
workflowVersion: 1.0.0
speakeasyVersion: latest
sources:
plexapi:
inputs:
- location: registry.speakeasyapi.dev/plexapi/plexapi/plexapi:main
- location: https://raw.githubusercontent.com/LukeHagar/plex-api-spec/refs/heads/main/plex-api-spec.yaml
registry:
location: registry.speakeasyapi.dev/plexapi/plexapi/plexapi
targets:
plexcsharp:
target: csharp
@@ -47,3 +50,5 @@ workflow:
output: codeSamples.yaml
registry:
location: registry.speakeasyapi.dev/plexapi/plexapi/code-samples-csharp-plexcsharp
labelOverride:
fixedValue: PlexCSharp

View File

@@ -3,7 +3,9 @@ speakeasyVersion: latest
sources:
plexapi:
inputs:
- location: registry.speakeasyapi.dev/plexapi/plexapi/plexapi:main
- location: https://raw.githubusercontent.com/LukeHagar/plex-api-spec/refs/heads/main/plex-api-spec.yaml
registry:
location: registry.speakeasyapi.dev/plexapi/plexapi/plexapi
targets:
plexcsharp:
target: csharp
@@ -15,3 +17,5 @@ targets:
output: codeSamples.yaml
registry:
location: registry.speakeasyapi.dev/plexapi/plexapi/code-samples-csharp-plexcsharp
labelOverride:
fixedValue: PlexCSharp

View File

@@ -13,25 +13,23 @@ namespace LukeHagar.PlexAPI.SDK
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// Activities are awesome. They provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints.<br/>
/// Activities provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints.<br/>
///
/// <remarks>
/// <br/>
/// Activities are associated with HTTP replies via a special `X-Plex-Activity` header which contains the UUID of the activity.<br/>
/// Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint. Other details:<br/>
/// - They can contain a `progress` (from 0 to 100) marking the percent completion of the activity.<br/>
/// - They must contain an `type` which is used by clients to distinguish the specific activity.<br/>
/// - They may contain a `Context` object with attributes which associate the activity with various specific entities (items, libraries, etc.)<br/>
/// - The may contain a `Response` object which attributes which represent the result of the asynchronous operation.<br/>
/// <br/>
/// Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint.<br/>
///
/// </remarks>
/// </summary>
@@ -39,82 +37,74 @@ namespace LukeHagar.PlexAPI.SDK
{
/// <summary>
/// Get Server Activities
/// Get all activities
///
/// <remarks>
/// Get Server Activities
/// List all activities on the server. Admins can see all activities but other users can only see their own
/// </remarks>
/// </summary>
Task<GetServerActivitiesResponse> GetServerActivitiesAsync();
Task<ListActivitiesResponse> ListActivitiesAsync();
/// <summary>
/// Cancel Server Activities
/// Cancel a running activity
///
/// <remarks>
/// Cancel Server Activities
/// Cancel a running activity. Admins can cancel all activities but other users can only cancel their own
/// </remarks>
/// </summary>
Task<CancelServerActivitiesResponse> CancelServerActivitiesAsync(string activityUUID);
Task<CancelActivityResponse> CancelActivityAsync(CancelActivityRequest request);
}
/// <summary>
/// Activities are awesome. They provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints.<br/>
/// Activities provide a way to monitor and control asynchronous operations on the server. In order to receive real-time updates for activities, a client would normally subscribe via either EventSource or Websocket endpoints.<br/>
///
/// <remarks>
/// <br/>
/// Activities are associated with HTTP replies via a special `X-Plex-Activity` header which contains the UUID of the activity.<br/>
/// Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint. Other details:<br/>
/// - They can contain a `progress` (from 0 to 100) marking the percent completion of the activity.<br/>
/// - They must contain an `type` which is used by clients to distinguish the specific activity.<br/>
/// - They may contain a `Context` object with attributes which associate the activity with various specific entities (items, libraries, etc.)<br/>
/// - The may contain a `Response` object which attributes which represent the result of the asynchronous operation.<br/>
/// <br/>
/// Activities are optional cancellable. If cancellable, they may be cancelled via the `DELETE` endpoint.<br/>
///
/// </remarks>
/// </summary>
public class Activities: IActivities
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = "csharp";
private const string _sdkVersion = "0.8.3";
private const string _sdkGenVersion = "2.426.2";
private const string _openapiDocVersion = "0.0.3";
private const string _userAgent = "speakeasy-sdk/csharp 0.8.3 2.426.2 0.0.3 LukeHagar.PlexAPI.SDK";
private string _serverUrl = "";
private ISpeakeasyHttpClient _client;
private Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? _securitySource;
public Activities(ISpeakeasyHttpClient client, Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? securitySource, string serverUrl, SDKConfig config)
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public Activities(SDKConfig config)
{
_client = client;
_securitySource = securitySource;
_serverUrl = serverUrl;
SDKConfiguration = config;
}
public async Task<GetServerActivitiesResponse> GetServerActivitiesAsync()
public async Task<ListActivitiesResponse> ListActivitiesAsync()
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = baseUrl + "/activities";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("getServerActivities", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "listActivities", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
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 < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -144,8 +134,18 @@ namespace LukeHagar.PlexAPI.SDK
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetServerActivitiesResponseBody>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
var response = new GetServerActivitiesResponse()
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
ListActivitiesResponseBody obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<ListActivitiesResponseBody>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into ListActivitiesResponseBody.", httpResponse, httpResponseBody, ex);
}
var response = new ListActivitiesResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
@@ -155,66 +155,61 @@ namespace LukeHagar.PlexAPI.SDK
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 400)
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetServerActivitiesBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetServerActivitiesUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<CancelServerActivitiesResponse> CancelServerActivitiesAsync(string activityUUID)
public async Task<CancelActivityResponse> CancelActivityAsync(CancelActivityRequest request)
{
var request = new CancelServerActivitiesRequest()
if (request == null)
{
ActivityUUID = activityUUID,
};
request = new CancelActivityRequest();
}
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, "/activities/{activityUUID}", request);
var urlString = URLBuilder.Build(baseUrl, "/activities/{activityId}", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Delete, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("cancelServerActivities", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "cancelActivity", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
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)
@@ -241,42 +236,24 @@ namespace LukeHagar.PlexAPI.SDK
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
return new CancelServerActivitiesResponse()
{
return new CancelActivityResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
else if(responseStatusCode == 400 || responseStatusCode == 404 || responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<CancelServerActivitiesBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<CancelServerActivitiesUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
}
}

View File

@@ -13,46 +13,18 @@ namespace LukeHagar.PlexAPI.SDK
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// API Calls regarding authentication for Plex Media Server<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public interface IAuthentication
{
/// <summary>
/// Get a Transient Token
///
/// <remarks>
/// This endpoint provides the caller with a temporary token with the same access level as the caller&apos;s token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted.<br/>
///
/// </remarks>
/// </summary>
Task<GetTransientTokenResponse> GetTransientTokenAsync(GetTransientTokenQueryParamType type, Scope scope);
/// <summary>
/// Get Source Connection Information
///
/// <remarks>
/// If a caller requires connection details and a transient token for a source that is known to the server, for example a cloud media provider or shared PMS, then this endpoint can be called. This endpoint is only accessible with either an admin token or a valid transient token generated from an admin token.<br/>
/// Note: requires Plex Media Server &gt;= 1.15.4.<br/>
///
/// </remarks>
/// </summary>
Task<GetSourceConnectionInformationResponse> GetSourceConnectionInformationAsync(string source);
/// <summary>
/// Get Token Details
///
@@ -60,7 +32,7 @@ namespace LukeHagar.PlexAPI.SDK
/// Get the User data from the provided X-Plex-Token
/// </remarks>
/// </summary>
Task<GetTokenDetailsResponse> GetTokenDetailsAsync(string? serverUrl = null);
Task<GetTokenDetailsResponse> GetTokenDetailsAsync(GetTokenDetailsRequest? request = null, string? serverUrl = null);
/// <summary>
/// Get User Sign In Data
@@ -72,13 +44,6 @@ namespace LukeHagar.PlexAPI.SDK
Task<PostUsersSignInDataResponse> PostUsersSignInDataAsync(PostUsersSignInDataRequest? request = null, string? serverUrl = null);
}
/// <summary>
/// API Calls regarding authentication for Plex Media Server<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class Authentication: IAuthentication
{
/// <summary>
@@ -94,210 +59,31 @@ namespace LukeHagar.PlexAPI.SDK
"https://plex.tv/api/v2",
};
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = "csharp";
private const string _sdkVersion = "0.8.3";
private const string _sdkGenVersion = "2.426.2";
private const string _openapiDocVersion = "0.0.3";
private const string _userAgent = "speakeasy-sdk/csharp 0.8.3 2.426.2 0.0.3 LukeHagar.PlexAPI.SDK";
private string _serverUrl = "";
private ISpeakeasyHttpClient _client;
private Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? _securitySource;
public Authentication(ISpeakeasyHttpClient client, Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? securitySource, string serverUrl, SDKConfig config)
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public Authentication(SDKConfig config)
{
_client = client;
_securitySource = securitySource;
_serverUrl = serverUrl;
SDKConfiguration = config;
}
public async Task<GetTransientTokenResponse> GetTransientTokenAsync(GetTransientTokenQueryParamType type, Scope scope)
{
var request = new GetTransientTokenRequest()
{
Type = type,
Scope = scope,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/security/token", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("getTransientToken", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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 GetTransientTokenResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetTransientTokenBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetTransientTokenUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<GetSourceConnectionInformationResponse> GetSourceConnectionInformationAsync(string source)
{
var request = new GetSourceConnectionInformationRequest()
{
Source = source,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/security/resources", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("getSourceConnectionInformation", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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 GetSourceConnectionInformationResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetSourceConnectionInformationBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetSourceConnectionInformationUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<GetTokenDetailsResponse> GetTokenDetailsAsync(string? serverUrl = null)
public async Task<GetTokenDetailsResponse> GetTokenDetailsAsync(GetTokenDetailsRequest? request = null, string? serverUrl = null)
{
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 = Utilities.TemplateUrl(GetTokenDetailsServerList[0], new Dictionary<string, string>(){
});
if (serverUrl != null)
@@ -308,21 +94,22 @@ namespace LukeHagar.PlexAPI.SDK
var urlString = baseUrl + "/user";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("getTokenDetails", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "getTokenDetails", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
httpResponse = await SDKConfiguration.Client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode == 401 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
@@ -355,7 +142,17 @@ namespace LukeHagar.PlexAPI.SDK
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetTokenDetailsUserPlexAccount>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
UserPlexAccount obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<UserPlexAccount>(httpResponseBody, NullValueHandling.Include);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into UserPlexAccount.", httpResponse, httpResponseBody, ex);
}
var response = new GetTokenDetailsResponse()
{
StatusCode = responseStatusCode,
@@ -366,45 +163,75 @@ namespace LukeHagar.PlexAPI.SDK
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetTokenDetailsBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
GetTokenDetailsBadRequestPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<GetTokenDetailsBadRequestPayload>(httpResponseBody, NullValueHandling.Include);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetTokenDetailsBadRequestPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new GetTokenDetailsBadRequest(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
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 obj = ResponseBodyDeserializer.Deserialize<GetTokenDetailsUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
GetTokenDetailsUnauthorizedPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<GetTokenDetailsUnauthorizedPayload>(httpResponseBody, NullValueHandling.Include);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetTokenDetailsUnauthorizedPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new GetTokenDetailsUnauthorized(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
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", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<PostUsersSignInDataResponse> PostUsersSignInDataAsync(PostUsersSignInDataRequest? request = null, string? serverUrl = null)
{
request.ClientID ??= SDKConfiguration.ClientID;
request.ClientName ??= SDKConfiguration.ClientName;
request.ClientVersion ??= SDKConfiguration.ClientVersion;
request.ClientPlatform ??= SDKConfiguration.ClientPlatform;
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 = Utilities.TemplateUrl(PostUsersSignInDataServerList[0], new Dictionary<string, string>(){
});
@@ -412,10 +239,12 @@ namespace LukeHagar.PlexAPI.SDK
{
baseUrl = serverUrl;
}
var urlString = URLBuilder.Build(baseUrl, "/users/signin", request);
var urlString = baseUrl + "/users/signin";
var httpRequest = new HttpRequestMessage(HttpMethod.Post, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
var serializedBody = RequestBodySerializer.Serialize(request, "RequestBody", "form", false, true);
if (serializedBody != null)
@@ -423,14 +252,14 @@ namespace LukeHagar.PlexAPI.SDK
httpRequest.Content = serializedBody;
}
var hookCtx = new HookContext("post-users-sign-in-data", null, null);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "post-users-sign-in-data", null, null);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
httpResponse = await SDKConfiguration.Client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode == 401 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
@@ -463,7 +292,17 @@ namespace LukeHagar.PlexAPI.SDK
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<PostUsersSignInDataUserPlexAccount>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Include);
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
PostUsersSignInDataUserPlexAccount obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<PostUsersSignInDataUserPlexAccount>(httpResponseBody, NullValueHandling.Include);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into PostUsersSignInDataUserPlexAccount.", httpResponse, httpResponseBody, ex);
}
var response = new PostUsersSignInDataResponse()
{
StatusCode = responseStatusCode,
@@ -474,36 +313,60 @@ namespace LukeHagar.PlexAPI.SDK
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<PostUsersSignInDataBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Include);
obj!.RawResponse = httpResponse;
throw obj!;
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
PostUsersSignInDataBadRequestPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<PostUsersSignInDataBadRequestPayload>(httpResponseBody, NullValueHandling.Include);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into PostUsersSignInDataBadRequestPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new PostUsersSignInDataBadRequest(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
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 obj = ResponseBodyDeserializer.Deserialize<PostUsersSignInDataUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Include);
obj!.RawResponse = httpResponse;
throw obj!;
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
PostUsersSignInDataUnauthorizedPayload payload;
try
{
payload = ResponseBodyDeserializer.DeserializeNotNull<PostUsersSignInDataUnauthorizedPayload>(httpResponseBody, NullValueHandling.Include);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into PostUsersSignInDataUnauthorizedPayload.", httpResponse, httpResponseBody, ex);
}
payload.RawResponse = httpResponse;
throw new PostUsersSignInDataUnauthorized(payload, httpResponse, httpResponseBody);
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
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", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
}
}

View File

@@ -13,135 +13,189 @@ namespace LukeHagar.PlexAPI.SDK
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// Butler is the task manager of the Plex Media Server Ecosystem.<br/>
///
/// <remarks>
///
/// </remarks>
/// The butler is responsible for running periodic tasks. Some tasks run daily, others every few days, and some weekly. These includes database maintenance, metadata updating, thumbnail generation, media analysis, and other tasks.
/// </summary>
public interface IButler
{
/// <summary>
/// Get Butler tasks
/// Stop all Butler tasks
///
/// <remarks>
/// Returns a list of butler tasks
/// This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue.
/// </remarks>
/// </summary>
Task<GetButlerTasksResponse> GetButlerTasksAsync();
Task<StopTasksResponse> StopTasksAsync();
/// <summary>
/// Get all Butler tasks
///
/// <remarks>
/// Get the list of butler tasks and their scheduling<br/>
///
/// </remarks>
/// </summary>
Task<GetTasksResponse> GetTasksAsync();
/// <summary>
/// Start all Butler tasks
///
/// <remarks>
/// This endpoint will attempt to start all Butler tasks that are enabled in the settings. Butler tasks normally run automatically during a time window configured on the server&apos;s Settings page but can be manually started using this endpoint. Tasks will run with the following criteria:<br/>
/// 1. Any tasks not scheduled to run on the current day will be skipped.<br/>
/// 2. If a task is configured to run at a random time during the configured window and we are outside that window, the task will start immediately.<br/>
/// 3. If a task is configured to run at a random time during the configured window and we are within that window, the task will be scheduled at a random time within the window.<br/>
/// 4. If we are outside the configured window, the task will start immediately.<br/>
/// <br/>
/// 1. Any tasks not scheduled to run on the current day will be skipped.<br/>
/// 2. If a task is configured to run at a random time during the configured window and we are outside that window, the task will start immediately.<br/>
/// 3. If a task is configured to run at a random time during the configured window and we are within that window, the task will be scheduled at a random time within the window.<br/>
/// 4. If we are outside the configured window, the task will start immediately.<br/>
///
/// </remarks>
/// </summary>
Task<StartAllTasksResponse> StartAllTasksAsync();
/// <summary>
/// Stop all Butler tasks
///
/// <remarks>
/// This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue.<br/>
///
/// </remarks>
/// </summary>
Task<StopAllTasksResponse> StopAllTasksAsync();
/// <summary>
/// Start a single Butler task
///
/// <remarks>
/// This endpoint will attempt to start a single Butler task that is enabled in the settings. Butler tasks normally run automatically during a time window configured on the server&apos;s Settings page but can be manually started using this endpoint. Tasks will run with the following criteria:<br/>
/// 1. Any tasks not scheduled to run on the current day will be skipped.<br/>
/// 2. If a task is configured to run at a random time during the configured window and we are outside that window, the task will start immediately.<br/>
/// 3. If a task is configured to run at a random time during the configured window and we are within that window, the task will be scheduled at a random time within the window.<br/>
/// 4. If we are outside the configured window, the task will start immediately.<br/>
///
/// </remarks>
/// </summary>
Task<StartTaskResponse> StartTaskAsync(TaskName taskName);
Task<StartTasksResponse> StartTasksAsync();
/// <summary>
/// Stop a single Butler task
///
/// <remarks>
/// This endpoint will stop a currently running task by name, or remove it from the list of scheduled tasks if it exists. See the section above for a list of task names for this endpoint.<br/>
/// This endpoint will stop a currently running task by name, or remove it from the list of scheduled tasks if it exists<br/>
///
/// </remarks>
/// </summary>
Task<StopTaskResponse> StopTaskAsync(PathParamTaskName taskName);
Task<StopTaskResponse> StopTaskAsync(StopTaskRequest request);
/// <summary>
/// Start a single Butler task
///
/// <remarks>
/// This endpoint will attempt to start a specific Butler task by name.<br/>
///
/// </remarks>
/// </summary>
Task<StartTaskResponse> StartTaskAsync(StartTaskRequest request);
}
/// <summary>
/// Butler is the task manager of the Plex Media Server Ecosystem.<br/>
///
/// <remarks>
///
/// </remarks>
/// The butler is responsible for running periodic tasks. Some tasks run daily, others every few days, and some weekly. These includes database maintenance, metadata updating, thumbnail generation, media analysis, and other tasks.
/// </summary>
public class Butler: IButler
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = "csharp";
private const string _sdkVersion = "0.8.3";
private const string _sdkGenVersion = "2.426.2";
private const string _openapiDocVersion = "0.0.3";
private const string _userAgent = "speakeasy-sdk/csharp 0.8.3 2.426.2 0.0.3 LukeHagar.PlexAPI.SDK";
private string _serverUrl = "";
private ISpeakeasyHttpClient _client;
private Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? _securitySource;
public Butler(ISpeakeasyHttpClient client, Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? securitySource, string serverUrl, SDKConfig config)
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public Butler(SDKConfig config)
{
_client = client;
_securitySource = securitySource;
_serverUrl = serverUrl;
SDKConfiguration = config;
}
public async Task<GetButlerTasksResponse> GetButlerTasksAsync()
public async Task<StopTasksResponse> StopTasksAsync()
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = baseUrl + "/butler";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
var httpRequest = new HttpRequestMessage(HttpMethod.Delete, urlString);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("getButlerTasks", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "stopTasks", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
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 < 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 StopTasksResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
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<GetTasksResponse> GetTasksAsync()
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = baseUrl + "/butler";
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, "getTasks", 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 < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -171,8 +225,18 @@ namespace LukeHagar.PlexAPI.SDK
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetButlerTasksResponseBody>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
var response = new GetButlerTasksResponse()
var httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
GetTasksResponseBody obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<GetTasksResponseBody>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetTasksResponseBody.", httpResponse, httpResponseBody, ex);
}
var response = new GetTasksResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
@@ -182,63 +246,45 @@ namespace LukeHagar.PlexAPI.SDK
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 400)
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetButlerTasksBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetButlerTasksUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<StartAllTasksResponse> StartAllTasksAsync()
public async Task<StartTasksResponse> StartTasksAsync()
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = baseUrl + "/butler";
var httpRequest = new HttpRequestMessage(HttpMethod.Post, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("startAllTasks", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "startTasks", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
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 < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -265,69 +311,67 @@ namespace LukeHagar.PlexAPI.SDK
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
return new StartAllTasksResponse()
{
return new StartTasksResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StartAllTasksBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StartAllTasksUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<StopAllTasksResponse> StopAllTasksAsync()
public async Task<StopTaskResponse> StopTaskAsync(StopTaskRequest request)
{
if (request == null)
{
request = new StopTaskRequest();
}
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 = baseUrl + "/butler";
var urlString = URLBuilder.Build(baseUrl, "/butler/{butlerTask}", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Delete, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("stopAllTasks", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "stopTask", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
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 == 404 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -354,72 +398,67 @@ namespace LukeHagar.PlexAPI.SDK
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
return new StopAllTasksResponse()
{
return new StopTaskResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
else if(responseStatusCode == 404 || responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StopAllTasksBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StopAllTasksUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<StartTaskResponse> StartTaskAsync(TaskName taskName)
public async Task<StartTaskResponse> StartTaskAsync(StartTaskRequest request)
{
var request = new StartTaskRequest()
if (request == null)
{
TaskName = taskName,
};
request = new StartTaskRequest();
}
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, "/butler/{taskName}", request);
var urlString = URLBuilder.Build(baseUrl, "/butler/{butlerTask}", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("startTask", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "startTask", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
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 == 404 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -446,7 +485,7 @@ namespace LukeHagar.PlexAPI.SDK
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(new List<int>{200, 202}.Contains(responseStatusCode))
{
{
return new StartTaskResponse()
{
StatusCode = responseStatusCode,
@@ -454,126 +493,16 @@ namespace LukeHagar.PlexAPI.SDK
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
else if(responseStatusCode == 404 || responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StartTaskBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StartTaskUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<StopTaskResponse> StopTaskAsync(PathParamTaskName taskName)
{
var request = new StopTaskRequest()
{
TaskName = taskName,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/butler/{taskName}", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Delete, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("stopTask", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode == 401 || _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)
{
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 StopTaskResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StopTaskBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<StopTaskUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 404 || responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
}
}

View File

@@ -0,0 +1,163 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK
{
using LukeHagar.PlexAPI.SDK.Hooks;
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// API Operations against the Collections
/// </summary>
public interface ICollections
{
/// <summary>
/// Create collection
///
/// <remarks>
/// Create a collection in the library
/// </remarks>
/// </summary>
Task<CreateCollectionResponse> CreateCollectionAsync(CreateCollectionRequest request);
}
/// <summary>
/// API Operations against the Collections
/// </summary>
public class Collections: ICollections
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public Collections(SDKConfig config)
{
SDKConfiguration = config;
}
public async Task<CreateCollectionResponse> CreateCollectionAsync(CreateCollectionRequest request)
{
if (request == null)
{
request = new CreateCollectionRequest();
}
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, "/library/collections", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, 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, "createCollection", 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();
MediaContainerWithMetadata obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<MediaContainerWithMetadata>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into MediaContainerWithMetadata.", httpResponse, httpResponseBody, ex);
}
var response = new CreateCollectionResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.MediaContainerWithMetadata = obj;
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 400 || 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());
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1033
LukeHagar/PlexAPI/SDK/Epg.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,258 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK
{
using LukeHagar.PlexAPI.SDK.Hooks;
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// The server can notify clients in real-time of a wide range of events, from library scanning, to preferences being modified, to changes to media, and many other things. This is also the mechanism by which activity progress is reported.<br/>
///
/// <remarks>
/// <br/>
/// Two protocols for receiving the events are available: EventSource (also known as SSE), and WebSocket.<br/>
///
/// </remarks>
/// </summary>
public interface IEvents
{
/// <summary>
/// Connect to Eventsource
///
/// <remarks>
/// Connect to the event source to get a stream of events
/// </remarks>
/// </summary>
Task<GetNotificationsResponse> GetNotificationsAsync(GetNotificationsRequest? request = null);
/// <summary>
/// Connect to WebSocket
///
/// <remarks>
/// Connect to the web socket to get a stream of events
/// </remarks>
/// </summary>
Task<ConnectWebSocketResponse> ConnectWebSocketAsync(ConnectWebSocketRequest? request = null);
}
/// <summary>
/// The server can notify clients in real-time of a wide range of events, from library scanning, to preferences being modified, to changes to media, and many other things. This is also the mechanism by which activity progress is reported.<br/>
///
/// <remarks>
/// <br/>
/// Two protocols for receiving the events are available: EventSource (also known as SSE), and WebSocket.<br/>
///
/// </remarks>
/// </summary>
public class Events: IEvents
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public Events(SDKConfig config)
{
SDKConfiguration = config;
}
public async Task<GetNotificationsResponse> GetNotificationsAsync(GetNotificationsRequest? request = null)
{
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, "/:/eventsource/notifications", request, null);
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, "getNotifications", 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 < 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/octet-stream", contentType))
{
var response = new GetNotificationsResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.Bytes = await httpResponse.Content.ReadAsByteArrayAsync();
return response;
}
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<ConnectWebSocketResponse> ConnectWebSocketAsync(ConnectWebSocketRequest? request = null)
{
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, "/:/websocket/notifications", request, null);
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, "connectWebSocket", 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 < 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/octet-stream", contentType))
{
var response = new ConnectWebSocketResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.Bytes = await httpResponse.Content.ReadAsByteArrayAsync();
return response;
}
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());
}
}
}

View File

@@ -0,0 +1,482 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK
{
using LukeHagar.PlexAPI.SDK.Hooks;
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// General endpoints for basic PMS operation not specific to any media provider
/// </summary>
public interface IGeneral
{
/// <summary>
/// Get PMS info
///
/// <remarks>
/// Information about this PMS setup and configuration
/// </remarks>
/// </summary>
Task<GetServerInfoResponse> GetServerInfoAsync(GetServerInfoRequest? request = null);
/// <summary>
/// Get PMS identity
///
/// <remarks>
/// Get details about this PMS&apos;s identity
/// </remarks>
/// </summary>
Task<GetIdentityResponse> GetIdentityAsync();
/// <summary>
/// Get Source Connection Information
///
/// <remarks>
/// If a caller requires connection details and a transient token for a source that is known to the server, for example a cloud media provider or shared PMS, then this endpoint can be called. This endpoint is only accessible with either an admin token or a valid transient token generated from an admin token.
/// </remarks>
/// </summary>
Task<GetSourceConnectionInformationResponse> GetSourceConnectionInformationAsync(GetSourceConnectionInformationRequest request);
/// <summary>
/// Get Transient Tokens
///
/// <remarks>
/// This endpoint provides the caller with a temporary token with the same access level as the caller&apos;s token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted.<br/>
/// Note: This endpoint responds to all HTTP verbs but POST in preferred
/// </remarks>
/// </summary>
Task<GetTransientTokenResponse> GetTransientTokenAsync(GetTransientTokenRequest request);
}
/// <summary>
/// General endpoints for basic PMS operation not specific to any media provider
/// </summary>
public class General: IGeneral
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public General(SDKConfig config)
{
SDKConfiguration = config;
}
public async Task<GetServerInfoResponse> GetServerInfoAsync(GetServerInfoRequest? request = null)
{
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 = baseUrl + "/";
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, "getServerInfo", 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 < 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();
MediaContainerWithDirectory obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<MediaContainerWithDirectory>(httpResponseBody, NullValueHandling.Include);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into MediaContainerWithDirectory.", httpResponse, httpResponseBody, ex);
}
var response = new GetServerInfoResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.MediaContainerWithDirectory = obj;
return response;
}
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<GetIdentityResponse> GetIdentityAsync()
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = baseUrl + "/identity";
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "getIdentity", null, null);
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 < 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();
GetIdentityResponseBody obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<GetIdentityResponseBody>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetIdentityResponseBody.", httpResponse, httpResponseBody, ex);
}
var response = new GetIdentityResponse()
{
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 >= 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<GetSourceConnectionInformationResponse> GetSourceConnectionInformationAsync(GetSourceConnectionInformationRequest request)
{
if (request == null)
{
request = new GetSourceConnectionInformationRequest();
}
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, "/security/resources", request, null);
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, "getSourceConnectionInformation", 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 == 403 || _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();
GetSourceConnectionInformationResponseBody obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<GetSourceConnectionInformationResponseBody>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetSourceConnectionInformationResponseBody.", httpResponse, httpResponseBody, ex);
}
var response = new GetSourceConnectionInformationResponse()
{
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 == 400 || responseStatusCode == 403 || 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<GetTransientTokenResponse> GetTransientTokenAsync(GetTransientTokenRequest request)
{
if (request == null)
{
request = new GetTransientTokenRequest();
}
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, "/security/token", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, 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, "getTransientToken", 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 == 403 || _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();
GetTransientTokenResponseBody obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<GetTransientTokenResponseBody>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into GetTransientTokenResponseBody.", httpResponse, httpResponseBody, ex);
}
var response = new GetTransientTokenResponse()
{
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 == 400 || responseStatusCode == 403 || 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());
}
}
}

View File

@@ -17,34 +17,47 @@ namespace LukeHagar.PlexAPI.SDK.Hooks
public class HookContext
{
public SDKConfig SDKConfiguration { get; set; }
public string BaseURL { get; set; } = "";
public string OperationID { get; set; }
public List<string>? Oauth2Scopes { get; set; }
public Func<object>? SecuritySource { get; set; }
public HookContext(string operationID, List<string>? oauth2Scopes, Func<object>? securitySource)
public HookContext(SDKConfig config, string baseURL, string operationID, List<string>? oauth2Scopes, Func<object>? securitySource)
{
SDKConfiguration = config;
BaseURL = baseURL;
OperationID = operationID;
Oauth2Scopes = oauth2Scopes;
SecuritySource = securitySource;
}
public HookContext(HookContext hookCtx)
{
SDKConfiguration = hookCtx.SDKConfiguration;
BaseURL = hookCtx.BaseURL;
OperationID = hookCtx.OperationID;
Oauth2Scopes = hookCtx.Oauth2Scopes;
SecuritySource = hookCtx.SecuritySource;
}
}
public class BeforeRequestContext : HookContext
{
public BeforeRequestContext(HookContext hookCtx)
: base(hookCtx.OperationID, hookCtx.Oauth2Scopes, hookCtx.SecuritySource) { }
: base(hookCtx) { }
}
public class AfterSuccessContext : HookContext
{
public AfterSuccessContext(HookContext hookCtx)
: base(hookCtx.OperationID, hookCtx.Oauth2Scopes, hookCtx.SecuritySource) { }
: base(hookCtx) { }
}
public class AfterErrorContext : HookContext
{
public AfterErrorContext(HookContext hookCtx)
: base(hookCtx.OperationID, hookCtx.Oauth2Scopes, hookCtx.SecuritySource) { }
: base(hookCtx) { }
}
/// <summary>

View File

@@ -52,7 +52,7 @@ namespace LukeHagar.PlexAPI.SDK.Hooks
{
this.afterErrorHooks.Add(hook);
}
public (string, ISpeakeasyHttpClient) SDKInit(string baseUrl, ISpeakeasyHttpClient client)
{
var urlAndClient = (baseUrl, client);
@@ -68,7 +68,7 @@ namespace LukeHagar.PlexAPI.SDK.Hooks
}
return urlAndClient;
}
public async Task<HttpRequestMessage> BeforeRequestAsync(BeforeRequestContext hookCtx, HttpRequestMessage request)
{
foreach (var hook in this.beforeRequestHooks)
@@ -76,7 +76,8 @@ namespace LukeHagar.PlexAPI.SDK.Hooks
try
{
request = await hook.BeforeRequestAsync(hookCtx, request);
} catch (Exception ex)
}
catch (Exception ex)
{
throw new Exception("An error occurred while calling BeforeRequestAsync hook", ex);
}
@@ -102,17 +103,18 @@ namespace LukeHagar.PlexAPI.SDK.Hooks
public async Task<HttpResponseMessage?> AfterErrorAsync(AfterErrorContext hookCtx, HttpResponseMessage? response, Exception? error)
{
(HttpResponseMessage?, Exception?) responseAndError = (response, error);
foreach (var hook in this.afterErrorHooks)
{
try
{
responseAndError = await hook.AfterErrorAsync(hookCtx, responseAndError.Item1, responseAndError.Item2);
} catch (FailEarlyException)
}
catch (FailEarlyException)
{
throw;
} catch (Exception ex)
}
catch (Exception ex)
{
throw new Exception("An error occurred while calling AfterErrorAsync hook", ex);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,391 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK
{
using LukeHagar.PlexAPI.SDK.Hooks;
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// Endpoints for manipulating collections. In addition to these endpoints, `/library/collections/:collectionId/X` will be rerouted to `/library/metadata/:collectionId/X` and respond to those endpoints as well.
/// </summary>
public interface ILibraryCollections
{
/// <summary>
/// Add items to a collection
///
/// <remarks>
/// Add items to a collection by uri
/// </remarks>
/// </summary>
Task<AddCollectionItemsResponse> AddCollectionItemsAsync(AddCollectionItemsRequest request);
/// <summary>
/// Delete an item from a collection
///
/// <remarks>
/// Delete an item from a collection
/// </remarks>
/// </summary>
Task<DeleteCollectionItemResponse> DeleteCollectionItemAsync(DeleteCollectionItemRequest request);
/// <summary>
/// Reorder an item in the collection
///
/// <remarks>
/// Reorder items in a collection with one item after another
/// </remarks>
/// </summary>
Task<MoveCollectionItemResponse> MoveCollectionItemAsync(MoveCollectionItemRequest request);
}
/// <summary>
/// Endpoints for manipulating collections. In addition to these endpoints, `/library/collections/:collectionId/X` will be rerouted to `/library/metadata/:collectionId/X` and respond to those endpoints as well.
/// </summary>
public class LibraryCollections: ILibraryCollections
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public LibraryCollections(SDKConfig config)
{
SDKConfiguration = config;
}
public async Task<AddCollectionItemsResponse> AddCollectionItemsAsync(AddCollectionItemsRequest request)
{
if (request == null)
{
request = new AddCollectionItemsRequest();
}
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, "/library/collections/{collectionId}/items", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Put, 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, "addCollectionItems", 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 == 404 || _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();
MediaContainerWithMetadata obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<MediaContainerWithMetadata>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into MediaContainerWithMetadata.", httpResponse, httpResponseBody, ex);
}
var response = new AddCollectionItemsResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.MediaContainerWithMetadata = obj;
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(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<DeleteCollectionItemResponse> DeleteCollectionItemAsync(DeleteCollectionItemRequest request)
{
if (request == null)
{
request = new DeleteCollectionItemRequest();
}
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, "/library/collections/{collectionId}/items/{itemId}", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Put, 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, "deleteCollectionItem", 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 == 404 || _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();
MediaContainerWithMetadata obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<MediaContainerWithMetadata>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into MediaContainerWithMetadata.", httpResponse, httpResponseBody, ex);
}
var response = new DeleteCollectionItemResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.MediaContainerWithMetadata = obj;
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
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<MoveCollectionItemResponse> MoveCollectionItemAsync(MoveCollectionItemRequest request)
{
if (request == null)
{
request = new MoveCollectionItemRequest();
}
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, "/library/collections/{collectionId}/items/{itemId}/move", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Put, 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, "moveCollectionItem", 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 == 404 || _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();
MediaContainerWithMetadata obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<MediaContainerWithMetadata>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into MediaContainerWithMetadata.", httpResponse, httpResponseBody, ex);
}
var response = new MoveCollectionItemResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.MediaContainerWithMetadata = obj;
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
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());
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,461 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK
{
using LukeHagar.PlexAPI.SDK.Hooks;
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// LiveTV contains the playback sessions of a channel from a DVR device<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public interface ILiveTV
{
/// <summary>
/// Get all sessions
///
/// <remarks>
/// Get all livetv sessions and metadata
/// </remarks>
/// </summary>
Task<GetSessionsResponse> GetSessionsAsync();
/// <summary>
/// Get a single session
///
/// <remarks>
/// Get a single livetv session and metadata
/// </remarks>
/// </summary>
Task<GetLiveTVSessionResponse> GetLiveTVSessionAsync(GetLiveTVSessionRequest request);
/// <summary>
/// Get a session playlist index
///
/// <remarks>
/// Get a playlist index for playing this session
/// </remarks>
/// </summary>
Task<GetSessionPlaylistIndexResponse> GetSessionPlaylistIndexAsync(GetSessionPlaylistIndexRequest request);
/// <summary>
/// Get a single session segment
///
/// <remarks>
/// Get a single LiveTV session segment
/// </remarks>
/// </summary>
Task<GetSessionSegmentResponse> GetSessionSegmentAsync(GetSessionSegmentRequest request);
}
/// <summary>
/// LiveTV contains the playback sessions of a channel from a DVR device<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class LiveTV: ILiveTV
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public LiveTV(SDKConfig config)
{
SDKConfiguration = config;
}
public async Task<GetSessionsResponse> GetSessionsAsync()
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = baseUrl + "/livetv/sessions";
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, "getSessions", 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 < 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();
MediaContainerWithMetadata obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<MediaContainerWithMetadata>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into MediaContainerWithMetadata.", httpResponse, httpResponseBody, ex);
}
var response = new GetSessionsResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.MediaContainerWithMetadata = obj;
return response;
}
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<GetLiveTVSessionResponse> GetLiveTVSessionAsync(GetLiveTVSessionRequest request)
{
if (request == null)
{
request = new GetLiveTVSessionRequest();
}
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, "/livetv/sessions/{sessionId}", request, null);
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, "getLiveTVSession", 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 < 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();
MediaContainerWithMetadata obj;
try
{
obj = ResponseBodyDeserializer.DeserializeNotNull<MediaContainerWithMetadata>(httpResponseBody, NullValueHandling.Ignore);
}
catch (Exception ex)
{
throw new ResponseValidationException("Failed to deserialize response body into MediaContainerWithMetadata.", httpResponse, httpResponseBody, ex);
}
var response = new GetLiveTVSessionResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.MediaContainerWithMetadata = obj;
return response;
}
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<GetSessionPlaylistIndexResponse> GetSessionPlaylistIndexAsync(GetSessionPlaylistIndexRequest request)
{
if (request == null)
{
request = new GetSessionPlaylistIndexRequest();
}
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, "/livetv/sessions/{sessionId}/{consumerId}/index.m3u8", request, null);
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, "getSessionPlaylistIndex", 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 == 404 || _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 GetSessionPlaylistIndexResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(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<GetSessionSegmentResponse> GetSessionSegmentAsync(GetSessionSegmentRequest request)
{
if (request == null)
{
request = new GetSessionSegmentRequest();
}
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, "/livetv/sessions/{sessionId}/{consumerId}/{segmentId}", request, null);
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, "getSessionSegment", 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 == 404 || _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 GetSessionSegmentResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(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());
}
}
}

View File

@@ -13,228 +13,103 @@ namespace LukeHagar.PlexAPI.SDK
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Threading.Tasks;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
/// <summary>
/// Submit logs to the Log Handler for Plex Media Server<br/>
///
/// <remarks>
///
/// </remarks>
/// Logging mechanism to allow clients to log to the server
/// </summary>
public interface ILog
{
/// <summary>
/// Logging a single line message.
/// Logging a multi-line message to the Plex Media Server log
///
/// <remarks>
/// This endpoint will write multiple lines to the main Plex Media Server log in a single request. It takes a set of query strings as would normally sent to the above PUT endpoint as a linefeed-separated block of POST data. The parameters for each query string match as above.<br/>
///
/// </remarks>
/// </summary>
Task<WriteLogResponse> WriteLogAsync(byte[] request);
/// <summary>
/// Logging a single-line message to the Plex Media Server log
///
/// <remarks>
/// This endpoint will write a single-line log message, including a level and source to the main Plex Media Server log.<br/>
/// <br/>
/// Note: This endpoint responds to all HTTP verbs **except POST** but PUT is preferred<br/>
///
/// </remarks>
/// </summary>
Task<LogLineResponse> LogLineAsync(Level level, string message, string source);
/// <summary>
/// Logging a multi-line message
///
/// <remarks>
/// This endpoint allows for the batch addition of log entries to the main Plex Media Server log. <br/>
/// It accepts a text/plain request body, where each line represents a distinct log entry. <br/>
/// Each log entry consists of URL-encoded key-value pairs, specifying log attributes such as &apos;level&apos;, &apos;message&apos;, and &apos;source&apos;. <br/>
/// <br/>
/// Log entries are separated by a newline character (`\n`). <br/>
/// Each entry&apos;s parameters should be URL-encoded to ensure accurate parsing and handling of special characters. <br/>
/// This method is efficient for logging multiple entries in a single API call, reducing the overhead of multiple individual requests. <br/>
/// <br/>
/// The &apos;level&apos; parameter specifies the log entry&apos;s severity or importance, with the following integer values:<br/>
/// - `0`: Error - Critical issues that require immediate attention.<br/>
/// - `1`: Warning - Important events that are not critical but may indicate potential issues.<br/>
/// - `2`: Info - General informational messages about system operation.<br/>
/// - `3`: Debug - Detailed information useful for debugging purposes.<br/>
/// - `4`: Verbose - Highly detailed diagnostic information for in-depth analysis.<br/>
/// <br/>
/// The &apos;message&apos; parameter contains the log text, and &apos;source&apos; identifies the log message&apos;s origin (e.g., an application name or module).<br/>
/// <br/>
/// Example of a single log entry format:<br/>
/// `level=4&amp;message=Sample%20log%20entry&amp;source=applicationName`<br/>
/// <br/>
/// Ensure each parameter is properly URL-encoded to avoid interpretation issues.<br/>
///
/// </remarks>
/// </summary>
Task<LogMultiLineResponse> LogMultiLineAsync(string request);
Task<WriteMessageResponse> WriteMessageAsync(WriteMessageRequest? request = null);
/// <summary>
/// Enabling Papertrail
///
/// <remarks>
/// This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time.<br/>
/// This endpoint will enable all Plex Media Server logs to be sent to the Papertrail networked logging site for a period of time<br/>
/// <br/>
/// Note: This endpoint responds to all HTTP verbs but POST is preferred<br/>
///
/// </remarks>
/// </summary>
Task<EnablePaperTrailResponse> EnablePaperTrailAsync();
Task<EnablePapertrailResponse> EnablePapertrailAsync(EnablePapertrailRequest? request = null);
}
/// <summary>
/// Submit logs to the Log Handler for Plex Media Server<br/>
///
/// <remarks>
///
/// </remarks>
/// Logging mechanism to allow clients to log to the server
/// </summary>
public class Log: ILog
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = "csharp";
private const string _sdkVersion = "0.8.3";
private const string _sdkGenVersion = "2.426.2";
private const string _openapiDocVersion = "0.0.3";
private const string _userAgent = "speakeasy-sdk/csharp 0.8.3 2.426.2 0.0.3 LukeHagar.PlexAPI.SDK";
private string _serverUrl = "";
private ISpeakeasyHttpClient _client;
private Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? _securitySource;
public Log(ISpeakeasyHttpClient client, Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? securitySource, string serverUrl, SDKConfig config)
private const string _language = Constants.Language;
private const string _sdkVersion = Constants.SdkVersion;
private const string _sdkGenVersion = Constants.SdkGenVersion;
private const string _openapiDocVersion = Constants.OpenApiDocVersion;
public Log(SDKConfig config)
{
_client = client;
_securitySource = securitySource;
_serverUrl = serverUrl;
SDKConfiguration = config;
}
public async Task<LogLineResponse> LogLineAsync(Level level, string message, string source)
{
var request = new LogLineRequest()
{
Level = level,
Message = message,
Source = source,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/log", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("logLine", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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 LogLineResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<LogLineBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<LogLineUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<LogMultiLineResponse> LogMultiLineAsync(string request)
public async Task<WriteLogResponse> WriteLogAsync(byte[] request)
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = baseUrl + "/log";
var httpRequest = new HttpRequestMessage(HttpMethod.Post, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
var serializedBody = RequestBodySerializer.Serialize(request, "Request", "string", false, false);
var serializedBody = RequestBodySerializer.Serialize(request, "Request", "raw", false, false);
if (serializedBody != null)
{
httpRequest.Content = serializedBody;
}
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("logMultiLine", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "writeLog", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
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 >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -261,69 +136,63 @@ namespace LukeHagar.PlexAPI.SDK
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
return new LogMultiLineResponse()
{
return new WriteLogResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
else if(responseStatusCode == 400 || responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<LogMultiLineBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
else if(responseStatusCode == 401)
else if(responseStatusCode >= 500 && responseStatusCode < 600)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<LogMultiLineUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("API error occurred", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
public async Task<EnablePaperTrailResponse> EnablePaperTrailAsync()
public async Task<WriteMessageResponse> WriteMessageAsync(WriteMessageRequest? request = null)
{
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, "/log", request, null);
var urlString = baseUrl + "/log/networked";
var httpRequest = new HttpRequestMessage(HttpMethod.Put, urlString);
httpRequest.Headers.Add("user-agent", SDKConfiguration.UserAgent);
HeaderSerializer.PopulateHeaders(ref httpRequest, request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
if (SDKConfiguration.SecuritySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
httpRequest = new SecurityMetadata(SDKConfiguration.SecuritySource).Apply(httpRequest);
}
var hookCtx = new HookContext("enablePaperTrail", null, _securitySource);
var hookCtx = new HookContext(SDKConfiguration, baseUrl, "writeMessage", null, SDKConfiguration.SecuritySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _client.SendAsync(httpRequest);
httpResponse = await SDKConfiguration.Client.SendAsync(httpRequest);
int _statusCode = (int)httpResponse.StatusCode;
if (_statusCode == 400 || _statusCode == 401 || _statusCode == 403 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
if (_statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
@@ -350,42 +219,107 @@ namespace LukeHagar.PlexAPI.SDK
var contentType = httpResponse.Content.Headers.ContentType?.MediaType;
int responseStatusCode = (int)httpResponse.StatusCode;
if(responseStatusCode == 200)
{
return new EnablePaperTrailResponse()
{
return new WriteMessageResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
else if(responseStatusCode >= 400 && responseStatusCode < 500)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
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<EnablePapertrailResponse> EnablePapertrailAsync(EnablePapertrailRequest? request = null)
{
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, "/log/networked", request, null);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, 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, "enablePapertrail", 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 == 403 || _statusCode >= 400 && _statusCode < 500 || _statusCode >= 500 && _statusCode < 600)
{
var obj = ResponseBodyDeserializer.Deserialize<EnablePaperTrailBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), httpResponse, null);
if (_httpResponse != null)
{
httpResponse = _httpResponse;
}
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
catch (Exception error)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
var _httpResponse = await this.SDKConfiguration.Hooks.AfterErrorAsync(new AfterErrorContext(hookCtx), null, error);
if (_httpResponse != null)
{
var obj = ResponseBodyDeserializer.Deserialize<EnablePaperTrailUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
httpResponse = _httpResponse;
}
else
{
throw;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 403 || responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
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)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
return new EnablePapertrailResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 403 || 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", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
throw new Models.Errors.SDKException("Unknown status code received", httpResponse, await httpResponse.Content.ReadAsStringAsync());
}
}
}

View File

@@ -3,38 +3,13 @@
<PropertyGroup>
<IsPackable>true</IsPackable>
<PackageId>LukeHagar.PlexAPI.SDK</PackageId>
<Version>0.8.3</Version>
<Version>0.20.0</Version>
<TargetFramework>net8.0</TargetFramework>
<Authors>LukeHagar</Authors>
<Copyright>Copyright (c) LukeHagar 2024</Copyright>
<Copyright>Copyright (c) LukeHagar 2025</Copyright>
<RepositoryUrl>https://github.com/LukeHagar/plexcsharp.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>Plex Media Server SDK</PackageTags>
<Description># Plex Media Server OpenAPI Specification
An Open Source OpenAPI Specification for Plex Media Server
Automation and SDKs provided by [Speakeasy](https://speakeasyapi.dev/)
## Documentation
[API Documentation](https://plexapi.dev)
## SDKs
The following SDKs are generated from the OpenAPI Specification. They are automatically generated and may not be fully tested. If you find any issues, please open an issue on the [main specification Repository](https://github.com/LukeHagar/plex-api-spec).
| Language | Repository | Releases | Other |
| --------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------- |
| Python | [GitHub](https://github.com/LukeHagar/plexpy) | [PyPI](https://pypi.org/project/plex-api-client/) | - |
| JavaScript/TypeScript | [GitHub](https://github.com/LukeHagar/plexjs) | [NPM](https://www.npmjs.com/package/@lukehagar/plexjs) \ [JSR](https://jsr.io/@lukehagar/plexjs) | - |
| Go | [GitHub](https://github.com/LukeHagar/plexgo) | [Releases](https://github.com/LukeHagar/plexgo/releases) | [GoDoc](https://pkg.go.dev/github.com/LukeHagar/plexgo) |
| Ruby | [GitHub](https://github.com/LukeHagar/plexruby) | [Releases](https://github.com/LukeHagar/plexruby/releases) | - |
| Swift | [GitHub](https://github.com/LukeHagar/plexswift) | [Releases](https://github.com/LukeHagar/plexswift/releases) | - |
| PHP | [GitHub](https://github.com/LukeHagar/plexphp) | [Releases](https://github.com/LukeHagar/plexphp/releases) | - |
| Java | [GitHub](https://github.com/LukeHagar/plexjava) | [Releases](https://github.com/LukeHagar/plexjava/releases) | - |
| C# | [GitHub](https://github.com/LukeHagar/plexcsharp) | [Releases](https://github.com/LukeHagar/plexcsharp/releases) | -
</Description>
</PropertyGroup>
<PropertyGroup>

View File

@@ -1,577 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK
{
using LukeHagar.PlexAPI.SDK.Hooks;
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Models.Errors;
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Utils.Retries;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Threading.Tasks;
using System;
/// <summary>
/// API Calls interacting with Plex Media Server Media<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public interface IMedia
{
/// <summary>
/// Mark Media Played
///
/// <remarks>
/// This will mark the provided media key as Played.
/// </remarks>
/// </summary>
Task<MarkPlayedResponse> MarkPlayedAsync(double key);
/// <summary>
/// Mark Media Unplayed
///
/// <remarks>
/// This will mark the provided media key as Unplayed.
/// </remarks>
/// </summary>
Task<MarkUnplayedResponse> MarkUnplayedAsync(double key);
/// <summary>
/// Update Media Play Progress
///
/// <remarks>
/// This API command can be used to update the play progress of a media item.<br/>
///
/// </remarks>
/// </summary>
Task<UpdatePlayProgressResponse> UpdatePlayProgressAsync(string key, double time, string state);
/// <summary>
/// Get Banner Image
///
/// <remarks>
/// Gets the banner image of the media item
/// </remarks>
/// </summary>
Task<GetBannerImageResponse> GetBannerImageAsync(GetBannerImageRequest request);
/// <summary>
/// Get Thumb Image
///
/// <remarks>
/// Gets the thumbnail image of the media item
/// </remarks>
/// </summary>
Task<GetThumbImageResponse> GetThumbImageAsync(GetThumbImageRequest request);
}
/// <summary>
/// API Calls interacting with Plex Media Server Media<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class Media: IMedia
{
public SDKConfig SDKConfiguration { get; private set; }
private const string _language = "csharp";
private const string _sdkVersion = "0.8.3";
private const string _sdkGenVersion = "2.426.2";
private const string _openapiDocVersion = "0.0.3";
private const string _userAgent = "speakeasy-sdk/csharp 0.8.3 2.426.2 0.0.3 LukeHagar.PlexAPI.SDK";
private string _serverUrl = "";
private ISpeakeasyHttpClient _client;
private Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? _securitySource;
public Media(ISpeakeasyHttpClient client, Func<LukeHagar.PlexAPI.SDK.Models.Components.Security>? securitySource, string serverUrl, SDKConfig config)
{
_client = client;
_securitySource = securitySource;
_serverUrl = serverUrl;
SDKConfiguration = config;
}
public async Task<MarkPlayedResponse> MarkPlayedAsync(double key)
{
var request = new MarkPlayedRequest()
{
Key = key,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/:/scrobble", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("markPlayed", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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 MarkPlayedResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<MarkPlayedBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<MarkPlayedUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<MarkUnplayedResponse> MarkUnplayedAsync(double key)
{
var request = new MarkUnplayedRequest()
{
Key = key,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/:/unscrobble", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("markUnplayed", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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 MarkUnplayedResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<MarkUnplayedBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<MarkUnplayedUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<UpdatePlayProgressResponse> UpdatePlayProgressAsync(string key, double time, string state)
{
var request = new UpdatePlayProgressRequest()
{
Key = key,
Time = time,
State = state,
};
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/:/progress", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("updatePlayProgress", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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 UpdatePlayProgressResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<UpdatePlayProgressBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<UpdatePlayProgressUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<GetBannerImageResponse> GetBannerImageAsync(GetBannerImageRequest request)
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/library/metadata/{ratingKey}/banner", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("get-banner-image", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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)
{
if(Utilities.IsContentTypeMatch("image/jpeg", contentType))
{
var response = new GetBannerImageResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.Bytes = await httpResponse.Content.ReadAsByteArrayAsync();
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetBannerImageBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetBannerImageUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
public async Task<GetThumbImageResponse> GetThumbImageAsync(GetThumbImageRequest request)
{
string baseUrl = this.SDKConfiguration.GetTemplatedServerUrl();
var urlString = URLBuilder.Build(baseUrl, "/library/metadata/{ratingKey}/thumb", request);
var httpRequest = new HttpRequestMessage(HttpMethod.Get, urlString);
httpRequest.Headers.Add("user-agent", _userAgent);
if (_securitySource != null)
{
httpRequest = new SecurityMetadata(_securitySource).Apply(httpRequest);
}
var hookCtx = new HookContext("get-thumb-image", null, _securitySource);
httpRequest = await this.SDKConfiguration.Hooks.BeforeRequestAsync(new BeforeRequestContext(hookCtx), httpRequest);
HttpResponseMessage httpResponse;
try
{
httpResponse = await _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)
{
if(Utilities.IsContentTypeMatch("image/jpeg", contentType))
{
var response = new GetThumbImageResponse()
{
StatusCode = responseStatusCode,
ContentType = contentType,
RawResponse = httpResponse
};
response.Bytes = await httpResponse.Content.ReadAsByteArrayAsync();
return response;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 400)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetThumbImageBadRequest>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode == 401)
{
if(Utilities.IsContentTypeMatch("application/json", contentType))
{
var obj = ResponseBodyDeserializer.Deserialize<GetThumbImageUnauthorized>(await httpResponse.Content.ReadAsStringAsync(), NullValueHandling.Ignore);
obj!.RawResponse = httpResponse;
throw obj!;
}
throw new Models.Errors.SDKException("Unknown content type received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
else if(responseStatusCode >= 400 && responseStatusCode < 500 || responseStatusCode >= 500 && responseStatusCode < 600)
{
throw new Models.Errors.SDKException("API error occurred", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
throw new Models.Errors.SDKException("Unknown status code received", responseStatusCode, await httpResponse.Content.ReadAsStringAsync(), httpResponse);
}
}
}

View File

@@ -0,0 +1,57 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum Accepts
{
[JsonProperty("application/json")]
ApplicationJson,
[JsonProperty("application/xml")]
ApplicationXml,
}
public static class AcceptsExtension
{
public static string Value(this Accepts value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static Accepts ToEnum(this string value)
{
foreach(var field in typeof(Accepts).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is Accepts)
{
return (Accepts)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum Accepts");
}
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum AdvancedSubtitles
{
[JsonProperty("burn")]
Burn,
[JsonProperty("text")]
Text,
[JsonProperty("unknown")]
Unknown,
}
public static class AdvancedSubtitlesExtension
{
public static string Value(this AdvancedSubtitles value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static AdvancedSubtitles ToEnum(this string value)
{
foreach(var field in typeof(AdvancedSubtitles).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is AdvancedSubtitles)
{
return (AdvancedSubtitles)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum AdvancedSubtitles");
}
}
}

View File

@@ -0,0 +1,57 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum AiringsType
{
[JsonProperty("New Airings Only")]
NewAiringsOnly,
[JsonProperty("New and Repeat Airings")]
NewAndRepeatAirings,
}
public static class AiringsTypeExtension
{
public static string Value(this AiringsType value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static AiringsType ToEnum(this string value)
{
foreach(var field in typeof(AiringsType).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is AiringsType)
{
return (AiringsType)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum AiringsType");
}
}
}

View File

@@ -7,7 +7,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Requests
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
@@ -16,8 +16,9 @@ namespace LukeHagar.PlexAPI.SDK.Models.Requests
/// </summary>
public enum AutoSelectSubtitle
{
Disable = 0,
Enable = 1,
ManuallySelected = 0,
ShownWithForeignAudio = 1,
AlwaysEnabled = 2,
}
}

View File

@@ -0,0 +1,20 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
public enum BoolInt
{
False = 0,
True = 1,
}
}

View File

@@ -0,0 +1,42 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class Channel
{
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("callSign")]
public string? CallSign { get; set; }
[JsonProperty("channelVcn")]
public string? ChannelVcn { get; set; }
[JsonProperty("hd")]
public bool? Hd { get; set; }
[JsonProperty("identifier")]
public string? Identifier { get; set; }
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("language")]
public string? Language { get; set; }
[JsonProperty("thumb")]
public string? Thumb { get; set; }
}
}

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class ChannelMapping
{
[JsonProperty("channelKey")]
public string? ChannelKey { get; set; }
[JsonProperty("deviceIdentifier")]
public string? DeviceIdentifier { get; set; }
[JsonProperty("enabled")]
public string? Enabled { get; set; }
[JsonProperty("lineupIdentifier")]
public string? LineupIdentifier { get; set; }
}
}

View File

@@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
public class Composite
{
/// <summary>
/// Limit composite to specified metadata types
/// </summary>
[SpeakeasyMetadata("queryParam:name=type")]
public long? Type { get; set; }
/// <summary>
/// The image type
/// </summary>
[SpeakeasyMetadata("queryParam:name=format")]
public Models.Components.Format? Format { get; set; }
/// <summary>
/// 6 character hex RGB value for background color for image
/// </summary>
[SpeakeasyMetadata("queryParam:name=backgroundColor")]
public string? BackgroundColor { get; set; }
/// <summary>
/// The width of the intra-image border
/// </summary>
[SpeakeasyMetadata("queryParam:name=border")]
public long? Border { get; set; }
/// <summary>
/// Number of columns to construct in the composite image
/// </summary>
[SpeakeasyMetadata("queryParam:name=cols")]
public long? Cols { get; set; }
/// <summary>
/// Where to crop source images to fit into composite image proportions
/// </summary>
[SpeakeasyMetadata("queryParam:name=crop")]
public Crop? Crop { get; set; }
/// <summary>
/// The height of the image
/// </summary>
[SpeakeasyMetadata("queryParam:name=height")]
public long? Height { get; set; }
/// <summary>
/// The default image type to use as the sources
/// </summary>
[SpeakeasyMetadata("queryParam:name=media")]
public CompositeMedia? Media { get; set; }
/// <summary>
/// Allow repetion of images if there are not enough source images to fill grid
/// </summary>
[SpeakeasyMetadata("queryParam:name=repeat")]
public bool? Repeat { get; set; }
/// <summary>
/// Number of rows to construct in the composite image
/// </summary>
[SpeakeasyMetadata("queryParam:name=rows")]
public long? Rows { get; set; }
/// <summary>
/// The width of the image
/// </summary>
[SpeakeasyMetadata("queryParam:name=width")]
public long? Width { get; set; }
}
}

View File

@@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
/// <summary>
/// The default image type to use as the sources
/// </summary>
public enum CompositeMedia
{
[JsonProperty("thumb")]
Thumb,
[JsonProperty("art")]
Art,
[JsonProperty("banner")]
Banner,
}
public static class CompositeMediaExtension
{
public static string Value(this CompositeMedia value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static CompositeMedia ToEnum(this string value)
{
foreach(var field in typeof(CompositeMedia).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is CompositeMedia)
{
return (CompositeMedia)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum CompositeMedia");
}
}
}

View File

@@ -7,9 +7,9 @@
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Requests
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Requests;
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
@@ -20,7 +20,7 @@ namespace LukeHagar.PlexAPI.SDK.Models.Requests
/// The protocol used for the connection (http, https, etc)
/// </summary>
[JsonProperty("protocol")]
public Protocol Protocol { get; set; } = default!;
public PlexDeviceProtocol Protocol { get; set; } = default!;
/// <summary>
/// The (ip) address or domain name used for the connection

View File

@@ -0,0 +1,60 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
/// <summary>
/// Where to crop source images to fit into composite image proportions
/// </summary>
public enum Crop
{
[JsonProperty("center")]
Center,
[JsonProperty("top")]
Top,
}
public static class CropExtension
{
public static string Value(this Crop value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static Crop ToEnum(this string value)
{
foreach(var field in typeof(Crop).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is Crop)
{
return (Crop)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum Crop");
}
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum Decision
{
[JsonProperty("directplay")]
Directplay,
[JsonProperty("transcode")]
Transcode,
[JsonProperty("none")]
None,
}
public static class DecisionExtension
{
public static string Value(this Decision value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static Decision ToEnum(this string value)
{
foreach(var field in typeof(Decision).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is Decision)
{
return (Decision)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum Decision");
}
}
}

View File

@@ -0,0 +1,207 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Reflection;
public class DefaultType
{
private DefaultType(string value) { Value = value; }
public string Value { get; private set; }
public static DefaultType Str { get { return new DefaultType("str"); } }
public static DefaultType Number { get { return new DefaultType("number"); } }
public static DefaultType Boolean { get { return new DefaultType("boolean"); } }
public override string ToString() { return Value; }
public static implicit operator String(DefaultType v) { return v.Value; }
public static DefaultType FromString(string v) {
switch(v) {
case "str": return Str;
case "number": return Number;
case "boolean": return Boolean;
default: throw new ArgumentException("Invalid value for DefaultType");
}
}
public override bool Equals(object? obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return Value.Equals(((DefaultType)obj).Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
}
/// <summary>
/// The default value of this setting
/// </summary>
[JsonConverter(typeof(Default.DefaultConverter))]
public class Default
{
public Default(DefaultType type)
{
Type = type;
}
[SpeakeasyMetadata("form:explode=true")]
public string? Str { get; set; }
[SpeakeasyMetadata("form:explode=true")]
public double? Number { get; set; }
[SpeakeasyMetadata("form:explode=true")]
public bool? Boolean { get; set; }
public DefaultType Type { get; set; }
public static Default CreateStr(string str)
{
DefaultType typ = DefaultType.Str;
Default res = new Default(typ);
res.Str = str;
return res;
}
public static Default CreateNumber(double number)
{
DefaultType typ = DefaultType.Number;
Default res = new Default(typ);
res.Number = number;
return res;
}
public static Default CreateBoolean(bool boolean)
{
DefaultType typ = DefaultType.Boolean;
Default res = new Default(typ);
res.Boolean = boolean;
return res;
}
public class DefaultConverter : JsonConverter
{
public override bool CanConvert(System.Type objectType) => objectType == typeof(Default);
public override bool CanRead => true;
public override object? ReadJson(JsonReader reader, System.Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
throw new InvalidOperationException("Received unexpected null JSON value");
}
var json = JRaw.Create(reader).ToString();
var fallbackCandidates = new List<(System.Type, object, string)>();
if (json[0] == '"' && json[^1] == '"'){
return new Default(DefaultType.Str)
{
Str = json[1..^1]
};
}
try
{
var converted = Convert.ToDouble(json);
return new Default(DefaultType.Number)
{
Number = converted
};
}
catch (System.FormatException)
{
// try next option
}
try
{
var converted = Convert.ToBoolean(json);
return new Default(DefaultType.Boolean)
{
Boolean = converted
};
}
catch (System.FormatException)
{
// try next option
}
if (fallbackCandidates.Count > 0)
{
fallbackCandidates.Sort((a, b) => ResponseBodyDeserializer.CompareFallbackCandidates(a.Item1, b.Item1, json));
foreach(var (deserializationType, returnObject, propertyName) in fallbackCandidates)
{
try
{
return ResponseBodyDeserializer.DeserializeUndiscriminatedUnionFallback(deserializationType, returnObject, propertyName, json);
}
catch (ResponseBodyDeserializer.DeserializationException)
{
// try next fallback option
}
catch (Exception)
{
throw;
}
}
}
throw new InvalidOperationException("Could not deserialize into any supported types.");
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
throw new InvalidOperationException("Unexpected null JSON value.");
}
Default res = (Default)value;
if (res.Str != null)
{
writer.WriteRawValue(Utilities.SerializeJSON(res.Str));
return;
}
if (res.Number != null)
{
writer.WriteRawValue(Utilities.SerializeJSON(res.Number));
return;
}
if (res.Boolean != null)
{
writer.WriteRawValue(Utilities.SerializeJSON(res.Boolean));
return;
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
/// <summary>
/// The audio accessibility mode (0 = Prefer non-accessibility audio, 1 = Prefer accessibility audio, 2 = Only show accessibility audio, 3 = Only show non-accessibility audio)
/// </summary>
public enum DefaultAudioAccessibility
{
PreferNonAccessibility = 0,
PreferAccessibility = 1,
OnlyAccessibility = 2,
OnlyNonAccessibility = 3,
}
}

View File

@@ -7,25 +7,21 @@
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Requests
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
/// <summary>
/// The direction of the sort. Can be either `asc` or `desc`.<br/>
///
/// <remarks>
///
/// </remarks>
/// This default diction of this sort
/// </summary>
public enum DefaultDirection
{
[JsonProperty("asc")]
Ascending,
Asc,
[JsonProperty("desc")]
Descending,
Desc,
}
public static class DefaultDirectionExtension

View File

@@ -7,7 +7,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Requests
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
@@ -16,8 +16,10 @@ namespace LukeHagar.PlexAPI.SDK.Models.Requests
/// </summary>
public enum DefaultSubtitleAccessibility
{
Disable = 0,
Enable = 1,
PreferNonSdh = 0,
PreferSdh = 1,
OnlySdh = 2,
OnlyNonSdh = 3,
}
}

View File

@@ -7,7 +7,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Requests
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
@@ -16,8 +16,10 @@ namespace LukeHagar.PlexAPI.SDK.Models.Requests
/// </summary>
public enum DefaultSubtitleForced
{
Disable = 0,
Enable = 1,
PreferNonForced = 0,
PreferForced = 1,
OnlyForced = 2,
OnlyNonForced = 3,
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Device
{
[JsonProperty("ChannelMapping")]
public List<Models.Components.ChannelMapping>? ChannelMapping { get; set; }
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("lastSeenAt")]
public long? LastSeenAt { get; set; }
[JsonProperty("make")]
public string? Make { get; set; }
[JsonProperty("model")]
public string? Model { get; set; }
[JsonProperty("modelNumber")]
public string? ModelNumber { get; set; }
[JsonProperty("protocol")]
public string? Protocol { get; set; }
[JsonProperty("sources")]
public string? Sources { get; set; }
[JsonProperty("state")]
public string? State { get; set; }
[JsonProperty("status")]
public string? Status { get; set; }
[JsonProperty("tuners")]
public string? Tuners { get; set; }
[JsonProperty("uri")]
public string? Uri { get; set; }
[JsonProperty("uuid")]
public string? Uuid { get; set; }
}
}

View File

@@ -0,0 +1,68 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Directory
{
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("type")]
public string? Type { get; set; }
[JsonProperty("art")]
public string? Art { get; set; }
[JsonProperty("content")]
public bool? Content { get; set; }
[JsonProperty("filter")]
public string? Filter { get; set; }
[JsonProperty("hasPrefs")]
public bool? HasPrefs { get; set; }
[JsonProperty("hasStoreServices")]
public bool? HasStoreServices { get; set; }
[JsonProperty("hubKey")]
public string? HubKey { get; set; }
[JsonProperty("identifier")]
public string? Identifier { get; set; }
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("lastAccessedAt")]
public long? LastAccessedAt { get; set; }
[JsonProperty("Pivot")]
public List<Pivot>? Pivot { get; set; }
[JsonProperty("share")]
public long? Share { get; set; }
[JsonProperty("thumb")]
public string? Thumb { get; set; }
[JsonProperty("titleBar")]
public string? TitleBar { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Dvr
{
[JsonProperty("Device")]
public List<Models.Components.Device>? Device { get; set; }
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("language")]
public string? Language { get; set; }
[JsonProperty("lineup")]
public string? Lineup { get; set; }
[JsonProperty("uuid")]
public string? Uuid { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// OK
/// </summary>
public class DvrRequestHandlerSlashGetResponses200
{
[JsonProperty("MediaContainer")]
public DvrRequestHandlerSlashGetResponses200MediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class DvrRequestHandlerSlashGetResponses200MediaContainer
{
[JsonProperty("MediaContainer")]
public DvrRequestHandlerSlashGetResponses200MediaContainerMediaContainer? MediaContainer { get; set; }
[JsonProperty("DVR")]
public List<Models.Components.Dvr>? Dvr { get; set; }
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class DvrRequestHandlerSlashGetResponses200MediaContainerMediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
/// <summary>
/// A status indicator. If present and non-zero, indicates an error
/// </summary>
[JsonProperty("status")]
public long? Status { get; set; }
}
}

View File

@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// Each `Filter` object contains a description of the filter. Note that it is not an exhaustive list of the full media query language, but an important subset useful for top-level API.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class Filter
{
/// <summary>
/// The title for the filter.
/// </summary>
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("type")]
public string? Type { get; set; }
[JsonProperty("art")]
public string? Art { get; set; }
[JsonProperty("content")]
public bool? Content { get; set; }
/// <summary>
/// This represents the filter name used for the filter, which can be used to construct complex media queries with.
/// </summary>
[JsonProperty("filter")]
public string? FilterValue { get; set; }
[JsonProperty("hasPrefs")]
public bool? HasPrefs { get; set; }
[JsonProperty("hasStoreServices")]
public bool? HasStoreServices { get; set; }
[JsonProperty("hubKey")]
public string? HubKey { get; set; }
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// This provides the endpoint where the possible range of values for the filter can be retrieved (e.g. for a &quot;Genre&quot; filter, it returns a list of all the genres in the library). This will include a `type` argument that matches the metadata type of the Type element.
/// </summary>
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("lastAccessedAt")]
public long? LastAccessedAt { get; set; }
[JsonProperty("Pivot")]
public List<FilterPivot>? Pivot { get; set; }
[JsonProperty("share")]
public long? Share { get; set; }
[JsonProperty("thumb")]
public string? Thumb { get; set; }
[JsonProperty("titleBar")]
public string? TitleBar { get; set; }
/// <summary>
/// This is either `string`, `integer`, or `boolean`, and describes the type of values used for the filter.
/// </summary>
[JsonProperty("filterType")]
public string? FilterType { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,36 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class FilterPivot
{
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("type")]
public string? Type { get; set; }
[JsonProperty("context")]
public string? Context { get; set; }
[JsonProperty("id")]
public string? Id { get; set; }
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("symbol")]
public string? Symbol { get; set; }
}
}

View File

@@ -0,0 +1,60 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
/// <summary>
/// The image type
/// </summary>
public enum Format
{
[JsonProperty("jpg")]
Jpg,
[JsonProperty("png")]
Png,
}
public static class FormatExtension
{
public static string Value(this Format value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static Format ToEnum(this string value)
{
foreach(var field in typeof(Format).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is Format)
{
return (Format)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum Format");
}
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// OK
/// </summary>
public class GetResponses200
{
[JsonProperty("MediaContainer")]
public GetResponses200MediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,77 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class GetResponses200Hub
{
/// <summary>
/// Whether this hub is visible on the home screen<br/>
///
/// <remarks>
/// - all: Visible to all users<br/>
/// - none: Visible to no users<br/>
/// - admin: Visible to only admin users<br/>
/// - shared: Visible to shared users<br/>
///
/// </remarks>
/// </summary>
[JsonProperty("homeVisibility")]
public Models.Components.HomeVisibility? HomeVisibility { get; set; }
/// <summary>
/// The identifier for this hub
/// </summary>
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// Whether this hub is visible to admin user home
/// </summary>
[JsonProperty("promotedToOwnHome")]
public bool? PromotedToOwnHome { get; set; }
/// <summary>
/// Whether this hub is promoted to all for recommendations
/// </summary>
[JsonProperty("promotedToRecommended")]
public bool? PromotedToRecommended { get; set; }
/// <summary>
/// Whether this hub is visible to shared user&apos;s home
/// </summary>
[JsonProperty("promotedToSharedHome")]
public bool? PromotedToSharedHome { get; set; }
/// <summary>
/// The visibility of this hub in recommendations:<br/>
///
/// <remarks>
/// - all: Visible to all users<br/>
/// - none: Visible to no users<br/>
/// - admin: Visible to only admin users<br/>
/// - shared: Visible to shared users<br/>
///
/// </remarks>
/// </summary>
[JsonProperty("recommendationsVisibility")]
public Models.Components.RecommendationsVisibility? RecommendationsVisibility { get; set; }
/// <summary>
/// The title of this hub
/// </summary>
[JsonProperty("title")]
public string? Title { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class GetResponses200MediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
[JsonProperty("Hub")]
public List<GetResponses200Hub>? Hub { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class Guids
{
/// <summary>
/// The unique identifier for the Guid. Can be prefixed with imdb://, tmdb://, tvdb://<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("id")]
public string Id { get; set; } = default!;
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// OK
/// </summary>
public class HistoryAllGetResponses200
{
[JsonProperty("MediaContainer")]
public HistoryAllGetResponses200MediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class HistoryAllGetResponses200MediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
[JsonProperty("Metadata")]
public List<HistoryAllGetResponses200Metadata>? Metadata { get; set; }
}
}

View File

@@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class HistoryAllGetResponses200Metadata
{
/// <summary>
/// The account id of this playback
/// </summary>
[JsonProperty("accountID")]
public long? AccountID { get; set; }
/// <summary>
/// The device id which played the item
/// </summary>
[JsonProperty("deviceID")]
public long? DeviceID { get; set; }
/// <summary>
/// The key for this individual history item
/// </summary>
[JsonProperty("historyKey")]
public string? HistoryKey { get; set; }
/// <summary>
/// The metadata key for the item played
/// </summary>
[JsonProperty("key")]
public string? Key { get; set; }
/// <summary>
/// The library section id containing the item played
/// </summary>
[JsonProperty("librarySectionID")]
public string? LibrarySectionID { get; set; }
/// <summary>
/// The originally available at of the item played
/// </summary>
[JsonProperty("originallyAvailableAt")]
public string? OriginallyAvailableAt { get; set; }
/// <summary>
/// The rating key for the item played
/// </summary>
[JsonProperty("ratingKey")]
public string? RatingKey { get; set; }
/// <summary>
/// The thumb of the item played
/// </summary>
[JsonProperty("thumb")]
public string? Thumb { get; set; }
/// <summary>
/// The title of the item played
/// </summary>
[JsonProperty("title")]
public string? Title { get; set; }
/// <summary>
/// The metadata type of the item played
/// </summary>
[JsonProperty("type")]
public string? Type { get; set; }
/// <summary>
/// The time when the item was played
/// </summary>
[JsonProperty("viewedAt")]
public long? ViewedAt { get; set; }
}
}

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
/// <summary>
/// Whether this hub is visible on the home screen<br/>
///
/// <remarks>
/// - all: Visible to all users<br/>
/// - none: Visible to no users<br/>
/// - admin: Visible to only admin users<br/>
/// - shared: Visible to shared users<br/>
///
/// </remarks>
/// </summary>
public enum HomeVisibility
{
[JsonProperty("all")]
All,
[JsonProperty("none")]
None,
[JsonProperty("admin")]
Admin,
[JsonProperty("shared")]
Shared,
}
public static class HomeVisibilityExtension
{
public static string Value(this HomeVisibility value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static HomeVisibility ToEnum(this string value)
{
foreach(var field in typeof(HomeVisibility).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is HomeVisibility)
{
return (HomeVisibility)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum HomeVisibility");
}
}
}

View File

@@ -0,0 +1,103 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Hub
{
/// <summary>
/// A title for this grouping of content
/// </summary>
[JsonProperty("title")]
public string? Title { get; set; }
/// <summary>
/// The type of the items contained in this hub, or possibly `mixed` if there are multiple types
/// </summary>
[JsonProperty("type")]
public string? Type { get; set; }
[JsonProperty("context")]
public string? Context { get; set; }
/// <summary>
/// A unique identifier for the hub
/// </summary>
[JsonProperty("hubIdentifier")]
public string? HubIdentifier { get; set; }
/// <summary>
/// A key at which the exact content currently displayed can be fetched again. This is particularly important when a hub is marked as random and requesting the `key` may get different results. It&apos;s otherwise optional.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("hubKey")]
public string? HubKey { get; set; }
/// <summary>
/// The key at which all of the content for this hub can be retrieved
/// </summary>
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("Metadata")]
public List<Models.Components.Metadata>? Metadata { get; set; }
/// <summary>
/// &quot;A boolean indicating that the hub contains more than what&apos;s included in the current response.&quot;<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("more")]
public bool? More { get; set; }
/// <summary>
/// Indicating if the hub should be promoted to the user&apos;s homescreen
/// </summary>
[JsonProperty("promoted")]
public bool? Promoted { get; set; }
/// <summary>
/// Indicating that the contents of the hub may change on each request
/// </summary>
[JsonProperty("random")]
public bool? Random { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// A suggestion on how this hub&apos;s contents might be displayed by a client. Some examples include `hero`, `list`, `spotlight`, and `upsell`
/// </summary>
[JsonProperty("style")]
public string? Style { get; set; }
/// <summary>
/// The subtype of the items contained in this hub, or possibly `mixed` if there are multiple types
/// </summary>
[JsonProperty("subtype")]
public string? Subtype { get; set; }
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,44 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// Images such as movie posters and background artwork are represented by Image elements.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class Image
{
/// <summary>
/// Describes both the purpose and intended presentation of the image.
/// </summary>
[JsonProperty("type")]
public ImageType? Type { get; set; }
/// <summary>
/// Title to use for accessibility.
/// </summary>
[JsonProperty("alt")]
public string? Alt { get; set; }
/// <summary>
/// The relative path or absolute url for the image.
/// </summary>
[JsonProperty("url")]
public string? Url { get; set; }
}
}

View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
/// <summary>
/// Describes both the purpose and intended presentation of the image.
/// </summary>
public enum ImageType
{
[JsonProperty("background")]
Background,
[JsonProperty("banner")]
Banner,
[JsonProperty("clearLogo")]
ClearLogo,
[JsonProperty("coverPoster")]
CoverPoster,
[JsonProperty("snapshot")]
Snapshot,
}
public static class ImageTypeExtension
{
public static string Value(this ImageType value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static ImageType ToEnum(this string value)
{
foreach(var field in typeof(ImageType).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is ImageType)
{
return (ImageType)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum ImageType");
}
}
}

View File

@@ -0,0 +1,431 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using NodaTime;
using System.Collections.Generic;
/// <summary>
/// Items in a library are referred to as &quot;metadata items.&quot; These metadata items are distinct from &quot;media items&quot; which represent actual instances of media that can be consumed. Consider a TV library that has a single video file in it for a particular episode of a show. The library has a single media item, but it has three metadata items: one for the show, one for the season, and one for the episode. Consider a movie library that has two video files in it: the same movie, but two different resolutions. The library has a single metadata item for the movie, but that metadata item has two media items, one for each resolution. Additionally a &quot;media item&quot; will have one or more &quot;media parts&quot; where the the parts are intended to be watched together, such as a CD1 and CD2 parts of the same movie.<br/>
///
/// <remarks>
/// <br/>
/// Note that when a metadata item has multiple media items, those media items should be isomorphic. That is, a 4K version and 1080p version of a movie are different versions of the same movie. They have the same duration, same summary, same rating, etc. and they can generally be considered interchangeable. A theatrical release vs. director&apos;s cut vs. unrated version on the other hand would be separate metadata items.<br/>
/// <br/>
/// Metadata items can often live in a hierarchy with relationships between them. For example, the metadata item for an episodes is associated with a season metadata item which is associated with a show metadata item. A similar hierarchy exists with track, album, and artist and photos and photo album. The relationships may be expressed via relative terms and absolute terms. For example, &quot;leaves&quot; refer to metadata items which has associated media (there is no media for a season nor show). A show will have &quot;children&quot; in the form of seasons and a season will have &quot;children&quot; in the form of episodes and episodes have &quot;parent&quot; in the form of a season which has a &quot;parent&quot; in the form of a show. Similarly, a show has &quot;grandchildren&quot; in the form of episodse and an episode has a &quot;grandparent&quot; in the form of a show.<br/>
///
/// </remarks>
/// </summary>
public class Items
{
/// <summary>
/// The title of the item (e.g. “300” or “The Simpsons”)
/// </summary>
[JsonProperty("title")]
public string Title { get; set; } = default!;
/// <summary>
/// The type of the video item, such as `movie`, `episode`, or `clip`.
/// </summary>
[JsonProperty("type")]
public string Type { get; set; } = default!;
/// <summary>
/// When present, contains the disc number for a track on multi-disc albums.
/// </summary>
[JsonProperty("absoluteIndex")]
public int? AbsoluteIndex { get; set; }
/// <summary>
/// In units of seconds since the epoch, returns the time at which the item was added to the library.
/// </summary>
[JsonProperty("addedAt")]
public long AddedAt { get; set; } = default!;
/// <summary>
/// When present, the URL for the background artwork for the item.
/// </summary>
[JsonProperty("art")]
public string? Art { get; set; }
/// <summary>
/// Some rating systems separate reviewer ratings from audience ratings
/// </summary>
[JsonProperty("audienceRating")]
public float? AudienceRating { get; set; }
/// <summary>
/// A URI representing the image to be shown with the audience rating (e.g. rottentomatoes://image.rating.spilled).
/// </summary>
[JsonProperty("audienceRatingImage")]
public string? AudienceRatingImage { get; set; }
[JsonProperty("Autotag")]
public List<Tag>? Autotag { get; set; }
/// <summary>
/// When present, the URL for a banner graphic for the item.
/// </summary>
[JsonProperty("banner")]
public string? Banner { get; set; }
/// <summary>
/// When present, indicates the source for the chapters in the media file. Can be media (the chapters were embedded in the media itself), agent (a metadata agent computed them), or mixed (a combination of the two).
/// </summary>
[JsonProperty("chapterSource")]
public string? ChapterSource { get; set; }
/// <summary>
/// The number of child items associated with this media item.
/// </summary>
[JsonProperty("childCount")]
public int? ChildCount { get; set; }
/// <summary>
/// When present, the URL for a composite image for descendent items (e.g. photo albums or playlists).
/// </summary>
[JsonProperty("composite")]
public string? Composite { get; set; }
/// <summary>
/// If known, the content rating (e.g. MPAA) for an item.
/// </summary>
[JsonProperty("contentRating")]
public string? ContentRating { get; set; }
[JsonProperty("Country")]
public List<Tag>? Country { get; set; }
[JsonProperty("Director")]
public List<Tag>? Director { get; set; }
/// <summary>
/// When present, the duration for the item, in units of milliseconds.
/// </summary>
[JsonProperty("duration")]
public int? Duration { get; set; }
/// <summary>
/// Typically only seen in metadata at a library&apos;s top level
/// </summary>
[JsonProperty("Filter")]
public List<Filter>? Filter { get; set; }
[JsonProperty("Genre")]
public List<Tag>? Genre { get; set; }
/// <summary>
/// The `art` of the grandparent
/// </summary>
[JsonProperty("grandparentArt")]
public string? GrandparentArt { get; set; }
/// <summary>
/// The GUID of the grandparent media item.
/// </summary>
[JsonProperty("grandparentGuid")]
public string? GrandparentGuid { get; set; }
/// <summary>
/// The `hero` of the grandparent
/// </summary>
[JsonProperty("grandparentHero")]
public string? GrandparentHero { get; set; }
/// <summary>
/// The `key` of the grandparent
/// </summary>
[JsonProperty("grandparentKey")]
public string? GrandparentKey { get; set; }
/// <summary>
/// The `ratingKey` of the grandparent
/// </summary>
[JsonProperty("grandparentRatingKey")]
public string? GrandparentRatingKey { get; set; }
/// <summary>
/// The `theme` of the grandparent
/// </summary>
[JsonProperty("grandparentTheme")]
public string? GrandparentTheme { get; set; }
/// <summary>
/// The `thumb` of the grandparent
/// </summary>
[JsonProperty("grandparentThumb")]
public string? GrandparentThumb { get; set; }
/// <summary>
/// The `title` of the grandparent
/// </summary>
[JsonProperty("grandparentTitle")]
public string? GrandparentTitle { get; set; }
/// <summary>
/// The globally unique identifier for the media item.
/// </summary>
[JsonProperty("guid")]
public string? Guid { get; set; }
[JsonProperty("Guid")]
public List<ItemsGuids>? Guids { get; set; }
/// <summary>
/// When present, the URL for a hero image for the item.
/// </summary>
[JsonProperty("hero")]
public string? Hero { get; set; }
[JsonProperty("Image")]
public List<Image>? Image { get; set; }
/// <summary>
/// When present, this represents the episode number for episodes, season number for seasons, or track number for audio tracks.
/// </summary>
[JsonProperty("index")]
public int? Index { get; set; }
/// <summary>
/// The key at which the item&apos;s details can be fetched. In many cases a metadata item may be passed without all the details (such as in a hub) and this key corresponds to the endpoint to fetch additional details.
/// </summary>
[JsonProperty("key")]
public string Key { get; set; } = default!;
[JsonProperty("lastViewedAt")]
public long? LastViewedAt { get; set; }
/// <summary>
/// For shows and seasons, contains the number of total episodes.
/// </summary>
[JsonProperty("leafCount")]
public int? LeafCount { get; set; }
[JsonProperty("Media")]
public List<Media>? Media { get; set; }
/// <summary>
/// When present, in the format YYYY-MM-DD [HH:MM:SS] (the hours/minutes/seconds part is not always present). The air date, or a higher resolution release date for an item, depending on type. For example, episodes usually have air date like 1979-08-10 (we don&apos;t use epoch seconds because media existed prior to 1970). In some cases, recorded over-the-air content has higher resolution air date which includes a time component. Albums and movies may have day-resolution release dates as well.
/// </summary>
[JsonProperty("originallyAvailableAt")]
public LocalDate? OriginallyAvailableAt { get; set; }
/// <summary>
/// When present, used to indicate an item&apos;s original title, e.g. a movie&apos;s foreign title.
/// </summary>
[JsonProperty("originalTitle")]
public string? OriginalTitle { get; set; }
/// <summary>
/// The GUID of the parent media item.
/// </summary>
[JsonProperty("parentGuid")]
public string? ParentGuid { get; set; }
/// <summary>
/// The `hero` of the parent
/// </summary>
[JsonProperty("parentHero")]
public string? ParentHero { get; set; }
/// <summary>
/// The `index` of the parent
/// </summary>
[JsonProperty("parentIndex")]
public int? ParentIndex { get; set; }
/// <summary>
/// The `key` of the parent
/// </summary>
[JsonProperty("parentKey")]
public string? ParentKey { get; set; }
/// <summary>
/// The `ratingKey` of the parent
/// </summary>
[JsonProperty("parentRatingKey")]
public string? ParentRatingKey { get; set; }
/// <summary>
/// The `thumb` of the parent
/// </summary>
[JsonProperty("parentThumb")]
public string? ParentThumb { get; set; }
/// <summary>
/// The `title` of the parent
/// </summary>
[JsonProperty("parentTitle")]
public string? ParentTitle { get; set; }
/// <summary>
/// Indicates that the item has a primary extra; for a movie, this is a trailer, and for a music track it is a music video. The URL points to the metadata details endpoint for the item.
/// </summary>
[JsonProperty("primaryExtraKey")]
public string? PrimaryExtraKey { get; set; }
/// <summary>
/// Prompt to give the user for this directory (such as `Search Movies`)
/// </summary>
[JsonProperty("prompt")]
public string? Prompt { get; set; }
/// <summary>
/// When present, the rating for the item. The exact meaning and representation depends on where the rating was sourced from.
/// </summary>
[JsonProperty("rating")]
public float? Rating { get; set; }
[JsonProperty("Rating")]
public List<Tag>? RatingArray { get; set; }
/// <summary>
/// Number of ratings under this metadata
/// </summary>
[JsonProperty("ratingCount")]
public int? RatingCount { get; set; }
/// <summary>
/// When present, indicates an image to be shown with the rating. This is passed back as a small set of defined URI values, e.g. rottentomatoes://image.rating.rotten.
/// </summary>
[JsonProperty("ratingImage")]
public string? RatingImage { get; set; }
/// <summary>
/// This is the opaque string to be passed into timeline, scrobble, and rating endpoints to identify them. While it often appears to be numeric, this is not guaranteed.
/// </summary>
[JsonProperty("ratingKey")]
public string? RatingKey { get; set; }
[JsonProperty("Role")]
public List<Tag>? Role { get; set; }
/// <summary>
/// Indicates this is a search directory
/// </summary>
[JsonProperty("search")]
public bool? Search { get; set; }
/// <summary>
/// Used by old clients to provide nested menus allowing for primative (but structured) navigation.
/// </summary>
[JsonProperty("secondary")]
public bool? Secondary { get; set; }
/// <summary>
/// When found on a show item, indicates that the children (seasons) should be skipped in favor of the grandchildren (episodes). Useful for mini-series, etc.
/// </summary>
[JsonProperty("skipChildren")]
public bool? SkipChildren { get; set; }
/// <summary>
/// When present on an episode or track item, indicates parent should be skipped in favor of grandparent (show).
/// </summary>
[JsonProperty("skipParent")]
public bool? SkipParent { get; set; }
/// <summary>
/// Typically only seen in metadata at a library&apos;s top level
/// </summary>
[JsonProperty("Sort")]
public List<Sort>? Sort { get; set; }
/// <summary>
/// When present, the studio or label which produced an item (e.g. movie studio for movies, record label for albums).
/// </summary>
[JsonProperty("studio")]
public string? Studio { get; set; }
/// <summary>
/// The subtype of the video item, such as `photo` when the video item is in a photo library
/// </summary>
[JsonProperty("subtype")]
public string? Subtype { get; set; }
/// <summary>
/// When present, the extended textual information about the item (e.g. movie plot, artist biography, album review).
/// </summary>
[JsonProperty("summary")]
public string? Summary { get; set; }
/// <summary>
/// When present, a pithy one-liner about the item (usually only seen for movies).
/// </summary>
[JsonProperty("tagline")]
public string? Tagline { get; set; }
/// <summary>
/// When present, the URL for theme music for the item (usually only for TV shows).
/// </summary>
[JsonProperty("theme")]
public string? Theme { get; set; }
/// <summary>
/// When present, the URL for the poster or thumbnail for the item. When available for types like movie, it will be the poster graphic, but fall-back to the extracted media thumbnail.
/// </summary>
[JsonProperty("thumb")]
public string? Thumb { get; set; }
/// <summary>
/// Whene present, this is the string used for sorting the item. It&apos;s usually the title with any leading articles removed (e.g. “Simpsons”).
/// </summary>
[JsonProperty("titleSort")]
public string? TitleSort { get; set; }
/// <summary>
/// In units of seconds since the epoch, returns the time at which the item was last changed (e.g. had its metadata updated).
/// </summary>
[JsonProperty("updatedAt")]
public long? UpdatedAt { get; set; }
/// <summary>
/// When the user has rated an item, this contains the user rating
/// </summary>
[JsonProperty("userRating")]
public float? UserRating { get; set; }
/// <summary>
/// When a users has completed watched or listened to an item, this attribute contains the number of consumptions.
/// </summary>
[JsonProperty("viewCount")]
public int? ViewCount { get; set; }
/// <summary>
/// For shows and seasons, contains the number of viewed episodes.
/// </summary>
[JsonProperty("viewedLeafCount")]
public int? ViewedLeafCount { get; set; }
/// <summary>
/// When a user is in the process of viewing or listening to this item, this attribute contains the current offset, in units of milliseconds.
/// </summary>
[JsonProperty("viewOffset")]
public int? ViewOffset { get; set; }
[JsonProperty("Writer")]
public List<Tag>? Writer { get; set; }
/// <summary>
/// When present, the year associated with the item&apos;s release (e.g. release year for a movie).
/// </summary>
[JsonProperty("year")]
public int? Year { get; set; }
[JsonProperty("MetadataItem")]
public List<Items>? MetadataItem { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class ItemsGuids
{
/// <summary>
/// The unique identifier for the Guid. Can be prefixed with imdb://, tmdb://, tvdb://<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("id")]
public string Id { get; set; } = default!;
}
}

View File

@@ -0,0 +1,102 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class LibrarySection
{
/// <summary>
/// The title of the library
/// </summary>
[JsonProperty("title")]
public string? Title { get; set; }
/// <summary>
/// The type of media content in the Plex library. This can represent videos, music, or photos.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("type")]
public MediaTypeString Type { get; set; } = default!;
[JsonProperty("agent")]
public string? Agent { get; set; }
[JsonProperty("allowSync")]
public bool? AllowSync { get; set; }
[JsonProperty("art")]
public string? Art { get; set; }
[JsonProperty("composite")]
public string? Composite { get; set; }
[JsonProperty("content")]
public bool? Content { get; set; }
[JsonProperty("contentChangedAt")]
public long? ContentChangedAt { get; set; }
[JsonProperty("createdAt")]
public long? CreatedAt { get; set; }
[JsonProperty("directory")]
public bool? Directory { get; set; }
/// <summary>
/// Indicates whether this section has filtering capabilities
/// </summary>
[JsonProperty("filters")]
public bool? Filters { get; set; }
[JsonProperty("hidden")]
public bool? Hidden { get; set; }
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("language")]
public string Language { get; set; } = default!;
/// <summary>
/// The universally unique identifier for the library.
/// </summary>
[JsonProperty("uuid")]
public string Uuid { get; set; } = default!;
[JsonProperty("Location")]
public List<LibrarySectionLocation>? Location { get; set; }
/// <summary>
/// Indicates whether this library section is currently scanning
/// </summary>
[JsonProperty("refreshing")]
public bool? Refreshing { get; set; }
[JsonProperty("scannedAt")]
public long? ScannedAt { get; set; }
[JsonProperty("scanner")]
public string? Scanner { get; set; }
[JsonProperty("thumb")]
public string? Thumb { get; set; }
[JsonProperty("updatedAt")]
public long? UpdatedAt { get; set; }
}
}

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// Represents a top-level location on disk where media in this library section is stored
/// </summary>
public class LibrarySectionLocation
{
[JsonProperty("id")]
public long? Id { get; set; }
/// <summary>
/// The path of where this directory exists on disk
/// </summary>
[JsonProperty("path")]
public object? Path { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// OK
/// </summary>
public class LibrarySections
{
[JsonProperty("MediaContainer")]
public LibrarySectionsMediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class LibrarySectionsDirectory
{
[JsonProperty("count")]
public long? Count { get; set; }
/// <summary>
/// The key where this directory is found
/// </summary>
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("title")]
public string? Title { get; set; }
}
}

View File

@@ -0,0 +1,211 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class LibrarySectionsMediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
[JsonProperty("allowCameraUpload")]
public bool? AllowCameraUpload { get; set; }
[JsonProperty("allowChannelAccess")]
public bool? AllowChannelAccess { get; set; }
[JsonProperty("allowMediaDeletion")]
public bool? AllowMediaDeletion { get; set; }
[JsonProperty("allowSharing")]
public bool? AllowSharing { get; set; }
[JsonProperty("allowSync")]
public bool? AllowSync { get; set; }
[JsonProperty("allowTuners")]
public bool? AllowTuners { get; set; }
[JsonProperty("backgroundProcessing")]
public bool? BackgroundProcessing { get; set; }
[JsonProperty("certificate")]
public bool? Certificate { get; set; }
[JsonProperty("companionProxy")]
public bool? CompanionProxy { get; set; }
[JsonProperty("countryCode")]
public string? CountryCode { get; set; }
[JsonProperty("diagnostics")]
public string? Diagnostics { get; set; }
[JsonProperty("eventStream")]
public bool? EventStream { get; set; }
[JsonProperty("friendlyName")]
public string? FriendlyName { get; set; }
[JsonProperty("hubSearch")]
public bool? HubSearch { get; set; }
[JsonProperty("itemClusters")]
public bool? ItemClusters { get; set; }
[JsonProperty("livetv")]
public long? Livetv { get; set; }
[JsonProperty("machineIdentifier")]
public object? MachineIdentifier { get; set; }
[JsonProperty("mediaProviders")]
public bool? MediaProviders { get; set; }
[JsonProperty("multiuser")]
public bool? Multiuser { get; set; }
[JsonProperty("musicAnalysis")]
public long? MusicAnalysis { get; set; }
[JsonProperty("myPlex")]
public bool? MyPlex { get; set; }
[JsonProperty("myPlexMappingState")]
public object? MyPlexMappingState { get; set; }
[JsonProperty("myPlexSigninState")]
public object? MyPlexSigninState { get; set; }
[JsonProperty("myPlexSubscription")]
public bool? MyPlexSubscription { get; set; }
[JsonProperty("myPlexUsername")]
public string? MyPlexUsername { get; set; }
[JsonProperty("offlineTranscode")]
public object? OfflineTranscode { get; set; }
/// <summary>
/// A comma-separated list of features which are enabled for the server owner
/// </summary>
[JsonProperty("ownerFeatures")]
public string? OwnerFeatures { get; set; }
[JsonProperty("platform")]
public string? Platform { get; set; }
[JsonProperty("platformVersion")]
public string? PlatformVersion { get; set; }
[JsonProperty("pluginHost")]
public bool? PluginHost { get; set; }
[JsonProperty("pushNotifications")]
public bool? PushNotifications { get; set; }
[JsonProperty("readOnlyLibraries")]
public bool? ReadOnlyLibraries { get; set; }
[JsonProperty("streamingBrainABRVersion")]
public long? StreamingBrainABRVersion { get; set; }
[JsonProperty("streamingBrainVersion")]
public long? StreamingBrainVersion { get; set; }
[JsonProperty("sync")]
public bool? Sync { get; set; }
[JsonProperty("transcoderActiveVideoSessions")]
public long? TranscoderActiveVideoSessions { get; set; }
[JsonProperty("transcoderAudio")]
public bool? TranscoderAudio { get; set; }
[JsonProperty("transcoderLyrics")]
public bool? TranscoderLyrics { get; set; }
[JsonProperty("transcoderPhoto")]
public bool? TranscoderPhoto { get; set; }
[JsonProperty("transcoderSubtitles")]
public bool? TranscoderSubtitles { get; set; }
[JsonProperty("transcoderVideo")]
public bool? TranscoderVideo { get; set; }
/// <summary>
/// The suggested video quality bitrates to present to the user
/// </summary>
[JsonProperty("transcoderVideoBitrates")]
public object? TranscoderVideoBitrates { get; set; }
[JsonProperty("transcoderVideoQualities")]
public string? TranscoderVideoQualities { get; set; }
/// <summary>
/// The suggested video resolutions to the above quality bitrates
/// </summary>
[JsonProperty("transcoderVideoResolutions")]
public object? TranscoderVideoResolutions { get; set; }
[JsonProperty("updatedAt")]
public long? UpdatedAt { get; set; }
[JsonProperty("updater")]
public bool? Updater { get; set; }
[JsonProperty("version")]
public string? Version { get; set; }
[JsonProperty("voiceSearch")]
public bool? VoiceSearch { get; set; }
[JsonProperty("Directory")]
public List<LibrarySectionsDirectory>? Directory { get; set; }
}
}

View File

@@ -0,0 +1,52 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class Lineup
{
[JsonProperty("title")]
public string? Title { get; set; }
/// <summary>
/// The type of this object (`lineup` in this case)
/// </summary>
[JsonProperty("type")]
public string? Type { get; set; }
/// <summary>
/// - `-1`: N/A<br/>
///
/// <remarks>
/// - `0`: Over the air<br/>
/// - `1`: Cable<br/>
/// - `2`: Satellite<br/>
/// - `3`: IPTV<br/>
/// - `4`: Virtual<br/>
///
/// </remarks>
/// </summary>
[JsonProperty("lineupType")]
public Models.Components.LineupType? LineupType { get; set; }
[JsonProperty("location")]
public string? Location { get; set; }
/// <summary>
/// The uuid of this lineup
/// </summary>
[JsonProperty("uuid")]
public string? Uuid { get; set; }
}
}

View File

@@ -0,0 +1,36 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
/// <summary>
/// - `-1`: N/A<br/>
///
/// <remarks>
/// - `0`: Over the air<br/>
/// - `1`: Cable<br/>
/// - `2`: Satellite<br/>
/// - `3`: IPTV<br/>
/// - `4`: Virtual<br/>
///
/// </remarks>
/// </summary>
public enum LineupType
{
Minus1 = -1,
Zero = 0,
One = 1,
Two = 2,
Three = 3,
Four = 4,
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum Location
{
[JsonProperty("lan")]
Lan,
[JsonProperty("wan")]
Wan,
[JsonProperty("cellular")]
Cellular,
}
public static class LocationExtension
{
public static string Value(this Location value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static Location ToEnum(this string value)
{
foreach(var field in typeof(Location).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is Location)
{
return (Location)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum Location");
}
}
}

View File

@@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
/// <summary>
/// Your current mailing list status
/// </summary>
public enum MailingListStatus
{
[JsonProperty("active")]
Active,
[JsonProperty("unsubscribed")]
Unsubscribed,
[JsonProperty("removed")]
Removed,
}
public static class MailingListStatusExtension
{
public static string Value(this MailingListStatus value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static MailingListStatus ToEnum(this string value)
{
foreach(var field in typeof(MailingListStatus).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is MailingListStatus)
{
return (MailingListStatus)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum MailingListStatus");
}
}
}

View File

@@ -0,0 +1,84 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `Media` represents an one or more media files (parts) and is a child of a metadata item. There aren&apos;t necessarily any guaranteed attributes on media elements since the attributes will vary based on the type. The possible attributes are not documented here, but they typically have self-evident names. High-level media information that can be used for badging and flagging, such as `videoResolution` and codecs, is included on the media element.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class Media
{
[JsonProperty("aspectRatio")]
public float? AspectRatio { get; set; }
[JsonProperty("audioChannels")]
public int? AudioChannels { get; set; }
[JsonProperty("audioCodec")]
public string? AudioCodec { get; set; }
[JsonProperty("audioProfile")]
public string? AudioProfile { get; set; }
[JsonProperty("bitrate")]
public int? Bitrate { get; set; }
[JsonProperty("container")]
public string? Container { get; set; }
[JsonProperty("duration")]
public int? Duration { get; set; }
[JsonProperty("has64bitOffsets")]
public bool? Has64bitOffsets { get; set; }
[JsonProperty("hasVoiceActivity")]
public bool? HasVoiceActivity { get; set; }
[JsonProperty("height")]
public int? Height { get; set; }
[JsonProperty("id")]
public long Id { get; set; } = default!;
[JsonProperty("optimizedForStreaming")]
public bool? OptimizedForStreaming { get; set; }
[JsonProperty("Part")]
public List<Part>? Part { get; set; }
[JsonProperty("videoCodec")]
public string? VideoCodec { get; set; }
[JsonProperty("videoFrameRate")]
public string? VideoFrameRate { get; set; }
[JsonProperty("videoProfile")]
public string? VideoProfile { get; set; }
[JsonProperty("videoResolution")]
public string? VideoResolution { get; set; }
[JsonProperty("width")]
public int? Width { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,53 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class MediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class MediaContainerWithArtwork
{
[JsonProperty("MediaContainer")]
public MediaContainerWithArtworkMediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class MediaContainerWithArtworkMediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
[JsonProperty("Metadata")]
public List<MediaContainerWithArtworkMetadata>? Metadata { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class MediaContainerWithArtworkMetadata
{
/// <summary>
/// The title of the item
/// </summary>
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("type")]
public MediaContainerWithArtworkType? Type { get; set; }
/// <summary>
/// The path to the artwork
/// </summary>
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum MediaContainerWithArtworkType
{
[JsonProperty("image")]
Image,
}
public static class MediaContainerWithArtworkTypeExtension
{
public static string Value(this MediaContainerWithArtworkType value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static MediaContainerWithArtworkType ToEnum(this string value)
{
foreach(var field in typeof(MediaContainerWithArtworkType).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is MediaContainerWithArtworkType)
{
return (MediaContainerWithArtworkType)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum MediaContainerWithArtworkType");
}
}
}

View File

@@ -0,0 +1,31 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
/// <summary>
/// `MediaContainer` is commonly found as the root of a response and is a pretty generic container. Common attributes include `identifier` and things related to paging (`offset`, `size`, `totalSize`).<br/>
///
/// <remarks>
/// <br/>
/// It is also common for a `MediaContainer` to contain attributes &quot;hoisted&quot; from its children. If every element in the container would have had the same attribute, then that attribute can be present on the container instead of being repeated on every element. For example, an album&apos;s list of tracks might include `parentTitle` on the container since all of the tracks have the same album title. A container may have a `source` attribute when all of the items came from the same source. Generally speaking, when looking for an attribute on an item, if the attribute wasn&apos;t found then the container should be checked for that attribute as well.<br/>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDecision
{
[JsonProperty("MediaContainer")]
public MediaContainerWithDecisionMediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,65 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum MediaContainerWithDecisionDecision
{
[JsonProperty("copy")]
Copy,
[JsonProperty("transcode")]
Transcode,
[JsonProperty("burn")]
Burn,
[JsonProperty("unavailable")]
Unavailable,
[JsonProperty("ignore")]
Ignore,
[JsonProperty("none")]
None,
}
public static class MediaContainerWithDecisionDecisionExtension
{
public static string Value(this MediaContainerWithDecisionDecision value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static MediaContainerWithDecisionDecision ToEnum(this string value)
{
foreach(var field in typeof(MediaContainerWithDecisionDecision).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is MediaContainerWithDecisionDecision)
{
return (MediaContainerWithDecisionDecision)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum MediaContainerWithDecisionDecision");
}
}
}

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class MediaContainerWithDecisionGuids
{
/// <summary>
/// The unique identifier for the Guid. Can be prefixed with imdb://, tmdb://, tvdb://<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("id")]
public string Id { get; set; } = default!;
}
}

View File

@@ -0,0 +1,69 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System;
public enum MediaContainerWithDecisionLocation
{
[JsonProperty("direct")]
Direct,
[JsonProperty("sidecar-subs")]
SidecarSubs,
[JsonProperty("segments-video")]
SegmentsVideo,
[JsonProperty("segments-audio")]
SegmentsAudio,
[JsonProperty("segments-av")]
SegmentsAv,
[JsonProperty("segments-subs")]
SegmentsSubs,
[JsonProperty("embedded")]
Embedded,
[JsonProperty("sidecar")]
Sidecar,
}
public static class MediaContainerWithDecisionLocationExtension
{
public static string Value(this MediaContainerWithDecisionLocation value)
{
return ((JsonPropertyAttribute)value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0]).PropertyName ?? value.ToString();
}
public static MediaContainerWithDecisionLocation ToEnum(this string value)
{
foreach(var field in typeof(MediaContainerWithDecisionLocation).GetFields())
{
var attributes = field.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (attributes.Length == 0)
{
continue;
}
var attribute = attributes[0] as JsonPropertyAttribute;
if (attribute != null && attribute.PropertyName == value)
{
var enumVal = field.GetValue(null);
if (enumVal is MediaContainerWithDecisionLocation)
{
return (MediaContainerWithDecisionLocation)enumVal;
}
}
}
throw new Exception($"Unknown value {value} for enum MediaContainerWithDecisionLocation");
}
}
}

View File

@@ -0,0 +1,93 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `Media` represents an one or more media files (parts) and is a child of a metadata item. There aren&apos;t necessarily any guaranteed attributes on media elements since the attributes will vary based on the type. The possible attributes are not documented here, but they typically have self-evident names. High-level media information that can be used for badging and flagging, such as `videoResolution` and codecs, is included on the media element.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDecisionMedia
{
[JsonProperty("aspectRatio")]
public float? AspectRatio { get; set; }
[JsonProperty("audioChannels")]
public int? AudioChannels { get; set; }
[JsonProperty("audioCodec")]
public string? AudioCodec { get; set; }
[JsonProperty("audioProfile")]
public string? AudioProfile { get; set; }
[JsonProperty("bitrate")]
public int? Bitrate { get; set; }
[JsonProperty("container")]
public string? Container { get; set; }
[JsonProperty("duration")]
public int? Duration { get; set; }
[JsonProperty("has64bitOffsets")]
public bool? Has64bitOffsets { get; set; }
[JsonProperty("hasVoiceActivity")]
public bool? HasVoiceActivity { get; set; }
[JsonProperty("height")]
public int? Height { get; set; }
[JsonProperty("id")]
public long Id { get; set; } = default!;
[JsonProperty("optimizedForStreaming")]
public bool? OptimizedForStreaming { get; set; }
[JsonProperty("Part")]
public List<MediaContainerWithDecisionPart>? Part { get; set; }
[JsonProperty("videoCodec")]
public string? VideoCodec { get; set; }
[JsonProperty("videoFrameRate")]
public string? VideoFrameRate { get; set; }
[JsonProperty("videoProfile")]
public string? VideoProfile { get; set; }
[JsonProperty("videoResolution")]
public string? VideoResolution { get; set; }
[JsonProperty("width")]
public int? Width { get; set; }
[JsonProperty("abr")]
public bool? Abr { get; set; }
[JsonProperty("resourceSession")]
public string? ResourceSession { get; set; }
[JsonProperty("selected")]
public bool? Selected { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,97 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDecisionMediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
/// <summary>
/// The maximum available bitrate when the decision was rendered.
/// </summary>
[JsonProperty("availableBandwidth")]
public long? AvailableBandwidth { get; set; }
[JsonProperty("directPlayDecisionCode")]
public long? DirectPlayDecisionCode { get; set; }
[JsonProperty("directPlayDecisionText")]
public string? DirectPlayDecisionText { get; set; }
/// <summary>
/// The overall decision. 1xxx are playback can succeed, 2xxx are a general error (such as insufficient bandwidth), 3xxx are errors in direct play, and 4xxx are errors in transcodes. Same codes are used in all.
/// </summary>
[JsonProperty("generalDecisionCode")]
public long? GeneralDecisionCode { get; set; }
[JsonProperty("generalDecisionText")]
public string? GeneralDecisionText { get; set; }
/// <summary>
/// The code indicating the status of evaluation of playback when client indicates `hasMDE=1`
/// </summary>
[JsonProperty("mdeDecisionCode")]
public long? MdeDecisionCode { get; set; }
/// <summary>
/// Descriptive text for the above code
/// </summary>
[JsonProperty("mdeDecisionText")]
public string? MdeDecisionText { get; set; }
[JsonProperty("Metadata")]
public List<MediaContainerWithDecisionMetadata>? Metadata { get; set; }
[JsonProperty("transcodeDecisionCode")]
public long? TranscodeDecisionCode { get; set; }
[JsonProperty("transcodeDecisionText")]
public string? TranscodeDecisionText { get; set; }
}
}

View File

@@ -0,0 +1,428 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using NodaTime;
using System.Collections.Generic;
/// <summary>
/// Items in a library are referred to as &quot;metadata items.&quot; These metadata items are distinct from &quot;media items&quot; which represent actual instances of media that can be consumed. Consider a TV library that has a single video file in it for a particular episode of a show. The library has a single media item, but it has three metadata items: one for the show, one for the season, and one for the episode. Consider a movie library that has two video files in it: the same movie, but two different resolutions. The library has a single metadata item for the movie, but that metadata item has two media items, one for each resolution. Additionally a &quot;media item&quot; will have one or more &quot;media parts&quot; where the the parts are intended to be watched together, such as a CD1 and CD2 parts of the same movie.<br/>
///
/// <remarks>
/// <br/>
/// Note that when a metadata item has multiple media items, those media items should be isomorphic. That is, a 4K version and 1080p version of a movie are different versions of the same movie. They have the same duration, same summary, same rating, etc. and they can generally be considered interchangeable. A theatrical release vs. director&apos;s cut vs. unrated version on the other hand would be separate metadata items.<br/>
/// <br/>
/// Metadata items can often live in a hierarchy with relationships between them. For example, the metadata item for an episodes is associated with a season metadata item which is associated with a show metadata item. A similar hierarchy exists with track, album, and artist and photos and photo album. The relationships may be expressed via relative terms and absolute terms. For example, &quot;leaves&quot; refer to metadata items which has associated media (there is no media for a season nor show). A show will have &quot;children&quot; in the form of seasons and a season will have &quot;children&quot; in the form of episodes and episodes have &quot;parent&quot; in the form of a season which has a &quot;parent&quot; in the form of a show. Similarly, a show has &quot;grandchildren&quot; in the form of episodse and an episode has a &quot;grandparent&quot; in the form of a show.<br/>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDecisionMetadata
{
/// <summary>
/// The title of the item (e.g. “300” or “The Simpsons”)
/// </summary>
[JsonProperty("title")]
public string Title { get; set; } = default!;
/// <summary>
/// The type of the video item, such as `movie`, `episode`, or `clip`.
/// </summary>
[JsonProperty("type")]
public string Type { get; set; } = default!;
/// <summary>
/// When present, contains the disc number for a track on multi-disc albums.
/// </summary>
[JsonProperty("absoluteIndex")]
public int? AbsoluteIndex { get; set; }
/// <summary>
/// In units of seconds since the epoch, returns the time at which the item was added to the library.
/// </summary>
[JsonProperty("addedAt")]
public long AddedAt { get; set; } = default!;
/// <summary>
/// When present, the URL for the background artwork for the item.
/// </summary>
[JsonProperty("art")]
public string? Art { get; set; }
/// <summary>
/// Some rating systems separate reviewer ratings from audience ratings
/// </summary>
[JsonProperty("audienceRating")]
public float? AudienceRating { get; set; }
/// <summary>
/// A URI representing the image to be shown with the audience rating (e.g. rottentomatoes://image.rating.spilled).
/// </summary>
[JsonProperty("audienceRatingImage")]
public string? AudienceRatingImage { get; set; }
[JsonProperty("Autotag")]
public List<Tag>? Autotag { get; set; }
/// <summary>
/// When present, the URL for a banner graphic for the item.
/// </summary>
[JsonProperty("banner")]
public string? Banner { get; set; }
/// <summary>
/// When present, indicates the source for the chapters in the media file. Can be media (the chapters were embedded in the media itself), agent (a metadata agent computed them), or mixed (a combination of the two).
/// </summary>
[JsonProperty("chapterSource")]
public string? ChapterSource { get; set; }
/// <summary>
/// The number of child items associated with this media item.
/// </summary>
[JsonProperty("childCount")]
public int? ChildCount { get; set; }
/// <summary>
/// When present, the URL for a composite image for descendent items (e.g. photo albums or playlists).
/// </summary>
[JsonProperty("composite")]
public string? Composite { get; set; }
/// <summary>
/// If known, the content rating (e.g. MPAA) for an item.
/// </summary>
[JsonProperty("contentRating")]
public string? ContentRating { get; set; }
[JsonProperty("Country")]
public List<Tag>? Country { get; set; }
[JsonProperty("Director")]
public List<Tag>? Director { get; set; }
/// <summary>
/// When present, the duration for the item, in units of milliseconds.
/// </summary>
[JsonProperty("duration")]
public int? Duration { get; set; }
/// <summary>
/// Typically only seen in metadata at a library&apos;s top level
/// </summary>
[JsonProperty("Filter")]
public List<Filter>? Filter { get; set; }
[JsonProperty("Genre")]
public List<Tag>? Genre { get; set; }
/// <summary>
/// The `art` of the grandparent
/// </summary>
[JsonProperty("grandparentArt")]
public string? GrandparentArt { get; set; }
/// <summary>
/// The GUID of the grandparent media item.
/// </summary>
[JsonProperty("grandparentGuid")]
public string? GrandparentGuid { get; set; }
/// <summary>
/// The `hero` of the grandparent
/// </summary>
[JsonProperty("grandparentHero")]
public string? GrandparentHero { get; set; }
/// <summary>
/// The `key` of the grandparent
/// </summary>
[JsonProperty("grandparentKey")]
public string? GrandparentKey { get; set; }
/// <summary>
/// The `ratingKey` of the grandparent
/// </summary>
[JsonProperty("grandparentRatingKey")]
public string? GrandparentRatingKey { get; set; }
/// <summary>
/// The `theme` of the grandparent
/// </summary>
[JsonProperty("grandparentTheme")]
public string? GrandparentTheme { get; set; }
/// <summary>
/// The `thumb` of the grandparent
/// </summary>
[JsonProperty("grandparentThumb")]
public string? GrandparentThumb { get; set; }
/// <summary>
/// The `title` of the grandparent
/// </summary>
[JsonProperty("grandparentTitle")]
public string? GrandparentTitle { get; set; }
/// <summary>
/// The globally unique identifier for the media item.
/// </summary>
[JsonProperty("guid")]
public string? Guid { get; set; }
[JsonProperty("Guid")]
public List<MediaContainerWithDecisionGuids>? Guids { get; set; }
/// <summary>
/// When present, the URL for a hero image for the item.
/// </summary>
[JsonProperty("hero")]
public string? Hero { get; set; }
[JsonProperty("Image")]
public List<Image>? Image { get; set; }
/// <summary>
/// When present, this represents the episode number for episodes, season number for seasons, or track number for audio tracks.
/// </summary>
[JsonProperty("index")]
public int? Index { get; set; }
/// <summary>
/// The key at which the item&apos;s details can be fetched. In many cases a metadata item may be passed without all the details (such as in a hub) and this key corresponds to the endpoint to fetch additional details.
/// </summary>
[JsonProperty("key")]
public string Key { get; set; } = default!;
[JsonProperty("lastViewedAt")]
public long? LastViewedAt { get; set; }
/// <summary>
/// For shows and seasons, contains the number of total episodes.
/// </summary>
[JsonProperty("leafCount")]
public int? LeafCount { get; set; }
[JsonProperty("Media")]
public List<MediaContainerWithDecisionMedia>? Media { get; set; }
/// <summary>
/// When present, in the format YYYY-MM-DD [HH:MM:SS] (the hours/minutes/seconds part is not always present). The air date, or a higher resolution release date for an item, depending on type. For example, episodes usually have air date like 1979-08-10 (we don&apos;t use epoch seconds because media existed prior to 1970). In some cases, recorded over-the-air content has higher resolution air date which includes a time component. Albums and movies may have day-resolution release dates as well.
/// </summary>
[JsonProperty("originallyAvailableAt")]
public LocalDate? OriginallyAvailableAt { get; set; }
/// <summary>
/// When present, used to indicate an item&apos;s original title, e.g. a movie&apos;s foreign title.
/// </summary>
[JsonProperty("originalTitle")]
public string? OriginalTitle { get; set; }
/// <summary>
/// The GUID of the parent media item.
/// </summary>
[JsonProperty("parentGuid")]
public string? ParentGuid { get; set; }
/// <summary>
/// The `hero` of the parent
/// </summary>
[JsonProperty("parentHero")]
public string? ParentHero { get; set; }
/// <summary>
/// The `index` of the parent
/// </summary>
[JsonProperty("parentIndex")]
public int? ParentIndex { get; set; }
/// <summary>
/// The `key` of the parent
/// </summary>
[JsonProperty("parentKey")]
public string? ParentKey { get; set; }
/// <summary>
/// The `ratingKey` of the parent
/// </summary>
[JsonProperty("parentRatingKey")]
public string? ParentRatingKey { get; set; }
/// <summary>
/// The `thumb` of the parent
/// </summary>
[JsonProperty("parentThumb")]
public string? ParentThumb { get; set; }
/// <summary>
/// The `title` of the parent
/// </summary>
[JsonProperty("parentTitle")]
public string? ParentTitle { get; set; }
/// <summary>
/// Indicates that the item has a primary extra; for a movie, this is a trailer, and for a music track it is a music video. The URL points to the metadata details endpoint for the item.
/// </summary>
[JsonProperty("primaryExtraKey")]
public string? PrimaryExtraKey { get; set; }
/// <summary>
/// Prompt to give the user for this directory (such as `Search Movies`)
/// </summary>
[JsonProperty("prompt")]
public string? Prompt { get; set; }
/// <summary>
/// When present, the rating for the item. The exact meaning and representation depends on where the rating was sourced from.
/// </summary>
[JsonProperty("rating")]
public float? Rating { get; set; }
[JsonProperty("Rating")]
public List<Tag>? RatingArray { get; set; }
/// <summary>
/// Number of ratings under this metadata
/// </summary>
[JsonProperty("ratingCount")]
public int? RatingCount { get; set; }
/// <summary>
/// When present, indicates an image to be shown with the rating. This is passed back as a small set of defined URI values, e.g. rottentomatoes://image.rating.rotten.
/// </summary>
[JsonProperty("ratingImage")]
public string? RatingImage { get; set; }
/// <summary>
/// This is the opaque string to be passed into timeline, scrobble, and rating endpoints to identify them. While it often appears to be numeric, this is not guaranteed.
/// </summary>
[JsonProperty("ratingKey")]
public string? RatingKey { get; set; }
[JsonProperty("Role")]
public List<Tag>? Role { get; set; }
/// <summary>
/// Indicates this is a search directory
/// </summary>
[JsonProperty("search")]
public bool? Search { get; set; }
/// <summary>
/// Used by old clients to provide nested menus allowing for primative (but structured) navigation.
/// </summary>
[JsonProperty("secondary")]
public bool? Secondary { get; set; }
/// <summary>
/// When found on a show item, indicates that the children (seasons) should be skipped in favor of the grandchildren (episodes). Useful for mini-series, etc.
/// </summary>
[JsonProperty("skipChildren")]
public bool? SkipChildren { get; set; }
/// <summary>
/// When present on an episode or track item, indicates parent should be skipped in favor of grandparent (show).
/// </summary>
[JsonProperty("skipParent")]
public bool? SkipParent { get; set; }
/// <summary>
/// Typically only seen in metadata at a library&apos;s top level
/// </summary>
[JsonProperty("Sort")]
public List<Sort>? Sort { get; set; }
/// <summary>
/// When present, the studio or label which produced an item (e.g. movie studio for movies, record label for albums).
/// </summary>
[JsonProperty("studio")]
public string? Studio { get; set; }
/// <summary>
/// The subtype of the video item, such as `photo` when the video item is in a photo library
/// </summary>
[JsonProperty("subtype")]
public string? Subtype { get; set; }
/// <summary>
/// When present, the extended textual information about the item (e.g. movie plot, artist biography, album review).
/// </summary>
[JsonProperty("summary")]
public string? Summary { get; set; }
/// <summary>
/// When present, a pithy one-liner about the item (usually only seen for movies).
/// </summary>
[JsonProperty("tagline")]
public string? Tagline { get; set; }
/// <summary>
/// When present, the URL for theme music for the item (usually only for TV shows).
/// </summary>
[JsonProperty("theme")]
public string? Theme { get; set; }
/// <summary>
/// When present, the URL for the poster or thumbnail for the item. When available for types like movie, it will be the poster graphic, but fall-back to the extracted media thumbnail.
/// </summary>
[JsonProperty("thumb")]
public string? Thumb { get; set; }
/// <summary>
/// Whene present, this is the string used for sorting the item. It&apos;s usually the title with any leading articles removed (e.g. “Simpsons”).
/// </summary>
[JsonProperty("titleSort")]
public string? TitleSort { get; set; }
/// <summary>
/// In units of seconds since the epoch, returns the time at which the item was last changed (e.g. had its metadata updated).
/// </summary>
[JsonProperty("updatedAt")]
public long? UpdatedAt { get; set; }
/// <summary>
/// When the user has rated an item, this contains the user rating
/// </summary>
[JsonProperty("userRating")]
public float? UserRating { get; set; }
/// <summary>
/// When a users has completed watched or listened to an item, this attribute contains the number of consumptions.
/// </summary>
[JsonProperty("viewCount")]
public int? ViewCount { get; set; }
/// <summary>
/// For shows and seasons, contains the number of viewed episodes.
/// </summary>
[JsonProperty("viewedLeafCount")]
public int? ViewedLeafCount { get; set; }
/// <summary>
/// When a user is in the process of viewing or listening to this item, this attribute contains the current offset, in units of milliseconds.
/// </summary>
[JsonProperty("viewOffset")]
public int? ViewOffset { get; set; }
[JsonProperty("Writer")]
public List<Tag>? Writer { get; set; }
/// <summary>
/// When present, the year associated with the item&apos;s release (e.g. release year for a movie).
/// </summary>
[JsonProperty("year")]
public int? Year { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,99 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `Part` represents a particular file or &quot;part&quot; of a media item. The part is the playable unit of the media hierarchy. Suppose that a movie library contains a movie that is broken up into files, reminiscent of a movie split across two BDs. The metadata item represents information about the movie, the media item represents this instance of the movie at this resolution and quality, and the part items represent the two playable files. If another media were added which contained the joining of these two parts transcoded down to a lower resolution, then this metadata would contain 2 medias, one with 2 parts and one with 1 part.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDecisionPart
{
/// <summary>
/// Indicates if the part is accessible.
/// </summary>
[JsonProperty("accessible")]
public bool? Accessible { get; set; }
[JsonProperty("audioProfile")]
public string? AudioProfile { get; set; }
/// <summary>
/// The container of the media file, such as `mp4` or `mkv`
/// </summary>
[JsonProperty("container")]
public string? Container { get; set; }
/// <summary>
/// The duration of the media item, in milliseconds
/// </summary>
[JsonProperty("duration")]
public int? Duration { get; set; }
/// <summary>
/// Indicates if the part exists.
/// </summary>
[JsonProperty("exists")]
public bool? Exists { get; set; }
/// <summary>
/// The local file path at which the part is stored on the server
/// </summary>
[JsonProperty("file")]
public string? File { get; set; }
[JsonProperty("has64bitOffsets")]
public bool? Has64bitOffsets { get; set; }
[JsonProperty("id")]
public long Id { get; set; } = default!;
[JsonProperty("indexes")]
public string? Indexes { get; set; }
/// <summary>
/// The key from which the media can be streamed
/// </summary>
[JsonProperty("key")]
public string Key { get; set; } = default!;
[JsonProperty("optimizedForStreaming")]
public bool? OptimizedForStreaming { get; set; }
/// <summary>
/// The size of the media, in bytes
/// </summary>
[JsonProperty("size")]
public long? Size { get; set; }
[JsonProperty("Stream")]
public List<MediaContainerWithDecisionStream>? Stream { get; set; }
[JsonProperty("videoProfile")]
public string? VideoProfile { get; set; }
[JsonProperty("decision")]
public Decision? Decision { get; set; }
[JsonProperty("selected")]
public bool? Selected { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,337 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `Stream` represents a particular stream from a media item, such as the video stream, audio stream, or subtitle stream. The stream may either be part of the file represented by the parent `Part` or, especially for subtitles, an external file. The stream contains more detailed information about the specific stream. For example, a video may include the `aspectRatio` at the `Media` level, but detailed information about the video stream like the color space will be included on the `Stream` for the video stream. Note that photos do not have streams (mostly as an optimization).<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDecisionStream
{
/// <summary>
/// Indicates if this stream is default.
/// </summary>
[JsonProperty("default")]
public bool? Default { get; set; }
/// <summary>
/// Audio channel layout.
/// </summary>
[JsonProperty("audioChannelLayout")]
public string? AudioChannelLayout { get; set; }
/// <summary>
/// Number of audio channels (for audio streams).
/// </summary>
[JsonProperty("channels")]
public int? Channels { get; set; }
/// <summary>
/// Bit depth of the video stream.
/// </summary>
[JsonProperty("bitDepth")]
public int? BitDepth { get; set; }
/// <summary>
/// Dolby Vision BL compatibility ID.
/// </summary>
[JsonProperty("DOVIBLCompatID")]
public int? DOVIBLCompatID { get; set; }
/// <summary>
/// Indicates if Dolby Vision BL is present.
/// </summary>
[JsonProperty("DOVIBLPresent")]
public bool? DOVIBLPresent { get; set; }
/// <summary>
/// Indicates if Dolby Vision EL is present.
/// </summary>
[JsonProperty("DOVIELPresent")]
public bool? DOVIELPresent { get; set; }
/// <summary>
/// Dolby Vision level.
/// </summary>
[JsonProperty("DOVILevel")]
public int? DOVILevel { get; set; }
/// <summary>
/// Indicates if Dolby Vision is present.
/// </summary>
[JsonProperty("DOVIPresent")]
public bool? DOVIPresent { get; set; }
/// <summary>
/// Dolby Vision profile.
/// </summary>
[JsonProperty("DOVIProfile")]
public int? DOVIProfile { get; set; }
/// <summary>
/// Indicates if Dolby Vision RPU is present.
/// </summary>
[JsonProperty("DOVIRPUPresent")]
public bool? DOVIRPUPresent { get; set; }
/// <summary>
/// Dolby Vision version.
/// </summary>
[JsonProperty("DOVIVersion")]
public string? DOVIVersion { get; set; }
/// <summary>
/// Bitrate of the stream.
/// </summary>
[JsonProperty("bitrate")]
public int? Bitrate { get; set; }
/// <summary>
/// Indicates if the stream can auto-sync.
/// </summary>
[JsonProperty("canAutoSync")]
public bool? CanAutoSync { get; set; }
/// <summary>
/// Chroma sample location.
/// </summary>
[JsonProperty("chromaLocation")]
public string? ChromaLocation { get; set; }
/// <summary>
/// Chroma subsampling format.
/// </summary>
[JsonProperty("chromaSubsampling")]
public string? ChromaSubsampling { get; set; }
/// <summary>
/// Coded video height.
/// </summary>
[JsonProperty("codedHeight")]
public int? CodedHeight { get; set; }
/// <summary>
/// Coded video width.
/// </summary>
[JsonProperty("codedWidth")]
public int? CodedWidth { get; set; }
[JsonProperty("closedCaptions")]
public bool? ClosedCaptions { get; set; }
/// <summary>
/// Codec used by the stream.
/// </summary>
[JsonProperty("codec")]
public string Codec { get; set; } = default!;
/// <summary>
/// Color primaries used.
/// </summary>
[JsonProperty("colorPrimaries")]
public string? ColorPrimaries { get; set; }
/// <summary>
/// Color range (e.g., tv).
/// </summary>
[JsonProperty("colorRange")]
public string? ColorRange { get; set; }
/// <summary>
/// Color space.
/// </summary>
[JsonProperty("colorSpace")]
public string? ColorSpace { get; set; }
/// <summary>
/// Color transfer characteristics.
/// </summary>
[JsonProperty("colorTrc")]
public string? ColorTrc { get; set; }
/// <summary>
/// Display title for the stream.
/// </summary>
[JsonProperty("displayTitle")]
public string DisplayTitle { get; set; } = default!;
/// <summary>
/// Extended display title for the stream.
/// </summary>
[JsonProperty("extendedDisplayTitle")]
public string? ExtendedDisplayTitle { get; set; }
/// <summary>
/// Frame rate of the stream.
/// </summary>
[JsonProperty("frameRate")]
public float? FrameRate { get; set; }
[JsonProperty("hasScalingMatrix")]
public bool? HasScalingMatrix { get; set; }
/// <summary>
/// Height of the video stream.
/// </summary>
[JsonProperty("height")]
public int? Height { get; set; }
/// <summary>
/// Unique stream identifier.
/// </summary>
[JsonProperty("id")]
public int Id { get; set; } = default!;
/// <summary>
/// Index of the stream.
/// </summary>
[JsonProperty("index")]
public int? Index { get; set; }
/// <summary>
/// Key to access this stream part.
/// </summary>
[JsonProperty("key")]
public string Key { get; set; } = default!;
/// <summary>
/// Language of the stream.
/// </summary>
[JsonProperty("language")]
public string? Language { get; set; }
/// <summary>
/// ISO language code.
/// </summary>
[JsonProperty("languageCode")]
public string? LanguageCode { get; set; }
/// <summary>
/// Language tag (e.g., en).
/// </summary>
[JsonProperty("languageTag")]
public string? LanguageTag { get; set; }
/// <summary>
/// Format of the stream (e.g., srt).
/// </summary>
[JsonProperty("format")]
public string? Format { get; set; }
/// <summary>
/// Indicates whether header compression is enabled.
/// </summary>
[JsonProperty("headerCompression")]
public bool? HeaderCompression { get; set; }
/// <summary>
/// Video level.
/// </summary>
[JsonProperty("level")]
public int? Level { get; set; }
/// <summary>
/// Indicates if this is the original stream.
/// </summary>
[JsonProperty("original")]
public bool? Original { get; set; }
/// <summary>
/// Video profile.
/// </summary>
[JsonProperty("profile")]
public string? Profile { get; set; }
/// <summary>
/// Number of reference frames.
/// </summary>
[JsonProperty("refFrames")]
public int? RefFrames { get; set; }
/// <summary>
/// Sampling rate for the audio stream.
/// </summary>
[JsonProperty("samplingRate")]
public int? SamplingRate { get; set; }
[JsonProperty("scanType")]
public string? ScanType { get; set; }
[JsonProperty("embeddedInVideo")]
public string? EmbeddedInVideo { get; set; }
/// <summary>
/// Indicates if this stream is selected (applicable for audio streams).
/// </summary>
[JsonProperty("selected")]
public bool? Selected { get; set; }
[JsonProperty("forced")]
public bool? Forced { get; set; }
/// <summary>
/// Indicates if the stream is for the hearing impaired.
/// </summary>
[JsonProperty("hearingImpaired")]
public bool? HearingImpaired { get; set; }
/// <summary>
/// Indicates if the stream is a dub.
/// </summary>
[JsonProperty("dub")]
public bool? Dub { get; set; }
/// <summary>
/// Optional title for the stream (e.g., language variant).
/// </summary>
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("streamIdentifier")]
public int? StreamIdentifier { get; set; }
/// <summary>
/// Stream type:<br/>
///
/// <remarks>
/// - VIDEO = 1<br/>
/// - AUDIO = 2<br/>
/// - SUBTITLE = 3<br/>
///
/// </remarks>
/// </summary>
[JsonProperty("streamType")]
public long StreamType { get; } = 1;
/// <summary>
/// Width of the video stream.
/// </summary>
[JsonProperty("width")]
public int? Width { get; set; }
[JsonProperty("decision")]
public MediaContainerWithDecisionDecision? Decision { get; set; }
[JsonProperty("location")]
public MediaContainerWithDecisionLocation? Location { get; set; }
[JsonProperty("additionalProperties")]
public Dictionary<string, object>? AdditionalProperties { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class MediaContainerWithDevice
{
[JsonProperty("MediaContainer")]
public MediaContainerWithDeviceMediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
public class MediaContainerWithDeviceDevice
{
[JsonProperty("ChannelMapping")]
public List<Models.Components.ChannelMapping>? ChannelMapping { get; set; }
[JsonProperty("key")]
public string? Key { get; set; }
[JsonProperty("lastSeenAt")]
public long? LastSeenAt { get; set; }
[JsonProperty("make")]
public string? Make { get; set; }
[JsonProperty("model")]
public string? Model { get; set; }
[JsonProperty("modelNumber")]
public string? ModelNumber { get; set; }
[JsonProperty("protocol")]
public string? Protocol { get; set; }
[JsonProperty("sources")]
public string? Sources { get; set; }
[JsonProperty("state")]
public string? State { get; set; }
[JsonProperty("status")]
public string? Status { get; set; }
[JsonProperty("tuners")]
public string? Tuners { get; set; }
[JsonProperty("uri")]
public string? Uri { get; set; }
[JsonProperty("uuid")]
public string? Uuid { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDeviceMediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
[JsonProperty("Device")]
public List<MediaContainerWithDeviceDevice>? Device { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
public class MediaContainerWithDirectory
{
[JsonProperty("MediaContainer")]
public MediaContainerWithDirectoryMediaContainer? MediaContainer { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace LukeHagar.PlexAPI.SDK.Models.Components
{
using LukeHagar.PlexAPI.SDK.Models.Components;
using LukeHagar.PlexAPI.SDK.Utils;
using Newtonsoft.Json;
using System.Collections.Generic;
/// <summary>
/// `MediaContainer` is the root element of most Plex API responses. It serves as a generic container for various types of content (Metadata, Hubs, Directories, etc.) and includes pagination information (offset, size, totalSize) when applicable.<br/>
///
/// <remarks>
/// Common attributes: - identifier: Unique identifier for this container - size: Number of items in this response page - totalSize: Total number of items available (for pagination) - offset: Starting index of this page (for pagination)<br/>
/// The container often &quot;hoists&quot; common attributes from its children. For example, if all tracks in a container share the same album title, the `parentTitle` attribute may appear on the MediaContainer rather than being repeated on each track.<br/>
///
/// </remarks>
/// </summary>
public class MediaContainerWithDirectoryMediaContainer
{
[JsonProperty("identifier")]
public string? Identifier { get; set; }
/// <summary>
/// The offset of where this container page starts among the total objects available. Also provided in the `X-Plex-Container-Start` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("offset")]
public long? Offset { get; set; }
[JsonProperty("size")]
public long? Size { get; set; }
/// <summary>
/// The total size of objects available. Also provided in the `X-Plex-Container-Total-Size` header.<br/>
///
/// <remarks>
///
/// </remarks>
/// </summary>
[JsonProperty("totalSize")]
public long? TotalSize { get; set; }
[JsonProperty("Directory")]
public List<Models.Components.Directory>? Directory { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More