From 2321f0edafbdfb03e4040c89d3ccf4b872ffdf54 Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Sat, 21 Dec 2024 00:10:57 +0000 Subject: [PATCH] ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.459.2 --- .speakeasy/gen.lock | 54 +- .speakeasy/gen.yaml | 7 +- .speakeasy/workflow.lock | 14 +- README.md | 145 ++- RELEASES.md | 12 +- USAGE.md | 12 +- codeSamples.yaml | 631 ++--------- composer.json | 6 +- .../Operations/GetLibraryItemsMetadata.md | 2 +- .../GetLibraryItemsQueryParamType.md | 4 +- .../Operations/GetLibraryItemsShowOrdering.md | 26 +- .../GetMetaDataByRatingKeyMetadata.md | 5 + docs/Models/Operations/GetPinRequest.md | 2 +- .../GetPlaylistContentsQueryParamType.md | 4 +- .../Operations/GetRecentlyAddedMetadata.md | 2 +- .../GetSearchAllLibrariesMetadata.md | 2 +- .../GetSearchAllLibrariesRequest.md | 2 +- .../GetSearchAllLibrariesShowOrdering.md | 26 +- .../GetSearchLibraryQueryParamType.md | 4 +- .../Operations/GetServerResourcesRequest.md | 4 +- .../Operations/GetTokenByPinIdRequest.md | 2 +- .../GetTopWatchedContentQueryParamType.md | 4 +- .../Operations/PostUsersSignInDataRequest.md | 2 +- docs/Models/Operations/QueryParamType.md | 4 +- docs/Models/Operations/ShowOrdering.md | 26 +- docs/Models/Operations/Tag.md | 3 +- docs/Models/Operations/Type.md | 4 +- docs/sdks/activities/README.md | 74 +- docs/sdks/authentication/README.md | 131 +-- docs/sdks/butler/README.md | 104 +- docs/sdks/hubs/README.md | 100 +- docs/sdks/library/README.md | 548 +++++----- docs/sdks/log/README.md | 108 +- docs/sdks/media/README.md | 234 ++--- docs/sdks/playlists/README.md | 298 +++--- docs/sdks/plex/README.md | 229 ++-- docs/sdks/plexapi/README.md | 3 + docs/sdks/search/README.md | 118 +-- docs/sdks/server/README.md | 228 ++-- docs/sdks/sessions/README.md | 102 +- docs/sdks/statistics/README.md | 64 +- docs/sdks/updater/README.md | 90 +- docs/sdks/video/README.md | 16 +- docs/sdks/watchlist/README.md | 8 +- src/Activities.php | 169 ++- src/Authentication.php | 302 ++++-- src/Butler.php | 281 +++-- src/Hooks/AfterErrorContext.php | 32 + src/Hooks/AfterErrorHook.php | 17 + src/Hooks/AfterSuccessContext.php | 18 + src/Hooks/AfterSuccessHook.php | 17 + src/Hooks/BeforeRequestContext.php | 32 + src/Hooks/BeforeRequestHook.php | 17 + src/Hooks/Credentials.php | 24 + src/Hooks/ErrorResponseContext.php | 23 + src/Hooks/FailEarlyException.php | 14 + src/Hooks/HookContext.php | 51 + src/Hooks/HookRegistration.php | 28 + src/Hooks/Hooks.php | 20 + src/Hooks/SDKHooks.php | 118 +++ src/Hooks/SDKInitHook.php | 15 + src/Hooks/SDKRequestContext.php | 22 + src/Hooks/Session.php | 37 + src/Hooks/TokenResponse.php | 17 + src/Hubs.php | 233 +++-- src/Library.php | 979 ++++++++++++------ src/Log.php | 244 +++-- src/Media.php | 408 +++++--- src/Models/Operations/Feature.php | 14 +- src/Models/Operations/Friend.php | 34 +- src/Models/Operations/GeoData.php | 50 +- .../Operations/GetBannerImageResponse.php | 12 +- src/Models/Operations/GetGeoDataGeoData.php | 50 +- .../Operations/GetLibraryItemsLibrarySort.php | 60 +- .../Operations/GetLibraryItemsMedia.php | 44 +- .../GetLibraryItemsMediaContainer.php | 56 +- .../Operations/GetLibraryItemsMetadata.php | 98 +- src/Models/Operations/GetLibraryItemsPart.php | 36 +- .../GetLibraryItemsQueryParamType.php | 2 + .../Operations/GetLibraryItemsRequest.php | 20 +- .../GetLibraryItemsShowOrdering.php | 18 +- src/Models/Operations/GetLibraryItemsSort.php | 60 +- .../Operations/GetLibraryItemsStream.php | 32 +- .../GetMetaDataByRatingKeyMetadata.php | 57 +- .../Operations/GetPinAuthPinContainer.php | 38 +- src/Models/Operations/GetPinRequest.php | 34 +- .../GetPlaylistContentsQueryParamType.php | 2 + .../GetRecentlyAddedLibraryRequest.php | 30 +- .../Operations/GetRecentlyAddedMetadata.php | 98 +- .../Operations/GetRecentlyAddedRequest.php | 30 +- .../Operations/GetRecentlyAddedSort.php | 60 +- .../Operations/GetResizedPhotoRequest.php | 18 +- .../Operations/GetSearchAllLibrariesMedia.php | 44 +- .../GetSearchAllLibrariesMetadata.php | 98 +- .../Operations/GetSearchAllLibrariesPart.php | 36 +- .../GetSearchAllLibrariesRequest.php | 8 +- .../GetSearchAllLibrariesShowOrdering.php | 18 +- .../GetSearchAllLibrariesStream.php | 32 +- .../GetSearchLibraryQueryParamType.php | 2 + .../Operations/GetServerResourcesRequest.php | 22 +- .../Operations/GetThumbImageResponse.php | 12 +- .../GetTokenByPinIdAuthPinContainer.php | 38 +- .../Operations/GetTokenByPinIdGeoData.php | 50 +- .../Operations/GetTokenByPinIdRequest.php | 8 +- .../GetTokenDetailsSubscription.php | 18 +- .../GetTokenDetailsUserPlexAccount.php | 358 +++---- .../GetTopWatchedContentQueryParamType.php | 2 + src/Models/Operations/GetWatchListRequest.php | 16 +- src/Models/Operations/Media.php | 44 +- src/Models/Operations/Part.php | 36 +- src/Models/Operations/PastSubscription.php | 62 +- src/Models/Operations/PlexDevice.php | 72 +- ...rsSignInDataAuthenticationSubscription.php | 18 +- .../Operations/PostUsersSignInDataRequest.php | 8 +- .../PostUsersSignInDataRequestBody.php | 14 +- .../PostUsersSignInDataServices.php | 16 +- .../PostUsersSignInDataSubscription.php | 18 +- .../PostUsersSignInDataUserPlexAccount.php | 374 +++---- .../PostUsersSignInDataUserProfile.php | 20 +- src/Models/Operations/QueryParamType.php | 2 + src/Models/Operations/Services.php | 16 +- src/Models/Operations/ShowOrdering.php | 18 +- src/Models/Operations/Sort.php | 60 +- src/Models/Operations/Stream.php | 32 +- src/Models/Operations/Subscription.php | 18 +- src/Models/Operations/Tag.php | 1 + src/Models/Operations/Type.php | 2 + src/Models/Operations/UserProfile.php | 20 +- src/Playlists.php | 619 +++++++---- src/Plex.php | 496 ++++++--- src/PlexAPI.php | 2 + src/PlexAPIBuilder.php | 90 +- src/SDKConfiguration.php | 62 +- src/Search.php | 265 +++-- src/Server.php | 559 +++++++--- src/Sessions.php | 245 +++-- src/Statistics.php | 193 +++- src/Updater.php | 227 ++-- src/Utils/Options.php | 67 ++ src/Utils/QueryParameters.php | 88 +- src/Utils/RequestBodies.php | 11 +- src/Utils/Retry/PermanentError.php | 17 + src/Utils/Retry/RetryConfig.php | 14 + src/Utils/Retry/RetryConfigBackoff.php | 41 + src/Utils/Retry/RetryConfigNone.php | 15 + src/Utils/Retry/RetryStrategy.php | 16 + src/Utils/Retry/RetryUtils.php | 129 +++ src/Utils/Retry/TemporaryError.php | 21 + src/Utils/SecurityClient.php | 2 +- src/Utils/ServerDetails.php | 29 + src/Utils/Utils.php | 193 +++- src/Video.php | 114 +- src/Watchlist.php | 81 +- 153 files changed, 7661 insertions(+), 5083 deletions(-) create mode 100644 src/Hooks/AfterErrorContext.php create mode 100644 src/Hooks/AfterErrorHook.php create mode 100644 src/Hooks/AfterSuccessContext.php create mode 100644 src/Hooks/AfterSuccessHook.php create mode 100644 src/Hooks/BeforeRequestContext.php create mode 100644 src/Hooks/BeforeRequestHook.php create mode 100644 src/Hooks/Credentials.php create mode 100644 src/Hooks/ErrorResponseContext.php create mode 100644 src/Hooks/FailEarlyException.php create mode 100644 src/Hooks/HookContext.php create mode 100644 src/Hooks/HookRegistration.php create mode 100644 src/Hooks/Hooks.php create mode 100644 src/Hooks/SDKHooks.php create mode 100644 src/Hooks/SDKInitHook.php create mode 100644 src/Hooks/SDKRequestContext.php create mode 100644 src/Hooks/Session.php create mode 100644 src/Hooks/TokenResponse.php create mode 100644 src/Utils/Options.php create mode 100644 src/Utils/Retry/PermanentError.php create mode 100644 src/Utils/Retry/RetryConfig.php create mode 100644 src/Utils/Retry/RetryConfigBackoff.php create mode 100644 src/Utils/Retry/RetryConfigNone.php create mode 100644 src/Utils/Retry/RetryStrategy.php create mode 100644 src/Utils/Retry/RetryUtils.php create mode 100644 src/Utils/Retry/TemporaryError.php create mode 100644 src/Utils/ServerDetails.php diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 0308cce..73299c0 100755 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: 01a51eb2-5d90-4a24-b154-68e491d02c36 management: - docChecksum: 2554ade61ed4d42b8e095168765d7dc0 + docChecksum: 48a69156b6fa2af10cd43e971790441b docVersion: 0.0.3 - speakeasyVersion: 1.438.3 - generationVersion: 2.457.9 - releaseVersion: 0.11.1 - configChecksum: 5bcbf0a3a539ef43a496b7ac1835018e + speakeasyVersion: 1.459.2 + generationVersion: 2.483.1 + releaseVersion: 0.12.0 + configChecksum: d7103804a0c3e64fde7baea5b9a89318 repoURL: https://github.com/LukeHagar/plexphp.git repoSubDirectory: . installationURL: https://github.com/LukeHagar/plexphp @@ -14,7 +14,7 @@ management: features: php: constsAndDefaults: 0.2.0 - core: 3.7.2 + core: 3.7.7 deprecations: 2.81.1 enums: 2.81.1 errors: 0.3.0 @@ -22,7 +22,6 @@ features: globalSecurity: 2.81.7 globalSecurityFlattening: 0.1.1 globalServerURLs: 2.82.1 - globals: 2.82.2 methodArguments: 0.1.0 methodServerURLs: 2.82.1 nameOverrides: 2.81.2 @@ -850,6 +849,22 @@ generatedFiles: - src/Activities.php - src/Authentication.php - src/Butler.php + - src/Hooks/AfterErrorContext.php + - src/Hooks/AfterErrorHook.php + - src/Hooks/AfterSuccessContext.php + - src/Hooks/AfterSuccessHook.php + - src/Hooks/BeforeRequestContext.php + - src/Hooks/BeforeRequestHook.php + - src/Hooks/Credentials.php + - src/Hooks/ErrorResponseContext.php + - src/Hooks/FailEarlyException.php + - src/Hooks/HookContext.php + - src/Hooks/Hooks.php + - src/Hooks/SDKHooks.php + - src/Hooks/SDKInitHook.php + - src/Hooks/SDKRequestContext.php + - src/Hooks/Session.php + - src/Hooks/TokenResponse.php - src/Hubs.php - src/Library.php - src/Log.php @@ -1821,15 +1836,24 @@ generatedFiles: - src/Utils/JSON.php - src/Utils/MixedJSONHandler.php - src/Utils/MultipartMetadata.php + - src/Utils/Options.php - src/Utils/ParamsMetadata.php - src/Utils/PathParameters.php - src/Utils/PhpDocTypeParser.php - src/Utils/QueryParameters.php - src/Utils/RequestBodies.php - src/Utils/RequestMetadata.php + - src/Utils/Retry/PermanentError.php + - src/Utils/Retry/RetryConfig.php + - src/Utils/Retry/RetryConfigBackoff.php + - src/Utils/Retry/RetryConfigNone.php + - src/Utils/Retry/RetryStrategy.php + - src/Utils/Retry/RetryUtils.php + - src/Utils/Retry/TemporaryError.php - src/Utils/Security.php - src/Utils/SecurityClient.php - src/Utils/SecurityMetadata.php + - src/Utils/ServerDetails.php - src/Utils/SpeakeasyMetadata.php - src/Utils/UnionHandler.php - src/Utils/Utils.php @@ -1843,7 +1867,8 @@ examples: application/json: {"errors": []} "401": application/json: {"errors": []} - "200": {} + "200": + application/json: {} getServerPreferences: speakeasy-default-get-server-preferences: responses: @@ -2049,7 +2074,8 @@ examples: application/json: {"errors": []} "401": application/json: {"errors": []} - "200": {} + "200": + application/json: {} cancelServerActivities: "": parameters: @@ -2354,7 +2380,7 @@ examples: X-Plex-Container-Size: 50 responses: "200": - application/json: {"MediaContainer": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}], "size": 70, "totalSize": 170, "offset": 0, "content": "secondary", "allowSync": true, "nocache": true, "art": "/:/resources/movie-fanart.jpg", "identifier": "com.plexapp.plugins.library", "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionUUID": "322a231a-b7f7-49f5-920f-14c61199cd30", "mediaTagPrefix": "/system/bundle/media/flags/", "mediaTagVersion": 1701731894, "thumb": "/:/resources/movie.png", "title1": "Movies", "title2": "Recently Released", "viewGroup": "movie", "viewMode": 65592, "mixedParents": true, "Metadata": [{"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "dvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [{"tag": "Adventure"}, {"tag": "Adventure"}, {"tag": "Adventure"}], "Country": [{"tag": "United States of America"}, {"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [{"image": "themoviedb://image.rating", "value": 3, "type": "audience"}], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}, {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "dvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [], "Country": [{"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}, {"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}], "Meta": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [], "Sort": [], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}]}}} + application/json: {"MediaContainer": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}], "size": 70, "totalSize": 170, "offset": 0, "content": "secondary", "allowSync": true, "nocache": true, "art": "/:/resources/movie-fanart.jpg", "identifier": "com.plexapp.plugins.library", "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionUUID": "322a231a-b7f7-49f5-920f-14c61199cd30", "mediaTagPrefix": "/system/bundle/media/flags/", "mediaTagVersion": 1701731894, "thumb": "/:/resources/movie.png", "title1": "Movies", "title2": "Recently Released", "viewGroup": "movie", "viewMode": 65592, "mixedParents": true, "Metadata": [{"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "tvdbDvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [{"tag": "Adventure"}, {"tag": "Adventure"}, {"tag": "Adventure"}], "Country": [{"tag": "United States of America"}, {"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [{"image": "themoviedb://image.rating", "value": 3, "type": "audience"}], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}, {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "tvdbDvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [], "Country": [{"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}, {"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}], "Meta": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [], "Sort": [], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}, {"type": "tag", "Operator": [{"key": "=", "title": "is"}, {"key": "=", "title": "is"}]}]}}} "400": application/json: {"errors": [{"code": 1000, "message": "X-Plex-Client-Identifier is missing", "status": 400}]} "401": @@ -2475,7 +2501,8 @@ examples: application/json: {"errors": []} "401": application/json: {"errors": []} - "200": {} + "200": + application/json: {} logLine: speakeasy-default-log-line: parameters: @@ -2863,7 +2890,7 @@ examples: X-Plex-Container-Size: 50 responses: "200": - application/json: {"MediaContainer": {"size": 50, "identifier": "com.plexapp.plugins.library", "Meta": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}]}, {"type": "tag", "Operator": []}, {"type": "tag", "Operator": []}]}, "Metadata": [{"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "dvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": []}]}], "Genre": [{"tag": "Adventure"}], "Country": [], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [], "Collection": [], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}]}} + application/json: {"MediaContainer": {"size": 50, "identifier": "com.plexapp.plugins.library", "Meta": {"Type": [{"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}, {"key": "/library/sections/2/all?type=2", "type": "show", "title": "TV Shows", "active": false, "Filter": [{"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}, {"filter": "genre", "filterType": "string", "key": "/library/sections/2/genre?type=2", "title": "Genre", "type": "filter"}], "Sort": [{"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}, {"default": "asc", "active": false, "activeDirection": "asc", "defaultDirection": "asc", "descKey": "titleSort:desc", "firstCharacterKey": "/library/sections/2/firstCharacter", "key": "titleSort", "title": "Title"}], "Field": [{"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}, {"key": "show.title", "title": "Show Title", "type": "string", "subType": "rating"}]}], "FieldType": [{"type": "tag", "Operator": [{"key": "=", "title": "is"}]}, {"type": "tag", "Operator": []}, {"type": "tag", "Operator": []}]}, "Metadata": [{"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "tvdbDvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": []}]}], "Genre": [{"tag": "Adventure"}], "Country": [], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [], "Collection": [], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}]}} get-recently-added-library: speakeasy-default-get-recently-added-library: parameters: @@ -2894,8 +2921,9 @@ examples: X-Plex-Client-Identifier: "3381b62b-9ab7-4e37-827b-203e9809eb58" responses: "200": - application/json: {"MediaContainer": {"size": "9266.90", "SearchResult": [{"score": "2698.71", "Metadata": {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "dvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}, {"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [{"tag": "Adventure"}, {"tag": "Adventure"}, {"tag": "Adventure"}], "Country": [{"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}], "Writer": [], "Collection": [{"tag": "Working NL Subs"}, {"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [], "Guid": [{"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}}, {"score": "9681.40", "Metadata": {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "dvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [], "Genre": [], "Country": [], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}, {"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}], "Guid": [], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [{"image": "themoviedb://image.rating", "value": 3, "type": "audience"}], "Image": [], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}}, {"score": "1665.12", "Metadata": {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "dvd", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [{"tag": "Adventure"}, {"tag": "Adventure"}], "Country": [{"tag": "United States of America"}, {"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}, {"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [{"image": "themoviedb://image.rating", "value": 3, "type": "audience"}], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}}]}} + application/json: {"MediaContainer": {"size": "9266.90", "SearchResult": [{"score": "2698.71", "Metadata": {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "tvdbAbsolute", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}, {"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}, {"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [{"tag": "Adventure"}, {"tag": "Adventure"}, {"tag": "Adventure"}], "Country": [{"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}], "Writer": [], "Collection": [{"tag": "Working NL Subs"}, {"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [], "Guid": [{"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}}, {"score": "9681.40", "Metadata": {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "tvdbAbsolute", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [], "Genre": [], "Country": [], "Director": [{"tag": "James Cameron"}, {"tag": "James Cameron"}, {"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}, {"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}], "Guid": [], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [{"image": "themoviedb://image.rating", "value": 3, "type": "audience"}], "Image": [], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}}, {"score": "1665.12", "Metadata": {"ratingKey": "58683", "key": "/library/metadata/58683", "guid": "plex://movie/5d7768ba96b655001fdc0408", "studio": "20th Century Studios", "skipChildren": false, "librarySectionID": 1, "librarySectionTitle": "Movies", "librarySectionKey": "/library/sections/1", "type": "movie", "title": "Avatar: The Way of Water", "slug": "4-for-texas", "contentRating": "PG-13", "summary": "Jake Sully lives with his newfound family formed on the extrasolar moon Pandora. Once a familiar threat returns to finish what was previously started, Jake must work with Neytiri and the army of the Na'vi race to protect their home.", "rating": 7.6, "audienceRating": 9.2, "year": 2022, "seasonCount": 2022, "tagline": "Return to Pandora.", "flattenSeasons": "1", "showOrdering": "tmdbAiring", "thumb": "/library/metadata/58683/thumb/1703239236", "art": "/library/metadata/58683/art/1703239236", "banner": "/library/metadata/58683/banner/1703239236", "duration": 11558112, "originallyAvailableAt": "2022-12-14T00:00:00Z", "addedAt": 1556281940, "updatedAt": 1556281940, "audienceRatingImage": "rottentomatoes://image.rating.upright", "chapterSource": "media", "primaryExtraKey": "/library/metadata/58684", "ratingImage": "rottentomatoes://image.rating.ripe", "grandparentRatingKey": "66", "grandparentGuid": "plex://show/5d9c081b170e24001f2a7be4", "grandparentKey": "/library/metadata/66", "grandparentTitle": "Caprica", "grandparentThumb": "/library/metadata/66/thumb/1705716261", "parentSlug": "alice-in-borderland-2020", "grandparentSlug": "alice-in-borderland-2020", "grandparentArt": "/library/metadata/66/art/1705716261", "grandparentTheme": "/library/metadata/66/theme/1705716261", "Media": [{"id": 119534, "duration": 11558112, "bitrate": 25025, "width": 3840, "height": 2072, "aspectRatio": 1.85, "audioProfile": "dts", "audioChannels": 6, "audioCodec": "eac3", "videoCodec": "hevc", "videoResolution": "4k", "container": "mkv", "videoFrameRate": "24p", "videoProfile": "main 10", "hasVoiceActivity": false, "optimizedForStreaming": 1, "has64bitOffsets": false, "Part": [{"id": 119542, "key": "/library/parts/119542/1680457526/file.mkv", "duration": 11558112, "file": "/movies/Avatar The Way of Water (2022)/Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv", "size": 36158371307, "container": "mkv", "audioProfile": "dts", "has64bitOffsets": false, "optimizedForStreaming": false, "videoProfile": "main 10", "indexes": "sd", "hasThumbnail": "1", "Stream": [{"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}, {"id": 272796, "streamType": 1, "default": true, "selected": true, "codec": "h264", "index": 0, "bitrate": 6273, "colorPrimaries": "bt709", "colorRange": "tv", "colorSpace": "bt709", "colorTrc": "bt709", "bitDepth": 8, "chromaLocation": "left", "streamIdentifier": "2", "chromaSubsampling": "4:2:0", "codedHeight": 1088, "codedWidth": 1920, "frameRate": 29.97, "hasScalingMatrix": false, "hearingImpaired": false, "closedCaptions": false, "embeddedInVideo": "1", "height": 1080, "level": 40, "profile": "main", "refFrames": 4, "scanType": "progressive", "width": 1920, "displayTitle": "1080p (H.264)", "extendedDisplayTitle": "1080p (H.264)", "channels": 2, "language": "English", "languageTag": "en", "languageCode": "eng", "audioChannelLayout": "stereo", "samplingRate": 48000, "title": "English", "canAutoSync": false}]}]}], "Genre": [{"tag": "Adventure"}, {"tag": "Adventure"}], "Country": [{"tag": "United States of America"}, {"tag": "United States of America"}], "Director": [{"tag": "James Cameron"}], "Writer": [{"tag": "James Cameron"}], "Collection": [{"tag": "Working NL Subs"}, {"tag": "Working NL Subs"}], "Role": [{"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}, {"id": 294129, "filter": "actor=294129", "thumb": "https://metadata-static.plex.tv/2/people/27b85844536c39f3f9ac943aaad46608.jpg", "tag": "Mike Smith", "tagKey": "668e7e7b22bcad9064350c91", "role": "Self"}], "Location": [{"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}, {"path": "/TV Shows/House"}], "Guid": [{"id": "imdb://tt13015952"}, {"id": "imdb://tt13015952"}], "UltraBlurColors": {"topLeft": "11333b", "topRight": "0a232d", "bottomRight": "73958", "bottomLeft": "1f5066"}, "Rating": [{"image": "themoviedb://image.rating", "value": 3, "type": "audience"}], "Image": [{"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}, {"alt": "Episode 1", "type": "background", "url": "/library/metadata/45521/thumb/1644710589"}], "titleSort": "Whale", "viewCount": 1, "lastViewedAt": 1682752242, "originalTitle": "映画 ブラッククローバー 魔法帝の剣", "viewOffset": 5222500, "skipCount": 1, "index": 1, "theme": "/library/metadata/1/theme/1705636920", "leafCount": 14, "viewedLeafCount": 0, "childCount": 1, "hasPremiumExtras": "1", "hasPremiumPrimaryExtra": "1", "parentRatingKey": "66", "parentGuid": "plex://show/5d9c081b170e24001f2a7be4", "parentStudio": "UCP", "parentKey": "/library/metadata/66", "parentTitle": "Caprica", "parentIndex": 1, "parentYear": 2010, "parentThumb": "/library/metadata/66/thumb/1705716261", "parentTheme": "/library/metadata/66/theme/1705716261"}}]}} "400": application/json: {"errors": []} "401": application/json: {"errors": [{"code": 1001, "message": "User could not be authenticated", "status": 401}]} +generatedTests: {} diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 75b8e49..0b83a5a 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -13,7 +13,12 @@ generation: oAuth2ClientCredentialsEnabled: false oAuth2PasswordEnabled: false php: - version: 0.11.1 + version: 0.12.0 + additionalDependencies: + autoload: {} + autoload-dev: {} + require: {} + require-dev: {} clientServerStatusCodesAsErrors: true defaultErrorName: SDKException flattenGlobalSecurity: true diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index b3d1032..d489aa8 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,4 +1,4 @@ -speakeasyVersion: 1.438.3 +speakeasyVersion: 1.459.2 sources: my-source: sourceNamespace: my-source @@ -9,19 +9,19 @@ sources: - main plexapi: sourceNamespace: plexapi - sourceRevisionDigest: sha256:37c6bfb15f4154eb89b112465107f20757411f22bd1cc7d0a04335df7127fcb4 - sourceBlobDigest: sha256:290473ebc909cada80ff428c685b897f4621cf121397e1417355e06d334e7206 + sourceRevisionDigest: sha256:ccba0c42f1644923e2209e28da7a78195a843e48da1aeaaedbf8759f1a8a0fe0 + sourceBlobDigest: sha256:b362c110ef633288220a55ab50627374b996c64f2d9b8e020944e84ea2840332 tags: - latest - - main + - speakeasy-sdk-regen-1734739773 targets: plexphp: source: plexapi sourceNamespace: plexapi - sourceRevisionDigest: sha256:37c6bfb15f4154eb89b112465107f20757411f22bd1cc7d0a04335df7127fcb4 - sourceBlobDigest: sha256:290473ebc909cada80ff428c685b897f4621cf121397e1417355e06d334e7206 + sourceRevisionDigest: sha256:ccba0c42f1644923e2209e28da7a78195a843e48da1aeaaedbf8759f1a8a0fe0 + sourceBlobDigest: sha256:b362c110ef633288220a55ab50627374b996c64f2d9b8e020944e84ea2840332 codeSamplesNamespace: code-samples-php-plexphp - codeSamplesRevisionDigest: sha256:ec39a1baa000076369129c6d77614e8a87e3e5d12991082cbd1c60a9cc9e9c59 + codeSamplesRevisionDigest: sha256:8bb8bad6945558485d64a156003735f5f0ed2a978ff2565fc7fda7876790c5cb workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/README.md b/README.md index 3106f7a..08e5358 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,20 @@ The following SDKs are generated from the OpenAPI Specification. They are automa ## Table of Contents + +* [lukehagar/plex-api](#lukehagarplex-api) +* [Plex Media Server OpenAPI Specification](#plex-media-server-openapi-specification) + * [Documentation](#documentation) + * [SDKs](#sdks) + * [SDK Installation](#sdk-installation) + * [SDK Example Usage](#sdk-example-usage) + * [Available Resources and Operations](#available-resources-and-operations) + * [Error Handling](#error-handling) + * [Server Selection](#server-selection) +* [Development](#development) + * [Maturity](#maturity) + * [Contributions](#contributions) -* [SDK Installation](#sdk-installation) -* [SDK Example Usage](#sdk-example-usage) -* [Available Resources and Operations](#available-resources-and-operations) -* [Error Handling](#error-handling) -* [Server Selection](#server-selection) @@ -73,13 +81,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -101,119 +103,119 @@ if ($response->object !== null) { ### [activities](docs/sdks/activities/README.md) -* [getServerActivities](docs/sdks/activities/README.md#getserveractivities) - Get Server Activities * [cancelServerActivities](docs/sdks/activities/README.md#cancelserveractivities) - Cancel Server Activities +* [getServerActivities](docs/sdks/activities/README.md#getserveractivities) - Get Server Activities ### [authentication](docs/sdks/authentication/README.md) -* [getTransientToken](docs/sdks/authentication/README.md#gettransienttoken) - Get a Transient Token * [getSourceConnectionInformation](docs/sdks/authentication/README.md#getsourceconnectioninformation) - Get Source Connection Information * [getTokenDetails](docs/sdks/authentication/README.md#gettokendetails) - Get Token Details +* [getTransientToken](docs/sdks/authentication/README.md#gettransienttoken) - Get a Transient Token * [postUsersSignInData](docs/sdks/authentication/README.md#postuserssignindata) - Get User Sign In Data ### [butler](docs/sdks/butler/README.md) * [getButlerTasks](docs/sdks/butler/README.md#getbutlertasks) - Get Butler tasks * [startAllTasks](docs/sdks/butler/README.md#startalltasks) - Start all Butler tasks -* [stopAllTasks](docs/sdks/butler/README.md#stopalltasks) - Stop all Butler tasks * [startTask](docs/sdks/butler/README.md#starttask) - Start a single Butler task +* [stopAllTasks](docs/sdks/butler/README.md#stopalltasks) - Stop all Butler tasks * [stopTask](docs/sdks/butler/README.md#stoptask) - Stop a single Butler task ### [hubs](docs/sdks/hubs/README.md) -* [getGlobalHubs](docs/sdks/hubs/README.md#getglobalhubs) - Get Global Hubs * [getRecentlyAdded](docs/sdks/hubs/README.md#getrecentlyadded) - Get Recently Added +* [getGlobalHubs](docs/sdks/hubs/README.md#getglobalhubs) - Get Global Hubs * [getLibraryHubs](docs/sdks/hubs/README.md#getlibraryhubs) - Get library specific hubs ### [library](docs/sdks/library/README.md) -* [getFileHash](docs/sdks/library/README.md#getfilehash) - Get Hash Value -* [getRecentlyAddedLibrary](docs/sdks/library/README.md#getrecentlyaddedlibrary) - Get Recently Added +* [deleteLibrary](docs/sdks/library/README.md#deletelibrary) - Delete Library Section * [getAllLibraries](docs/sdks/library/README.md#getalllibraries) - Get All Libraries * [getLibraryDetails](docs/sdks/library/README.md#getlibrarydetails) - Get Library Details -* [deleteLibrary](docs/sdks/library/README.md#deletelibrary) - Delete Library Section * [getLibraryItems](docs/sdks/library/README.md#getlibraryitems) - Get Library Items +* [getMetaDataByRatingKey](docs/sdks/library/README.md#getmetadatabyratingkey) - Get Metadata by RatingKey +* [getRecentlyAddedLibrary](docs/sdks/library/README.md#getrecentlyaddedlibrary) - Get Recently Added * [getRefreshLibraryMetadata](docs/sdks/library/README.md#getrefreshlibrarymetadata) - Refresh Metadata Of The Library -* [getSearchLibrary](docs/sdks/library/README.md#getsearchlibrary) - Search Library * [getSearchAllLibraries](docs/sdks/library/README.md#getsearchalllibraries) - Search All Libraries -* [getMetaDataByRatingKey](docs/sdks/library/README.md#getmetadatabyratingkey) - Get Metadata by RatingKey +* [getSearchLibrary](docs/sdks/library/README.md#getsearchlibrary) - Search Library +* [getFileHash](docs/sdks/library/README.md#getfilehash) - Get Hash Value * [getMetadataChildren](docs/sdks/library/README.md#getmetadatachildren) - Get Items Children -* [getTopWatchedContent](docs/sdks/library/README.md#gettopwatchedcontent) - Get Top Watched Content * [getOnDeck](docs/sdks/library/README.md#getondeck) - Get On Deck +* [getTopWatchedContent](docs/sdks/library/README.md#gettopwatchedcontent) - Get Top Watched Content ### [log](docs/sdks/log/README.md) +* [enablePaperTrail](docs/sdks/log/README.md#enablepapertrail) - Enabling Papertrail * [logLine](docs/sdks/log/README.md#logline) - Logging a single line message. * [logMultiLine](docs/sdks/log/README.md#logmultiline) - Logging a multi-line message -* [enablePaperTrail](docs/sdks/log/README.md#enablepapertrail) - Enabling Papertrail ### [media](docs/sdks/media/README.md) +* [getBannerImage](docs/sdks/media/README.md#getbannerimage) - Get Banner Image +* [getThumbImage](docs/sdks/media/README.md#getthumbimage) - Get Thumb Image * [markPlayed](docs/sdks/media/README.md#markplayed) - Mark Media Played * [markUnplayed](docs/sdks/media/README.md#markunplayed) - Mark Media Unplayed * [updatePlayProgress](docs/sdks/media/README.md#updateplayprogress) - Update Media Play Progress -* [getBannerImage](docs/sdks/media/README.md#getbannerimage) - Get Banner Image -* [getThumbImage](docs/sdks/media/README.md#getthumbimage) - Get Thumb Image ### [playlists](docs/sdks/playlists/README.md) +* [addPlaylistContents](docs/sdks/playlists/README.md#addplaylistcontents) - Adding to a Playlist +* [clearPlaylistContents](docs/sdks/playlists/README.md#clearplaylistcontents) - Delete Playlist Contents * [createPlaylist](docs/sdks/playlists/README.md#createplaylist) - Create a Playlist -* [getPlaylists](docs/sdks/playlists/README.md#getplaylists) - Get All Playlists -* [getPlaylist](docs/sdks/playlists/README.md#getplaylist) - Retrieve Playlist * [deletePlaylist](docs/sdks/playlists/README.md#deleteplaylist) - Deletes a Playlist -* [updatePlaylist](docs/sdks/playlists/README.md#updateplaylist) - Update a Playlist +* [getPlaylist](docs/sdks/playlists/README.md#getplaylist) - Retrieve Playlist * [getPlaylistContents](docs/sdks/playlists/README.md#getplaylistcontents) - Retrieve Playlist Contents -* [clearPlaylistContents](docs/sdks/playlists/README.md#clearplaylistcontents) - Delete Playlist Contents -* [addPlaylistContents](docs/sdks/playlists/README.md#addplaylistcontents) - Adding to a Playlist +* [getPlaylists](docs/sdks/playlists/README.md#getplaylists) - Get All Playlists +* [updatePlaylist](docs/sdks/playlists/README.md#updateplaylist) - Update a Playlist * [uploadPlaylist](docs/sdks/playlists/README.md#uploadplaylist) - Upload Playlist ### [plex](docs/sdks/plex/README.md) +* [getServerResources](docs/sdks/plex/README.md#getserverresources) - Get Server Resources * [getCompanionsData](docs/sdks/plex/README.md#getcompanionsdata) - Get Companions Data -* [getUserFriends](docs/sdks/plex/README.md#getuserfriends) - Get list of friends of the user logged in * [getGeoData](docs/sdks/plex/README.md#getgeodata) - Get Geo Data * [getHomeData](docs/sdks/plex/README.md#gethomedata) - Get Plex Home Data -* [getServerResources](docs/sdks/plex/README.md#getserverresources) - Get Server Resources * [getPin](docs/sdks/plex/README.md#getpin) - Get a Pin * [getTokenByPinId](docs/sdks/plex/README.md#gettokenbypinid) - Get Access Token by PinId +* [getUserFriends](docs/sdks/plex/README.md#getuserfriends) - Get list of friends of the user logged in ### [search](docs/sdks/search/README.md) +* [getSearchResults](docs/sdks/search/README.md#getsearchresults) - Get Search Results * [performSearch](docs/sdks/search/README.md#performsearch) - Perform a search * [performVoiceSearch](docs/sdks/search/README.md#performvoicesearch) - Perform a voice search -* [getSearchResults](docs/sdks/search/README.md#getsearchresults) - Get Search Results ### [server](docs/sdks/server/README.md) -* [getServerCapabilities](docs/sdks/server/README.md#getservercapabilities) - Get Server Capabilities -* [getServerPreferences](docs/sdks/server/README.md#getserverpreferences) - Get Server Preferences +* [getMediaProviders](docs/sdks/server/README.md#getmediaproviders) - Get Media Providers +* [getServerIdentity](docs/sdks/server/README.md#getserveridentity) - Get Server Identity * [getAvailableClients](docs/sdks/server/README.md#getavailableclients) - Get Available Clients * [getDevices](docs/sdks/server/README.md#getdevices) - Get Devices -* [getServerIdentity](docs/sdks/server/README.md#getserveridentity) - Get Server Identity * [getMyPlexAccount](docs/sdks/server/README.md#getmyplexaccount) - Get MyPlex Account * [getResizedPhoto](docs/sdks/server/README.md#getresizedphoto) - Get a Resized Photo -* [getMediaProviders](docs/sdks/server/README.md#getmediaproviders) - Get Media Providers +* [getServerCapabilities](docs/sdks/server/README.md#getservercapabilities) - Get Server Capabilities * [getServerList](docs/sdks/server/README.md#getserverlist) - Get Server List +* [getServerPreferences](docs/sdks/server/README.md#getserverpreferences) - Get Server Preferences ### [sessions](docs/sdks/sessions/README.md) -* [getSessions](docs/sdks/sessions/README.md#getsessions) - Get Active Sessions * [getSessionHistory](docs/sdks/sessions/README.md#getsessionhistory) - Get Session History +* [getSessions](docs/sdks/sessions/README.md#getsessions) - Get Active Sessions * [getTranscodeSessions](docs/sdks/sessions/README.md#gettranscodesessions) - Get Transcode Sessions * [stopTranscodeSession](docs/sdks/sessions/README.md#stoptranscodesession) - Stop a Transcode Session ### [statistics](docs/sdks/statistics/README.md) -* [getStatistics](docs/sdks/statistics/README.md#getstatistics) - Get Media Statistics -* [getResourcesStatistics](docs/sdks/statistics/README.md#getresourcesstatistics) - Get Resources Statistics * [getBandwidthStatistics](docs/sdks/statistics/README.md#getbandwidthstatistics) - Get Bandwidth Statistics +* [getResourcesStatistics](docs/sdks/statistics/README.md#getresourcesstatistics) - Get Resources Statistics +* [getStatistics](docs/sdks/statistics/README.md#getstatistics) - Get Media Statistics ### [updater](docs/sdks/updater/README.md) -* [getUpdateStatus](docs/sdks/updater/README.md#getupdatestatus) - Querying status of updates -* [checkForUpdates](docs/sdks/updater/README.md#checkforupdates) - Checking for updates * [applyUpdates](docs/sdks/updater/README.md#applyupdates) - Apply Updates +* [checkForUpdates](docs/sdks/updater/README.md#checkforupdates) - Checking for updates +* [getUpdateStatus](docs/sdks/updater/README.md#getupdatestatus) - Querying status of updates ### [video](docs/sdks/video/README.md) @@ -241,13 +243,13 @@ By default an API error will raise a `Errors\SDKException` exception, which has | `$rawResponse` | *?\Psr\Http\Message\ResponseInterface* | The raw HTTP response | | `$body` | *string* | The response content | -When custom error responses are specified for an operation, the SDK may also throw their associated exception. You can refer to respective *Errors* tables in SDK docs for more details on possible exception types for each operation. For example, the `getServerCapabilities` method throws the following exceptions: +When custom error responses are specified for an operation, the SDK may also throw their associated exception. You can refer to respective *Errors* tables in SDK docs for more details on possible exception types for each operation. For example, the `getMediaProviders` method throws the following exceptions: -| Error Type | Status Code | Content Type | -| ---------------------------------------- | ----------- | ---------------- | -| Errors\GetServerCapabilitiesBadRequest | 400 | application/json | -| Errors\GetServerCapabilitiesUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------------ | ----------- | ---------------- | +| Errors\GetMediaProvidersBadRequest | 400 | application/json | +| Errors\GetMediaProvidersUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ### Example @@ -260,26 +262,20 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); try { - $response = $sdk->server->getServerCapabilities( - + $response = $sdk->server->getMediaProviders( + xPlexToken: 'CV5xoxjTpFKUzBTShsaf' ); if ($response->object !== null) { // handle response } -} catch (Errors\GetServerCapabilitiesBadRequestThrowable $e) { +} catch (Errors\GetMediaProvidersBadRequestThrowable $e) { // handle $e->$container data throw $e; -} catch (Errors\GetServerCapabilitiesUnauthorizedThrowable $e) { +} catch (Errors\GetMediaProvidersUnauthorizedThrowable $e) { // handle $e->$container data throw $e; } catch (Errors\SDKException $e) { @@ -312,18 +308,13 @@ use LukeHagar\Plex_API; $security = ''; $sdk = Plex_API\PlexAPI::builder() - ->setServerURL("https://10.10.10.47:32400") - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') + ->setServerURL('https://10.10.10.47:32400') ->setSecurity($security)->build(); -$response = $sdk->server->getServerCapabilities( - +$response = $sdk->server->getMediaProviders( + xPlexToken: 'CV5xoxjTpFKUzBTShsaf' ); if ($response->object !== null) { @@ -340,24 +331,24 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); + +$response = $sdk->plex->getServerResources( + 'https://plex.tv/api/v2', + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + includeHttps: Operations\IncludeHttps::Enable, + includeRelay: Operations\IncludeRelay::Enable, + includeIPv6: Operations\IncludeIPv6::Enable -$response = $sdk->plex->getCompanionsData( - "https://plex.tv/api/v2" ); -if ($response->responseBodies !== null) { +if ($response->plexDevices !== null) { // handle response } ``` diff --git a/RELEASES.md b/RELEASES.md index aa7d2ff..70777bf 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -712,4 +712,14 @@ Based on: ### Generated - [php v0.11.1] . ### Releases -- [Composer v0.11.1] https://packagist.org/packages/lukehagar/plex-api#v0.11.1 - . \ No newline at end of file +- [Composer v0.11.1] https://packagist.org/packages/lukehagar/plex-api#v0.11.1 - . + +## 2024-12-21 00:09:29 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.459.2 (2.483.1) https://github.com/speakeasy-api/speakeasy +### Generated +- [php v0.12.0] . +### Releases +- [Composer v0.12.0] https://packagist.org/packages/lukehagar/plex-api#v0.12.0 - . \ No newline at end of file diff --git a/USAGE.md b/USAGE.md index 99d6e91..5af5518 100644 --- a/USAGE.md +++ b/USAGE.md @@ -8,18 +8,12 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->server->getServerCapabilities( - +$response = $sdk->server->getMediaProviders( + xPlexToken: 'CV5xoxjTpFKUzBTShsaf' ); if ($response->object !== null) { diff --git a/codeSamples.yaml b/codeSamples.yaml index e128103..9d767cf 100644 --- a/codeSamples.yaml +++ b/codeSamples.yaml @@ -17,13 +17,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -48,13 +42,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -79,13 +67,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -113,13 +95,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -145,13 +121,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetTimelineRequest( ratingKey: 23409, @@ -187,13 +157,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -218,13 +182,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -249,13 +207,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -280,13 +232,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -311,13 +257,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -342,13 +282,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -374,13 +308,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -406,13 +334,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -437,13 +359,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -468,13 +384,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -499,13 +409,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -530,13 +434,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -559,13 +457,7 @@ actions: use LukeHagar\Plex_API; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); + $sdk = Plex_API\PlexAPI::builder()->build(); @@ -590,13 +482,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -622,13 +508,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -656,13 +536,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetRecentlyAddedRequest( contentDirectoryID: 470161, @@ -694,13 +568,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -728,13 +596,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -763,13 +625,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -795,13 +651,7 @@ actions: use LukeHagar\Plex_API; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); + $sdk = Plex_API\PlexAPI::builder()->build(); @@ -827,13 +677,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -860,13 +704,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -893,13 +731,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -925,13 +757,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetBannerImageRequest( ratingKey: 9518, @@ -963,13 +789,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -997,13 +817,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetThumbImageRequest( ratingKey: 9518, @@ -1035,13 +849,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1067,13 +875,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetRecentlyAddedLibraryRequest( contentDirectoryID: 2, @@ -1120,16 +922,11 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetSearchAllLibrariesRequest( query: '', + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', searchTypes: [ Operations\SearchTypes::People, ], @@ -1158,13 +955,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1190,13 +981,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetWatchListRequest( filter: Operations\Filter::Available, @@ -1226,13 +1011,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1258,13 +1037,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1292,13 +1065,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1326,13 +1093,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1360,13 +1121,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetLibraryItemsRequest( tag: Operations\Tag::Edition, @@ -1400,13 +1155,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1434,13 +1183,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = 'level=4&message=Test%20message%201&source=postman level=3&message=Test%20message%202&source=postman @@ -1467,13 +1210,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1498,13 +1235,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1529,13 +1260,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1561,13 +1286,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetResizedPhotoRequest( width: 110, @@ -1599,15 +1318,15 @@ actions: use LukeHagar\Plex_API; use LukeHagar\Plex_API\Models\Operations; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); + $sdk = Plex_API\PlexAPI::builder()->build(); - $request = new Operations\GetPinRequest(); + $request = new Operations\GetPinRequest( + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + clientName: 'Plex for Roku', + deviceNickname: 'Roku 3', + clientVersion: '2.4.1', + platform: 'Roku', + ); $response = $sdk->plex->getPin( request: $request @@ -1629,16 +1348,15 @@ actions: use LukeHagar\Plex_API; use LukeHagar\Plex_API\Models\Operations; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); + $sdk = Plex_API\PlexAPI::builder()->build(); $request = new Operations\GetTokenByPinIdRequest( pinID: 408895, + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + clientName: 'Plex for Roku', + deviceNickname: 'Roku 3', + clientVersion: '2.4.1', + platform: 'Roku', ); $response = $sdk->plex->getTokenByPinId( @@ -1663,13 +1381,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1697,13 +1409,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\CreatePlaylistRequest( title: '', @@ -1734,13 +1440,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1768,13 +1468,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1799,13 +1493,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1830,13 +1518,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1864,13 +1546,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1896,13 +1572,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1929,13 +1599,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -1964,21 +1628,15 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $response = $sdk->plex->getServerResources( + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', includeHttps: Operations\IncludeHttps::Enable, includeRelay: Operations\IncludeRelay::Enable, - includeIPv6: Operations\IncludeIPv6::Enable, - clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58' + includeIPv6: Operations\IncludeIPv6::Enable ); @@ -1999,13 +1657,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2030,13 +1682,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2062,13 +1708,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2095,13 +1735,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2126,13 +1760,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2157,13 +1785,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2188,13 +1810,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2219,13 +1835,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2251,13 +1861,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $filter = new Operations\QueryParamFilter(); @@ -2286,13 +1890,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2317,13 +1915,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2349,13 +1941,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2383,13 +1969,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2414,13 +1994,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2445,13 +2019,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -2475,15 +2043,14 @@ actions: use LukeHagar\Plex_API; use LukeHagar\Plex_API\Models\Operations; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); + $sdk = Plex_API\PlexAPI::builder()->build(); $request = new Operations\PostUsersSignInDataRequest( + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + clientName: 'Plex for Roku', + deviceNickname: 'Roku 3', + clientVersion: '2.4.1', + platform: 'Roku', requestBody: new Operations\PostUsersSignInDataRequestBody( login: 'username@email.com', password: 'password123', @@ -2513,13 +2080,7 @@ actions: $security = ''; - $sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); + $sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\StartUniversalTranscodeRequest( hasMDE: 1, diff --git a/composer.json b/composer.json index b08e2db..8a38c76 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "license": "MIT", "require": { "php": "^8.2", + "galbar/jsonpath": "^3.0", "guzzlehttp/guzzle": "^7.0", "speakeasy/serializer": "^4.0.0", "brick/date-time": "^0.7.0", @@ -27,14 +28,15 @@ "config": { "optimize-autoloader": true, "classmap-authoritative": true, - "sort-packages": true + "sort-packages": true, + "process-timeout": 60 }, "scripts": { "test": [ "./vendor/bin/phpunit --testdox --display-warnings --colors=always" ], "stan": [ - "./vendor/bin/phpstan analyse --memory-limit=2g" + "./vendor/bin/phpstan analyse --memory-limit=2g --error-format=table" ] }, "script-descriptions": { diff --git a/docs/Models/Operations/GetLibraryItemsMetadata.md b/docs/Models/Operations/GetLibraryItemsMetadata.md index 3f583fa..e5c5c03 100644 --- a/docs/Models/Operations/GetLibraryItemsMetadata.md +++ b/docs/Models/Operations/GetLibraryItemsMetadata.md @@ -25,7 +25,7 @@ | `seasonCount` | *?int* | :heavy_minus_sign: | N/A | 2022 | | `tagline` | *?string* | :heavy_minus_sign: | N/A | Return to Pandora. | | `flattenSeasons` | [?Operations\GetLibraryItemsFlattenSeasons](../../Models/Operations/GetLibraryItemsFlattenSeasons.md) | :heavy_minus_sign: | N/A | 1 | -| `showOrdering` | [?Operations\GetLibraryItemsShowOrdering](../../Models/Operations/GetLibraryItemsShowOrdering.md) | :heavy_minus_sign: | Setting that indicates the episode ordering for the show
None = Library default,
tmdbAiring = The Movie Database (Aired),
aired = TheTVDB (Aired),
dvd = TheTVDB (DVD),
absolute = TheTVDB (Absolute)).
| dvd | +| `showOrdering` | [?Operations\GetLibraryItemsShowOrdering](../../Models/Operations/GetLibraryItemsShowOrdering.md) | :heavy_minus_sign: | Setting that indicates the episode ordering for the show
None = Library default,
tmdbAiring = The Movie Database (Aired),
tvdbAiring = TheTVDB (Aired),
tvdbDvd = TheTVDB (DVD),
tvdbAbsolute = TheTVDB (Absolute)).
| tvdbDvd | | `thumb` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/thumb/1703239236 | | `art` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/art/1703239236 | | `banner` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/banner/1703239236 | diff --git a/docs/Models/Operations/GetLibraryItemsQueryParamType.md b/docs/Models/Operations/GetLibraryItemsQueryParamType.md index 3add83f..c0b1304 100644 --- a/docs/Models/Operations/GetLibraryItemsQueryParamType.md +++ b/docs/Models/Operations/GetLibraryItemsQueryParamType.md @@ -17,4 +17,6 @@ E.g. A movie library will not return anything with type 3 as there are no season | `TvShow` | 2 | | `Season` | 3 | | `Episode` | 4 | -| `Audio` | 8 | \ No newline at end of file +| `Audio` | 8 | +| `Album` | 9 | +| `Track` | 10 | \ No newline at end of file diff --git a/docs/Models/Operations/GetLibraryItemsShowOrdering.md b/docs/Models/Operations/GetLibraryItemsShowOrdering.md index 1d7aa8c..a82729c 100644 --- a/docs/Models/Operations/GetLibraryItemsShowOrdering.md +++ b/docs/Models/Operations/GetLibraryItemsShowOrdering.md @@ -1,20 +1,20 @@ # GetLibraryItemsShowOrdering -Setting that indicates the episode ordering for the show -None = Library default, -tmdbAiring = The Movie Database (Aired), -aired = TheTVDB (Aired), -dvd = TheTVDB (DVD), -absolute = TheTVDB (Absolute)). +Setting that indicates the episode ordering for the show +None = Library default, +tmdbAiring = The Movie Database (Aired), +tvdbAiring = TheTVDB (Aired), +tvdbDvd = TheTVDB (DVD), +tvdbAbsolute = TheTVDB (Absolute)). ## Values -| Name | Value | -| ------------ | ------------ | -| `None` | None | -| `TmdbAiring` | tmdbAiring | -| `Aired` | aired | -| `Dvd` | dvd | -| `Absolute` | absolute | \ No newline at end of file +| Name | Value | +| -------------- | -------------- | +| `None` | None | +| `TmdbAiring` | tmdbAiring | +| `TvdbAiring` | tvdbAiring | +| `TvdbDvd` | tvdbDvd | +| `TvdbAbsolute` | tvdbAbsolute | \ No newline at end of file diff --git a/docs/Models/Operations/GetMetaDataByRatingKeyMetadata.md b/docs/Models/Operations/GetMetaDataByRatingKeyMetadata.md index 21dd078..c4da7d4 100644 --- a/docs/Models/Operations/GetMetaDataByRatingKeyMetadata.md +++ b/docs/Models/Operations/GetMetaDataByRatingKeyMetadata.md @@ -14,6 +14,11 @@ | `librarySectionTitle` | *?string* | :heavy_minus_sign: | N/A | Movies | | `librarySectionID` | *?int* | :heavy_minus_sign: | N/A | 1 | | `librarySectionKey` | *?string* | :heavy_minus_sign: | N/A | /library/sections/1 | +| `grandparentTitle` | *?string* | :heavy_minus_sign: | The name of the album artist for the track when audio, and the name of the TV show for the episode when video. | | +| `parentTitle` | *?string* | :heavy_minus_sign: | The name of the album for the track when audio, and the name of the season for the episode when TV show. | | +| `originalTitle` | *?string* | :heavy_minus_sign: | The orginal untranslated name of the media item when non-english. | | +| `index` | *?int* | :heavy_minus_sign: | The index starting from 0 of this media item in the MetaData array. | | +| `parentIndex` | *?int* | :heavy_minus_sign: | The parent index starting from 0 of this media item in the parent MetaData array. | | | `contentRating` | *?string* | :heavy_minus_sign: | N/A | PG-13 | | `summary` | *?string* | :heavy_minus_sign: | N/A | Serenity continues the story of the TV series it was based upon ("Firefly"). River Tam had a secret - one in which she's not even aware - so dangerous, no one's safe, as an Alliance operative's sent to capture her, and all others are considered irrelevant to his job. | | `rating` | *?float* | :heavy_minus_sign: | N/A | 8.2 | diff --git a/docs/Models/Operations/GetPinRequest.md b/docs/Models/Operations/GetPinRequest.md index 7b9b393..4f96acd 100644 --- a/docs/Models/Operations/GetPinRequest.md +++ b/docs/Models/Operations/GetPinRequest.md @@ -5,8 +5,8 @@ | Field | Type | Required | Description | Example | | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `clientID` | *string* | :heavy_check_mark: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | | `strong` | *?bool* | :heavy_minus_sign: | Determines the kind of code returned by the API call
Strong codes are used for Pin authentication flows
Non-Strong codes are used for `Plex.tv/link`
| | -| `clientID` | *?string* | :heavy_minus_sign: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | | `clientName` | *?string* | :heavy_minus_sign: | The name of the client application. (Plex Web, Plex Media Server, etc.) | Plex for Roku | | `deviceNickname` | *?string* | :heavy_minus_sign: | A relatively friendly name for the client device | Roku 3 | | `clientVersion` | *?string* | :heavy_minus_sign: | The version of the client application. | 2.4.1 | diff --git a/docs/Models/Operations/GetPlaylistContentsQueryParamType.md b/docs/Models/Operations/GetPlaylistContentsQueryParamType.md index 7defe60..b5b34ab 100644 --- a/docs/Models/Operations/GetPlaylistContentsQueryParamType.md +++ b/docs/Models/Operations/GetPlaylistContentsQueryParamType.md @@ -17,4 +17,6 @@ E.g. A movie library will not return anything with type 3 as there are no season | `TvShow` | 2 | | `Season` | 3 | | `Episode` | 4 | -| `Audio` | 8 | \ No newline at end of file +| `Audio` | 8 | +| `Album` | 9 | +| `Track` | 10 | \ No newline at end of file diff --git a/docs/Models/Operations/GetRecentlyAddedMetadata.md b/docs/Models/Operations/GetRecentlyAddedMetadata.md index 64d0a10..02b1f8a 100644 --- a/docs/Models/Operations/GetRecentlyAddedMetadata.md +++ b/docs/Models/Operations/GetRecentlyAddedMetadata.md @@ -25,7 +25,7 @@ | `seasonCount` | *?int* | :heavy_minus_sign: | N/A | 2022 | | `tagline` | *?string* | :heavy_minus_sign: | N/A | Return to Pandora. | | `flattenSeasons` | [?Operations\FlattenSeasons](../../Models/Operations/FlattenSeasons.md) | :heavy_minus_sign: | N/A | 1 | -| `showOrdering` | [?Operations\ShowOrdering](../../Models/Operations/ShowOrdering.md) | :heavy_minus_sign: | Setting that indicates the episode ordering for the show
None = Library default,
tmdbAiring = The Movie Database (Aired),
aired = TheTVDB (Aired),
dvd = TheTVDB (DVD),
absolute = TheTVDB (Absolute)).
| dvd | +| `showOrdering` | [?Operations\ShowOrdering](../../Models/Operations/ShowOrdering.md) | :heavy_minus_sign: | Setting that indicates the episode ordering for the show
None = Library default,
tmdbAiring = The Movie Database (Aired),
tvdbAiring = TheTVDB (Aired),
tvdbDvd = TheTVDB (DVD),
tvdbAbsolute = TheTVDB (Absolute)).
| tvdbDvd | | `thumb` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/thumb/1703239236 | | `art` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/art/1703239236 | | `banner` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/banner/1703239236 | diff --git a/docs/Models/Operations/GetSearchAllLibrariesMetadata.md b/docs/Models/Operations/GetSearchAllLibrariesMetadata.md index 5f26097..b9f50b5 100644 --- a/docs/Models/Operations/GetSearchAllLibrariesMetadata.md +++ b/docs/Models/Operations/GetSearchAllLibrariesMetadata.md @@ -25,7 +25,7 @@ | `seasonCount` | *?int* | :heavy_minus_sign: | N/A | 2022 | | `tagline` | *?string* | :heavy_minus_sign: | N/A | Return to Pandora. | | `flattenSeasons` | [?Operations\GetSearchAllLibrariesFlattenSeasons](../../Models/Operations/GetSearchAllLibrariesFlattenSeasons.md) | :heavy_minus_sign: | N/A | 1 | -| `showOrdering` | [?Operations\GetSearchAllLibrariesShowOrdering](../../Models/Operations/GetSearchAllLibrariesShowOrdering.md) | :heavy_minus_sign: | Setting that indicates the episode ordering for the show
None = Library default,
tmdbAiring = The Movie Database (Aired),
aired = TheTVDB (Aired),
dvd = TheTVDB (DVD),
absolute = TheTVDB (Absolute)).
| dvd | +| `showOrdering` | [?Operations\GetSearchAllLibrariesShowOrdering](../../Models/Operations/GetSearchAllLibrariesShowOrdering.md) | :heavy_minus_sign: | Setting that indicates the episode ordering for the show
None = Library default,
tmdbAiring = The Movie Database (Aired),
tvdbAiring = TheTVDB (Aired),
tvdbDvd = TheTVDB (DVD),
tvdbAbsolute = TheTVDB (Absolute)).
| tvdbDvd | | `thumb` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/thumb/1703239236 | | `art` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/art/1703239236 | | `banner` | *?string* | :heavy_minus_sign: | N/A | /library/metadata/58683/banner/1703239236 | diff --git a/docs/Models/Operations/GetSearchAllLibrariesRequest.md b/docs/Models/Operations/GetSearchAllLibrariesRequest.md index bb99057..814f826 100644 --- a/docs/Models/Operations/GetSearchAllLibrariesRequest.md +++ b/docs/Models/Operations/GetSearchAllLibrariesRequest.md @@ -6,7 +6,7 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | `query` | *string* | :heavy_check_mark: | The search query term. | | -| `clientID` | *?string* | :heavy_minus_sign: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | +| `clientID` | *string* | :heavy_check_mark: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | | `limit` | *?int* | :heavy_minus_sign: | Limit the number of results returned. | | | `searchTypes` | array<[Operations\SearchTypes](../../Models/Operations/SearchTypes.md)> | :heavy_minus_sign: | A comma-separated list of search types to include. Valid values are: movies, music, otherVideos, people, tv.
| movies,music,otherVideos,people,tv | | `includeCollections` | [?Operations\QueryParamIncludeCollections](../../Models/Operations/QueryParamIncludeCollections.md) | :heavy_minus_sign: | Whether to include collections in the search results. | 1 | diff --git a/docs/Models/Operations/GetSearchAllLibrariesShowOrdering.md b/docs/Models/Operations/GetSearchAllLibrariesShowOrdering.md index 5876c45..fc54022 100644 --- a/docs/Models/Operations/GetSearchAllLibrariesShowOrdering.md +++ b/docs/Models/Operations/GetSearchAllLibrariesShowOrdering.md @@ -1,20 +1,20 @@ # GetSearchAllLibrariesShowOrdering -Setting that indicates the episode ordering for the show -None = Library default, -tmdbAiring = The Movie Database (Aired), -aired = TheTVDB (Aired), -dvd = TheTVDB (DVD), -absolute = TheTVDB (Absolute)). +Setting that indicates the episode ordering for the show +None = Library default, +tmdbAiring = The Movie Database (Aired), +tvdbAiring = TheTVDB (Aired), +tvdbDvd = TheTVDB (DVD), +tvdbAbsolute = TheTVDB (Absolute)). ## Values -| Name | Value | -| ------------ | ------------ | -| `None` | None | -| `TmdbAiring` | tmdbAiring | -| `Aired` | aired | -| `Dvd` | dvd | -| `Absolute` | absolute | \ No newline at end of file +| Name | Value | +| -------------- | -------------- | +| `None` | None | +| `TmdbAiring` | tmdbAiring | +| `TvdbAiring` | tvdbAiring | +| `TvdbDvd` | tvdbDvd | +| `TvdbAbsolute` | tvdbAbsolute | \ No newline at end of file diff --git a/docs/Models/Operations/GetSearchLibraryQueryParamType.md b/docs/Models/Operations/GetSearchLibraryQueryParamType.md index 7242bfd..9e3a482 100644 --- a/docs/Models/Operations/GetSearchLibraryQueryParamType.md +++ b/docs/Models/Operations/GetSearchLibraryQueryParamType.md @@ -17,4 +17,6 @@ E.g. A movie library will not return anything with type 3 as there are no season | `TvShow` | 2 | | `Season` | 3 | | `Episode` | 4 | -| `Audio` | 8 | \ No newline at end of file +| `Audio` | 8 | +| `Album` | 9 | +| `Track` | 10 | \ No newline at end of file diff --git a/docs/Models/Operations/GetServerResourcesRequest.md b/docs/Models/Operations/GetServerResourcesRequest.md index cf9235f..1d3ab8e 100644 --- a/docs/Models/Operations/GetServerResourcesRequest.md +++ b/docs/Models/Operations/GetServerResourcesRequest.md @@ -5,7 +5,7 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | +| `clientID` | *string* | :heavy_check_mark: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | | `includeHttps` | [?Operations\IncludeHttps](../../Models/Operations/IncludeHttps.md) | :heavy_minus_sign: | Include Https entries in the results | 1 | | `includeRelay` | [?Operations\IncludeRelay](../../Models/Operations/IncludeRelay.md) | :heavy_minus_sign: | Include Relay addresses in the results
E.g: https://10-0-0-25.bbf8e10c7fa20447cacee74cd9914cde.plex.direct:32400
| 1 | -| `includeIPv6` | [?Operations\IncludeIPv6](../../Models/Operations/IncludeIPv6.md) | :heavy_minus_sign: | Include IPv6 entries in the results | 1 | -| `clientID` | *?string* | :heavy_minus_sign: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | \ No newline at end of file +| `includeIPv6` | [?Operations\IncludeIPv6](../../Models/Operations/IncludeIPv6.md) | :heavy_minus_sign: | Include IPv6 entries in the results | 1 | \ No newline at end of file diff --git a/docs/Models/Operations/GetTokenByPinIdRequest.md b/docs/Models/Operations/GetTokenByPinIdRequest.md index ec9931d..6aaf238 100644 --- a/docs/Models/Operations/GetTokenByPinIdRequest.md +++ b/docs/Models/Operations/GetTokenByPinIdRequest.md @@ -6,7 +6,7 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | | `pinID` | *int* | :heavy_check_mark: | The PinID to retrieve an access token for | | -| `clientID` | *?string* | :heavy_minus_sign: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | +| `clientID` | *string* | :heavy_check_mark: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | | `clientName` | *?string* | :heavy_minus_sign: | The name of the client application. (Plex Web, Plex Media Server, etc.) | Plex for Roku | | `deviceNickname` | *?string* | :heavy_minus_sign: | A relatively friendly name for the client device | Roku 3 | | `clientVersion` | *?string* | :heavy_minus_sign: | The version of the client application. | 2.4.1 | diff --git a/docs/Models/Operations/GetTopWatchedContentQueryParamType.md b/docs/Models/Operations/GetTopWatchedContentQueryParamType.md index c178f9e..6736d2a 100644 --- a/docs/Models/Operations/GetTopWatchedContentQueryParamType.md +++ b/docs/Models/Operations/GetTopWatchedContentQueryParamType.md @@ -17,4 +17,6 @@ E.g. A movie library will not return anything with type 3 as there are no season | `TvShow` | 2 | | `Season` | 3 | | `Episode` | 4 | -| `Audio` | 8 | \ No newline at end of file +| `Audio` | 8 | +| `Album` | 9 | +| `Track` | 10 | \ No newline at end of file diff --git a/docs/Models/Operations/PostUsersSignInDataRequest.md b/docs/Models/Operations/PostUsersSignInDataRequest.md index 7744f6d..9d1c826 100644 --- a/docs/Models/Operations/PostUsersSignInDataRequest.md +++ b/docs/Models/Operations/PostUsersSignInDataRequest.md @@ -5,7 +5,7 @@ | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| `clientID` | *?string* | :heavy_minus_sign: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | +| `clientID` | *string* | :heavy_check_mark: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | | `clientName` | *?string* | :heavy_minus_sign: | The name of the client application. (Plex Web, Plex Media Server, etc.) | Plex for Roku | | `deviceNickname` | *?string* | :heavy_minus_sign: | A relatively friendly name for the client device | Roku 3 | | `clientVersion` | *?string* | :heavy_minus_sign: | The version of the client application. | 2.4.1 | diff --git a/docs/Models/Operations/QueryParamType.md b/docs/Models/Operations/QueryParamType.md index 326696d..13fedec 100644 --- a/docs/Models/Operations/QueryParamType.md +++ b/docs/Models/Operations/QueryParamType.md @@ -17,4 +17,6 @@ E.g. A movie library will not return anything with type 3 as there are no season | `TvShow` | 2 | | `Season` | 3 | | `Episode` | 4 | -| `Audio` | 8 | \ No newline at end of file +| `Audio` | 8 | +| `Album` | 9 | +| `Track` | 10 | \ No newline at end of file diff --git a/docs/Models/Operations/ShowOrdering.md b/docs/Models/Operations/ShowOrdering.md index b8a243b..f969631 100644 --- a/docs/Models/Operations/ShowOrdering.md +++ b/docs/Models/Operations/ShowOrdering.md @@ -1,20 +1,20 @@ # ShowOrdering -Setting that indicates the episode ordering for the show -None = Library default, -tmdbAiring = The Movie Database (Aired), -aired = TheTVDB (Aired), -dvd = TheTVDB (DVD), -absolute = TheTVDB (Absolute)). +Setting that indicates the episode ordering for the show +None = Library default, +tmdbAiring = The Movie Database (Aired), +tvdbAiring = TheTVDB (Aired), +tvdbDvd = TheTVDB (DVD), +tvdbAbsolute = TheTVDB (Absolute)). ## Values -| Name | Value | -| ------------ | ------------ | -| `None` | None | -| `TmdbAiring` | tmdbAiring | -| `Aired` | aired | -| `Dvd` | dvd | -| `Absolute` | absolute | \ No newline at end of file +| Name | Value | +| -------------- | -------------- | +| `None` | None | +| `TmdbAiring` | tmdbAiring | +| `TvdbAiring` | tvdbAiring | +| `TvdbDvd` | tvdbDvd | +| `TvdbAbsolute` | tvdbAbsolute | \ No newline at end of file diff --git a/docs/Models/Operations/Tag.md b/docs/Models/Operations/Tag.md index 99c8927..8524353 100644 --- a/docs/Models/Operations/Tag.md +++ b/docs/Models/Operations/Tag.md @@ -25,4 +25,5 @@ A key representing a specific tag within the section. | `Rating` | rating | | `Resolution` | resolution | | `FirstCharacter` | firstCharacter | -| `Folder` | folder | \ No newline at end of file +| `Folder` | folder | +| `Albums` | albums | \ No newline at end of file diff --git a/docs/Models/Operations/Type.md b/docs/Models/Operations/Type.md index 1ef815d..e0e804e 100644 --- a/docs/Models/Operations/Type.md +++ b/docs/Models/Operations/Type.md @@ -17,4 +17,6 @@ E.g. A movie library will not return anything with type 3 as there are no season | `TvShow` | 2 | | `Season` | 3 | | `Episode` | 4 | -| `Audio` | 8 | \ No newline at end of file +| `Audio` | 8 | +| `Album` | 9 | +| `Track` | 10 | \ No newline at end of file diff --git a/docs/sdks/activities/README.md b/docs/sdks/activities/README.md index 6e98113..ab4a2fc 100644 --- a/docs/sdks/activities/README.md +++ b/docs/sdks/activities/README.md @@ -14,12 +14,12 @@ Activities are optional cancellable. If cancellable, they may be cancelled via t ### Available Operations -* [getServerActivities](#getserveractivities) - Get Server Activities * [cancelServerActivities](#cancelserveractivities) - Cancel Server Activities +* [getServerActivities](#getserveractivities) - Get Server Activities -## getServerActivities +## cancelServerActivities -Get Server Activities +Cancel Server Activities ### Example Usage @@ -32,40 +32,40 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->activities->getServerActivities( +$response = $sdk->activities->cancelServerActivities( + activityUUID: '25b71ed5-0f9d-461c-baa7-d404e9e10d3e' ); -if ($response->object !== null) { +if ($response->statusCode === 200) { // handle response } ``` +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | +| `activityUUID` | *string* | :heavy_check_mark: | The UUID of the activity to cancel. | 25b71ed5-0f9d-461c-baa7-d404e9e10d3e | + ### Response -**[?Operations\GetServerActivitiesResponse](../../Models/Operations/GetServerActivitiesResponse.md)** +**[?Operations\CancelServerActivitiesResponse](../../Models/Operations/CancelServerActivitiesResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| -------------------------------------- | -------------------------------------- | -------------------------------------- | -| Errors\GetServerActivitiesBadRequest | 400 | application/json | -| Errors\GetServerActivitiesUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| Errors\CancelServerActivitiesBadRequest | 400 | application/json | +| Errors\CancelServerActivitiesUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## cancelServerActivities +## getServerActivities -Cancel Server Activities +Get Server Activities ### Example Usage @@ -78,39 +78,27 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->activities->cancelServerActivities( - activityUUID: '25b71ed5-0f9d-461c-baa7-d404e9e10d3e' +$response = $sdk->activities->getServerActivities( + ); -if ($response->statusCode === 200) { +if ($response->object !== null) { // handle response } ``` -### Parameters - -| Parameter | Type | Required | Description | Example | -| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | -| `activityUUID` | *string* | :heavy_check_mark: | The UUID of the activity to cancel. | 25b71ed5-0f9d-461c-baa7-d404e9e10d3e | - ### Response -**[?Operations\CancelServerActivitiesResponse](../../Models/Operations/CancelServerActivitiesResponse.md)** +**[?Operations\GetServerActivitiesResponse](../../Models/Operations/GetServerActivitiesResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | -| Errors\CancelServerActivitiesBadRequest | 400 | application/json | -| Errors\CancelServerActivitiesUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Error Type | Status Code | Content Type | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | +| Errors\GetServerActivitiesBadRequest | 400 | application/json | +| Errors\GetServerActivitiesUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/authentication/README.md b/docs/sdks/authentication/README.md index cfed8ad..5710bc3 100644 --- a/docs/sdks/authentication/README.md +++ b/docs/sdks/authentication/README.md @@ -8,14 +8,15 @@ API Calls regarding authentication for Plex Media Server ### Available Operations -* [getTransientToken](#gettransienttoken) - Get a Transient Token * [getSourceConnectionInformation](#getsourceconnectioninformation) - Get Source Connection Information * [getTokenDetails](#gettokendetails) - Get Token Details +* [getTransientToken](#gettransienttoken) - Get a Transient Token * [postUsersSignInData](#postuserssignindata) - Get User Sign In Data -## getTransientToken +## getSourceConnectionInformation -This endpoint provides the caller with a temporary token with the same access level as the caller's token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted. +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. +Note: requires Plex Media Server >= 1.15.4. ### Example Usage @@ -26,24 +27,15 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->authentication->getTransientToken( - type: Operations\GetTransientTokenQueryParamType::Delegation, - scope: Operations\Scope::All +$response = $sdk->authentication->getSourceConnectionInformation( + source: 'server://client-identifier' ); if ($response->statusCode === 200) { @@ -53,28 +45,25 @@ if ($response->statusCode === 200) { ### Parameters -| Parameter | Type | Required | Description | -| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| `type` | [Operations\GetTransientTokenQueryParamType](../../Models/Operations/GetTransientTokenQueryParamType.md) | :heavy_check_mark: | `delegation` - This is the only supported `type` parameter. | -| `scope` | [Operations\Scope](../../Models/Operations/Scope.md) | :heavy_check_mark: | `all` - This is the only supported `scope` parameter. | +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | +| `source` | *string* | :heavy_check_mark: | The source identifier with an included prefix. | server://client-identifier | ### Response -**[?Operations\GetTransientTokenResponse](../../Models/Operations/GetTransientTokenResponse.md)** +**[?Operations\GetSourceConnectionInformationResponse](../../Models/Operations/GetSourceConnectionInformationResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------------ | ------------------------------------ | ------------------------------------ | -| Errors\GetTransientTokenBadRequest | 400 | application/json | -| Errors\GetTransientTokenUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - -## getSourceConnectionInformation +| Error Type | Status Code | Content Type | +| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | +| Errors\GetSourceConnectionInformationBadRequest | 400 | application/json | +| Errors\GetSourceConnectionInformationUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -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. -Note: requires Plex Media Server >= 1.15.4. +## getTokenDetails +Get the User data from the provided X-Plex-Token ### Example Usage @@ -87,46 +76,41 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->authentication->getSourceConnectionInformation( - source: 'server://client-identifier' +$response = $sdk->authentication->getTokenDetails( + ); -if ($response->statusCode === 200) { +if ($response->userPlexAccount !== null) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | Example | -| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | -| `source` | *string* | :heavy_check_mark: | The source identifier with an included prefix. | server://client-identifier | +| Parameter | Type | Required | Description | +| ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | +| `$serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | ### Response -**[?Operations\GetSourceConnectionInformationResponse](../../Models/Operations/GetSourceConnectionInformationResponse.md)** +**[?Operations\GetTokenDetailsResponse](../../Models/Operations/GetTokenDetailsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | -| Errors\GetSourceConnectionInformationBadRequest | 400 | application/json | -| Errors\GetSourceConnectionInformationUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| Errors\GetTokenDetailsBadRequest | 400 | application/json | +| Errors\GetTokenDetailsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getTokenDetails +## getTransientToken + +This endpoint provides the caller with a temporary token with the same access level as the caller's token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted. -Get the User data from the provided X-Plex-Token ### Example Usage @@ -136,45 +120,43 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->authentication->getTokenDetails( +$response = $sdk->authentication->getTransientToken( + type: Operations\GetTransientTokenQueryParamType::Delegation, + scope: Operations\Scope::All ); -if ($response->userPlexAccount !== null) { +if ($response->statusCode === 200) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | -| ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | -| `$serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | +| Parameter | Type | Required | Description | +| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `type` | [Operations\GetTransientTokenQueryParamType](../../Models/Operations/GetTransientTokenQueryParamType.md) | :heavy_check_mark: | `delegation` - This is the only supported `type` parameter. | +| `scope` | [Operations\Scope](../../Models/Operations/Scope.md) | :heavy_check_mark: | `all` - This is the only supported `scope` parameter. | ### Response -**[?Operations\GetTokenDetailsResponse](../../Models/Operations/GetTokenDetailsResponse.md)** +**[?Operations\GetTransientTokenResponse](../../Models/Operations/GetTransientTokenResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ---------------------------------- | ---------------------------------- | ---------------------------------- | -| Errors\GetTokenDetailsBadRequest | 400 | application/json | -| Errors\GetTokenDetailsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | +| Errors\GetTransientTokenBadRequest | 400 | application/json | +| Errors\GetTransientTokenUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## postUsersSignInData @@ -190,15 +172,14 @@ require 'vendor/autoload.php'; use LukeHagar\Plex_API; use LukeHagar\Plex_API\Models\Operations; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); +$sdk = Plex_API\PlexAPI::builder()->build(); $request = new Operations\PostUsersSignInDataRequest( + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + clientName: 'Plex for Roku', + deviceNickname: 'Roku 3', + clientVersion: '2.4.1', + platform: 'Roku', requestBody: new Operations\PostUsersSignInDataRequestBody( login: 'username@email.com', password: 'password123', diff --git a/docs/sdks/butler/README.md b/docs/sdks/butler/README.md index 41bd8d6..b8a5249 100644 --- a/docs/sdks/butler/README.md +++ b/docs/sdks/butler/README.md @@ -10,8 +10,8 @@ Butler is the task manager of the Plex Media Server Ecosystem. * [getButlerTasks](#getbutlertasks) - Get Butler tasks * [startAllTasks](#startalltasks) - Start all Butler tasks -* [stopAllTasks](#stopalltasks) - Stop all Butler tasks * [startTask](#starttask) - Start a single Butler task +* [stopAllTasks](#stopalltasks) - Stop all Butler tasks * [stopTask](#stoptask) - Stop a single Butler task ## getButlerTasks @@ -29,13 +29,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -80,13 +74,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -111,9 +99,13 @@ if ($response->statusCode === 200) { | Errors\StartAllTasksUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## stopAllTasks +## startTask -This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue. +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's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria: +1. Any tasks not scheduled to run on the current day will be skipped. +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. +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. +4. If we are outside the configured window, the task will start immediately. ### Example Usage @@ -124,21 +116,16 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->butler->stopAllTasks( +$response = $sdk->butler->startTask( + taskName: Operations\TaskName::CleanOldBundles ); if ($response->statusCode === 200) { @@ -146,25 +133,27 @@ if ($response->statusCode === 200) { } ``` +### Parameters + +| Parameter | Type | Required | Description | +| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| `taskName` | [Operations\TaskName](../../Models/Operations/TaskName.md) | :heavy_check_mark: | the name of the task to be started. | + ### Response -**[?Operations\StopAllTasksResponse](../../Models/Operations/StopAllTasksResponse.md)** +**[?Operations\StartTaskResponse](../../Models/Operations/StartTaskResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------- | ------------------------------- | ------------------------------- | -| Errors\StopAllTasksBadRequest | 400 | application/json | -| Errors\StopAllTasksUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ---------------------------- | ---------------------------- | ---------------------------- | +| Errors\StartTaskBadRequest | 400 | application/json | +| Errors\StartTaskUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## startTask +## stopAllTasks -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's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria: -1. Any tasks not scheduled to run on the current day will be skipped. -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. -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. -4. If we are outside the configured window, the task will start immediately. +This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue. ### Example Usage @@ -175,22 +164,15 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->butler->startTask( - taskName: Operations\TaskName::CleanOldBundles +$response = $sdk->butler->stopAllTasks( + ); if ($response->statusCode === 200) { @@ -198,23 +180,17 @@ if ($response->statusCode === 200) { } ``` -### Parameters - -| Parameter | Type | Required | Description | -| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | -| `taskName` | [Operations\TaskName](../../Models/Operations/TaskName.md) | :heavy_check_mark: | the name of the task to be started. | - ### Response -**[?Operations\StartTaskResponse](../../Models/Operations/StartTaskResponse.md)** +**[?Operations\StopAllTasksResponse](../../Models/Operations/StopAllTasksResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ---------------------------- | ---------------------------- | ---------------------------- | -| Errors\StartTaskBadRequest | 400 | application/json | -| Errors\StartTaskUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------- | ------------------------------- | ------------------------------- | +| Errors\StopAllTasksBadRequest | 400 | application/json | +| Errors\StopAllTasksUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## stopTask @@ -233,13 +209,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); diff --git a/docs/sdks/hubs/README.md b/docs/sdks/hubs/README.md index 1ce6ad5..c0c2563 100644 --- a/docs/sdks/hubs/README.md +++ b/docs/sdks/hubs/README.md @@ -8,13 +8,14 @@ Hubs are a structured two-dimensional container for media, generally represented ### Available Operations -* [getGlobalHubs](#getglobalhubs) - Get Global Hubs * [getRecentlyAdded](#getrecentlyadded) - Get Recently Added +* [getGlobalHubs](#getglobalhubs) - Get Global Hubs * [getLibraryHubs](#getlibraryhubs) - Get library specific hubs -## getGlobalHubs +## getRecentlyAdded + +This endpoint will return the recently added content. -Get Global Hubs filtered by the parameters provided. ### Example Usage @@ -28,20 +29,19 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); +$request = new Operations\GetRecentlyAddedRequest( + contentDirectoryID: 470161, + type: Operations\Type::TvShow, + sectionID: 2, + includeMeta: Operations\IncludeMeta::Enable, + xPlexContainerStart: 0, + xPlexContainerSize: 50, +); -$response = $sdk->hubs->getGlobalHubs( - count: 1262.49, - onlyTransient: Operations\OnlyTransient::One - +$response = $sdk->hubs->getRecentlyAdded( + request: $request ); if ($response->object !== null) { @@ -51,27 +51,23 @@ if ($response->object !== null) { ### Parameters -| Parameter | Type | Required | Description | -| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -| `count` | *?float* | :heavy_minus_sign: | The number of items to return with each hub. | -| `onlyTransient` | [?Operations\OnlyTransient](../../Models/Operations/OnlyTransient.md) | :heavy_minus_sign: | Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added). | +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| `$request` | [Operations\GetRecentlyAddedRequest](../../Models/Operations/GetRecentlyAddedRequest.md) | :heavy_check_mark: | The request object to use for the request. | ### Response -**[?Operations\GetGlobalHubsResponse](../../Models/Operations/GetGlobalHubsResponse.md)** +**[?Operations\GetRecentlyAddedResponse](../../Models/Operations/GetRecentlyAddedResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| -------------------------------- | -------------------------------- | -------------------------------- | -| Errors\GetGlobalHubsBadRequest | 400 | application/json | -| Errors\GetGlobalHubsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - -## getRecentlyAdded +| Error Type | Status Code | Content Type | +| ------------------- | ------------------- | ------------------- | +| Errors\SDKException | 4XX, 5XX | \*/\* | -This endpoint will return the recently added content. +## getGlobalHubs +Get Global Hubs filtered by the parameters provided. ### Example Usage @@ -85,25 +81,14 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$request = new Operations\GetRecentlyAddedRequest( - contentDirectoryID: 470161, - type: Operations\Type::TvShow, - sectionID: 2, - includeMeta: Operations\IncludeMeta::Enable, - xPlexContainerStart: 0, - xPlexContainerSize: 50, -); -$response = $sdk->hubs->getRecentlyAdded( - request: $request + +$response = $sdk->hubs->getGlobalHubs( + count: 1262.49, + onlyTransient: Operations\OnlyTransient::One + ); if ($response->object !== null) { @@ -113,19 +98,22 @@ if ($response->object !== null) { ### Parameters -| Parameter | Type | Required | Description | -| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `$request` | [Operations\GetRecentlyAddedRequest](../../Models/Operations/GetRecentlyAddedRequest.md) | :heavy_check_mark: | The request object to use for the request. | +| Parameter | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `count` | *?float* | :heavy_minus_sign: | The number of items to return with each hub. | +| `onlyTransient` | [?Operations\OnlyTransient](../../Models/Operations/OnlyTransient.md) | :heavy_minus_sign: | Only return hubs which are "transient", meaning those which are prone to changing after media playback or addition (e.g. On Deck, or Recently Added). | ### Response -**[?Operations\GetRecentlyAddedResponse](../../Models/Operations/GetRecentlyAddedResponse.md)** +**[?Operations\GetGlobalHubsResponse](../../Models/Operations/GetGlobalHubsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------- | ------------------- | ------------------- | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| Errors\GetGlobalHubsBadRequest | 400 | application/json | +| Errors\GetGlobalHubsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getLibraryHubs @@ -144,13 +132,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); diff --git a/docs/sdks/library/README.md b/docs/sdks/library/README.md index f2ceb18..cc81de9 100644 --- a/docs/sdks/library/README.md +++ b/docs/sdks/library/README.md @@ -8,23 +8,23 @@ API Calls interacting with Plex Media Server Libraries ### Available Operations -* [getFileHash](#getfilehash) - Get Hash Value -* [getRecentlyAddedLibrary](#getrecentlyaddedlibrary) - Get Recently Added +* [deleteLibrary](#deletelibrary) - Delete Library Section * [getAllLibraries](#getalllibraries) - Get All Libraries * [getLibraryDetails](#getlibrarydetails) - Get Library Details -* [deleteLibrary](#deletelibrary) - Delete Library Section * [getLibraryItems](#getlibraryitems) - Get Library Items +* [getMetaDataByRatingKey](#getmetadatabyratingkey) - Get Metadata by RatingKey +* [getRecentlyAddedLibrary](#getrecentlyaddedlibrary) - Get Recently Added * [getRefreshLibraryMetadata](#getrefreshlibrarymetadata) - Refresh Metadata Of The Library -* [getSearchLibrary](#getsearchlibrary) - Search Library * [getSearchAllLibraries](#getsearchalllibraries) - Search All Libraries -* [getMetaDataByRatingKey](#getmetadatabyratingkey) - Get Metadata by RatingKey +* [getSearchLibrary](#getsearchlibrary) - Search Library +* [getFileHash](#getfilehash) - Get Hash Value * [getMetadataChildren](#getmetadatachildren) - Get Items Children -* [getTopWatchedContent](#gettopwatchedcontent) - Get Top Watched Content * [getOnDeck](#getondeck) - Get On Deck +* [getTopWatchedContent](#gettopwatchedcontent) - Get Top Watched Content -## getFileHash +## deleteLibrary -This resource returns hash values for local files +Delete a library using a specific section id ### Example Usage @@ -37,20 +37,12 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->library->getFileHash( - url: 'file://C:\Image.png&type=13', - type: 4462.17 - +$response = $sdk->library->deleteLibrary( + sectionKey: 9518 ); if ($response->statusCode === 200) { @@ -60,97 +52,21 @@ if ($response->statusCode === 200) { ### Parameters -| Parameter | Type | Required | Description | Example | -| ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | -| `url` | *string* | :heavy_check_mark: | This is the path to the local file, must be prefixed by `file://` | file://C:\Image.png&type=13 | -| `type` | *?float* | :heavy_minus_sign: | Item type | | - -### Response - -**[?Operations\GetFileHashResponse](../../Models/Operations/GetFileHashResponse.md)** - -### Errors - -| Error Type | Status Code | Content Type | -| ------------------------------ | ------------------------------ | ------------------------------ | -| Errors\GetFileHashBadRequest | 400 | application/json | -| Errors\GetFileHashUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - -## getRecentlyAddedLibrary - -This endpoint will return the recently added content. - - -### Example Usage - -```php -declare(strict_types=1); - -require 'vendor/autoload.php'; - -use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; - -$security = ''; - -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - -$request = new Operations\GetRecentlyAddedLibraryRequest( - type: Operations\QueryParamType::TvShow, - contentDirectoryID: 2, - pinnedContentDirectoryID: [ - 3, - 5, - 7, - 13, - 12, - 1, - 6, - 14, - 2, - 10, - 16, - 17, - ], - sectionID: 2, - includeMeta: Operations\QueryParamIncludeMeta::Enable, - xPlexContainerStart: 0, - xPlexContainerSize: 50, -); - -$response = $sdk->library->getRecentlyAddedLibrary( - request: $request -); - -if ($response->object !== null) { - // handle response -} -``` - -### Parameters - -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | -| `$request` | [Operations\GetRecentlyAddedLibraryRequest](../../Models/Operations/GetRecentlyAddedLibraryRequest.md) | :heavy_check_mark: | The request object to use for the request. | +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `sectionKey` | *int* | :heavy_check_mark: | The unique key of the Plex library.
Note: This is unique in the context of the Plex server.
| 9518 | ### Response -**[?Operations\GetRecentlyAddedLibraryResponse](../../Models/Operations/GetRecentlyAddedLibraryResponse.md)** +**[?Operations\DeleteLibraryResponse](../../Models/Operations/DeleteLibraryResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | -| Errors\GetRecentlyAddedLibraryBadRequest | 400 | application/json | -| Errors\GetRecentlyAddedLibraryUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| Errors\DeleteLibraryBadRequest | 400 | application/json | +| Errors\DeleteLibraryUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getAllLibraries @@ -173,13 +89,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -259,13 +169,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -299,58 +203,6 @@ if ($response->object !== null) { | Errors\GetLibraryDetailsUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## deleteLibrary - -Delete a library using a specific section id - -### Example Usage - -```php -declare(strict_types=1); - -require 'vendor/autoload.php'; - -use LukeHagar\Plex_API; - -$security = ''; - -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - - - -$response = $sdk->library->deleteLibrary( - sectionKey: 9518 -); - -if ($response->statusCode === 200) { - // handle response -} -``` - -### Parameters - -| Parameter | Type | Required | Description | Example | -| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -| `sectionKey` | *int* | :heavy_check_mark: | The unique key of the Plex library.
Note: This is unique in the context of the Plex server.
| 9518 | - -### Response - -**[?Operations\DeleteLibraryResponse](../../Models/Operations/DeleteLibraryResponse.md)** - -### Errors - -| Error Type | Status Code | Content Type | -| -------------------------------- | -------------------------------- | -------------------------------- | -| Errors\DeleteLibraryBadRequest | 400 | application/json | -| Errors\DeleteLibraryUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - ## getLibraryItems Fetches details from a specific section of the library identified by a section key and a tag. The tag parameter accepts the following values: @@ -373,6 +225,7 @@ Fetches details from a specific section of the library identified by a section k - `resolution`: Items categorized by resolution. - `firstCharacter`: Items categorized by the first letter. - `folder`: Items categorized by folder. +- `albums`: Items categorized by album. ### Example Usage @@ -387,13 +240,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetLibraryItemsRequest( tag: Operations\Tag::Edition, @@ -432,9 +279,9 @@ if ($response->object !== null) { | Errors\GetLibraryItemsUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## getRefreshLibraryMetadata +## getMetaDataByRatingKey -This endpoint Refreshes all the Metadata of the library. +This endpoint will return the metadata of a library item specified with the ratingKey. ### Example Usage @@ -445,70 +292,112 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->library->getRefreshLibraryMetadata( - sectionKey: 9518, - force: Operations\Force::One - +$response = $sdk->library->getMetaDataByRatingKey( + ratingKey: 9518 ); -if ($response->statusCode === 200) { +if ($response->object !== null) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | Example | -| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -| `sectionKey` | *int* | :heavy_check_mark: | The unique key of the Plex library.
Note: This is unique in the context of the Plex server.
| 9518 | -| `force` | [?Operations\Force](../../Models/Operations/Force.md) | :heavy_minus_sign: | Force the refresh even if the library is already being refreshed. | 0 | +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | +| `ratingKey` | *int* | :heavy_check_mark: | the id of the library item to return the children of. | 9518 | ### Response -**[?Operations\GetRefreshLibraryMetadataResponse](../../Models/Operations/GetRefreshLibraryMetadataResponse.md)** +**[?Operations\GetMetaDataByRatingKeyResponse](../../Models/Operations/GetMetaDataByRatingKeyResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -| Errors\GetRefreshLibraryMetadataBadRequest | 400 | application/json | -| Errors\GetRefreshLibraryMetadataUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| Errors\GetMetaDataByRatingKeyBadRequest | 400 | application/json | +| Errors\GetMetaDataByRatingKeyUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getSearchLibrary +## getRecentlyAddedLibrary -Search for content within a specific section of the library. +This endpoint will return the recently added content. -### Types -Each type in the library comes with a set of filters and sorts, aiding in building dynamic media controls: -- **Type Object Attributes**: - - `type`: Metadata type (if standard Plex type). - - `title`: Title for this content type (e.g., "Movies"). +### Example Usage -- **Filter Objects**: - - Subset of the media query language. - - Attributes include `filter` (name), `filterType` (data type), `key` (endpoint for value range), and `title`. +```php +declare(strict_types=1); -- **Sort Objects**: - - Description of sort fields. - - Attributes include `defaultDirection` (asc/desc), `descKey` and `key` (sort parameters), and `title`. +require 'vendor/autoload.php'; -> **Note**: Filters and sorts are optional; without them, no filtering controls are rendered. +use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; + +$security = ''; + +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); + +$request = new Operations\GetRecentlyAddedLibraryRequest( + type: Operations\QueryParamType::TvShow, + contentDirectoryID: 2, + pinnedContentDirectoryID: [ + 3, + 5, + 7, + 13, + 12, + 1, + 6, + 14, + 2, + 10, + 16, + 17, + ], + sectionID: 2, + includeMeta: Operations\QueryParamIncludeMeta::Enable, + xPlexContainerStart: 0, + xPlexContainerSize: 50, +); + +$response = $sdk->library->getRecentlyAddedLibrary( + request: $request +); + +if ($response->object !== null) { + // handle response +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `$request` | [Operations\GetRecentlyAddedLibraryRequest](../../Models/Operations/GetRecentlyAddedLibraryRequest.md) | :heavy_check_mark: | The request object to use for the request. | + +### Response + +**[?Operations\GetRecentlyAddedLibraryResponse](../../Models/Operations/GetRecentlyAddedLibraryResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | +| Errors\GetRecentlyAddedLibraryBadRequest | 400 | application/json | +| Errors\GetRecentlyAddedLibraryUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | + +## getRefreshLibraryMetadata + +This endpoint Refreshes all the Metadata of the library. ### Example Usage @@ -523,45 +412,39 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->library->getSearchLibrary( +$response = $sdk->library->getRefreshLibraryMetadata( sectionKey: 9518, - type: Operations\GetSearchLibraryQueryParamType::TvShow + force: Operations\Force::One ); -if ($response->object !== null) { +if ($response->statusCode === 200) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sectionKey` | *int* | :heavy_check_mark: | The unique key of the Plex library.
Note: This is unique in the context of the Plex server.
| 9518 | -| `type` | [Operations\GetSearchLibraryQueryParamType](../../Models/Operations/GetSearchLibraryQueryParamType.md) | :heavy_check_mark: | The type of media to retrieve.
1 = movie
2 = show
3 = season
4 = episode
E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries
| 2 | +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `sectionKey` | *int* | :heavy_check_mark: | The unique key of the Plex library.
Note: This is unique in the context of the Plex server.
| 9518 | +| `force` | [?Operations\Force](../../Models/Operations/Force.md) | :heavy_minus_sign: | Force the refresh even if the library is already being refreshed. | 0 | ### Response -**[?Operations\GetSearchLibraryResponse](../../Models/Operations/GetSearchLibraryResponse.md)** +**[?Operations\GetRefreshLibraryMetadataResponse](../../Models/Operations/GetRefreshLibraryMetadataResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ----------------------------------- | ----------------------------------- | ----------------------------------- | -| Errors\GetSearchLibraryBadRequest | 400 | application/json | -| Errors\GetSearchLibraryUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | +| Errors\GetRefreshLibraryMetadataBadRequest | 400 | application/json | +| Errors\GetRefreshLibraryMetadataUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getSearchAllLibraries @@ -580,16 +463,11 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetSearchAllLibrariesRequest( query: '', + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', searchTypes: [ Operations\SearchTypes::People, ], @@ -624,9 +502,26 @@ if ($response->object !== null) { | Errors\GetSearchAllLibrariesUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## getMetaDataByRatingKey +## getSearchLibrary -This endpoint will return the metadata of a library item specified with the ratingKey. +Search for content within a specific section of the library. + +### Types +Each type in the library comes with a set of filters and sorts, aiding in building dynamic media controls: + +- **Type Object Attributes**: + - `type`: Metadata type (if standard Plex type). + - `title`: Title for this content type (e.g., "Movies"). + +- **Filter Objects**: + - Subset of the media query language. + - Attributes include `filter` (name), `filterType` (data type), `key` (endpoint for value range), and `title`. + +- **Sort Objects**: + - Description of sort fields. + - Attributes include `defaultDirection` (asc/desc), `descKey` and `key` (sort parameters), and `title`. + +> **Note**: Filters and sorts are optional; without them, no filtering controls are rendered. ### Example Usage @@ -637,21 +532,18 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->library->getMetaDataByRatingKey( - ratingKey: 9518 +$response = $sdk->library->getSearchLibrary( + sectionKey: 9518, + type: Operations\GetSearchLibraryQueryParamType::TvShow + ); if ($response->object !== null) { @@ -661,21 +553,71 @@ if ($response->object !== null) { ### Parameters -| Parameter | Type | Required | Description | Example | -| ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | -| `ratingKey` | *int* | :heavy_check_mark: | the id of the library item to return the children of. | 9518 | +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `sectionKey` | *int* | :heavy_check_mark: | The unique key of the Plex library.
Note: This is unique in the context of the Plex server.
| 9518 | +| `type` | [Operations\GetSearchLibraryQueryParamType](../../Models/Operations/GetSearchLibraryQueryParamType.md) | :heavy_check_mark: | The type of media to retrieve.
1 = movie
2 = show
3 = season
4 = episode
E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries
| 2 | ### Response -**[?Operations\GetMetaDataByRatingKeyResponse](../../Models/Operations/GetMetaDataByRatingKeyResponse.md)** +**[?Operations\GetSearchLibraryResponse](../../Models/Operations/GetSearchLibraryResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | -| Errors\GetMetaDataByRatingKeyBadRequest | 400 | application/json | -| Errors\GetMetaDataByRatingKeyUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ----------------------------------- | ----------------------------------- | ----------------------------------- | +| Errors\GetSearchLibraryBadRequest | 400 | application/json | +| Errors\GetSearchLibraryUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | + +## getFileHash + +This resource returns hash values for local files + +### Example Usage + +```php +declare(strict_types=1); + +require 'vendor/autoload.php'; + +use LukeHagar\Plex_API; + +$security = ''; + +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); + + + +$response = $sdk->library->getFileHash( + url: 'file://C:\Image.png&type=13', + type: 4462.17 + +); + +if ($response->statusCode === 200) { + // handle response +} +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------- | +| `url` | *string* | :heavy_check_mark: | This is the path to the local file, must be prefixed by `file://` | file://C:\Image.png&type=13 | +| `type` | *?float* | :heavy_minus_sign: | Item type | | + +### Response + +**[?Operations\GetFileHashResponse](../../Models/Operations/GetFileHashResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| ------------------------------ | ------------------------------ | ------------------------------ | +| Errors\GetFileHashBadRequest | 400 | application/json | +| Errors\GetFileHashUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getMetadataChildren @@ -693,13 +635,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -733,9 +669,9 @@ if ($response->object !== null) { | Errors\GetMetadataChildrenUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## getTopWatchedContent +## getOnDeck -This endpoint will return the top watched content from libraries of a certain type +This endpoint will return the on deck content. ### Example Usage @@ -746,23 +682,14 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->library->getTopWatchedContent( - type: Operations\GetTopWatchedContentQueryParamType::TvShow, - includeGuids: 1 +$response = $sdk->library->getOnDeck( ); @@ -771,28 +698,21 @@ if ($response->object !== null) { } ``` -### Parameters - -| Parameter | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | [Operations\GetTopWatchedContentQueryParamType](../../Models/Operations/GetTopWatchedContentQueryParamType.md) | :heavy_check_mark: | The type of media to retrieve.
1 = movie
2 = show
3 = season
4 = episode
E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries
| 2 | -| `includeGuids` | *?int* | :heavy_minus_sign: | Adds the Guids object to the response
| 1 | - ### Response -**[?Operations\GetTopWatchedContentResponse](../../Models/Operations/GetTopWatchedContentResponse.md)** +**[?Operations\GetOnDeckResponse](../../Models/Operations/GetOnDeckResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| --------------------------------------- | --------------------------------------- | --------------------------------------- | -| Errors\GetTopWatchedContentBadRequest | 400 | application/json | -| Errors\GetTopWatchedContentUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ---------------------------- | ---------------------------- | ---------------------------- | +| Errors\GetOnDeckBadRequest | 400 | application/json | +| Errors\GetOnDeckUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getOnDeck +## getTopWatchedContent -This endpoint will return the on deck content. +This endpoint will return the top watched content from libraries of a certain type ### Example Usage @@ -803,20 +723,17 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->library->getOnDeck( +$response = $sdk->library->getTopWatchedContent( + type: Operations\GetTopWatchedContentQueryParamType::TvShow, + includeGuids: 1 ); @@ -825,14 +742,21 @@ if ($response->object !== null) { } ``` +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | [Operations\GetTopWatchedContentQueryParamType](../../Models/Operations/GetTopWatchedContentQueryParamType.md) | :heavy_check_mark: | The type of media to retrieve.
1 = movie
2 = show
3 = season
4 = episode
E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries
| 2 | +| `includeGuids` | *?int* | :heavy_minus_sign: | Adds the Guids object to the response
| 1 | + ### Response -**[?Operations\GetOnDeckResponse](../../Models/Operations/GetOnDeckResponse.md)** +**[?Operations\GetTopWatchedContentResponse](../../Models/Operations/GetTopWatchedContentResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ---------------------------- | ---------------------------- | ---------------------------- | -| Errors\GetOnDeckBadRequest | 400 | application/json | -| Errors\GetOnDeckUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Error Type | Status Code | Content Type | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | +| Errors\GetTopWatchedContentBadRequest | 400 | application/json | +| Errors\GetTopWatchedContentUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/log/README.md b/docs/sdks/log/README.md index 64e4d1d..6091ece 100644 --- a/docs/sdks/log/README.md +++ b/docs/sdks/log/README.md @@ -8,9 +8,50 @@ Submit logs to the Log Handler for Plex Media Server ### Available Operations +* [enablePaperTrail](#enablepapertrail) - Enabling Papertrail * [logLine](#logline) - Logging a single line message. * [logMultiLine](#logmultiline) - Logging a multi-line message -* [enablePaperTrail](#enablepapertrail) - Enabling Papertrail + +## enablePaperTrail + +This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time. + + +### Example Usage + +```php +declare(strict_types=1); + +require 'vendor/autoload.php'; + +use LukeHagar\Plex_API; + +$security = ''; + +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); + + + +$response = $sdk->log->enablePaperTrail( + +); + +if ($response->statusCode === 200) { + // handle response +} +``` + +### Response + +**[?Operations\EnablePaperTrailResponse](../../Models/Operations/EnablePaperTrailResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| ----------------------------------- | ----------------------------------- | ----------------------------------- | +| Errors\EnablePaperTrailBadRequest | 400 | application/json | +| Errors\EnablePaperTrailUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## logLine @@ -29,13 +70,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -107,13 +142,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = 'level=4&message=Test%20message%201&source=postman level=3&message=Test%20message%202&source=postman @@ -144,51 +173,4 @@ if ($response->statusCode === 200) { | ------------------------------- | ------------------------------- | ------------------------------- | | Errors\LogMultiLineBadRequest | 400 | application/json | | Errors\LogMultiLineUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - -## enablePaperTrail - -This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time. - - -### Example Usage - -```php -declare(strict_types=1); - -require 'vendor/autoload.php'; - -use LukeHagar\Plex_API; - -$security = ''; - -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - - - -$response = $sdk->log->enablePaperTrail( - -); - -if ($response->statusCode === 200) { - // handle response -} -``` - -### Response - -**[?Operations\EnablePaperTrailResponse](../../Models/Operations/EnablePaperTrailResponse.md)** - -### Errors - -| Error Type | Status Code | Content Type | -| ----------------------------------- | ----------------------------------- | ----------------------------------- | -| Errors\EnablePaperTrailBadRequest | 400 | application/json | -| Errors\EnablePaperTrailUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/media/README.md b/docs/sdks/media/README.md index 0325603..8f5f453 100644 --- a/docs/sdks/media/README.md +++ b/docs/sdks/media/README.md @@ -8,15 +8,15 @@ API Calls interacting with Plex Media Server Media ### Available Operations +* [getBannerImage](#getbannerimage) - Get Banner Image +* [getThumbImage](#getthumbimage) - Get Thumb Image * [markPlayed](#markplayed) - Mark Media Played * [markUnplayed](#markunplayed) - Mark Media Unplayed * [updatePlayProgress](#updateplayprogress) - Update Media Play Progress -* [getBannerImage](#getbannerimage) - Get Banner Image -* [getThumbImage](#getthumbimage) - Get Thumb Image -## markPlayed +## getBannerImage -This will mark the provided media key as Played. +Gets the banner image of the media item ### Example Usage @@ -26,49 +26,51 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); +$request = new Operations\GetBannerImageRequest( + ratingKey: 9518, + width: 396, + height: 396, + minSize: 1, + upscale: 1, + xPlexToken: 'CV5xoxjTpFKUzBTShsaf', +); -$response = $sdk->media->markPlayed( - key: 59398 +$response = $sdk->media->getBannerImage( + request: $request ); -if ($response->statusCode === 200) { +if ($response->bytes !== null) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | Example | -| ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | -| `key` | *float* | :heavy_check_mark: | The media key to mark as played | 59398 | +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | +| `$request` | [Operations\GetBannerImageRequest](../../Models/Operations/GetBannerImageRequest.md) | :heavy_check_mark: | The request object to use for the request. | ### Response -**[?Operations\MarkPlayedResponse](../../Models/Operations/MarkPlayedResponse.md)** +**[?Operations\GetBannerImageResponse](../../Models/Operations/GetBannerImageResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ----------------------------- | ----------------------------- | ----------------------------- | -| Errors\MarkPlayedBadRequest | 400 | application/json | -| Errors\MarkPlayedUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| --------------------------------- | --------------------------------- | --------------------------------- | +| Errors\GetBannerImageBadRequest | 400 | application/json | +| Errors\GetBannerImageUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## markUnplayed +## getThumbImage -This will mark the provided media key as Unplayed. +Gets the thumbnail image of the media item ### Example Usage @@ -78,50 +80,51 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); +$request = new Operations\GetThumbImageRequest( + ratingKey: 9518, + width: 396, + height: 396, + minSize: 1, + upscale: 1, + xPlexToken: 'CV5xoxjTpFKUzBTShsaf', +); -$response = $sdk->media->markUnplayed( - key: 59398 +$response = $sdk->media->getThumbImage( + request: $request ); -if ($response->statusCode === 200) { +if ($response->bytes !== null) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | Example | -| --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | -| `key` | *float* | :heavy_check_mark: | The media key to mark as Unplayed | 59398 | +| Parameter | Type | Required | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| `$request` | [Operations\GetThumbImageRequest](../../Models/Operations/GetThumbImageRequest.md) | :heavy_check_mark: | The request object to use for the request. | ### Response -**[?Operations\MarkUnplayedResponse](../../Models/Operations/MarkUnplayedResponse.md)** +**[?Operations\GetThumbImageResponse](../../Models/Operations/GetThumbImageResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------- | ------------------------------- | ------------------------------- | -| Errors\MarkUnplayedBadRequest | 400 | application/json | -| Errors\MarkUnplayedUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - -## updatePlayProgress +| Error Type | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| Errors\GetThumbImageBadRequest | 400 | application/json | +| Errors\GetThumbImageUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -This API command can be used to update the play progress of a media item. +## markPlayed +This will mark the provided media key as Played. ### Example Usage @@ -134,21 +137,12 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->media->updatePlayProgress( - key: '', - time: 90000, - state: 'played' - +$response = $sdk->media->markPlayed( + key: 59398 ); if ($response->statusCode === 200) { @@ -158,27 +152,25 @@ if ($response->statusCode === 200) { ### Parameters -| Parameter | Type | Required | Description | Example | -| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | -| `key` | *string* | :heavy_check_mark: | the media key | | -| `time` | *float* | :heavy_check_mark: | The time, in milliseconds, used to set the media playback progress. | 90000 | -| `state` | *string* | :heavy_check_mark: | The playback state of the media item. | played | +| Parameter | Type | Required | Description | Example | +| ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | +| `key` | *float* | :heavy_check_mark: | The media key to mark as played | 59398 | ### Response -**[?Operations\UpdatePlayProgressResponse](../../Models/Operations/UpdatePlayProgressResponse.md)** +**[?Operations\MarkPlayedResponse](../../Models/Operations/MarkPlayedResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------------- | ------------------------------------- | ------------------------------------- | -| Errors\UpdatePlayProgressBadRequest | 400 | application/json | -| Errors\UpdatePlayProgressUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ----------------------------- | ----------------------------- | ----------------------------- | +| Errors\MarkPlayedBadRequest | 400 | application/json | +| Errors\MarkPlayedUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getBannerImage +## markUnplayed -Gets the banner image of the media item +This will mark the provided media key as Unplayed. ### Example Usage @@ -188,57 +180,44 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$request = new Operations\GetBannerImageRequest( - ratingKey: 9518, - width: 396, - height: 396, - minSize: 1, - upscale: 1, - xPlexToken: 'CV5xoxjTpFKUzBTShsaf', -); -$response = $sdk->media->getBannerImage( - request: $request + +$response = $sdk->media->markUnplayed( + key: 59398 ); -if ($response->bytes !== null) { +if ($response->statusCode === 200) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | -| `$request` | [Operations\GetBannerImageRequest](../../Models/Operations/GetBannerImageRequest.md) | :heavy_check_mark: | The request object to use for the request. | +| Parameter | Type | Required | Description | Example | +| --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | +| `key` | *float* | :heavy_check_mark: | The media key to mark as Unplayed | 59398 | ### Response -**[?Operations\GetBannerImageResponse](../../Models/Operations/GetBannerImageResponse.md)** +**[?Operations\MarkUnplayedResponse](../../Models/Operations/MarkUnplayedResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| --------------------------------- | --------------------------------- | --------------------------------- | -| Errors\GetBannerImageBadRequest | 400 | application/json | -| Errors\GetBannerImageUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------- | ------------------------------- | ------------------------------- | +| Errors\MarkUnplayedBadRequest | 400 | application/json | +| Errors\MarkUnplayedUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getThumbImage +## updatePlayProgress + +This API command can be used to update the play progress of a media item. -Gets the thumbnail image of the media item ### Example Usage @@ -248,50 +227,41 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$request = new Operations\GetThumbImageRequest( - ratingKey: 9518, - width: 396, - height: 396, - minSize: 1, - upscale: 1, - xPlexToken: 'CV5xoxjTpFKUzBTShsaf', -); -$response = $sdk->media->getThumbImage( - request: $request + +$response = $sdk->media->updatePlayProgress( + key: '', + time: 90000, + state: 'played' + ); -if ($response->bytes !== null) { +if ($response->statusCode === 200) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | -| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -| `$request` | [Operations\GetThumbImageRequest](../../Models/Operations/GetThumbImageRequest.md) | :heavy_check_mark: | The request object to use for the request. | +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `key` | *string* | :heavy_check_mark: | the media key | | +| `time` | *float* | :heavy_check_mark: | The time, in milliseconds, used to set the media playback progress. | 90000 | +| `state` | *string* | :heavy_check_mark: | The playback state of the media item. | played | ### Response -**[?Operations\GetThumbImageResponse](../../Models/Operations/GetThumbImageResponse.md)** +**[?Operations\UpdatePlayProgressResponse](../../Models/Operations/UpdatePlayProgressResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| -------------------------------- | -------------------------------- | -------------------------------- | -| Errors\GetThumbImageBadRequest | 400 | application/json | -| Errors\GetThumbImageUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Error Type | Status Code | Content Type | +| ------------------------------------- | ------------------------------------- | ------------------------------------- | +| Errors\UpdatePlayProgressBadRequest | 400 | application/json | +| Errors\UpdatePlayProgressUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/playlists/README.md b/docs/sdks/playlists/README.md index 6e5f3fe..2435c74 100644 --- a/docs/sdks/playlists/README.md +++ b/docs/sdks/playlists/README.md @@ -11,21 +11,20 @@ This may cause the duration and number of items to change. ### Available Operations +* [addPlaylistContents](#addplaylistcontents) - Adding to a Playlist +* [clearPlaylistContents](#clearplaylistcontents) - Delete Playlist Contents * [createPlaylist](#createplaylist) - Create a Playlist -* [getPlaylists](#getplaylists) - Get All Playlists -* [getPlaylist](#getplaylist) - Retrieve Playlist * [deletePlaylist](#deleteplaylist) - Deletes a Playlist -* [updatePlaylist](#updateplaylist) - Update a Playlist +* [getPlaylist](#getplaylist) - Retrieve Playlist * [getPlaylistContents](#getplaylistcontents) - Retrieve Playlist Contents -* [clearPlaylistContents](#clearplaylistcontents) - Delete Playlist Contents -* [addPlaylistContents](#addplaylistcontents) - Adding to a Playlist +* [getPlaylists](#getplaylists) - Get All Playlists +* [updatePlaylist](#updateplaylist) - Update a Playlist * [uploadPlaylist](#uploadplaylist) - Upload Playlist -## createPlaylist +## addPlaylistContents -Create a new playlist. By default the playlist is blank. To create a playlist along with a first item, pass: -- `uri` - The content URI for what we're playing (e.g. `server://1234/com.plexapp.plugins.library/library/metadata/1`). -- `playQueueID` - To create a playlist from an existing play queue. +Adds a generator to a playlist, same parameters as the POST to create. With a dumb playlist, this adds the specified items to the playlist. +With a smart playlist, passing a new `uri` parameter replaces the rules for the playlist. Returns the playlist. ### Example Usage @@ -36,27 +35,18 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$request = new Operations\CreatePlaylistRequest( - title: '', - type: Operations\CreatePlaylistQueryParamType::Photo, - smart: Operations\Smart::One, - uri: 'https://hoarse-testing.info/', -); -$response = $sdk->playlists->createPlaylist( - request: $request + +$response = $sdk->playlists->addPlaylistContents( + playlistID: 8502.00, + uri: 'server://12345/com.plexapp.plugins.library/library/metadata/1', + playQueueID: 123 + ); if ($response->object !== null) { @@ -66,25 +56,28 @@ if ($response->object !== null) { ### Parameters -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | -| `$request` | [Operations\CreatePlaylistRequest](../../Models/Operations/CreatePlaylistRequest.md) | :heavy_check_mark: | The request object to use for the request. | +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | +| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | | +| `uri` | *string* | :heavy_check_mark: | the content URI for the playlist | server://12345/com.plexapp.plugins.library/library/metadata/1 | +| `playQueueID` | *?float* | :heavy_minus_sign: | the play queue to add to a playlist | 123 | ### Response -**[?Operations\CreatePlaylistResponse](../../Models/Operations/CreatePlaylistResponse.md)** +**[?Operations\AddPlaylistContentsResponse](../../Models/Operations/AddPlaylistContentsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| --------------------------------- | --------------------------------- | --------------------------------- | -| Errors\CreatePlaylistBadRequest | 400 | application/json | -| Errors\CreatePlaylistUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | +| Errors\AddPlaylistContentsBadRequest | 400 | application/json | +| Errors\AddPlaylistContentsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getPlaylists +## clearPlaylistContents + +Clears a playlist, only works with dumb playlists. Returns the playlist. -Get All Playlists given the specified filters. ### Example Usage @@ -94,54 +87,45 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->playlists->getPlaylists( - playlistType: Operations\PlaylistType::Audio, - smart: Operations\QueryParamSmart::Zero - +$response = $sdk->playlists->clearPlaylistContents( + playlistID: 1893.18 ); -if ($response->object !== null) { +if ($response->statusCode === 200) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | -| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| `playlistType` | [?Operations\PlaylistType](../../Models/Operations/PlaylistType.md) | :heavy_minus_sign: | limit to a type of playlist. | -| `smart` | [?Operations\QueryParamSmart](../../Models/Operations/QueryParamSmart.md) | :heavy_minus_sign: | type of playlists to return (default is all). | +| Parameter | Type | Required | Description | +| ---------------------- | ---------------------- | ---------------------- | ---------------------- | +| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | ### Response -**[?Operations\GetPlaylistsResponse](../../Models/Operations/GetPlaylistsResponse.md)** +**[?Operations\ClearPlaylistContentsResponse](../../Models/Operations/ClearPlaylistContentsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------- | ------------------------------- | ------------------------------- | -| Errors\GetPlaylistsBadRequest | 400 | application/json | -| Errors\GetPlaylistsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | +| Errors\ClearPlaylistContentsBadRequest | 400 | application/json | +| Errors\ClearPlaylistContentsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getPlaylist +## createPlaylist -Gets detailed metadata for a playlist. A playlist for many purposes (rating, editing metadata, tagging), can be treated like a regular metadata item: -Smart playlist details contain the `content` attribute. This is the content URI for the generator. This can then be parsed by a client to provide smart playlist editing. +Create a new playlist. By default the playlist is blank. To create a playlist along with a first item, pass: +- `uri` - The content URI for what we're playing (e.g. `server://1234/com.plexapp.plugins.library/library/metadata/1`). +- `playQueueID` - To create a playlist from an existing play queue. ### Example Usage @@ -152,21 +136,21 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); +$request = new Operations\CreatePlaylistRequest( + title: '', + type: Operations\CreatePlaylistQueryParamType::Photo, + smart: Operations\Smart::One, + uri: 'https://hoarse-testing.info/', +); -$response = $sdk->playlists->getPlaylist( - playlistID: 4109.48 +$response = $sdk->playlists->createPlaylist( + request: $request ); if ($response->object !== null) { @@ -176,21 +160,21 @@ if ($response->object !== null) { ### Parameters -| Parameter | Type | Required | Description | -| ---------------------- | ---------------------- | ---------------------- | ---------------------- | -| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | +| `$request` | [Operations\CreatePlaylistRequest](../../Models/Operations/CreatePlaylistRequest.md) | :heavy_check_mark: | The request object to use for the request. | ### Response -**[?Operations\GetPlaylistResponse](../../Models/Operations/GetPlaylistResponse.md)** +**[?Operations\CreatePlaylistResponse](../../Models/Operations/CreatePlaylistResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------ | ------------------------------ | ------------------------------ | -| Errors\GetPlaylistBadRequest | 400 | application/json | -| Errors\GetPlaylistUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| --------------------------------- | --------------------------------- | --------------------------------- | +| Errors\CreatePlaylistBadRequest | 400 | application/json | +| Errors\CreatePlaylistUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## deletePlaylist @@ -208,13 +192,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -245,9 +223,10 @@ if ($response->statusCode === 200) { | Errors\DeletePlaylistUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## updatePlaylist +## getPlaylist -From PMS version 1.9.1 clients can also edit playlist metadata using this endpoint as they would via `PUT /library/metadata/{playlistID}` +Gets detailed metadata for a playlist. A playlist for many purposes (rating, editing metadata, tagging), can be treated like a regular metadata item: +Smart playlist details contain the `content` attribute. This is the content URI for the generator. This can then be parsed by a client to provide smart playlist editing. ### Example Usage @@ -261,47 +240,36 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->playlists->updatePlaylist( - playlistID: 3915.00, - title: '', - summary: '' - +$response = $sdk->playlists->getPlaylist( + playlistID: 4109.48 ); -if ($response->statusCode === 200) { +if ($response->object !== null) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | -| ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | -| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | -| `title` | *?string* | :heavy_minus_sign: | name of the playlist | -| `summary` | *?string* | :heavy_minus_sign: | summary description of the playlist | +| Parameter | Type | Required | Description | +| ---------------------- | ---------------------- | ---------------------- | ---------------------- | +| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | ### Response -**[?Operations\UpdatePlaylistResponse](../../Models/Operations/UpdatePlaylistResponse.md)** +**[?Operations\GetPlaylistResponse](../../Models/Operations/GetPlaylistResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| --------------------------------- | --------------------------------- | --------------------------------- | -| Errors\UpdatePlaylistBadRequest | 400 | application/json | -| Errors\UpdatePlaylistUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------ | ------------------------------ | ------------------------------ | +| Errors\GetPlaylistBadRequest | 400 | application/json | +| Errors\GetPlaylistUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getPlaylistContents @@ -323,13 +291,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -363,10 +325,9 @@ if ($response->object !== null) { | Errors\GetPlaylistContentsUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## clearPlaylistContents - -Clears a playlist, only works with dumb playlists. Returns the playlist. +## getPlaylists +Get All Playlists given the specified filters. ### Example Usage @@ -376,50 +337,47 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->playlists->clearPlaylistContents( - playlistID: 1893.18 +$response = $sdk->playlists->getPlaylists( + playlistType: Operations\PlaylistType::Audio, + smart: Operations\QueryParamSmart::Zero + ); -if ($response->statusCode === 200) { +if ($response->object !== null) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | -| ---------------------- | ---------------------- | ---------------------- | ---------------------- | -| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| `playlistType` | [?Operations\PlaylistType](../../Models/Operations/PlaylistType.md) | :heavy_minus_sign: | limit to a type of playlist. | +| `smart` | [?Operations\QueryParamSmart](../../Models/Operations/QueryParamSmart.md) | :heavy_minus_sign: | type of playlists to return (default is all). | ### Response -**[?Operations\ClearPlaylistContentsResponse](../../Models/Operations/ClearPlaylistContentsResponse.md)** +**[?Operations\GetPlaylistsResponse](../../Models/Operations/GetPlaylistsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | -| Errors\ClearPlaylistContentsBadRequest | 400 | application/json | -| Errors\ClearPlaylistContentsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------- | ------------------------------- | ------------------------------- | +| Errors\GetPlaylistsBadRequest | 400 | application/json | +| Errors\GetPlaylistsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## addPlaylistContents +## updatePlaylist -Adds a generator to a playlist, same parameters as the POST to create. With a dumb playlist, this adds the specified items to the playlist. -With a smart playlist, passing a new `uri` parameter replaces the rules for the playlist. Returns the playlist. +From PMS version 1.9.1 clients can also edit playlist metadata using this endpoint as they would via `PUT /library/metadata/{playlistID}` ### Example Usage @@ -433,47 +391,41 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->playlists->addPlaylistContents( - playlistID: 8502.00, - uri: 'server://12345/com.plexapp.plugins.library/library/metadata/1', - playQueueID: 123 +$response = $sdk->playlists->updatePlaylist( + playlistID: 3915.00, + title: '', + summary: '' ); -if ($response->object !== null) { +if ($response->statusCode === 200) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | Example | -| ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | -| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | | -| `uri` | *string* | :heavy_check_mark: | the content URI for the playlist | server://12345/com.plexapp.plugins.library/library/metadata/1 | -| `playQueueID` | *?float* | :heavy_minus_sign: | the play queue to add to a playlist | 123 | +| Parameter | Type | Required | Description | +| ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | +| `playlistID` | *float* | :heavy_check_mark: | the ID of the playlist | +| `title` | *?string* | :heavy_minus_sign: | name of the playlist | +| `summary` | *?string* | :heavy_minus_sign: | summary description of the playlist | ### Response -**[?Operations\AddPlaylistContentsResponse](../../Models/Operations/AddPlaylistContentsResponse.md)** +**[?Operations\UpdatePlaylistResponse](../../Models/Operations/UpdatePlaylistResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| -------------------------------------- | -------------------------------------- | -------------------------------------- | -| Errors\AddPlaylistContentsBadRequest | 400 | application/json | -| Errors\AddPlaylistContentsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| --------------------------------- | --------------------------------- | --------------------------------- | +| Errors\UpdatePlaylistBadRequest | 400 | application/json | +| Errors\UpdatePlaylistUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## uploadPlaylist @@ -492,13 +444,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); diff --git a/docs/sdks/plex/README.md b/docs/sdks/plex/README.md index 723eb1f..a7accee 100644 --- a/docs/sdks/plex/README.md +++ b/docs/sdks/plex/README.md @@ -8,17 +8,17 @@ API Calls that perform operations directly against https://Plex.tv ### Available Operations +* [getServerResources](#getserverresources) - Get Server Resources * [getCompanionsData](#getcompanionsdata) - Get Companions Data -* [getUserFriends](#getuserfriends) - Get list of friends of the user logged in * [getGeoData](#getgeodata) - Get Geo Data * [getHomeData](#gethomedata) - Get Plex Home Data -* [getServerResources](#getserverresources) - Get Server Resources * [getPin](#getpin) - Get a Pin * [getTokenByPinId](#gettokenbypinid) - Get Access Token by PinId +* [getUserFriends](#getuserfriends) - Get list of friends of the user logged in -## getCompanionsData +## getServerResources -Get Companions Data +Get Plex server access tokens and server connections ### Example Usage @@ -28,49 +28,52 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->plex->getCompanionsData( +$response = $sdk->plex->getServerResources( + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + includeHttps: Operations\IncludeHttps::Enable, + includeRelay: Operations\IncludeRelay::Enable, + includeIPv6: Operations\IncludeIPv6::Enable ); -if ($response->responseBodies !== null) { +if ($response->plexDevices !== null) { // handle response } ``` ### Parameters -| Parameter | Type | Required | Description | -| ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | -| `$serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | +| `clientID` | *string* | :heavy_check_mark: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | +| `includeHttps` | [?Operations\IncludeHttps](../../Models/Operations/IncludeHttps.md) | :heavy_minus_sign: | Include Https entries in the results | 1 | +| `includeRelay` | [?Operations\IncludeRelay](../../Models/Operations/IncludeRelay.md) | :heavy_minus_sign: | Include Relay addresses in the results
E.g: https://10-0-0-25.bbf8e10c7fa20447cacee74cd9914cde.plex.direct:32400
| 1 | +| `includeIPv6` | [?Operations\IncludeIPv6](../../Models/Operations/IncludeIPv6.md) | :heavy_minus_sign: | Include IPv6 entries in the results | 1 | +| `$serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | http://localhost:8080 | ### Response -**[?Operations\GetCompanionsDataResponse](../../Models/Operations/GetCompanionsDataResponse.md)** +**[?Operations\GetServerResourcesResponse](../../Models/Operations/GetServerResourcesResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------------ | ------------------------------------ | ------------------------------------ | -| Errors\GetCompanionsDataBadRequest | 400 | application/json | -| Errors\GetCompanionsDataUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------------- | ------------------------------------- | ------------------------------------- | +| Errors\GetServerResourcesBadRequest | 400 | application/json | +| Errors\GetServerResourcesUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getUserFriends +## getCompanionsData -Get friends of provided auth token. +Get Companions Data ### Example Usage @@ -83,21 +86,15 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->plex->getUserFriends( +$response = $sdk->plex->getCompanionsData( ); -if ($response->friends !== null) { +if ($response->responseBodies !== null) { // handle response } ``` @@ -110,15 +107,15 @@ if ($response->friends !== null) { ### Response -**[?Operations\GetUserFriendsResponse](../../Models/Operations/GetUserFriendsResponse.md)** +**[?Operations\GetCompanionsDataResponse](../../Models/Operations/GetCompanionsDataResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| --------------------------------- | --------------------------------- | --------------------------------- | -| Errors\GetUserFriendsBadRequest | 400 | application/json | -| Errors\GetUserFriendsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | +| Errors\GetCompanionsDataBadRequest | 400 | application/json | +| Errors\GetCompanionsDataUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getGeoData @@ -133,13 +130,7 @@ require 'vendor/autoload.php'; use LukeHagar\Plex_API; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); +$sdk = Plex_API\PlexAPI::builder()->build(); @@ -185,13 +176,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -216,67 +201,6 @@ if ($response->object !== null) { | Errors\GetHomeDataUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## getServerResources - -Get Plex server access tokens and server connections - -### Example Usage - -```php -declare(strict_types=1); - -require 'vendor/autoload.php'; - -use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; - -$security = ''; - -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - - - -$response = $sdk->plex->getServerResources( - includeHttps: Operations\IncludeHttps::Enable, - includeRelay: Operations\IncludeRelay::Enable, - includeIPv6: Operations\IncludeIPv6::Enable, - clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58' - -); - -if ($response->plexDevices !== null) { - // handle response -} -``` - -### Parameters - -| Parameter | Type | Required | Description | Example | -| ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | -| `includeHttps` | [?Operations\IncludeHttps](../../Models/Operations/IncludeHttps.md) | :heavy_minus_sign: | Include Https entries in the results | 1 | -| `includeRelay` | [?Operations\IncludeRelay](../../Models/Operations/IncludeRelay.md) | :heavy_minus_sign: | Include Relay addresses in the results
E.g: https://10-0-0-25.bbf8e10c7fa20447cacee74cd9914cde.plex.direct:32400
| 1 | -| `includeIPv6` | [?Operations\IncludeIPv6](../../Models/Operations/IncludeIPv6.md) | :heavy_minus_sign: | Include IPv6 entries in the results | 1 | -| `clientID` | *?string* | :heavy_minus_sign: | An opaque identifier unique to the client (UUID, serial number, or other unique device ID) | 3381b62b-9ab7-4e37-827b-203e9809eb58 | -| `$serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | http://localhost:8080 | - -### Response - -**[?Operations\GetServerResourcesResponse](../../Models/Operations/GetServerResourcesResponse.md)** - -### Errors - -| Error Type | Status Code | Content Type | -| ------------------------------------- | ------------------------------------- | ------------------------------------- | -| Errors\GetServerResourcesBadRequest | 400 | application/json | -| Errors\GetServerResourcesUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - ## getPin Retrieve a Pin ID from Plex.tv to use for authentication flows @@ -291,15 +215,15 @@ require 'vendor/autoload.php'; use LukeHagar\Plex_API; use LukeHagar\Plex_API\Models\Operations; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); +$sdk = Plex_API\PlexAPI::builder()->build(); -$request = new Operations\GetPinRequest(); +$request = new Operations\GetPinRequest( + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + clientName: 'Plex for Roku', + deviceNickname: 'Roku 3', + clientVersion: '2.4.1', + platform: 'Roku', +); $response = $sdk->plex->getPin( request: $request @@ -342,16 +266,15 @@ require 'vendor/autoload.php'; use LukeHagar\Plex_API; use LukeHagar\Plex_API\Models\Operations; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); +$sdk = Plex_API\PlexAPI::builder()->build(); $request = new Operations\GetTokenByPinIdRequest( pinID: 408895, + clientID: '3381b62b-9ab7-4e37-827b-203e9809eb58', + clientName: 'Plex for Roku', + deviceNickname: 'Roku 3', + clientVersion: '2.4.1', + platform: 'Roku', ); $response = $sdk->plex->getTokenByPinId( @@ -380,4 +303,50 @@ if ($response->authPinContainer !== null) { | ---------------------------------- | ---------------------------------- | ---------------------------------- | | Errors\GetTokenByPinIdBadRequest | 400 | application/json | | Errors\GetTokenByPinIdResponseBody | 404 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Errors\SDKException | 4XX, 5XX | \*/\* | + +## getUserFriends + +Get friends of provided auth token. + +### Example Usage + +```php +declare(strict_types=1); + +require 'vendor/autoload.php'; + +use LukeHagar\Plex_API; + +$security = ''; + +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); + + + +$response = $sdk->plex->getUserFriends( + +); + +if ($response->friends !== null) { + // handle response +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | +| `$serverURL` | *string* | :heavy_minus_sign: | An optional server URL to use. | + +### Response + +**[?Operations\GetUserFriendsResponse](../../Models/Operations/GetUserFriendsResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| --------------------------------- | --------------------------------- | --------------------------------- | +| Errors\GetUserFriendsBadRequest | 400 | application/json | +| Errors\GetUserFriendsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/plexapi/README.md b/docs/sdks/plexapi/README.md index e91fa37..1e395e4 100644 --- a/docs/sdks/plexapi/README.md +++ b/docs/sdks/plexapi/README.md @@ -26,3 +26,6 @@ The following SDKs are generated from the OpenAPI Specification. They are automa | 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) | - + + +### Available Operations diff --git a/docs/sdks/search/README.md b/docs/sdks/search/README.md index 78a4cdb..b23de24 100644 --- a/docs/sdks/search/README.md +++ b/docs/sdks/search/README.md @@ -8,9 +8,55 @@ API Calls that perform search operations with Plex Media Server ### Available Operations +* [getSearchResults](#getsearchresults) - Get Search Results * [performSearch](#performsearch) - Perform a search * [performVoiceSearch](#performvoicesearch) - Perform a voice search -* [getSearchResults](#getsearchresults) - Get Search Results + +## getSearchResults + +This will search the database for the string provided. + +### Example Usage + +```php +declare(strict_types=1); + +require 'vendor/autoload.php'; + +use LukeHagar\Plex_API; + +$security = ''; + +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); + + + +$response = $sdk->search->getSearchResults( + query: '110' +); + +if ($response->object !== null) { + // handle response +} +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | +| `query` | *string* | :heavy_check_mark: | The search query string to use | 110 | + +### Response + +**[?Operations\GetSearchResultsResponse](../../Models/Operations/GetSearchResultsResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| ----------------------------------- | ----------------------------------- | ----------------------------------- | +| Errors\GetSearchResultsBadRequest | 400 | application/json | +| Errors\GetSearchResultsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## performSearch @@ -39,13 +85,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -100,13 +140,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -140,56 +174,4 @@ if ($response->statusCode === 200) { | ------------------------------------- | ------------------------------------- | ------------------------------------- | | Errors\PerformVoiceSearchBadRequest | 400 | application/json | | Errors\PerformVoiceSearchUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - -## getSearchResults - -This will search the database for the string provided. - -### Example Usage - -```php -declare(strict_types=1); - -require 'vendor/autoload.php'; - -use LukeHagar\Plex_API; - -$security = ''; - -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - - - -$response = $sdk->search->getSearchResults( - query: '110' -); - -if ($response->object !== null) { - // handle response -} -``` - -### Parameters - -| Parameter | Type | Required | Description | Example | -| ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | -| `query` | *string* | :heavy_check_mark: | The search query string to use | 110 | - -### Response - -**[?Operations\GetSearchResultsResponse](../../Models/Operations/GetSearchResultsResponse.md)** - -### Errors - -| Error Type | Status Code | Content Type | -| ----------------------------------- | ----------------------------------- | ----------------------------------- | -| Errors\GetSearchResultsBadRequest | 400 | application/json | -| Errors\GetSearchResultsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/server/README.md b/docs/sdks/server/README.md index 6bd26e3..71c84f8 100644 --- a/docs/sdks/server/README.md +++ b/docs/sdks/server/README.md @@ -8,19 +8,19 @@ Operations against the Plex Media Server System. ### Available Operations -* [getServerCapabilities](#getservercapabilities) - Get Server Capabilities -* [getServerPreferences](#getserverpreferences) - Get Server Preferences +* [getMediaProviders](#getmediaproviders) - Get Media Providers +* [getServerIdentity](#getserveridentity) - Get Server Identity * [getAvailableClients](#getavailableclients) - Get Available Clients * [getDevices](#getdevices) - Get Devices -* [getServerIdentity](#getserveridentity) - Get Server Identity * [getMyPlexAccount](#getmyplexaccount) - Get MyPlex Account * [getResizedPhoto](#getresizedphoto) - Get a Resized Photo -* [getMediaProviders](#getmediaproviders) - Get Media Providers +* [getServerCapabilities](#getservercapabilities) - Get Server Capabilities * [getServerList](#getserverlist) - Get Server List +* [getServerPreferences](#getserverpreferences) - Get Server Preferences -## getServerCapabilities +## getMediaProviders -Get Server Capabilities +Retrieves media providers and their features from the Plex server. ### Example Usage @@ -33,18 +33,12 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->server->getServerCapabilities( - +$response = $sdk->server->getMediaProviders( + xPlexToken: 'CV5xoxjTpFKUzBTShsaf' ); if ($response->object !== null) { @@ -52,21 +46,27 @@ if ($response->object !== null) { } ``` +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | +| `xPlexToken` | *string* | :heavy_check_mark: | An authentication token, obtained from plex.tv | CV5xoxjTpFKUzBTShsaf | + ### Response -**[?Operations\GetServerCapabilitiesResponse](../../Models/Operations/GetServerCapabilitiesResponse.md)** +**[?Operations\GetMediaProvidersResponse](../../Models/Operations/GetMediaProvidersResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | -| Errors\GetServerCapabilitiesBadRequest | 400 | application/json | -| Errors\GetServerCapabilitiesUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | +| Errors\GetMediaProvidersBadRequest | 400 | application/json | +| Errors\GetMediaProvidersUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getServerPreferences +## getServerIdentity -Get Server Preferences +This request is useful to determine if the server is online or offline ### Example Usage @@ -77,19 +77,11 @@ require 'vendor/autoload.php'; use LukeHagar\Plex_API; -$security = ''; - -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->build(); -$response = $sdk->server->getServerPreferences( +$response = $sdk->server->getServerIdentity( ); @@ -100,15 +92,14 @@ if ($response->object !== null) { ### Response -**[?Operations\GetServerPreferencesResponse](../../Models/Operations/GetServerPreferencesResponse.md)** +**[?Operations\GetServerIdentityResponse](../../Models/Operations/GetServerIdentityResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| --------------------------------------- | --------------------------------------- | --------------------------------------- | -| Errors\GetServerPreferencesBadRequest | 400 | application/json | -| Errors\GetServerPreferencesUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| -------------------------------------- | -------------------------------------- | -------------------------------------- | +| Errors\GetServerIdentityRequestTimeout | 408 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getAvailableClients @@ -125,13 +116,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -171,13 +156,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -202,49 +181,6 @@ if ($response->object !== null) { | Errors\GetDevicesUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## getServerIdentity - -This request is useful to determine if the server is online or offline - -### Example Usage - -```php -declare(strict_types=1); - -require 'vendor/autoload.php'; - -use LukeHagar\Plex_API; - -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->build(); - - - -$response = $sdk->server->getServerIdentity( - -); - -if ($response->object !== null) { - // handle response -} -``` - -### Response - -**[?Operations\GetServerIdentityResponse](../../Models/Operations/GetServerIdentityResponse.md)** - -### Errors - -| Error Type | Status Code | Content Type | -| -------------------------------------- | -------------------------------------- | -------------------------------------- | -| Errors\GetServerIdentityRequestTimeout | 408 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | - ## getMyPlexAccount Returns MyPlex Account Information @@ -260,13 +196,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -308,13 +238,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetResizedPhotoRequest( width: 110, @@ -353,9 +277,9 @@ if ($response->statusCode === 200) { | Errors\GetResizedPhotoUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## getMediaProviders +## getServerCapabilities -Retrieves media providers and their features from the Plex server. +Get Server Capabilities ### Example Usage @@ -368,18 +292,12 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->server->getMediaProviders( - xPlexToken: 'CV5xoxjTpFKUzBTShsaf' +$response = $sdk->server->getServerCapabilities( + ); if ($response->object !== null) { @@ -387,23 +305,17 @@ if ($response->object !== null) { } ``` -### Parameters - -| Parameter | Type | Required | Description | Example | -| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | -| `xPlexToken` | *string* | :heavy_check_mark: | An authentication token, obtained from plex.tv | CV5xoxjTpFKUzBTShsaf | - ### Response -**[?Operations\GetMediaProvidersResponse](../../Models/Operations/GetMediaProvidersResponse.md)** +**[?Operations\GetServerCapabilitiesResponse](../../Models/Operations/GetServerCapabilitiesResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------------ | ------------------------------------ | ------------------------------------ | -| Errors\GetMediaProvidersBadRequest | 400 | application/json | -| Errors\GetMediaProvidersUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | +| Errors\GetServerCapabilitiesBadRequest | 400 | application/json | +| Errors\GetServerCapabilitiesUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getServerList @@ -420,13 +332,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -449,4 +355,44 @@ if ($response->object !== null) { | -------------------------------- | -------------------------------- | -------------------------------- | | Errors\GetServerListBadRequest | 400 | application/json | | Errors\GetServerListUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Errors\SDKException | 4XX, 5XX | \*/\* | + +## getServerPreferences + +Get Server Preferences + +### Example Usage + +```php +declare(strict_types=1); + +require 'vendor/autoload.php'; + +use LukeHagar\Plex_API; + +$security = ''; + +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); + + + +$response = $sdk->server->getServerPreferences( + +); + +if ($response->object !== null) { + // handle response +} +``` + +### Response + +**[?Operations\GetServerPreferencesResponse](../../Models/Operations/GetServerPreferencesResponse.md)** + +### Errors + +| Error Type | Status Code | Content Type | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | +| Errors\GetServerPreferencesBadRequest | 400 | application/json | +| Errors\GetServerPreferencesUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/sessions/README.md b/docs/sdks/sessions/README.md index 0253434..9ec415c 100644 --- a/docs/sdks/sessions/README.md +++ b/docs/sdks/sessions/README.md @@ -8,14 +8,14 @@ API Calls that perform search operations with Plex Media Server Sessions ### Available Operations -* [getSessions](#getsessions) - Get Active Sessions * [getSessionHistory](#getsessionhistory) - Get Session History +* [getSessions](#getsessions) - Get Active Sessions * [getTranscodeSessions](#gettranscodesessions) - Get Transcode Sessions * [stopTranscodeSession](#stoptranscodesession) - Stop a Transcode Session -## getSessions +## getSessionHistory -This will retrieve the "Now Playing" Information of the PMS. +This will Retrieve a listing of all history views. ### Example Usage @@ -25,20 +25,19 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); - +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); +$filter = new Operations\QueryParamFilter(); -$response = $sdk->sessions->getSessions( +$response = $sdk->sessions->getSessionHistory( + sort: '', + accountId: 1, + filter: $filter, + librarySectionID: 12 ); @@ -47,21 +46,30 @@ if ($response->object !== null) { } ``` +### Parameters + +| Parameter | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `sort` | *?string* | :heavy_minus_sign: | Sorts the results by the specified field followed by the direction (asc, desc)
| | +| `accountId` | *?int* | :heavy_minus_sign: | Filter results by those that are related to a specific users id
| 1 | +| `filter` | [?Operations\QueryParamFilter](../../Models/Operations/QueryParamFilter.md) | :heavy_minus_sign: | Filters content by field and direction/equality
(Unknown if viewedAt is the only supported column)
| {
"viewed-at-greater-than": {
"value": "viewedAt\u003e"
},
"viewed-at-greater-than-or-equal-to": {
"value": "viewedAt\u003e=\u003e"
},
"viewed-at-less-than": {
"value": "viewedAt\u003c"
}
} | +| `librarySectionID` | *?int* | :heavy_minus_sign: | Filters the results based on the id of a valid library section
| 12 | + ### Response -**[?Operations\GetSessionsResponse](../../Models/Operations/GetSessionsResponse.md)** +**[?Operations\GetSessionHistoryResponse](../../Models/Operations/GetSessionHistoryResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------ | ------------------------------ | ------------------------------ | -| Errors\GetSessionsBadRequest | 400 | application/json | -| Errors\GetSessionsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | +| Errors\GetSessionHistoryBadRequest | 400 | application/json | +| Errors\GetSessionHistoryUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | -## getSessionHistory +## getSessions -This will Retrieve a listing of all history views. +This will retrieve the "Now Playing" Information of the PMS. ### Example Usage @@ -71,25 +79,14 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$filter = new Operations\QueryParamFilter(); -$response = $sdk->sessions->getSessionHistory( - sort: '', - accountId: 1, - filter: $filter, - librarySectionID: 12 + +$response = $sdk->sessions->getSessions( ); @@ -98,26 +95,17 @@ if ($response->object !== null) { } ``` -### Parameters - -| Parameter | Type | Required | Description | Example | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sort` | *?string* | :heavy_minus_sign: | Sorts the results by the specified field followed by the direction (asc, desc)
| | -| `accountId` | *?int* | :heavy_minus_sign: | Filter results by those that are related to a specific users id
| 1 | -| `filter` | [?Operations\QueryParamFilter](../../Models/Operations/QueryParamFilter.md) | :heavy_minus_sign: | Filters content by field and direction/equality
(Unknown if viewedAt is the only supported column)
| {
"viewed-at-greater-than": {
"value": "viewedAt\u003e"
},
"viewed-at-greater-than-or-equal-to": {
"value": "viewedAt\u003e=\u003e"
},
"viewed-at-less-than": {
"value": "viewedAt\u003c"
}
} | -| `librarySectionID` | *?int* | :heavy_minus_sign: | Filters the results based on the id of a valid library section
| 12 | - ### Response -**[?Operations\GetSessionHistoryResponse](../../Models/Operations/GetSessionHistoryResponse.md)** +**[?Operations\GetSessionsResponse](../../Models/Operations/GetSessionsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------------ | ------------------------------------ | ------------------------------------ | -| Errors\GetSessionHistoryBadRequest | 400 | application/json | -| Errors\GetSessionHistoryUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------ | ------------------------------ | ------------------------------ | +| Errors\GetSessionsBadRequest | 400 | application/json | +| Errors\GetSessionsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getTranscodeSessions @@ -134,13 +122,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -180,13 +162,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); diff --git a/docs/sdks/statistics/README.md b/docs/sdks/statistics/README.md index e456297..501d5b5 100644 --- a/docs/sdks/statistics/README.md +++ b/docs/sdks/statistics/README.md @@ -8,13 +8,13 @@ API Calls that perform operations with Plex Media Server Statistics ### Available Operations -* [getStatistics](#getstatistics) - Get Media Statistics -* [getResourcesStatistics](#getresourcesstatistics) - Get Resources Statistics * [getBandwidthStatistics](#getbandwidthstatistics) - Get Bandwidth Statistics +* [getResourcesStatistics](#getresourcesstatistics) - Get Resources Statistics +* [getStatistics](#getstatistics) - Get Media Statistics -## getStatistics +## getBandwidthStatistics -This will return the media statistics for the server +This will return the bandwidth statistics for the server ### Example Usage @@ -27,17 +27,11 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->statistics->getStatistics( +$response = $sdk->statistics->getBandwidthStatistics( timespan: 4 ); @@ -54,15 +48,15 @@ if ($response->object !== null) { ### Response -**[?Operations\GetStatisticsResponse](../../Models/Operations/GetStatisticsResponse.md)** +**[?Operations\GetBandwidthStatisticsResponse](../../Models/Operations/GetBandwidthStatisticsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| -------------------------------- | -------------------------------- | -------------------------------- | -| Errors\GetStatisticsBadRequest | 400 | application/json | -| Errors\GetStatisticsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | +| Errors\GetBandwidthStatisticsBadRequest | 400 | application/json | +| Errors\GetBandwidthStatisticsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## getResourcesStatistics @@ -79,13 +73,7 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -116,9 +104,9 @@ if ($response->object !== null) { | Errors\GetResourcesStatisticsUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## getBandwidthStatistics +## getStatistics -This will return the bandwidth statistics for the server +This will return the media statistics for the server ### Example Usage @@ -131,17 +119,11 @@ use LukeHagar\Plex_API; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->statistics->getBandwidthStatistics( +$response = $sdk->statistics->getStatistics( timespan: 4 ); @@ -158,12 +140,12 @@ if ($response->object !== null) { ### Response -**[?Operations\GetBandwidthStatisticsResponse](../../Models/Operations/GetBandwidthStatisticsResponse.md)** +**[?Operations\GetStatisticsResponse](../../Models/Operations/GetStatisticsResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ----------------------------------------- | ----------------------------------------- | ----------------------------------------- | -| Errors\GetBandwidthStatisticsBadRequest | 400 | application/json | -| Errors\GetBandwidthStatisticsUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Error Type | Status Code | Content Type | +| -------------------------------- | -------------------------------- | -------------------------------- | +| Errors\GetStatisticsBadRequest | 400 | application/json | +| Errors\GetStatisticsUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/updater/README.md b/docs/sdks/updater/README.md index 4867048..79fd9f2 100644 --- a/docs/sdks/updater/README.md +++ b/docs/sdks/updater/README.md @@ -9,13 +9,14 @@ Updates to the status can be observed via the Event API. ### Available Operations -* [getUpdateStatus](#getupdatestatus) - Querying status of updates -* [checkForUpdates](#checkforupdates) - Checking for updates * [applyUpdates](#applyupdates) - Apply Updates +* [checkForUpdates](#checkforupdates) - Checking for updates +* [getUpdateStatus](#getupdatestatus) - Querying status of updates -## getUpdateStatus +## applyUpdates + +Note that these two parameters are effectively mutually exclusive. The `tonight` parameter takes precedence and `skip` will be ignored if `tonight` is also passed -Querying status of updates ### Example Usage @@ -25,39 +26,43 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; +use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->updater->getUpdateStatus( +$response = $sdk->updater->applyUpdates( + tonight: Operations\Tonight::One, + skip: Operations\Skip::One ); -if ($response->object !== null) { +if ($response->statusCode === 200) { // handle response } ``` +### Parameters + +| Parameter | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `tonight` | [?Operations\Tonight](../../Models/Operations/Tonight.md) | :heavy_minus_sign: | Indicate that you want the update to run during the next Butler execution. Omitting this or setting it to false indicates that the update should install | 1 | +| `skip` | [?Operations\Skip](../../Models/Operations/Skip.md) | :heavy_minus_sign: | Indicate that the latest version should be marked as skipped. The [Release] entry for this version will have the `state` set to `skipped`. | 1 | + ### Response -**[?Operations\GetUpdateStatusResponse](../../Models/Operations/GetUpdateStatusResponse.md)** +**[?Operations\ApplyUpdatesResponse](../../Models/Operations/ApplyUpdatesResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ---------------------------------- | ---------------------------------- | ---------------------------------- | -| Errors\GetUpdateStatusBadRequest | 400 | application/json | -| Errors\GetUpdateStatusUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | +| Error Type | Status Code | Content Type | +| ------------------------------- | ------------------------------- | ------------------------------- | +| Errors\ApplyUpdatesBadRequest | 400 | application/json | +| Errors\ApplyUpdatesUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | ## checkForUpdates @@ -75,13 +80,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); @@ -112,10 +111,9 @@ if ($response->statusCode === 200) { | Errors\CheckForUpdatesUnauthorized | 401 | application/json | | Errors\SDKException | 4XX, 5XX | \*/\* | -## applyUpdates - -Note that these two parameters are effectively mutually exclusive. The `tonight` parameter takes precedence and `skip` will be ignored if `tonight` is also passed +## getUpdateStatus +Querying status of updates ### Example Usage @@ -125,46 +123,30 @@ declare(strict_types=1); require 'vendor/autoload.php'; use LukeHagar\Plex_API; -use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); -$response = $sdk->updater->applyUpdates( - tonight: Operations\Tonight::One, - skip: Operations\Skip::One +$response = $sdk->updater->getUpdateStatus( ); -if ($response->statusCode === 200) { +if ($response->object !== null) { // handle response } ``` -### Parameters - -| Parameter | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `tonight` | [?Operations\Tonight](../../Models/Operations/Tonight.md) | :heavy_minus_sign: | Indicate that you want the update to run during the next Butler execution. Omitting this or setting it to false indicates that the update should install | 1 | -| `skip` | [?Operations\Skip](../../Models/Operations/Skip.md) | :heavy_minus_sign: | Indicate that the latest version should be marked as skipped. The [Release] entry for this version will have the `state` set to `skipped`. | 1 | - ### Response -**[?Operations\ApplyUpdatesResponse](../../Models/Operations/ApplyUpdatesResponse.md)** +**[?Operations\GetUpdateStatusResponse](../../Models/Operations/GetUpdateStatusResponse.md)** ### Errors -| Error Type | Status Code | Content Type | -| ------------------------------- | ------------------------------- | ------------------------------- | -| Errors\ApplyUpdatesBadRequest | 400 | application/json | -| Errors\ApplyUpdatesUnauthorized | 401 | application/json | -| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file +| Error Type | Status Code | Content Type | +| ---------------------------------- | ---------------------------------- | ---------------------------------- | +| Errors\GetUpdateStatusBadRequest | 400 | application/json | +| Errors\GetUpdateStatusUnauthorized | 401 | application/json | +| Errors\SDKException | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/video/README.md b/docs/sdks/video/README.md index 0209a14..99b0383 100644 --- a/docs/sdks/video/README.md +++ b/docs/sdks/video/README.md @@ -27,13 +27,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetTimelineRequest( ratingKey: 23409, @@ -91,13 +85,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\StartUniversalTranscodeRequest( hasMDE: 1, diff --git a/docs/sdks/watchlist/README.md b/docs/sdks/watchlist/README.md index 7bfe034..6613c3c 100644 --- a/docs/sdks/watchlist/README.md +++ b/docs/sdks/watchlist/README.md @@ -26,13 +26,7 @@ use LukeHagar\Plex_API\Models\Operations; $security = ''; -$sdk = Plex_API\PlexAPI::builder() - ->setClientID('3381b62b-9ab7-4e37-827b-203e9809eb58') - ->setClientName('Plex for Roku') - ->setClientVersion('2.4.1') - ->setPlatform('Roku') - ->setDeviceNickname('Roku 3') - ->setSecurity($security)->build(); +$sdk = Plex_API\PlexAPI::builder()->setSecurity($security)->build(); $request = new Operations\GetWatchListRequest( filter: Operations\Filter::Available, diff --git a/src/Activities.php b/src/Activities.php index aa1eda5..d1596aa 100644 --- a/src/Activities.php +++ b/src/Activities.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Activities @@ -21,47 +23,84 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Get Server Activities + * Cancel Server Activities * - * Get Server Activities + * Cancel Server Activities * - * @return Operations\GetServerActivitiesResponse + * @param string $activityUUID + * @return Operations\CancelServerActivitiesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getServerActivities(): Operations\GetServerActivitiesResponse + public function cancelServerActivities(string $activityUUID, ?Options $options = null): Operations\CancelServerActivitiesResponse { + $request = new Operations\CancelServerActivitiesRequest( + activityUUID: $activityUUID, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/activities'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/activities/{activityUUID}', Operations\CancelServerActivitiesRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); + $hookContext = new HookContext('cancelServerActivities', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetServerActivitiesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetServerActivitiesResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\CancelServerActivitiesResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerActivitiesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\CancelServerActivitiesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -69,8 +108,11 @@ public function getServerActivities(): Operations\GetServerActivitiesResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerActivitiesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\CancelServerActivitiesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -84,41 +126,67 @@ public function getServerActivities(): Operations\GetServerActivitiesResponse } /** - * Cancel Server Activities + * Get Server Activities * - * Cancel Server Activities + * Get Server Activities * - * @param string $activityUUID - * @return Operations\CancelServerActivitiesResponse + * @return Operations\GetServerActivitiesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function cancelServerActivities(string $activityUUID): Operations\CancelServerActivitiesResponse + public function getServerActivities(?Options $options = null): Operations\GetServerActivitiesResponse { - $request = new Operations\CancelServerActivitiesRequest( - activityUUID: $activityUUID, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/activities/{activityUUID}', Operations\CancelServerActivitiesRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/activities'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getServerActivities', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\CancelServerActivitiesResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetServerActivitiesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetServerActivitiesResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\CancelServerActivitiesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerActivitiesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -126,8 +194,11 @@ public function cancelServerActivities(string $activityUUID): Operations\CancelS } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\CancelServerActivitiesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerActivitiesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Authentication.php b/src/Authentication.php index 3432bd9..22ae0e0 100644 --- a/src/Authentication.php +++ b/src/Authentication.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Authentication @@ -29,66 +31,25 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } - /** - * Get a Transient Token - * - * This endpoint provides the caller with a temporary token with the same access level as the caller's token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted. - * + * @param string $baseUrl + * @param array $urlVariables * - * @param Operations\GetTransientTokenQueryParamType $type - * @param Operations\Scope $scope - * @return Operations\GetTransientTokenResponse - * @throws \LukeHagar\Plex_API\Models\Errors\SDKException + * @return string */ - public function getTransientToken(Operations\GetTransientTokenQueryParamType $type, Operations\Scope $scope): Operations\GetTransientTokenResponse + public function getUrl(string $baseUrl, array $urlVariables): string { - $request = new Operations\GetTransientTokenRequest( - type: $type, - scope: $scope, - ); - $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/security/token'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetTransientTokenRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $serverDetails = $this->sdkConfiguration->getServerDetails(); - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); - $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } - $statusCode = $httpResponse->getStatusCode(); - if ($statusCode == 200) { - return new Operations\GetTransientTokenResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); - } elseif ($statusCode == 400) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTransientTokenBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode == 401) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTransientTokenUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); } /** @@ -102,25 +63,45 @@ public function getTransientToken(Operations\GetTransientTokenQueryParamType $ty * @return Operations\GetSourceConnectionInformationResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getSourceConnectionInformation(string $source): Operations\GetSourceConnectionInformationResponse + public function getSourceConnectionInformation(string $source, ?Options $options = null): Operations\GetSourceConnectionInformationResponse { $request = new Operations\GetSourceConnectionInformationRequest( source: $source, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/security/resources'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetSourceConnectionInformationRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetSourceConnectionInformationRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getSourceConnectionInformation', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\GetSourceConnectionInformationResponse( statusCode: $statusCode, contentType: $contentType, @@ -128,8 +109,11 @@ public function getSourceConnectionInformation(string $source): Operations\GetSo ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSourceConnectionInformationBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSourceConnectionInformationBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -137,8 +121,11 @@ public function getSourceConnectionInformation(string $source): Operations\GetSo } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSourceConnectionInformationUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSourceConnectionInformationUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -156,11 +143,11 @@ public function getSourceConnectionInformation(string $source): Operations\GetSo * * Get the User data from the provided X-Plex-Token * - * @param string $serverURL + * @param ?string $serverURL * @return Operations\GetTokenDetailsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getTokenDetails(?string $serverURL = null): Operations\GetTokenDetailsResponse + public function getTokenDetails(?string $serverURL = null, ?Options $options = null): Operations\GetTokenDetailsResponse { $baseUrl = Utils\Utils::templateUrl(Authentication::GET_TOKEN_DETAILS_SERVERS[0], [ ]); @@ -168,20 +155,39 @@ public function getTokenDetails(?string $serverURL = null): Operations\GetTokenD $baseUrl = $serverURL; } $url = Utils\Utils::generateUrl($baseUrl, '/user'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getTokenDetails', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetTokenDetailsUserPlexAccount', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetTokenDetailsUserPlexAccount', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetTokenDetailsResponse( statusCode: $statusCode, contentType: $contentType, @@ -194,8 +200,98 @@ public function getTokenDetails(?string $serverURL = null): Operations\GetTokenD } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTokenDetailsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 401) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTokenDetailsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } + + /** + * Get a Transient Token + * + * This endpoint provides the caller with a temporary token with the same access level as the caller's token. These tokens are valid for up to 48 hours and are destroyed if the server instance is restarted. + * + * + * @param Operations\GetTransientTokenQueryParamType $type + * @param Operations\Scope $scope + * @return Operations\GetTransientTokenResponse + * @throws \LukeHagar\Plex_API\Models\Errors\SDKException + */ + public function getTransientToken(Operations\GetTransientTokenQueryParamType $type, Operations\Scope $scope, ?Options $options = null): Operations\GetTransientTokenResponse + { + $request = new Operations\GetTransientTokenRequest( + type: $type, + scope: $scope, + ); + $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); + $url = Utils\Utils::generateUrl($baseUrl, '/security/token'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + + $qp = Utils\Utils::getQueryParams(Operations\GetTransientTokenRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getTransientToken', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } + $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; + + $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } + if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + return new Operations\GetTransientTokenResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); + } elseif ($statusCode == 400) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTokenDetailsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTransientTokenBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -203,8 +299,11 @@ public function getTokenDetails(?string $serverURL = null): Operations\GetTokenD } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTokenDetailsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTransientTokenUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -222,12 +321,12 @@ public function getTokenDetails(?string $serverURL = null): Operations\GetTokenD * * Sign in user with username and password and return user data with Plex authentication token * - * @param ?Operations\PostUsersSignInDataRequest $request - * @param string $serverURL + * @param Operations\PostUsersSignInDataRequest $request + * @param ?string $serverURL * @return Operations\PostUsersSignInDataResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function postUsersSignInData(?Operations\PostUsersSignInDataRequest $request = null, ?string $serverURL = null): Operations\PostUsersSignInDataResponse + public function postUsersSignInData(Operations\PostUsersSignInDataRequest $request, ?string $serverURL = null, ?Options $options = null): Operations\PostUsersSignInDataResponse { $baseUrl = Utils\Utils::templateUrl(Authentication::POST_USERS_SIGN_IN_DATA_SERVERS[0], [ ]); @@ -235,26 +334,47 @@ public function postUsersSignInData(?Operations\PostUsersSignInDataRequest $requ $baseUrl = $serverURL; } $url = Utils\Utils::generateUrl($baseUrl, '/users/signin'); - $options = ['http_errors' => false]; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; $body = Utils\Utils::serializeRequestBody($request, 'requestBody', 'form'); if ($body !== null) { - $options = array_merge_recursive($options, $body); + $httpOptions = array_merge_recursive($httpOptions, $body); } - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; } - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); - $httpResponse = $this->sdkConfiguration->defaultClient->send($httpRequest, $options); + $hookContext = new HookContext('post-users-sign-in-data', null, null); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 201) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataUserPlexAccount', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataUserPlexAccount', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\PostUsersSignInDataResponse( statusCode: $statusCode, contentType: $contentType, @@ -267,8 +387,11 @@ public function postUsersSignInData(?Operations\PostUsersSignInDataRequest $requ } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\PostUsersSignInDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\PostUsersSignInDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -276,8 +399,11 @@ public function postUsersSignInData(?Operations\PostUsersSignInDataRequest $requ } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\PostUsersSignInDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\PostUsersSignInDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Butler.php b/src/Butler.php index b160685..21eb29a 100644 --- a/src/Butler.php +++ b/src/Butler.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Butler @@ -21,6 +23,26 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** * Get Butler tasks @@ -30,24 +52,43 @@ public function __construct(public SDKConfiguration $sdkConfig) * @return Operations\GetButlerTasksResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getButlerTasks(): Operations\GetButlerTasksResponse + public function getButlerTasks(?Options $options = null): Operations\GetButlerTasksResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/butler'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getButlerTasks', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetButlerTasksResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetButlerTasksResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetButlerTasksResponse( statusCode: $statusCode, contentType: $contentType, @@ -60,8 +101,11 @@ public function getButlerTasks(): Operations\GetButlerTasksResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetButlerTasksBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetButlerTasksBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -69,8 +113,11 @@ public function getButlerTasks(): Operations\GetButlerTasksResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetButlerTasksUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetButlerTasksUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -96,21 +143,39 @@ public function getButlerTasks(): Operations\GetButlerTasksResponse * @return Operations\StartAllTasksResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function startAllTasks(): Operations\StartAllTasksResponse + public function startAllTasks(?Options $options = null): Operations\StartAllTasksResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/butler'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('startAllTasks', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\StartAllTasksResponse( statusCode: $statusCode, contentType: $contentType, @@ -118,8 +183,11 @@ public function startAllTasks(): Operations\StartAllTasksResponse ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StartAllTasksBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StartAllTasksBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -127,8 +195,11 @@ public function startAllTasks(): Operations\StartAllTasksResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StartAllTasksUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StartAllTasksUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -142,38 +213,67 @@ public function startAllTasks(): Operations\StartAllTasksResponse } /** - * Stop all Butler tasks + * Start a single Butler task * - * This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue. + * 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's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria: + * 1. Any tasks not scheduled to run on the current day will be skipped. + * 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. + * 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. + * 4. If we are outside the configured window, the task will start immediately. * * - * @return Operations\StopAllTasksResponse + * @param Operations\TaskName $taskName + * @return Operations\StartTaskResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function stopAllTasks(): Operations\StopAllTasksResponse + public function startTask(Operations\TaskName $taskName, ?Options $options = null): Operations\StartTaskResponse { + $request = new Operations\StartTaskRequest( + taskName: $taskName, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/butler'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/butler/{taskName}', Operations\StartTaskRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); + $hookContext = new HookContext('startTask', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); - if ($statusCode == 200) { - return new Operations\StopAllTasksResponse( + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } + if (in_array($statusCode, [200, 202])) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + return new Operations\StartTaskResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StopAllTasksBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StartTaskBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -181,8 +281,11 @@ public function stopAllTasks(): Operations\StopAllTasksResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StopAllTasksUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StartTaskUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -196,46 +299,59 @@ public function stopAllTasks(): Operations\StopAllTasksResponse } /** - * Start a single Butler task + * Stop all Butler tasks * - * 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's Settings page but can be manually started using this endpoint. Tasks will run with the following criteria: - * 1. Any tasks not scheduled to run on the current day will be skipped. - * 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. - * 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. - * 4. If we are outside the configured window, the task will start immediately. + * This endpoint will stop all currently running tasks and remove any scheduled tasks from the queue. * * - * @param Operations\TaskName $taskName - * @return Operations\StartTaskResponse + * @return Operations\StopAllTasksResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function startTask(Operations\TaskName $taskName): Operations\StartTaskResponse + public function stopAllTasks(?Options $options = null): Operations\StopAllTasksResponse { - $request = new Operations\StartTaskRequest( - taskName: $taskName, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/butler/{taskName}', Operations\StartTaskRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/butler'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); + $hookContext = new HookContext('stopAllTasks', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); - if (in_array($statusCode, [200, 202])) { - return new Operations\StartTaskResponse( + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } + if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + return new Operations\StopAllTasksResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StartTaskBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StopAllTasksBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -243,8 +359,11 @@ public function startTask(Operations\TaskName $taskName): Operations\StartTaskRe } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StartTaskUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StopAllTasksUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -267,24 +386,42 @@ public function startTask(Operations\TaskName $taskName): Operations\StartTaskRe * @return Operations\StopTaskResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function stopTask(Operations\PathParamTaskName $taskName): Operations\StopTaskResponse + public function stopTask(Operations\PathParamTaskName $taskName, ?Options $options = null): Operations\StopTaskResponse { $request = new Operations\StopTaskRequest( taskName: $taskName, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/butler/{taskName}', Operations\StopTaskRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/butler/{taskName}', Operations\StopTaskRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('stopTask', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode == 404 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\StopTaskResponse( statusCode: $statusCode, contentType: $contentType, @@ -292,8 +429,11 @@ public function stopTask(Operations\PathParamTaskName $taskName): Operations\Sto ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StopTaskBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StopTaskBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -301,8 +441,11 @@ public function stopTask(Operations\PathParamTaskName $taskName): Operations\Sto } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StopTaskUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StopTaskUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Hooks/AfterErrorContext.php b/src/Hooks/AfterErrorContext.php new file mode 100644 index 0000000..e779da1 --- /dev/null +++ b/src/Hooks/AfterErrorContext.php @@ -0,0 +1,32 @@ +operationID, $hookCtx->oauth2Scopes, $hookCtx->securitySource); + } + + /** + * @param string $name + * @param array $args + * @return mixed + */ + public function __call($name, $args): mixed + { + if ($name === 'securitySource') { + return call_user_func_array($this->securitySource, $args); + } + + return null; + } +} diff --git a/src/Hooks/AfterErrorHook.php b/src/Hooks/AfterErrorHook.php new file mode 100644 index 0000000..e476caa --- /dev/null +++ b/src/Hooks/AfterErrorHook.php @@ -0,0 +1,17 @@ +operationID, $hookCtx->oauth2Scopes, $hookCtx->securitySource); + } +} diff --git a/src/Hooks/AfterSuccessHook.php b/src/Hooks/AfterSuccessHook.php new file mode 100644 index 0000000..443fb2f --- /dev/null +++ b/src/Hooks/AfterSuccessHook.php @@ -0,0 +1,17 @@ +operationID, $hookCtx->oauth2Scopes, $hookCtx->securitySource); + } + + /** + * @param string $name + * @param array $args + * @return mixed + */ + public function __call($name, $args): mixed + { + if ($name === 'securitySource') { + return call_user_func_array($this->securitySource, $args); + } + + return null; + } +} diff --git a/src/Hooks/BeforeRequestHook.php b/src/Hooks/BeforeRequestHook.php new file mode 100644 index 0000000..12cd242 --- /dev/null +++ b/src/Hooks/BeforeRequestHook.php @@ -0,0 +1,17 @@ +clientID = $clientID; + $this->clientSecret = $clientSecret; + $this->tokenURL = $tokenURL; + } +} diff --git a/src/Hooks/ErrorResponseContext.php b/src/Hooks/ErrorResponseContext.php new file mode 100644 index 0000000..8979283 --- /dev/null +++ b/src/Hooks/ErrorResponseContext.php @@ -0,0 +1,23 @@ +response = $response; + $this->e = $e; + } +} diff --git a/src/Hooks/FailEarlyException.php b/src/Hooks/FailEarlyException.php new file mode 100644 index 0000000..287235e --- /dev/null +++ b/src/Hooks/FailEarlyException.php @@ -0,0 +1,14 @@ + $oauth2Scopes; + */ + public ?array $oauth2Scopes; + /** + * @var ?\Closure(): ?mixed $securitySource + */ + public ?\Closure $securitySource; + + /** + * @param string $operationID + * @param ?array $oauth2Scopes + * @param ?\Closure(): ?mixed $securitySource + */ + public function __construct(string $operationID, ?array $oauth2Scopes, ?\Closure $securitySource) + { + $this->operationID = $operationID; + $this->oauth2Scopes = $oauth2Scopes; + $this->securitySource = $securitySource; + } + /** + * @param string $name + * @param array $args + * @return mixed + */ + public function __call($name, $args): mixed + { + if ($name === 'securitySource') { + return call_user_func_array($this->securitySource, $args); + } + + return null; + } +} diff --git a/src/Hooks/HookRegistration.php b/src/Hooks/HookRegistration.php new file mode 100644 index 0000000..a726233 --- /dev/null +++ b/src/Hooks/HookRegistration.php @@ -0,0 +1,28 @@ +registerSDKInitHook($myHook); + // $hooks->registerBeforeRequestHook($myHook); + // $hooks->registerAfterSuccessHook($myHook); + // $hooks->registerAfterErrorHook($myHook); + } +} diff --git a/src/Hooks/Hooks.php b/src/Hooks/Hooks.php new file mode 100644 index 0000000..e183585 --- /dev/null +++ b/src/Hooks/Hooks.php @@ -0,0 +1,20 @@ + $sdkInitHooks + */ + private array $sdkInitHooks = []; + /** + * @var array $beforeRequestHooks + */ + private array $beforeRequestHooks = []; + /** + * @var array $afterSuccessHooks + */ + private array $afterSuccessHooks = []; + /** + * @var array $afterErrorHooks + */ + private array $afterErrorHooks = []; + + public function __construct() + { + HookRegistration::initHooks($this); + } + + public function registerSDKInitHook(SDKInitHook $hook): void + { + $this->sdkInitHooks[] = $hook; + } + + public function registerBeforeRequestHook(BeforeRequestHook $hook): void + { + $this->beforeRequestHooks[] = $hook; + } + + public function registerAfterSuccessHook(AfterSuccessHook $hook): void + { + $this->afterSuccessHooks[] = $hook; + } + + public function registerAfterErrorHook(AfterErrorHook $hook): void + { + $this->afterErrorHooks[] = $hook; + } + + public function sdkInit(string $baseUrl, \GuzzleHttp\ClientInterface $client): SDKRequestContext + { + $rc = new SDKRequestContext($baseUrl, $client); + foreach ($this->sdkInitHooks as $hook) { + try { + $rc = $hook->sdkInit($rc->url, $rc->client); + } catch (\Exception $e) { + throw new \Exception('An error occurred while calling SDKInit hook.', $e->getCode(), $e); + } + + } + + return $rc; + } + + public function beforeRequest(BeforeRequestContext $context, RequestInterface $request): RequestInterface + { + foreach ($this->beforeRequestHooks as $hook) { + try { + $request = $hook->beforeRequest($context, $request); + } catch (\Exception $e) { + throw new \Exception('An error occurred while calling BeforeRequest hook.', $e->getCode(), $e); + } + } + + return $request; + } + + public function afterSuccess(AfterSuccessContext $context, ResponseInterface $response): ResponseInterface + { + foreach ($this->afterSuccessHooks as $hook) { + try { + $response = $hook->afterSuccess($context, $response); + } catch (\Exception $e) { + throw new \Exception('An error occurred while calling AfterSuccess hook.', $e->getCode(), $e); + } + } + + return $response; + } + + public function afterError(AfterErrorContext $context, ?ResponseInterface $response, ?\Throwable $exception): ResponseInterface + { + $errorContext = new ErrorResponseContext($response, $exception); + foreach ($this->afterErrorHooks as $hook) { + try { + $errorContext = $hook->afterError($context, $errorContext->response, $errorContext->e); + } catch (FailEarlyException $e) { + throw $e; + } catch (\Exception $e) { + throw new \Exception('An error occurred while calling AfterError hook.', $e->getCode(), $e); + } + } + if ($errorContext->e !== null) { + throw $errorContext->e; + } else { + return $errorContext->response; + } + } +} diff --git a/src/Hooks/SDKInitHook.php b/src/Hooks/SDKInitHook.php new file mode 100644 index 0000000..8f871ef --- /dev/null +++ b/src/Hooks/SDKInitHook.php @@ -0,0 +1,15 @@ +url = $url; + $this->client = $client; + } +} diff --git a/src/Hooks/Session.php b/src/Hooks/Session.php new file mode 100644 index 0000000..5360513 --- /dev/null +++ b/src/Hooks/Session.php @@ -0,0 +1,37 @@ + scopes + */ + public array $scopes; + public ?LocalTime $expiresAt; + + /** + * @param Credentials $credentials + * @param string $token + * @param array $scopes + * @param ?LocalTime $expiresAt + */ + public function __construct(Credentials $credentials, string $token, array $scopes, ?LocalTime $expiresAt = null) + { + $this->credentials = $credentials; + $this->token = $token; + $this->scopes = $scopes; + $this->expiresAt = $expiresAt; + } +} diff --git a/src/Hooks/TokenResponse.php b/src/Hooks/TokenResponse.php new file mode 100644 index 0000000..0b0383e --- /dev/null +++ b/src/Hooks/TokenResponse.php @@ -0,0 +1,17 @@ +sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Get Global Hubs + * Get Recently Added * - * Get Global Hubs filtered by the parameters provided. + * This endpoint will return the recently added content. * - * @param ?float $count - * @param ?Operations\OnlyTransient $onlyTransient - * @return Operations\GetGlobalHubsResponse + * + * @param Operations\GetRecentlyAddedRequest $request + * @return Operations\GetRecentlyAddedResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getGlobalHubs(?float $count = null, ?Operations\OnlyTransient $onlyTransient = null): Operations\GetGlobalHubsResponse + public function getRecentlyAdded(Operations\GetRecentlyAddedRequest $request, ?Options $options = null): Operations\GetRecentlyAddedResponse { - $request = new Operations\GetGlobalHubsRequest( - count: $count, - onlyTransient: $onlyTransient, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/hubs'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetGlobalHubsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/hubs/home/recentlyAdded'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetRecentlyAddedRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-recently-added', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetGlobalHubsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetGlobalHubsResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetRecentlyAddedResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -65,25 +104,7 @@ public function getGlobalHubs(?float $count = null, ?Operations\OnlyTransient $o } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode == 400) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetGlobalHubsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode == 401) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetGlobalHubsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + } elseif ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); @@ -91,35 +112,60 @@ public function getGlobalHubs(?float $count = null, ?Operations\OnlyTransient $o } /** - * Get Recently Added - * - * This endpoint will return the recently added content. + * Get Global Hubs * + * Get Global Hubs filtered by the parameters provided. * - * @param Operations\GetRecentlyAddedRequest $request - * @return Operations\GetRecentlyAddedResponse + * @param ?float $count + * @param ?Operations\OnlyTransient $onlyTransient + * @return Operations\GetGlobalHubsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getRecentlyAdded(Operations\GetRecentlyAddedRequest $request): Operations\GetRecentlyAddedResponse + public function getGlobalHubs(?float $count = null, ?Operations\OnlyTransient $onlyTransient = null, ?Options $options = null): Operations\GetGlobalHubsResponse { + $request = new Operations\GetGlobalHubsRequest( + count: $count, + onlyTransient: $onlyTransient, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/hubs/home/recentlyAdded'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetRecentlyAddedRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/hubs'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetGlobalHubsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getGlobalHubs', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetRecentlyAddedResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetGlobalHubsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetGlobalHubsResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -129,7 +175,31 @@ public function getRecentlyAdded(Operations\GetRecentlyAddedRequest $request): O } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + } elseif ($statusCode == 400) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetGlobalHubsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 401) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetGlobalHubsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); @@ -148,7 +218,7 @@ public function getRecentlyAdded(Operations\GetRecentlyAddedRequest $request): O * @return Operations\GetLibraryHubsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getLibraryHubs(float $sectionId, ?float $count = null, ?Operations\QueryParamOnlyTransient $onlyTransient = null): Operations\GetLibraryHubsResponse + public function getLibraryHubs(float $sectionId, ?float $count = null, ?Operations\QueryParamOnlyTransient $onlyTransient = null, ?Options $options = null): Operations\GetLibraryHubsResponse { $request = new Operations\GetLibraryHubsRequest( sectionId: $sectionId, @@ -156,22 +226,43 @@ public function getLibraryHubs(float $sectionId, ?float $count = null, ?Operatio onlyTransient: $onlyTransient, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/hubs/sections/{sectionId}', Operations\GetLibraryHubsRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetLibraryHubsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $url = Utils\Utils::generateUrl($baseUrl, '/hubs/sections/{sectionId}', Operations\GetLibraryHubsRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetLibraryHubsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getLibraryHubs', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetLibraryHubsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetLibraryHubsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetLibraryHubsResponse( statusCode: $statusCode, contentType: $contentType, @@ -184,8 +275,11 @@ public function getLibraryHubs(float $sectionId, ?float $count = null, ?Operatio } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetLibraryHubsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetLibraryHubsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -193,8 +287,11 @@ public function getLibraryHubs(float $sectionId, ?float $count = null, ?Operatio } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetLibraryHubsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetLibraryHubsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Library.php b/src/Library.php index 43afc76..1f10954 100644 --- a/src/Library.php +++ b/src/Library.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Library @@ -21,110 +23,84 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } - /** - * Get Hash Value - * - * This resource returns hash values for local files + * @param string $baseUrl + * @param array $urlVariables * - * @param string $url - * @param ?float $type - * @return Operations\GetFileHashResponse - * @throws \LukeHagar\Plex_API\Models\Errors\SDKException + * @return string */ - public function getFileHash(string $url, ?float $type = null): Operations\GetFileHashResponse + public function getUrl(string $baseUrl, array $urlVariables): string { - $request = new Operations\GetFileHashRequest( - url: $url, - type: $type, - ); - $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/hashes'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetFileHashRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $serverDetails = $this->sdkConfiguration->getServerDetails(); + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); - $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; - - $statusCode = $httpResponse->getStatusCode(); - if ($statusCode == 200) { - return new Operations\GetFileHashResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); - } elseif ($statusCode == 400) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetFileHashBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode == 401) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetFileHashUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); } /** - * Get Recently Added - * - * This endpoint will return the recently added content. + * Delete Library Section * + * Delete a library using a specific section id * - * @param Operations\GetRecentlyAddedLibraryRequest $request - * @return Operations\GetRecentlyAddedLibraryResponse + * @param int $sectionKey + * @return Operations\DeleteLibraryResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getRecentlyAddedLibrary(Operations\GetRecentlyAddedLibraryRequest $request): Operations\GetRecentlyAddedLibraryResponse + public function deleteLibrary(int $sectionKey, ?Options $options = null): Operations\DeleteLibraryResponse { + $request = new Operations\DeleteLibraryRequest( + sectionKey: $sectionKey, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/recentlyAdded'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetRecentlyAddedLibraryRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}', Operations\DeleteLibraryRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); + $hookContext = new HookContext('deleteLibrary', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedLibraryResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetRecentlyAddedLibraryResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\DeleteLibraryResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetRecentlyAddedLibraryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\DeleteLibraryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -132,8 +108,11 @@ public function getRecentlyAddedLibrary(Operations\GetRecentlyAddedLibraryReques } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetRecentlyAddedLibraryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\DeleteLibraryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -160,24 +139,43 @@ public function getRecentlyAddedLibrary(Operations\GetRecentlyAddedLibraryReques * @return Operations\GetAllLibrariesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getAllLibraries(): Operations\GetAllLibrariesResponse + public function getAllLibraries(?Options $options = null): Operations\GetAllLibrariesResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/library/sections'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('get-all-libraries', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetAllLibrariesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetAllLibrariesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetAllLibrariesResponse( statusCode: $statusCode, contentType: $contentType, @@ -190,8 +188,11 @@ public function getAllLibraries(): Operations\GetAllLibrariesResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetAllLibrariesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetAllLibrariesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -199,8 +200,11 @@ public function getAllLibraries(): Operations\GetAllLibrariesResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetAllLibrariesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetAllLibrariesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -262,29 +266,50 @@ public function getAllLibraries(): Operations\GetAllLibrariesResponse * @return Operations\GetLibraryDetailsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getLibraryDetails(int $sectionKey, ?Operations\IncludeDetails $includeDetails = null): Operations\GetLibraryDetailsResponse + public function getLibraryDetails(int $sectionKey, ?Operations\IncludeDetails $includeDetails = null, ?Options $options = null): Operations\GetLibraryDetailsResponse { $request = new Operations\GetLibraryDetailsRequest( sectionKey: $sectionKey, includeDetails: $includeDetails, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}', Operations\GetLibraryDetailsRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetLibraryDetailsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}', Operations\GetLibraryDetailsRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetLibraryDetailsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-library-details', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetLibraryDetailsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetLibraryDetailsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetLibraryDetailsResponse( statusCode: $statusCode, contentType: $contentType, @@ -297,8 +322,11 @@ public function getLibraryDetails(int $sectionKey, ?Operations\IncludeDetails $i } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetLibraryDetailsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetLibraryDetailsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -306,8 +334,11 @@ public function getLibraryDetails(int $sectionKey, ?Operations\IncludeDetails $i } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetLibraryDetailsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetLibraryDetailsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -321,41 +352,92 @@ public function getLibraryDetails(int $sectionKey, ?Operations\IncludeDetails $i } /** - * Delete Library Section + * Get Library Items * - * Delete a library using a specific section id + * Fetches details from a specific section of the library identified by a section key and a tag. The tag parameter accepts the following values: + * - `all`: All items in the section. + * - `unwatched`: Items that have not been played. + * - `newest`: Items that are recently released. + * - `recentlyAdded`: Items that are recently added to the library. + * - `recentlyViewed`: Items that were recently viewed. + * - `onDeck`: Items to continue watching. + * - `collection`: Items categorized by collection. + * - `edition`: Items categorized by edition. + * - `genre`: Items categorized by genre. + * - `year`: Items categorized by year of release. + * - `decade`: Items categorized by decade. + * - `director`: Items categorized by director. + * - `actor`: Items categorized by starring actor. + * - `country`: Items categorized by country of origin. + * - `contentRating`: Items categorized by content rating. + * - `rating`: Items categorized by rating. + * - `resolution`: Items categorized by resolution. + * - `firstCharacter`: Items categorized by the first letter. + * - `folder`: Items categorized by folder. + * - `albums`: Items categorized by album. * - * @param int $sectionKey - * @return Operations\DeleteLibraryResponse + * + * @param Operations\GetLibraryItemsRequest $request + * @return Operations\GetLibraryItemsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function deleteLibrary(int $sectionKey): Operations\DeleteLibraryResponse + public function getLibraryItems(Operations\GetLibraryItemsRequest $request, ?Options $options = null): Operations\GetLibraryItemsResponse { - $request = new Operations\DeleteLibraryRequest( - sectionKey: $sectionKey, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}', Operations\DeleteLibraryRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}/{tag}', Operations\GetLibraryItemsRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetLibraryItemsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-library-items', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\DeleteLibraryResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetLibraryItemsResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\DeleteLibraryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetLibraryItemsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -363,8 +445,11 @@ public function deleteLibrary(int $sectionKey): Operations\DeleteLibraryResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\DeleteLibraryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetLibraryItemsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -378,54 +463,147 @@ public function deleteLibrary(int $sectionKey): Operations\DeleteLibraryResponse } /** - * Get Library Items + * Get Metadata by RatingKey * - * Fetches details from a specific section of the library identified by a section key and a tag. The tag parameter accepts the following values: - * - `all`: All items in the section. - * - `unwatched`: Items that have not been played. - * - `newest`: Items that are recently released. - * - `recentlyAdded`: Items that are recently added to the library. - * - `recentlyViewed`: Items that were recently viewed. - * - `onDeck`: Items to continue watching. - * - `collection`: Items categorized by collection. - * - `edition`: Items categorized by edition. - * - `genre`: Items categorized by genre. - * - `year`: Items categorized by year of release. - * - `decade`: Items categorized by decade. - * - `director`: Items categorized by director. - * - `actor`: Items categorized by starring actor. - * - `country`: Items categorized by country of origin. - * - `contentRating`: Items categorized by content rating. - * - `rating`: Items categorized by rating. - * - `resolution`: Items categorized by resolution. - * - `firstCharacter`: Items categorized by the first letter. - * - `folder`: Items categorized by folder. + * This endpoint will return the metadata of a library item specified with the ratingKey. * * - * @param Operations\GetLibraryItemsRequest $request - * @return Operations\GetLibraryItemsResponse + * @param int $ratingKey + * @return Operations\GetMetaDataByRatingKeyResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getLibraryItems(Operations\GetLibraryItemsRequest $request): Operations\GetLibraryItemsResponse + public function getMetaDataByRatingKey(int $ratingKey, ?Options $options = null): Operations\GetMetaDataByRatingKeyResponse { + $request = new Operations\GetMetaDataByRatingKeyRequest( + ratingKey: $ratingKey, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}/{tag}', Operations\GetLibraryItemsRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetLibraryItemsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}', Operations\GetMetaDataByRatingKeyRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-meta-data-by-rating-key', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } + $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; + $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } + if ($statusCode == 200) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetMetaDataByRatingKeyResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetMetaDataByRatingKeyResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 400) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMetaDataByRatingKeyBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 401) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMetaDataByRatingKeyUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } + + /** + * Get Recently Added + * + * This endpoint will return the recently added content. + * + * + * @param Operations\GetRecentlyAddedLibraryRequest $request + * @return Operations\GetRecentlyAddedLibraryResponse + * @throws \LukeHagar\Plex_API\Models\Errors\SDKException + */ + public function getRecentlyAddedLibrary(Operations\GetRecentlyAddedLibraryRequest $request, ?Options $options = null): Operations\GetRecentlyAddedLibraryResponse + { + $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); + $url = Utils\Utils::generateUrl($baseUrl, '/library/recentlyAdded'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + + $qp = Utils\Utils::getQueryParams(Operations\GetRecentlyAddedLibraryRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-recently-added-library', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetLibraryItemsResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedLibraryResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetRecentlyAddedLibraryResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -437,8 +615,11 @@ public function getLibraryItems(Operations\GetLibraryItemsRequest $request): Ope } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetLibraryItemsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetRecentlyAddedLibraryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -446,8 +627,11 @@ public function getLibraryItems(Operations\GetLibraryItemsRequest $request): Ope } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetLibraryItemsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetRecentlyAddedLibraryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -471,26 +655,46 @@ public function getLibraryItems(Operations\GetLibraryItemsRequest $request): Ope * @return Operations\GetRefreshLibraryMetadataResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getRefreshLibraryMetadata(int $sectionKey, ?Operations\Force $force = null): Operations\GetRefreshLibraryMetadataResponse + public function getRefreshLibraryMetadata(int $sectionKey, ?Operations\Force $force = null, ?Options $options = null): Operations\GetRefreshLibraryMetadataResponse { $request = new Operations\GetRefreshLibraryMetadataRequest( sectionKey: $sectionKey, force: $force, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}/refresh', Operations\GetRefreshLibraryMetadataRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetRefreshLibraryMetadataRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}/refresh', Operations\GetRefreshLibraryMetadataRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetRefreshLibraryMetadataRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-refresh-library-metadata', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\GetRefreshLibraryMetadataResponse( statusCode: $statusCode, contentType: $contentType, @@ -498,8 +702,11 @@ public function getRefreshLibraryMetadata(int $sectionKey, ?Operations\Force $fo ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetRefreshLibraryMetadataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetRefreshLibraryMetadataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -507,8 +714,11 @@ public function getRefreshLibraryMetadata(int $sectionKey, ?Operations\Force $fo } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetRefreshLibraryMetadataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetRefreshLibraryMetadataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -522,57 +732,60 @@ public function getRefreshLibraryMetadata(int $sectionKey, ?Operations\Force $fo } /** - * Search Library - * - * Search for content within a specific section of the library. - * - * ### Types - * Each type in the library comes with a set of filters and sorts, aiding in building dynamic media controls: - * - * - **Type Object Attributes**: - * - `type`: Metadata type (if standard Plex type). - * - `title`: Title for this content type (e.g., "Movies"). - * - * - **Filter Objects**: - * - Subset of the media query language. - * - Attributes include `filter` (name), `filterType` (data type), `key` (endpoint for value range), and `title`. - * - * - **Sort Objects**: - * - Description of sort fields. - * - Attributes include `defaultDirection` (asc/desc), `descKey` and `key` (sort parameters), and `title`. + * Search All Libraries * - * > **Note**: Filters and sorts are optional; without them, no filtering controls are rendered. + * Search the provided query across all library sections, or a single section, and return matches as hubs, split up by type. * * - * @param int $sectionKey - * @param Operations\GetSearchLibraryQueryParamType $type - * @return Operations\GetSearchLibraryResponse + * @param Operations\GetSearchAllLibrariesRequest $request + * @return Operations\GetSearchAllLibrariesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getSearchLibrary(int $sectionKey, Operations\GetSearchLibraryQueryParamType $type): Operations\GetSearchLibraryResponse + public function getSearchAllLibraries(Operations\GetSearchAllLibrariesRequest $request, ?Options $options = null): Operations\GetSearchAllLibrariesResponse { - $request = new Operations\GetSearchLibraryRequest( - sectionKey: $sectionKey, - type: $type, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}/search', Operations\GetSearchLibraryRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetSearchLibraryRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/library/search'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetSearchAllLibrariesRequest::class, $request, $urlOverride); + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; + } + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-search-all-libraries', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetSearchLibraryResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetSearchLibraryResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetSearchAllLibrariesResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -584,8 +797,11 @@ public function getSearchLibrary(int $sectionKey, Operations\GetSearchLibraryQue } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSearchLibraryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSearchAllLibrariesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -593,8 +809,11 @@ public function getSearchLibrary(int $sectionKey, Operations\GetSearchLibraryQue } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSearchLibraryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSearchAllLibrariesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -608,39 +827,78 @@ public function getSearchLibrary(int $sectionKey, Operations\GetSearchLibraryQue } /** - * Search All Libraries + * Search Library * - * Search the provided query across all library sections, or a single section, and return matches as hubs, split up by type. + * Search for content within a specific section of the library. * + * ### Types + * Each type in the library comes with a set of filters and sorts, aiding in building dynamic media controls: * - * @param Operations\GetSearchAllLibrariesRequest $request - * @return Operations\GetSearchAllLibrariesResponse + * - **Type Object Attributes**: + * - `type`: Metadata type (if standard Plex type). + * - `title`: Title for this content type (e.g., "Movies"). + * + * - **Filter Objects**: + * - Subset of the media query language. + * - Attributes include `filter` (name), `filterType` (data type), `key` (endpoint for value range), and `title`. + * + * - **Sort Objects**: + * - Description of sort fields. + * - Attributes include `defaultDirection` (asc/desc), `descKey` and `key` (sort parameters), and `title`. + * + * > **Note**: Filters and sorts are optional; without them, no filtering controls are rendered. + * + * + * @param int $sectionKey + * @param Operations\GetSearchLibraryQueryParamType $type + * @return Operations\GetSearchLibraryResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getSearchAllLibraries(Operations\GetSearchAllLibrariesRequest $request): Operations\GetSearchAllLibrariesResponse + public function getSearchLibrary(int $sectionKey, Operations\GetSearchLibraryQueryParamType $type, ?Options $options = null): Operations\GetSearchLibraryResponse { + $request = new Operations\GetSearchLibraryRequest( + sectionKey: $sectionKey, + type: $type, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/search'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetSearchAllLibrariesRequest::class, $request, $this->sdkConfiguration->globals)); - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; - } - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/{sectionKey}/search', Operations\GetSearchLibraryRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetSearchLibraryRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-search-library', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetSearchAllLibrariesResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetSearchLibraryResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetSearchLibraryResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -652,8 +910,11 @@ public function getSearchAllLibraries(Operations\GetSearchAllLibrariesRequest $r } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSearchAllLibrariesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSearchLibraryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -661,8 +922,11 @@ public function getSearchAllLibraries(Operations\GetSearchAllLibrariesRequest $r } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSearchAllLibrariesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSearchLibraryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -676,50 +940,67 @@ public function getSearchAllLibraries(Operations\GetSearchAllLibrariesRequest $r } /** - * Get Metadata by RatingKey - * - * This endpoint will return the metadata of a library item specified with the ratingKey. + * Get Hash Value * + * This resource returns hash values for local files * - * @param int $ratingKey - * @return Operations\GetMetaDataByRatingKeyResponse + * @param string $url + * @param ?float $type + * @return Operations\GetFileHashResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getMetaDataByRatingKey(int $ratingKey): Operations\GetMetaDataByRatingKeyResponse + public function getFileHash(string $url, ?float $type = null, ?Options $options = null): Operations\GetFileHashResponse { - $request = new Operations\GetMetaDataByRatingKeyRequest( - ratingKey: $ratingKey, + $request = new Operations\GetFileHashRequest( + url: $url, + type: $type, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}', Operations\GetMetaDataByRatingKeyRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/library/hashes'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetFileHashRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getFileHash', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetMetaDataByRatingKeyResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetMetaDataByRatingKeyResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\GetFileHashResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMetaDataByRatingKeyBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetFileHashBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -727,8 +1008,11 @@ public function getMetaDataByRatingKey(int $ratingKey): Operations\GetMetaDataBy } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMetaDataByRatingKeyUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetFileHashUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -752,29 +1036,50 @@ public function getMetaDataByRatingKey(int $ratingKey): Operations\GetMetaDataBy * @return Operations\GetMetadataChildrenResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getMetadataChildren(float $ratingKey, ?string $includeElements = null): Operations\GetMetadataChildrenResponse + public function getMetadataChildren(float $ratingKey, ?string $includeElements = null, ?Options $options = null): Operations\GetMetadataChildrenResponse { $request = new Operations\GetMetadataChildrenRequest( ratingKey: $ratingKey, includeElements: $includeElements, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}/children', Operations\GetMetadataChildrenRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetMetadataChildrenRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}/children', Operations\GetMetadataChildrenRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetMetadataChildrenRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getMetadataChildren', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetMetadataChildrenResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetMetadataChildrenResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetMetadataChildrenResponse( statusCode: $statusCode, contentType: $contentType, @@ -787,8 +1092,11 @@ public function getMetadataChildren(float $ratingKey, ?string $includeElements = } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMetadataChildrenBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMetadataChildrenBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -796,8 +1104,11 @@ public function getMetadataChildren(float $ratingKey, ?string $includeElements = } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMetadataChildrenUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMetadataChildrenUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -811,40 +1122,52 @@ public function getMetadataChildren(float $ratingKey, ?string $includeElements = } /** - * Get Top Watched Content + * Get On Deck * - * This endpoint will return the top watched content from libraries of a certain type + * This endpoint will return the on deck content. * * - * @param Operations\GetTopWatchedContentQueryParamType $type - * @param ?int $includeGuids - * @return Operations\GetTopWatchedContentResponse + * @return Operations\GetOnDeckResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getTopWatchedContent(Operations\GetTopWatchedContentQueryParamType $type, ?int $includeGuids = null): Operations\GetTopWatchedContentResponse + public function getOnDeck(?Options $options = null): Operations\GetOnDeckResponse { - $request = new Operations\GetTopWatchedContentRequest( - type: $type, - includeGuids: $includeGuids, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/all/top'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetTopWatchedContentRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/library/onDeck'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getOnDeck', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetTopWatchedContentResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetTopWatchedContentResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetOnDeckResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetOnDeckResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -856,8 +1179,11 @@ public function getTopWatchedContent(Operations\GetTopWatchedContentQueryParamTy } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTopWatchedContentBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetOnDeckBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -865,8 +1191,11 @@ public function getTopWatchedContent(Operations\GetTopWatchedContentQueryParamTy } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTopWatchedContentUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetOnDeckUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -880,33 +1209,61 @@ public function getTopWatchedContent(Operations\GetTopWatchedContentQueryParamTy } /** - * Get On Deck + * Get Top Watched Content * - * This endpoint will return the on deck content. + * This endpoint will return the top watched content from libraries of a certain type * * - * @return Operations\GetOnDeckResponse + * @param Operations\GetTopWatchedContentQueryParamType $type + * @param ?int $includeGuids + * @return Operations\GetTopWatchedContentResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getOnDeck(): Operations\GetOnDeckResponse + public function getTopWatchedContent(Operations\GetTopWatchedContentQueryParamType $type, ?int $includeGuids = null, ?Options $options = null): Operations\GetTopWatchedContentResponse { + $request = new Operations\GetTopWatchedContentRequest( + type: $type, + includeGuids: $includeGuids, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/onDeck'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/library/all/top'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetTopWatchedContentRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getTopWatchedContent', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetOnDeckResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetOnDeckResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetTopWatchedContentResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetTopWatchedContentResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -918,8 +1275,11 @@ public function getOnDeck(): Operations\GetOnDeckResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetOnDeckBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTopWatchedContentBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -927,8 +1287,11 @@ public function getOnDeck(): Operations\GetOnDeckResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetOnDeckUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTopWatchedContentUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Log.php b/src/Log.php index 1b920c3..79f8435 100644 --- a/src/Log.php +++ b/src/Log.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Log @@ -21,6 +23,104 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } + + /** + * Enabling Papertrail + * + * This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time. + * + * + * @return Operations\EnablePaperTrailResponse + * @throws \LukeHagar\Plex_API\Models\Errors\SDKException + */ + public function enablePaperTrail(?Options $options = null): Operations\EnablePaperTrailResponse + { + $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); + $url = Utils\Utils::generateUrl($baseUrl, '/log/networked'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('enablePaperTrail', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } + $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; + + $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode == 403 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } + if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + return new Operations\EnablePaperTrailResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); + } elseif ($statusCode == 400) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\EnablePaperTrailBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 401) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\EnablePaperTrailUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 403 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } /** * Logging a single line message. @@ -34,7 +134,7 @@ public function __construct(public SDKConfiguration $sdkConfig) * @return Operations\LogLineResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function logLine(Operations\Level $level, string $message, string $source): Operations\LogLineResponse + public function logLine(Operations\Level $level, string $message, string $source, ?Options $options = null): Operations\LogLineResponse { $request = new Operations\LogLineRequest( level: $level, @@ -43,18 +143,38 @@ public function logLine(Operations\Level $level, string $message, string $source ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/log'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\LogLineRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\LogLineRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('logLine', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\LogLineResponse( statusCode: $statusCode, contentType: $contentType, @@ -62,8 +182,11 @@ public function logLine(Operations\Level $level, string $message, string $source ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\LogLineBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\LogLineBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -71,8 +194,11 @@ public function logLine(Operations\Level $level, string $message, string $source } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\LogLineUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\LogLineUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -115,89 +241,56 @@ public function logLine(Operations\Level $level, string $message, string $source * @return Operations\LogMultiLineResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function logMultiLine(string $request): Operations\LogMultiLineResponse + public function logMultiLine(string $request, ?Options $options = null): Operations\LogMultiLineResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/log'); - $options = ['http_errors' => false]; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; $body = Utils\Utils::serializeRequestBody($request, 'request', 'string'); if ($body === null) { throw new \Exception('Request body is required'); } - $options = array_merge_recursive($options, $body); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpOptions = array_merge_recursive($httpOptions, $body); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); - $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; - - $statusCode = $httpResponse->getStatusCode(); - if ($statusCode == 200) { - return new Operations\LogMultiLineResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); - } elseif ($statusCode == 400) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\LogMultiLineBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode == 401) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\LogMultiLineUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + $hookContext = new HookContext('logMultiLine', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; } - } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } - - /** - * Enabling Papertrail - * - * This endpoint will enable all Plex Media Serverlogs to be sent to the Papertrail networked logging site for a period of time. - * - * - * @return Operations\EnablePaperTrailResponse - * @throws \LukeHagar\Plex_API\Models\Errors\SDKException - */ - public function enablePaperTrail(): Operations\EnablePaperTrailResponse - { - $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/log/networked'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\EnablePaperTrailResponse( + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + return new Operations\LogMultiLineResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\EnablePaperTrailBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\LogMultiLineBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -205,14 +298,17 @@ public function enablePaperTrail(): Operations\EnablePaperTrailResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\EnablePaperTrailUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\LogMultiLineUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode == 403 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); diff --git a/src/Media.php b/src/Media.php index 5c410be..5309f24 100644 --- a/src/Media.php +++ b/src/Media.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Media @@ -21,44 +23,95 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Mark Media Played + * Get Banner Image * - * This will mark the provided media key as Played. + * Gets the banner image of the media item * - * @param float $key - * @return Operations\MarkPlayedResponse + * @param Operations\GetBannerImageRequest $request + * @return Operations\GetBannerImageResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function markPlayed(float $key): Operations\MarkPlayedResponse + public function getBannerImage(Operations\GetBannerImageRequest $request, ?Options $options = null): Operations\GetBannerImageResponse { - $request = new Operations\MarkPlayedRequest( - key: $key, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/:/scrobble'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\MarkPlayedRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}/banner', Operations\GetBannerImageRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetBannerImageRequest::class, $request, $urlOverride); + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; + } + $httpOptions['headers']['Accept'] = 'image/jpeg'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-banner-image', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\MarkPlayedResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'image/jpeg')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $obj = $httpResponse->getBody()->getContents(); + + return new Operations\GetBannerImageResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + headers: $httpResponse->getHeaders(), + bytes: $obj); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\MarkPlayedBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetBannerImageBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -66,8 +119,11 @@ public function markPlayed(float $key): Operations\MarkPlayedResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\MarkPlayedUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetBannerImageUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -81,42 +137,73 @@ public function markPlayed(float $key): Operations\MarkPlayedResponse } /** - * Mark Media Unplayed + * Get Thumb Image * - * This will mark the provided media key as Unplayed. + * Gets the thumbnail image of the media item * - * @param float $key - * @return Operations\MarkUnplayedResponse + * @param Operations\GetThumbImageRequest $request + * @return Operations\GetThumbImageResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function markUnplayed(float $key): Operations\MarkUnplayedResponse + public function getThumbImage(Operations\GetThumbImageRequest $request, ?Options $options = null): Operations\GetThumbImageResponse { - $request = new Operations\MarkUnplayedRequest( - key: $key, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/:/unscrobble'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\MarkUnplayedRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}/thumb', Operations\GetThumbImageRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetThumbImageRequest::class, $request, $urlOverride); + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; + } + $httpOptions['headers']['Accept'] = 'image/jpeg'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-thumb-image', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\MarkUnplayedResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'image/jpeg')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $obj = $httpResponse->getBody()->getContents(); + + return new Operations\GetThumbImageResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + headers: $httpResponse->getHeaders(), + bytes: $obj); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\MarkUnplayedBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetThumbImageBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -124,8 +211,11 @@ public function markUnplayed(float $key): Operations\MarkUnplayedResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\MarkUnplayedUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetThumbImageUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -139,47 +229,65 @@ public function markUnplayed(float $key): Operations\MarkUnplayedResponse } /** - * Update Media Play Progress - * - * This API command can be used to update the play progress of a media item. + * Mark Media Played * + * This will mark the provided media key as Played. * - * @param string $key - * @param float $time - * @param string $state - * @return Operations\UpdatePlayProgressResponse + * @param float $key + * @return Operations\MarkPlayedResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function updatePlayProgress(string $key, float $time, string $state): Operations\UpdatePlayProgressResponse + public function markPlayed(float $key, ?Options $options = null): Operations\MarkPlayedResponse { - $request = new Operations\UpdatePlayProgressRequest( + $request = new Operations\MarkPlayedRequest( key: $key, - time: $time, - state: $state, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/:/progress'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\UpdatePlayProgressRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/:/scrobble'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\MarkPlayedRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('markPlayed', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\UpdatePlayProgressResponse( + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + return new Operations\MarkPlayedResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\UpdatePlayProgressBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\MarkPlayedBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -187,8 +295,11 @@ public function updatePlayProgress(string $key, float $time, string $state): Ope } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\UpdatePlayProgressUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\MarkPlayedUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -202,50 +313,65 @@ public function updatePlayProgress(string $key, float $time, string $state): Ope } /** - * Get Banner Image + * Mark Media Unplayed * - * Gets the banner image of the media item + * This will mark the provided media key as Unplayed. * - * @param Operations\GetBannerImageRequest $request - * @return Operations\GetBannerImageResponse + * @param float $key + * @return Operations\MarkUnplayedResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getBannerImage(Operations\GetBannerImageRequest $request): Operations\GetBannerImageResponse + public function markUnplayed(float $key, ?Options $options = null): Operations\MarkUnplayedResponse { + $request = new Operations\MarkUnplayedRequest( + key: $key, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}/banner', Operations\GetBannerImageRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetBannerImageRequest::class, $request, $this->sdkConfiguration->globals)); - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; - } - $options['headers']['Accept'] = 'image/jpeg'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/:/unscrobble'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\MarkUnplayedRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('markUnplayed', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'image/jpeg')) { - $obj = $httpResponse->getBody()->getContents(); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return new Operations\GetBannerImageResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - headers: $httpResponse->getHeaders(), - bytes: $obj); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\MarkUnplayedResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetBannerImageBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\MarkUnplayedBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -253,8 +379,11 @@ public function getBannerImage(Operations\GetBannerImageRequest $request): Opera } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetBannerImageUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\MarkUnplayedUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -268,50 +397,70 @@ public function getBannerImage(Operations\GetBannerImageRequest $request): Opera } /** - * Get Thumb Image + * Update Media Play Progress * - * Gets the thumbnail image of the media item + * This API command can be used to update the play progress of a media item. * - * @param Operations\GetThumbImageRequest $request - * @return Operations\GetThumbImageResponse + * + * @param string $key + * @param float $time + * @param string $state + * @return Operations\UpdatePlayProgressResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getThumbImage(Operations\GetThumbImageRequest $request): Operations\GetThumbImageResponse + public function updatePlayProgress(string $key, float $time, string $state, ?Options $options = null): Operations\UpdatePlayProgressResponse { + $request = new Operations\UpdatePlayProgressRequest( + key: $key, + time: $time, + state: $state, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/library/metadata/{ratingKey}/thumb', Operations\GetThumbImageRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetThumbImageRequest::class, $request, $this->sdkConfiguration->globals)); - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; - } - $options['headers']['Accept'] = 'image/jpeg'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/:/progress'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\UpdatePlayProgressRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); + $hookContext = new HookContext('updatePlayProgress', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'image/jpeg')) { - $obj = $httpResponse->getBody()->getContents(); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return new Operations\GetThumbImageResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - headers: $httpResponse->getHeaders(), - bytes: $obj); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\UpdatePlayProgressResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetThumbImageBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\UpdatePlayProgressBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -319,8 +468,11 @@ public function getThumbImage(Operations\GetThumbImageRequest $request): Operati } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetThumbImageUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\UpdatePlayProgressUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Models/Operations/Feature.php b/src/Models/Operations/Feature.php index 3e1b4c9..c1004c6 100644 --- a/src/Models/Operations/Feature.php +++ b/src/Models/Operations/Feature.php @@ -13,18 +13,18 @@ class Feature { /** * - * @var ?string $key + * @var string $type */ - #[\Speakeasy\Serializer\Annotation\SerializedName('key')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $key = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('type')] + public string $type; /** * - * @var string $type + * @var ?string $key */ - #[\Speakeasy\Serializer\Annotation\SerializedName('type')] - public string $type; + #[\Speakeasy\Serializer\Annotation\SerializedName('key')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $key = null; /** * diff --git a/src/Models/Operations/Friend.php b/src/Models/Operations/Friend.php index a7e627d..59ba998 100644 --- a/src/Models/Operations/Friend.php +++ b/src/Models/Operations/Friend.php @@ -19,14 +19,6 @@ class Friend #[\Speakeasy\Serializer\Annotation\SerializedName('email')] public string $email; - /** - * The account full name - * - * @var ?string $friendlyName - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('friendlyName')] - public ?string $friendlyName; - /** * If the account is a Plex Home user * @@ -43,15 +35,6 @@ class Friend #[\Speakeasy\Serializer\Annotation\SerializedName('id')] public int $id; - /** - * If the account is a Plex Home managed user - * - * @var ?bool $restricted - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('restricted')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $restricted = null; - /** * $sharedServers * @@ -111,6 +94,23 @@ class Friend #[\Speakeasy\Serializer\Annotation\SerializedName('uuid')] public string $uuid; + /** + * The account full name + * + * @var ?string $friendlyName + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('friendlyName')] + public ?string $friendlyName; + + /** + * If the account is a Plex Home managed user + * + * @var ?bool $restricted + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('restricted')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $restricted = null; + /** * @param string $email * @param bool $home diff --git a/src/Models/Operations/GeoData.php b/src/Models/Operations/GeoData.php index 867dbc4..f1e0402 100644 --- a/src/Models/Operations/GeoData.php +++ b/src/Models/Operations/GeoData.php @@ -44,15 +44,6 @@ class GeoData #[\Speakeasy\Serializer\Annotation\SerializedName('city')] public string $city; - /** - * Indicates if the country is a member of the European Union. - * - * @var ?bool $europeanUnionMember - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('european_union_member')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $europeanUnionMember = null; - /** * The time zone of the country. * @@ -69,6 +60,31 @@ class GeoData #[\Speakeasy\Serializer\Annotation\SerializedName('postal_code')] public string $postalCode; + /** + * The name of the primary administrative subdivision. + * + * @var string $subdivisions + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subdivisions')] + public string $subdivisions; + + /** + * The geographical coordinates (latitude, longitude) of the location. + * + * @var string $coordinates + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('coordinates')] + public string $coordinates; + + /** + * Indicates if the country is a member of the European Union. + * + * @var ?bool $europeanUnionMember + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('european_union_member')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $europeanUnionMember = null; + /** * Indicates if the country has privacy restrictions. * @@ -87,22 +103,6 @@ class GeoData #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $inPrivacyRestrictedRegion = null; - /** - * The name of the primary administrative subdivision. - * - * @var string $subdivisions - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subdivisions')] - public string $subdivisions; - - /** - * The geographical coordinates (latitude, longitude) of the location. - * - * @var string $coordinates - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('coordinates')] - public string $coordinates; - /** * @param string $code * @param string $continentCode diff --git a/src/Models/Operations/GetBannerImageResponse.php b/src/Models/Operations/GetBannerImageResponse.php index 5e0c13d..bb9759b 100644 --- a/src/Models/Operations/GetBannerImageResponse.php +++ b/src/Models/Operations/GetBannerImageResponse.php @@ -33,18 +33,18 @@ class GetBannerImageResponse public \Psr\Http\Message\ResponseInterface $rawResponse; /** - * Successful response returning an image + * $headers * - * @var ?string $bytes + * @var array> $headers */ - public ?string $bytes = null; + public array $headers; /** - * $headers + * Successful response returning an image * - * @var array> $headers + * @var ?string $bytes */ - public array $headers; + public ?string $bytes = null; /** * @param string $contentType diff --git a/src/Models/Operations/GetGeoDataGeoData.php b/src/Models/Operations/GetGeoDataGeoData.php index 304a820..6ca6c35 100644 --- a/src/Models/Operations/GetGeoDataGeoData.php +++ b/src/Models/Operations/GetGeoDataGeoData.php @@ -44,15 +44,6 @@ class GetGeoDataGeoData #[\Speakeasy\Serializer\Annotation\SerializedName('city')] public string $city; - /** - * Indicates if the country is a member of the European Union. - * - * @var ?bool $europeanUnionMember - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('european_union_member')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $europeanUnionMember = null; - /** * The time zone of the country. * @@ -69,6 +60,31 @@ class GetGeoDataGeoData #[\Speakeasy\Serializer\Annotation\SerializedName('postal_code')] public string $postalCode; + /** + * The name of the primary administrative subdivision. + * + * @var string $subdivisions + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subdivisions')] + public string $subdivisions; + + /** + * The geographical coordinates (latitude, longitude) of the location. + * + * @var string $coordinates + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('coordinates')] + public string $coordinates; + + /** + * Indicates if the country is a member of the European Union. + * + * @var ?bool $europeanUnionMember + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('european_union_member')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $europeanUnionMember = null; + /** * Indicates if the country has privacy restrictions. * @@ -87,22 +103,6 @@ class GetGeoDataGeoData #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $inPrivacyRestrictedRegion = null; - /** - * The name of the primary administrative subdivision. - * - * @var string $subdivisions - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subdivisions')] - public string $subdivisions; - - /** - * The geographical coordinates (latitude, longitude) of the location. - * - * @var string $coordinates - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('coordinates')] - public string $coordinates; - /** * @param string $code * @param string $continentCode diff --git a/src/Models/Operations/GetLibraryItemsLibrarySort.php b/src/Models/Operations/GetLibraryItemsLibrarySort.php index 8e68f71..717f61b 100644 --- a/src/Models/Operations/GetLibraryItemsLibrarySort.php +++ b/src/Models/Operations/GetLibraryItemsLibrarySort.php @@ -13,43 +13,33 @@ class GetLibraryItemsLibrarySort { /** * - * @var ?string $default + * @var string $key */ - #[\Speakeasy\Serializer\Annotation\SerializedName('default')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $default = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('key')] + public string $key; /** * - * @var ?bool $active + * @var string $title */ - #[\Speakeasy\Serializer\Annotation\SerializedName('active')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $active = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; /** - * The direction of the sort. Can be either `asc` or `desc`. * - * - * - * @var ?GetLibraryItemsLibraryActiveDirection $activeDirection + * @var ?string $default */ - #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsLibraryActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('default')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetLibraryItemsLibraryActiveDirection $activeDirection = null; + public ?string $default = null; /** - * The direction of the sort. Can be either `asc` or `desc`. - * - * * - * @var ?GetLibraryItemsLibraryDefaultDirection $defaultDirection + * @var ?bool $active */ - #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsLibraryDefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('active')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetLibraryItemsLibraryDefaultDirection $defaultDirection = null; + public ?bool $active = null; /** * @@ -68,18 +58,28 @@ class GetLibraryItemsLibrarySort public ?string $firstCharacterKey = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $key + * + * + * @var ?GetLibraryItemsLibraryActiveDirection $activeDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('key')] - public string $key; + #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsLibraryActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetLibraryItemsLibraryActiveDirection $activeDirection = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $title + * + * + * @var ?GetLibraryItemsLibraryDefaultDirection $defaultDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; + #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsLibraryDefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetLibraryItemsLibraryDefaultDirection $defaultDirection = null; /** * @param string $key @@ -97,9 +97,9 @@ public function __construct(string $key, string $title, ?string $default = null, $this->title = $title; $this->default = $default; $this->active = $active; - $this->activeDirection = $activeDirection; - $this->defaultDirection = $defaultDirection; $this->descKey = $descKey; $this->firstCharacterKey = $firstCharacterKey; + $this->activeDirection = $activeDirection; + $this->defaultDirection = $defaultDirection; } } \ No newline at end of file diff --git a/src/Models/Operations/GetLibraryItemsMedia.php b/src/Models/Operations/GetLibraryItemsMedia.php index 2800e84..5714782 100644 --- a/src/Models/Operations/GetLibraryItemsMedia.php +++ b/src/Models/Operations/GetLibraryItemsMedia.php @@ -18,6 +18,22 @@ class GetLibraryItemsMedia #[\Speakeasy\Serializer\Annotation\SerializedName('id')] public int $id; + /** + * + * @var string $container + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('container')] + public string $container; + + /** + * $part + * + * @var array $part + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('Part')] + #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsPart>')] + public array $part; + /** * * @var ?int $duration @@ -98,13 +114,6 @@ class GetLibraryItemsMedia #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $videoResolution = null; - /** - * - * @var string $container - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('container')] - public string $container; - /** * * @var ?string $videoFrameRate @@ -129,15 +138,6 @@ class GetLibraryItemsMedia #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $hasVoiceActivity = null; - /** - * - * @var ?GetLibraryItemsOptimizedForStreaming $optimizedForStreaming - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('optimizedForStreaming')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsOptimizedForStreaming|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetLibraryItemsOptimizedForStreaming $optimizedForStreaming = null; - /** * * @var ?bool $has64bitOffsets @@ -147,13 +147,13 @@ class GetLibraryItemsMedia public ?bool $has64bitOffsets = null; /** - * $part * - * @var array $part + * @var ?GetLibraryItemsOptimizedForStreaming $optimizedForStreaming */ - #[\Speakeasy\Serializer\Annotation\SerializedName('Part')] - #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsPart>')] - public array $part; + #[\Speakeasy\Serializer\Annotation\SerializedName('optimizedForStreaming')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsOptimizedForStreaming|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetLibraryItemsOptimizedForStreaming $optimizedForStreaming = null; /** * @param int $id @@ -193,7 +193,7 @@ public function __construct(int $id, string $container, array $part, ?int $durat $this->videoFrameRate = $videoFrameRate; $this->videoProfile = $videoProfile; $this->hasVoiceActivity = $hasVoiceActivity; - $this->optimizedForStreaming = $optimizedForStreaming; $this->has64bitOffsets = $has64bitOffsets; + $this->optimizedForStreaming = $optimizedForStreaming; } } \ No newline at end of file diff --git a/src/Models/Operations/GetLibraryItemsMediaContainer.php b/src/Models/Operations/GetLibraryItemsMediaContainer.php index 05da2f4..92ca65a 100644 --- a/src/Models/Operations/GetLibraryItemsMediaContainer.php +++ b/src/Models/Operations/GetLibraryItemsMediaContainer.php @@ -16,26 +16,6 @@ */ class GetLibraryItemsMediaContainer { - /** - * $type - * - * @var ?array $type - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('Type')] - #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsType>|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?array $type = null; - - /** - * $fieldType - * - * @var ?array $fieldType - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('FieldType')] - #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsFieldType>|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?array $fieldType = null; - /** * * @var int $size @@ -71,14 +51,6 @@ class GetLibraryItemsMediaContainer #[\Speakeasy\Serializer\Annotation\SerializedName('allowSync')] public bool $allowSync; - /** - * - * @var ?bool $nocache - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('nocache')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $nocache = null; - /** * * @var string $art @@ -156,6 +128,34 @@ class GetLibraryItemsMediaContainer #[\Speakeasy\Serializer\Annotation\SerializedName('viewGroup')] public string $viewGroup; + /** + * $type + * + * @var ?array $type + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('Type')] + #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsType>|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?array $type = null; + + /** + * $fieldType + * + * @var ?array $fieldType + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('FieldType')] + #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsFieldType>|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?array $fieldType = null; + + /** + * + * @var ?bool $nocache + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('nocache')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $nocache = null; + /** * * @var ?int $viewMode diff --git a/src/Models/Operations/GetLibraryItemsMetadata.php b/src/Models/Operations/GetLibraryItemsMetadata.php index bbfb925..1e32796 100644 --- a/src/Models/Operations/GetLibraryItemsMetadata.php +++ b/src/Models/Operations/GetLibraryItemsMetadata.php @@ -36,6 +36,39 @@ class GetLibraryItemsMetadata #[\Speakeasy\Serializer\Annotation\SerializedName('guid')] public string $guid; + /** + * The type of media content + * + * + * + * @var GetLibraryItemsLibraryType $type + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('type')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsLibraryType')] + public GetLibraryItemsLibraryType $type; + + /** + * + * @var string $title + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; + + /** + * + * @var string $summary + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('summary')] + public string $summary; + + /** + * Unix epoch datetime in seconds + * + * @var int $addedAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('addedAt')] + public int $addedAt; + /** * * @var ?string $studio @@ -76,24 +109,6 @@ class GetLibraryItemsMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $librarySectionKey = null; - /** - * The type of media content - * - * - * - * @var GetLibraryItemsLibraryType $type - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('type')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsLibraryType')] - public GetLibraryItemsLibraryType $type; - - /** - * - * @var string $title - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; - /** * * @var ?string $slug @@ -110,13 +125,6 @@ class GetLibraryItemsMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $contentRating = null; - /** - * - * @var string $summary - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('summary')] - public string $summary; - /** * * @var ?float $rating @@ -158,22 +166,13 @@ class GetLibraryItemsMetadata public ?string $tagline = null; /** + * Setting that indicates the episode ordering for the show * - * @var ?GetLibraryItemsFlattenSeasons $flattenSeasons - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('flattenSeasons')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsFlattenSeasons|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetLibraryItemsFlattenSeasons $flattenSeasons = null; - - /** - * Setting that indicates the episode ordering for the show - * - * None = Library default, - * tmdbAiring = The Movie Database (Aired), - * aired = TheTVDB (Aired), - * dvd = TheTVDB (DVD), - * absolute = TheTVDB (Absolute)). + * None = Library default, + * tmdbAiring = The Movie Database (Aired), + * tvdbAiring = TheTVDB (Aired), + * tvdbDvd = TheTVDB (DVD), + * tvdbAbsolute = TheTVDB (Absolute)). * * * @var ?GetLibraryItemsShowOrdering $showOrdering @@ -223,14 +222,6 @@ class GetLibraryItemsMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?LocalDate $originallyAvailableAt = null; - /** - * Unix epoch datetime in seconds - * - * @var int $addedAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('addedAt')] - public int $addedAt; - /** * Unix epoch datetime in seconds * @@ -646,6 +637,15 @@ class GetLibraryItemsMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $parentTheme = null; + /** + * + * @var ?GetLibraryItemsFlattenSeasons $flattenSeasons + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('flattenSeasons')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsFlattenSeasons|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetLibraryItemsFlattenSeasons $flattenSeasons = null; + /** * @param string $ratingKey * @param string $key @@ -743,7 +743,6 @@ public function __construct(string $ratingKey, string $key, string $guid, GetLib $this->year = $year; $this->seasonCount = $seasonCount; $this->tagline = $tagline; - $this->flattenSeasons = $flattenSeasons; $this->showOrdering = $showOrdering; $this->thumb = $thumb; $this->art = $art; @@ -798,5 +797,6 @@ public function __construct(string $ratingKey, string $key, string $guid, GetLib $this->parentYear = $parentYear; $this->parentThumb = $parentThumb; $this->parentTheme = $parentTheme; + $this->flattenSeasons = $flattenSeasons; } } \ No newline at end of file diff --git a/src/Models/Operations/GetLibraryItemsPart.php b/src/Models/Operations/GetLibraryItemsPart.php index c309d62..e2d459e 100644 --- a/src/Models/Operations/GetLibraryItemsPart.php +++ b/src/Models/Operations/GetLibraryItemsPart.php @@ -25,14 +25,6 @@ class GetLibraryItemsPart #[\Speakeasy\Serializer\Annotation\SerializedName('key')] public string $key; - /** - * - * @var ?int $duration - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('duration')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?int $duration = null; - /** * * @var string $file @@ -57,6 +49,14 @@ class GetLibraryItemsPart #[\Speakeasy\Serializer\Annotation\SerializedName('container')] public string $container; + /** + * + * @var ?int $duration + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('duration')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?int $duration = null; + /** * * @var ?string $audioProfile @@ -97,15 +97,6 @@ class GetLibraryItemsPart #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $indexes = null; - /** - * - * @var ?GetLibraryItemsHasThumbnail $hasThumbnail - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('hasThumbnail')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsHasThumbnail|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetLibraryItemsHasThumbnail $hasThumbnail = null; - /** * $stream * @@ -116,6 +107,15 @@ class GetLibraryItemsPart #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?array $stream = null; + /** + * + * @var ?GetLibraryItemsHasThumbnail $hasThumbnail + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('hasThumbnail')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsHasThumbnail|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetLibraryItemsHasThumbnail $hasThumbnail = null; + /** * @param int $id * @param string $key @@ -144,7 +144,7 @@ public function __construct(int $id, string $key, string $file, int $size, strin $this->optimizedForStreaming = $optimizedForStreaming; $this->videoProfile = $videoProfile; $this->indexes = $indexes; - $this->hasThumbnail = $hasThumbnail; $this->stream = $stream; + $this->hasThumbnail = $hasThumbnail; } } \ No newline at end of file diff --git a/src/Models/Operations/GetLibraryItemsQueryParamType.php b/src/Models/Operations/GetLibraryItemsQueryParamType.php index 2518931..05606d4 100644 --- a/src/Models/Operations/GetLibraryItemsQueryParamType.php +++ b/src/Models/Operations/GetLibraryItemsQueryParamType.php @@ -26,4 +26,6 @@ enum GetLibraryItemsQueryParamType: int case Season = 3; case Episode = 4; case Audio = 8; + case Album = 9; + case Track = 10; } diff --git a/src/Models/Operations/GetLibraryItemsRequest.php b/src/Models/Operations/GetLibraryItemsRequest.php index 2362840..6947d6d 100644 --- a/src/Models/Operations/GetLibraryItemsRequest.php +++ b/src/Models/Operations/GetLibraryItemsRequest.php @@ -20,14 +20,15 @@ class GetLibraryItemsRequest public Tag $tag; /** - * Adds the Guids object to the response + * The unique key of the Plex library. * + * Note: This is unique in the context of the Plex server. * * - * @var ?IncludeGuids $includeGuids + * @var int $sectionKey */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=includeGuids')] - public ?IncludeGuids $includeGuids = null; + #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=sectionKey')] + public int $sectionKey; /** * The type of media to retrieve. @@ -45,15 +46,14 @@ class GetLibraryItemsRequest public ?GetLibraryItemsQueryParamType $type = null; /** - * The unique key of the Plex library. + * Adds the Guids object to the response * - * Note: This is unique in the context of the Plex server. * * - * @var int $sectionKey + * @var ?IncludeGuids $includeGuids */ - #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=sectionKey')] - public int $sectionKey; + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=includeGuids')] + public ?IncludeGuids $includeGuids = null; /** * Adds the Meta object to the response @@ -102,8 +102,8 @@ public function __construct(Tag $tag, int $sectionKey, ?GetLibraryItemsQueryPara { $this->tag = $tag; $this->sectionKey = $sectionKey; - $this->includeGuids = $includeGuids; $this->type = $type; + $this->includeGuids = $includeGuids; $this->includeMeta = $includeMeta; $this->xPlexContainerStart = $xPlexContainerStart; $this->xPlexContainerSize = $xPlexContainerSize; diff --git a/src/Models/Operations/GetLibraryItemsShowOrdering.php b/src/Models/Operations/GetLibraryItemsShowOrdering.php index 968b4c2..7b2e187 100644 --- a/src/Models/Operations/GetLibraryItemsShowOrdering.php +++ b/src/Models/Operations/GetLibraryItemsShowOrdering.php @@ -10,20 +10,20 @@ /** - * Setting that indicates the episode ordering for the show + * Setting that indicates the episode ordering for the show * - * None = Library default, - * tmdbAiring = The Movie Database (Aired), - * aired = TheTVDB (Aired), - * dvd = TheTVDB (DVD), - * absolute = TheTVDB (Absolute)). + * None = Library default, + * tmdbAiring = The Movie Database (Aired), + * tvdbAiring = TheTVDB (Aired), + * tvdbDvd = TheTVDB (DVD), + * tvdbAbsolute = TheTVDB (Absolute)). * */ enum GetLibraryItemsShowOrdering: string { case None = 'None'; case TmdbAiring = 'tmdbAiring'; - case Aired = 'aired'; - case Dvd = 'dvd'; - case Absolute = 'absolute'; + case TvdbAiring = 'tvdbAiring'; + case TvdbDvd = 'tvdbDvd'; + case TvdbAbsolute = 'tvdbAbsolute'; } diff --git a/src/Models/Operations/GetLibraryItemsSort.php b/src/Models/Operations/GetLibraryItemsSort.php index 2c2cea2..523a5e0 100644 --- a/src/Models/Operations/GetLibraryItemsSort.php +++ b/src/Models/Operations/GetLibraryItemsSort.php @@ -13,43 +13,33 @@ class GetLibraryItemsSort { /** * - * @var ?string $default + * @var string $key */ - #[\Speakeasy\Serializer\Annotation\SerializedName('default')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $default = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('key')] + public string $key; /** * - * @var ?bool $active + * @var string $title */ - #[\Speakeasy\Serializer\Annotation\SerializedName('active')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $active = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; /** - * The direction of the sort. Can be either `asc` or `desc`. * - * - * - * @var ?GetLibraryItemsActiveDirection $activeDirection + * @var ?string $default */ - #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('default')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetLibraryItemsActiveDirection $activeDirection = null; + public ?string $default = null; /** - * The direction of the sort. Can be either `asc` or `desc`. - * - * * - * @var ?GetLibraryItemsDefaultDirection $defaultDirection + * @var ?bool $active */ - #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsDefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('active')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetLibraryItemsDefaultDirection $defaultDirection = null; + public ?bool $active = null; /** * @@ -68,18 +58,28 @@ class GetLibraryItemsSort public ?string $firstCharacterKey = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $key + * + * + * @var ?GetLibraryItemsActiveDirection $activeDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('key')] - public string $key; + #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetLibraryItemsActiveDirection $activeDirection = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $title + * + * + * @var ?GetLibraryItemsDefaultDirection $defaultDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; + #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetLibraryItemsDefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetLibraryItemsDefaultDirection $defaultDirection = null; /** * @param string $key @@ -97,9 +97,9 @@ public function __construct(string $key, string $title, ?string $default = null, $this->title = $title; $this->default = $default; $this->active = $active; - $this->activeDirection = $activeDirection; - $this->defaultDirection = $defaultDirection; $this->descKey = $descKey; $this->firstCharacterKey = $firstCharacterKey; + $this->activeDirection = $activeDirection; + $this->defaultDirection = $defaultDirection; } } \ No newline at end of file diff --git a/src/Models/Operations/GetLibraryItemsStream.php b/src/Models/Operations/GetLibraryItemsStream.php index 69471d4..fe9e7b2 100644 --- a/src/Models/Operations/GetLibraryItemsStream.php +++ b/src/Models/Operations/GetLibraryItemsStream.php @@ -26,6 +26,22 @@ class GetLibraryItemsStream #[\Speakeasy\Serializer\Annotation\SerializedName('streamType')] public int $streamType; + /** + * Codec used by the stream + * + * @var string $codec + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('codec')] + public string $codec; + + /** + * The index of the stream + * + * @var int $index + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('index')] + public int $index; + /** * Indicates if this is the default stream * @@ -44,22 +60,6 @@ class GetLibraryItemsStream #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $selected = null; - /** - * Codec used by the stream - * - * @var string $codec - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('codec')] - public string $codec; - - /** - * The index of the stream - * - * @var int $index - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('index')] - public int $index; - /** * The bitrate of the stream in kbps * diff --git a/src/Models/Operations/GetMetaDataByRatingKeyMetadata.php b/src/Models/Operations/GetMetaDataByRatingKeyMetadata.php index 32bdd02..3e13570 100644 --- a/src/Models/Operations/GetMetaDataByRatingKeyMetadata.php +++ b/src/Models/Operations/GetMetaDataByRatingKeyMetadata.php @@ -83,6 +83,51 @@ class GetMetaDataByRatingKeyMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $librarySectionKey = null; + /** + * The name of the album artist for the track when audio, and the name of the TV show for the episode when video. + * + * @var ?string $grandparentTitle + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('grandparentTitle')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $grandparentTitle = null; + + /** + * The name of the album for the track when audio, and the name of the season for the episode when TV show. + * + * @var ?string $parentTitle + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('parentTitle')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $parentTitle = null; + + /** + * The orginal untranslated name of the media item when non-english. + * + * @var ?string $originalTitle + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('originalTitle')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $originalTitle = null; + + /** + * The index starting from 0 of this media item in the MetaData array. + * + * @var ?int $index + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('index')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?int $index = null; + + /** + * The parent index starting from 0 of this media item in the parent MetaData array. + * + * @var ?int $parentIndex + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('parentIndex')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?int $parentIndex = null; + /** * * @var ?string $contentRating @@ -303,6 +348,11 @@ class GetMetaDataByRatingKeyMetadata * @param ?string $librarySectionTitle * @param ?int $librarySectionID * @param ?string $librarySectionKey + * @param ?string $grandparentTitle + * @param ?string $parentTitle + * @param ?string $originalTitle + * @param ?int $index + * @param ?int $parentIndex * @param ?string $contentRating * @param ?string $summary * @param ?float $rating @@ -328,7 +378,7 @@ class GetMetaDataByRatingKeyMetadata * @param ?array $role * @param ?array $producer */ - public function __construct(?string $ratingKey = null, ?string $key = null, ?string $guid = null, ?string $studio = null, ?string $type = null, ?string $title = null, ?string $librarySectionTitle = null, ?int $librarySectionID = null, ?string $librarySectionKey = null, ?string $contentRating = null, ?string $summary = null, ?float $rating = null, ?float $audienceRating = null, ?int $year = null, ?string $tagline = null, ?string $thumb = null, ?string $art = null, ?int $duration = null, ?LocalDate $originallyAvailableAt = null, ?int $addedAt = null, ?int $updatedAt = null, ?string $audienceRatingImage = null, ?string $hasPremiumPrimaryExtra = null, ?string $ratingImage = null, ?array $media = null, ?array $genre = null, ?array $country = null, ?array $guids = null, ?array $ratings = null, ?array $director = null, ?array $writer = null, ?array $role = null, ?array $producer = null) + public function __construct(?string $ratingKey = null, ?string $key = null, ?string $guid = null, ?string $studio = null, ?string $type = null, ?string $title = null, ?string $librarySectionTitle = null, ?int $librarySectionID = null, ?string $librarySectionKey = null, ?string $grandparentTitle = null, ?string $parentTitle = null, ?string $originalTitle = null, ?int $index = null, ?int $parentIndex = null, ?string $contentRating = null, ?string $summary = null, ?float $rating = null, ?float $audienceRating = null, ?int $year = null, ?string $tagline = null, ?string $thumb = null, ?string $art = null, ?int $duration = null, ?LocalDate $originallyAvailableAt = null, ?int $addedAt = null, ?int $updatedAt = null, ?string $audienceRatingImage = null, ?string $hasPremiumPrimaryExtra = null, ?string $ratingImage = null, ?array $media = null, ?array $genre = null, ?array $country = null, ?array $guids = null, ?array $ratings = null, ?array $director = null, ?array $writer = null, ?array $role = null, ?array $producer = null) { $this->ratingKey = $ratingKey; $this->key = $key; @@ -339,6 +389,11 @@ public function __construct(?string $ratingKey = null, ?string $key = null, ?str $this->librarySectionTitle = $librarySectionTitle; $this->librarySectionID = $librarySectionID; $this->librarySectionKey = $librarySectionKey; + $this->grandparentTitle = $grandparentTitle; + $this->parentTitle = $parentTitle; + $this->originalTitle = $originalTitle; + $this->index = $index; + $this->parentIndex = $parentIndex; $this->contentRating = $contentRating; $this->summary = $summary; $this->rating = $rating; diff --git a/src/Models/Operations/GetPinAuthPinContainer.php b/src/Models/Operations/GetPinAuthPinContainer.php index 7edc760..726c48d 100644 --- a/src/Models/Operations/GetPinAuthPinContainer.php +++ b/src/Models/Operations/GetPinAuthPinContainer.php @@ -33,14 +33,6 @@ class GetPinAuthPinContainer #[\Speakeasy\Serializer\Annotation\SerializedName('product')] public string $product; - /** - * - * @var ?bool $trusted - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('trusted')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $trusted = null; - /** * * @var string $qr @@ -65,15 +57,6 @@ class GetPinAuthPinContainer #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GeoData')] public GeoData $location; - /** - * The number of seconds this pin expires, by default 900 seconds - * - * @var ?int $expiresIn - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('expiresIn')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?int $expiresIn = null; - /** * * @var \DateTime $createdAt @@ -105,6 +88,23 @@ class GetPinAuthPinContainer #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public mixed $newRegistration = null; + /** + * + * @var ?bool $trusted + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('trusted')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $trusted = null; + + /** + * The number of seconds this pin expires, by default 900 seconds + * + * @var ?int $expiresIn + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('expiresIn')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?int $expiresIn = null; + /** * @param int $id * @param string $code @@ -129,9 +129,9 @@ public function __construct(int $id, string $code, string $product, string $qr, $this->location = $location; $this->createdAt = $createdAt; $this->expiresAt = $expiresAt; - $this->trusted = $trusted; - $this->expiresIn = $expiresIn; $this->authToken = $authToken; $this->newRegistration = $newRegistration; + $this->trusted = $trusted; + $this->expiresIn = $expiresIn; } } \ No newline at end of file diff --git a/src/Models/Operations/GetPinRequest.php b/src/Models/Operations/GetPinRequest.php index d10cfcb..4956346 100644 --- a/src/Models/Operations/GetPinRequest.php +++ b/src/Models/Operations/GetPinRequest.php @@ -11,25 +11,13 @@ use LukeHagar\Plex_API\Utils\SpeakeasyMetadata; class GetPinRequest { - /** - * Determines the kind of code returned by the API call - * - * Strong codes are used for Pin authentication flows - * Non-Strong codes are used for `Plex.tv/link` - * - * - * @var ?bool $strong - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=strong')] - public ?bool $strong = null; - /** * An opaque identifier unique to the client (UUID, serial number, or other unique device ID) * - * @var ?string $clientID + * @var string $clientID */ #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Client-Identifier')] - public ?string $clientID = null; + public string $clientID; /** * The name of the client application. (Plex Web, Plex Media Server, etc.) @@ -64,20 +52,32 @@ class GetPinRequest public ?string $platform = null; /** + * Determines the kind of code returned by the API call + * + * Strong codes are used for Pin authentication flows + * Non-Strong codes are used for `Plex.tv/link` + * + * + * @var ?bool $strong + */ + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=strong')] + public ?bool $strong = null; + + /** + * @param string $clientID * @param ?bool $strong - * @param ?string $clientID * @param ?string $clientName * @param ?string $deviceNickname * @param ?string $clientVersion * @param ?string $platform */ - public function __construct(?string $clientID = null, ?string $clientName = null, ?string $deviceNickname = null, ?string $clientVersion = null, ?string $platform = null, ?bool $strong = false) + public function __construct(string $clientID, ?string $clientName = null, ?string $deviceNickname = null, ?string $clientVersion = null, ?string $platform = null, ?bool $strong = false) { - $this->strong = $strong; $this->clientID = $clientID; $this->clientName = $clientName; $this->deviceNickname = $deviceNickname; $this->clientVersion = $clientVersion; $this->platform = $platform; + $this->strong = $strong; } } \ No newline at end of file diff --git a/src/Models/Operations/GetPlaylistContentsQueryParamType.php b/src/Models/Operations/GetPlaylistContentsQueryParamType.php index d5f69f1..9ef11e8 100644 --- a/src/Models/Operations/GetPlaylistContentsQueryParamType.php +++ b/src/Models/Operations/GetPlaylistContentsQueryParamType.php @@ -26,4 +26,6 @@ enum GetPlaylistContentsQueryParamType: int case Season = 3; case Episode = 4; case Audio = 8; + case Album = 9; + case Track = 10; } diff --git a/src/Models/Operations/GetRecentlyAddedLibraryRequest.php b/src/Models/Operations/GetRecentlyAddedLibraryRequest.php index b394ab1..209f25d 100644 --- a/src/Models/Operations/GetRecentlyAddedLibraryRequest.php +++ b/src/Models/Operations/GetRecentlyAddedLibraryRequest.php @@ -11,6 +11,21 @@ use LukeHagar\Plex_API\Utils\SpeakeasyMetadata; class GetRecentlyAddedLibraryRequest { + /** + * The type of media to retrieve. + * + * 1 = movie + * 2 = show + * 3 = season + * 4 = episode + * E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries + * + * + * @var QueryParamType $type + */ + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=type')] + public QueryParamType $type; + /** * * @var ?int $contentDirectoryID @@ -34,21 +49,6 @@ class GetRecentlyAddedLibraryRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=sectionID')] public ?int $sectionID = null; - /** - * The type of media to retrieve. - * - * 1 = movie - * 2 = show - * 3 = season - * 4 = episode - * E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries - * - * - * @var QueryParamType $type - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=type')] - public QueryParamType $type; - /** * Adds the Meta object to the response * diff --git a/src/Models/Operations/GetRecentlyAddedMetadata.php b/src/Models/Operations/GetRecentlyAddedMetadata.php index f036bd4..8a0bc07 100644 --- a/src/Models/Operations/GetRecentlyAddedMetadata.php +++ b/src/Models/Operations/GetRecentlyAddedMetadata.php @@ -36,6 +36,39 @@ class GetRecentlyAddedMetadata #[\Speakeasy\Serializer\Annotation\SerializedName('guid')] public string $guid; + /** + * The type of media content + * + * + * + * @var GetRecentlyAddedHubsType $type + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('type')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedHubsType')] + public GetRecentlyAddedHubsType $type; + + /** + * + * @var string $title + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; + + /** + * + * @var string $summary + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('summary')] + public string $summary; + + /** + * Unix epoch datetime in seconds + * + * @var int $addedAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('addedAt')] + public int $addedAt; + /** * * @var ?string $studio @@ -76,24 +109,6 @@ class GetRecentlyAddedMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $librarySectionKey = null; - /** - * The type of media content - * - * - * - * @var GetRecentlyAddedHubsType $type - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('type')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedHubsType')] - public GetRecentlyAddedHubsType $type; - - /** - * - * @var string $title - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; - /** * * @var ?string $slug @@ -110,13 +125,6 @@ class GetRecentlyAddedMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $contentRating = null; - /** - * - * @var string $summary - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('summary')] - public string $summary; - /** * * @var ?float $rating @@ -158,22 +166,13 @@ class GetRecentlyAddedMetadata public ?string $tagline = null; /** + * Setting that indicates the episode ordering for the show * - * @var ?FlattenSeasons $flattenSeasons - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('flattenSeasons')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\FlattenSeasons|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?FlattenSeasons $flattenSeasons = null; - - /** - * Setting that indicates the episode ordering for the show - * - * None = Library default, - * tmdbAiring = The Movie Database (Aired), - * aired = TheTVDB (Aired), - * dvd = TheTVDB (DVD), - * absolute = TheTVDB (Absolute)). + * None = Library default, + * tmdbAiring = The Movie Database (Aired), + * tvdbAiring = TheTVDB (Aired), + * tvdbDvd = TheTVDB (DVD), + * tvdbAbsolute = TheTVDB (Absolute)). * * * @var ?ShowOrdering $showOrdering @@ -223,14 +222,6 @@ class GetRecentlyAddedMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?LocalDate $originallyAvailableAt = null; - /** - * Unix epoch datetime in seconds - * - * @var int $addedAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('addedAt')] - public int $addedAt; - /** * Unix epoch datetime in seconds * @@ -646,6 +637,15 @@ class GetRecentlyAddedMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $parentTheme = null; + /** + * + * @var ?FlattenSeasons $flattenSeasons + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('flattenSeasons')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\FlattenSeasons|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?FlattenSeasons $flattenSeasons = null; + /** * @param string $ratingKey * @param string $key @@ -743,7 +743,6 @@ public function __construct(string $ratingKey, string $key, string $guid, GetRec $this->year = $year; $this->seasonCount = $seasonCount; $this->tagline = $tagline; - $this->flattenSeasons = $flattenSeasons; $this->showOrdering = $showOrdering; $this->thumb = $thumb; $this->art = $art; @@ -798,5 +797,6 @@ public function __construct(string $ratingKey, string $key, string $guid, GetRec $this->parentYear = $parentYear; $this->parentThumb = $parentThumb; $this->parentTheme = $parentTheme; + $this->flattenSeasons = $flattenSeasons; } } \ No newline at end of file diff --git a/src/Models/Operations/GetRecentlyAddedRequest.php b/src/Models/Operations/GetRecentlyAddedRequest.php index ffc710a..297295c 100644 --- a/src/Models/Operations/GetRecentlyAddedRequest.php +++ b/src/Models/Operations/GetRecentlyAddedRequest.php @@ -19,6 +19,21 @@ class GetRecentlyAddedRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=contentDirectoryID')] public int $contentDirectoryID; + /** + * The type of media to retrieve. + * + * 1 = movie + * 2 = show + * 3 = season + * 4 = episode + * E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries + * + * + * @var Type $type + */ + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=type')] + public Type $type; + /** * Comma-separated list of pinned content directory IDs. * @@ -35,21 +50,6 @@ class GetRecentlyAddedRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=sectionID')] public ?int $sectionID = null; - /** - * The type of media to retrieve. - * - * 1 = movie - * 2 = show - * 3 = season - * 4 = episode - * E.g. A movie library will not return anything with type 3 as there are no seasons for movie libraries - * - * - * @var Type $type - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=type')] - public Type $type; - /** * Adds the Meta object to the response * diff --git a/src/Models/Operations/GetRecentlyAddedSort.php b/src/Models/Operations/GetRecentlyAddedSort.php index b2e7f66..1770b30 100644 --- a/src/Models/Operations/GetRecentlyAddedSort.php +++ b/src/Models/Operations/GetRecentlyAddedSort.php @@ -13,43 +13,33 @@ class GetRecentlyAddedSort { /** * - * @var ?string $default + * @var string $key */ - #[\Speakeasy\Serializer\Annotation\SerializedName('default')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $default = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('key')] + public string $key; /** * - * @var ?bool $active + * @var string $title */ - #[\Speakeasy\Serializer\Annotation\SerializedName('active')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $active = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; /** - * The direction of the sort. Can be either `asc` or `desc`. * - * - * - * @var ?GetRecentlyAddedActiveDirection $activeDirection + * @var ?string $default */ - #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('default')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetRecentlyAddedActiveDirection $activeDirection = null; + public ?string $default = null; /** - * The direction of the sort. Can be either `asc` or `desc`. - * - * * - * @var ?GetRecentlyAddedDefaultDirection $defaultDirection + * @var ?bool $active */ - #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedDefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('active')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetRecentlyAddedDefaultDirection $defaultDirection = null; + public ?bool $active = null; /** * @@ -68,18 +58,28 @@ class GetRecentlyAddedSort public ?string $firstCharacterKey = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $key + * + * + * @var ?GetRecentlyAddedActiveDirection $activeDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('key')] - public string $key; + #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetRecentlyAddedActiveDirection $activeDirection = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $title + * + * + * @var ?GetRecentlyAddedDefaultDirection $defaultDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; + #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetRecentlyAddedDefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetRecentlyAddedDefaultDirection $defaultDirection = null; /** * @param string $key @@ -97,9 +97,9 @@ public function __construct(string $key, string $title, ?string $default = null, $this->title = $title; $this->default = $default; $this->active = $active; - $this->activeDirection = $activeDirection; - $this->defaultDirection = $defaultDirection; $this->descKey = $descKey; $this->firstCharacterKey = $firstCharacterKey; + $this->activeDirection = $activeDirection; + $this->defaultDirection = $defaultDirection; } } \ No newline at end of file diff --git a/src/Models/Operations/GetResizedPhotoRequest.php b/src/Models/Operations/GetResizedPhotoRequest.php index d035426..2228301 100644 --- a/src/Models/Operations/GetResizedPhotoRequest.php +++ b/src/Models/Operations/GetResizedPhotoRequest.php @@ -27,14 +27,6 @@ class GetResizedPhotoRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=height')] public float $height; - /** - * The opacity for the resized photo - * - * @var int $opacity - */ - #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=opacity')] - public int $opacity; - /** * The width for the resized photo * @@ -67,6 +59,14 @@ class GetResizedPhotoRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=url')] public string $url; + /** + * The opacity for the resized photo + * + * @var int $opacity + */ + #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=opacity')] + public int $opacity; + /** * @param float $width * @param float $height @@ -80,10 +80,10 @@ public function __construct(float $width, float $height, float $blur, MinSize $m { $this->width = $width; $this->height = $height; - $this->opacity = $opacity; $this->blur = $blur; $this->minSize = $minSize; $this->upscale = $upscale; $this->url = $url; + $this->opacity = $opacity; } } \ No newline at end of file diff --git a/src/Models/Operations/GetSearchAllLibrariesMedia.php b/src/Models/Operations/GetSearchAllLibrariesMedia.php index bf0f553..7f8991f 100644 --- a/src/Models/Operations/GetSearchAllLibrariesMedia.php +++ b/src/Models/Operations/GetSearchAllLibrariesMedia.php @@ -18,6 +18,22 @@ class GetSearchAllLibrariesMedia #[\Speakeasy\Serializer\Annotation\SerializedName('id')] public int $id; + /** + * + * @var string $container + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('container')] + public string $container; + + /** + * $part + * + * @var array $part + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('Part')] + #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesPart>')] + public array $part; + /** * * @var ?int $duration @@ -98,13 +114,6 @@ class GetSearchAllLibrariesMedia #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $videoResolution = null; - /** - * - * @var string $container - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('container')] - public string $container; - /** * * @var ?string $videoFrameRate @@ -129,15 +138,6 @@ class GetSearchAllLibrariesMedia #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $hasVoiceActivity = null; - /** - * - * @var ?GetSearchAllLibrariesOptimizedForStreaming $optimizedForStreaming - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('optimizedForStreaming')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesOptimizedForStreaming|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetSearchAllLibrariesOptimizedForStreaming $optimizedForStreaming = null; - /** * * @var ?bool $has64bitOffsets @@ -147,13 +147,13 @@ class GetSearchAllLibrariesMedia public ?bool $has64bitOffsets = null; /** - * $part * - * @var array $part + * @var ?GetSearchAllLibrariesOptimizedForStreaming $optimizedForStreaming */ - #[\Speakeasy\Serializer\Annotation\SerializedName('Part')] - #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesPart>')] - public array $part; + #[\Speakeasy\Serializer\Annotation\SerializedName('optimizedForStreaming')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesOptimizedForStreaming|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetSearchAllLibrariesOptimizedForStreaming $optimizedForStreaming = null; /** * @param int $id @@ -193,7 +193,7 @@ public function __construct(int $id, string $container, array $part, ?int $durat $this->videoFrameRate = $videoFrameRate; $this->videoProfile = $videoProfile; $this->hasVoiceActivity = $hasVoiceActivity; - $this->optimizedForStreaming = $optimizedForStreaming; $this->has64bitOffsets = $has64bitOffsets; + $this->optimizedForStreaming = $optimizedForStreaming; } } \ No newline at end of file diff --git a/src/Models/Operations/GetSearchAllLibrariesMetadata.php b/src/Models/Operations/GetSearchAllLibrariesMetadata.php index 99a23d5..f11db4a 100644 --- a/src/Models/Operations/GetSearchAllLibrariesMetadata.php +++ b/src/Models/Operations/GetSearchAllLibrariesMetadata.php @@ -36,6 +36,39 @@ class GetSearchAllLibrariesMetadata #[\Speakeasy\Serializer\Annotation\SerializedName('guid')] public string $guid; + /** + * The type of media content + * + * + * + * @var GetSearchAllLibrariesType $type + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('type')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesType')] + public GetSearchAllLibrariesType $type; + + /** + * + * @var string $title + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; + + /** + * + * @var string $summary + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('summary')] + public string $summary; + + /** + * Unix epoch datetime in seconds + * + * @var int $addedAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('addedAt')] + public int $addedAt; + /** * * @var ?string $studio @@ -76,24 +109,6 @@ class GetSearchAllLibrariesMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $librarySectionKey = null; - /** - * The type of media content - * - * - * - * @var GetSearchAllLibrariesType $type - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('type')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesType')] - public GetSearchAllLibrariesType $type; - - /** - * - * @var string $title - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; - /** * * @var ?string $slug @@ -110,13 +125,6 @@ class GetSearchAllLibrariesMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $contentRating = null; - /** - * - * @var string $summary - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('summary')] - public string $summary; - /** * * @var ?float $rating @@ -158,22 +166,13 @@ class GetSearchAllLibrariesMetadata public ?string $tagline = null; /** + * Setting that indicates the episode ordering for the show * - * @var ?GetSearchAllLibrariesFlattenSeasons $flattenSeasons - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('flattenSeasons')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesFlattenSeasons|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetSearchAllLibrariesFlattenSeasons $flattenSeasons = null; - - /** - * Setting that indicates the episode ordering for the show - * - * None = Library default, - * tmdbAiring = The Movie Database (Aired), - * aired = TheTVDB (Aired), - * dvd = TheTVDB (DVD), - * absolute = TheTVDB (Absolute)). + * None = Library default, + * tmdbAiring = The Movie Database (Aired), + * tvdbAiring = TheTVDB (Aired), + * tvdbDvd = TheTVDB (DVD), + * tvdbAbsolute = TheTVDB (Absolute)). * * * @var ?GetSearchAllLibrariesShowOrdering $showOrdering @@ -223,14 +222,6 @@ class GetSearchAllLibrariesMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?LocalDate $originallyAvailableAt = null; - /** - * Unix epoch datetime in seconds - * - * @var int $addedAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('addedAt')] - public int $addedAt; - /** * Unix epoch datetime in seconds * @@ -646,6 +637,15 @@ class GetSearchAllLibrariesMetadata #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $parentTheme = null; + /** + * + * @var ?GetSearchAllLibrariesFlattenSeasons $flattenSeasons + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('flattenSeasons')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesFlattenSeasons|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetSearchAllLibrariesFlattenSeasons $flattenSeasons = null; + /** * @param string $ratingKey * @param string $key @@ -743,7 +743,6 @@ public function __construct(string $ratingKey, string $key, string $guid, GetSea $this->year = $year; $this->seasonCount = $seasonCount; $this->tagline = $tagline; - $this->flattenSeasons = $flattenSeasons; $this->showOrdering = $showOrdering; $this->thumb = $thumb; $this->art = $art; @@ -798,5 +797,6 @@ public function __construct(string $ratingKey, string $key, string $guid, GetSea $this->parentYear = $parentYear; $this->parentThumb = $parentThumb; $this->parentTheme = $parentTheme; + $this->flattenSeasons = $flattenSeasons; } } \ No newline at end of file diff --git a/src/Models/Operations/GetSearchAllLibrariesPart.php b/src/Models/Operations/GetSearchAllLibrariesPart.php index e116339..379ffb3 100644 --- a/src/Models/Operations/GetSearchAllLibrariesPart.php +++ b/src/Models/Operations/GetSearchAllLibrariesPart.php @@ -25,14 +25,6 @@ class GetSearchAllLibrariesPart #[\Speakeasy\Serializer\Annotation\SerializedName('key')] public string $key; - /** - * - * @var ?int $duration - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('duration')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?int $duration = null; - /** * * @var string $file @@ -57,6 +49,14 @@ class GetSearchAllLibrariesPart #[\Speakeasy\Serializer\Annotation\SerializedName('container')] public string $container; + /** + * + * @var ?int $duration + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('duration')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?int $duration = null; + /** * * @var ?string $audioProfile @@ -97,15 +97,6 @@ class GetSearchAllLibrariesPart #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $indexes = null; - /** - * - * @var ?GetSearchAllLibrariesHasThumbnail $hasThumbnail - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('hasThumbnail')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesHasThumbnail|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?GetSearchAllLibrariesHasThumbnail $hasThumbnail = null; - /** * $stream * @@ -116,6 +107,15 @@ class GetSearchAllLibrariesPart #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?array $stream = null; + /** + * + * @var ?GetSearchAllLibrariesHasThumbnail $hasThumbnail + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('hasThumbnail')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetSearchAllLibrariesHasThumbnail|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?GetSearchAllLibrariesHasThumbnail $hasThumbnail = null; + /** * @param int $id * @param string $key @@ -144,7 +144,7 @@ public function __construct(int $id, string $key, string $file, int $size, strin $this->optimizedForStreaming = $optimizedForStreaming; $this->videoProfile = $videoProfile; $this->indexes = $indexes; - $this->hasThumbnail = $hasThumbnail; $this->stream = $stream; + $this->hasThumbnail = $hasThumbnail; } } \ No newline at end of file diff --git a/src/Models/Operations/GetSearchAllLibrariesRequest.php b/src/Models/Operations/GetSearchAllLibrariesRequest.php index 837ed8d..aa59420 100644 --- a/src/Models/Operations/GetSearchAllLibrariesRequest.php +++ b/src/Models/Operations/GetSearchAllLibrariesRequest.php @@ -22,10 +22,10 @@ class GetSearchAllLibrariesRequest /** * An opaque identifier unique to the client (UUID, serial number, or other unique device ID) * - * @var ?string $clientID + * @var string $clientID */ #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Client-Identifier')] - public ?string $clientID = null; + public string $clientID; /** * Limit the number of results returned. @@ -63,13 +63,13 @@ class GetSearchAllLibrariesRequest /** * @param string $query - * @param ?string $clientID + * @param string $clientID * @param ?int $limit * @param ?array $searchTypes * @param ?QueryParamIncludeCollections $includeCollections * @param ?QueryParamIncludeExternalMedia $includeExternalMedia */ - public function __construct(string $query, ?string $clientID = null, ?int $limit = null, ?array $searchTypes = null, ?QueryParamIncludeCollections $includeCollections = QueryParamIncludeCollections::Disable, ?QueryParamIncludeExternalMedia $includeExternalMedia = QueryParamIncludeExternalMedia::Disable) + public function __construct(string $query, string $clientID, ?int $limit = null, ?array $searchTypes = null, ?QueryParamIncludeCollections $includeCollections = QueryParamIncludeCollections::Disable, ?QueryParamIncludeExternalMedia $includeExternalMedia = QueryParamIncludeExternalMedia::Disable) { $this->query = $query; $this->clientID = $clientID; diff --git a/src/Models/Operations/GetSearchAllLibrariesShowOrdering.php b/src/Models/Operations/GetSearchAllLibrariesShowOrdering.php index 330776e..42a879c 100644 --- a/src/Models/Operations/GetSearchAllLibrariesShowOrdering.php +++ b/src/Models/Operations/GetSearchAllLibrariesShowOrdering.php @@ -10,20 +10,20 @@ /** - * Setting that indicates the episode ordering for the show + * Setting that indicates the episode ordering for the show * - * None = Library default, - * tmdbAiring = The Movie Database (Aired), - * aired = TheTVDB (Aired), - * dvd = TheTVDB (DVD), - * absolute = TheTVDB (Absolute)). + * None = Library default, + * tmdbAiring = The Movie Database (Aired), + * tvdbAiring = TheTVDB (Aired), + * tvdbDvd = TheTVDB (DVD), + * tvdbAbsolute = TheTVDB (Absolute)). * */ enum GetSearchAllLibrariesShowOrdering: string { case None = 'None'; case TmdbAiring = 'tmdbAiring'; - case Aired = 'aired'; - case Dvd = 'dvd'; - case Absolute = 'absolute'; + case TvdbAiring = 'tvdbAiring'; + case TvdbDvd = 'tvdbDvd'; + case TvdbAbsolute = 'tvdbAbsolute'; } diff --git a/src/Models/Operations/GetSearchAllLibrariesStream.php b/src/Models/Operations/GetSearchAllLibrariesStream.php index 5dd5bee..fa354db 100644 --- a/src/Models/Operations/GetSearchAllLibrariesStream.php +++ b/src/Models/Operations/GetSearchAllLibrariesStream.php @@ -26,6 +26,22 @@ class GetSearchAllLibrariesStream #[\Speakeasy\Serializer\Annotation\SerializedName('streamType')] public int $streamType; + /** + * Codec used by the stream + * + * @var string $codec + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('codec')] + public string $codec; + + /** + * The index of the stream + * + * @var int $index + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('index')] + public int $index; + /** * Indicates if this is the default stream * @@ -44,22 +60,6 @@ class GetSearchAllLibrariesStream #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $selected = null; - /** - * Codec used by the stream - * - * @var string $codec - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('codec')] - public string $codec; - - /** - * The index of the stream - * - * @var int $index - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('index')] - public int $index; - /** * The bitrate of the stream in kbps * diff --git a/src/Models/Operations/GetSearchLibraryQueryParamType.php b/src/Models/Operations/GetSearchLibraryQueryParamType.php index a367c5b..76c3401 100644 --- a/src/Models/Operations/GetSearchLibraryQueryParamType.php +++ b/src/Models/Operations/GetSearchLibraryQueryParamType.php @@ -26,4 +26,6 @@ enum GetSearchLibraryQueryParamType: int case Season = 3; case Episode = 4; case Audio = 8; + case Album = 9; + case Track = 10; } diff --git a/src/Models/Operations/GetServerResourcesRequest.php b/src/Models/Operations/GetServerResourcesRequest.php index 2f60527..8aed970 100644 --- a/src/Models/Operations/GetServerResourcesRequest.php +++ b/src/Models/Operations/GetServerResourcesRequest.php @@ -11,6 +11,14 @@ use LukeHagar\Plex_API\Utils\SpeakeasyMetadata; class GetServerResourcesRequest { + /** + * An opaque identifier unique to the client (UUID, serial number, or other unique device ID) + * + * @var string $clientID + */ + #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Client-Identifier')] + public string $clientID; + /** * Include Https entries in the results * @@ -39,24 +47,16 @@ class GetServerResourcesRequest public ?IncludeIPv6 $includeIPv6 = null; /** - * An opaque identifier unique to the client (UUID, serial number, or other unique device ID) - * - * @var ?string $clientID - */ - #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Client-Identifier')] - public ?string $clientID = null; - - /** + * @param string $clientID * @param ?IncludeHttps $includeHttps * @param ?IncludeRelay $includeRelay * @param ?IncludeIPv6 $includeIPv6 - * @param ?string $clientID */ - public function __construct(?string $clientID = null, ?IncludeHttps $includeHttps = IncludeHttps::Disable, ?IncludeRelay $includeRelay = IncludeRelay::Disable, ?IncludeIPv6 $includeIPv6 = IncludeIPv6::Disable) + public function __construct(string $clientID, ?IncludeHttps $includeHttps = IncludeHttps::Disable, ?IncludeRelay $includeRelay = IncludeRelay::Disable, ?IncludeIPv6 $includeIPv6 = IncludeIPv6::Disable) { + $this->clientID = $clientID; $this->includeHttps = $includeHttps; $this->includeRelay = $includeRelay; $this->includeIPv6 = $includeIPv6; - $this->clientID = $clientID; } } \ No newline at end of file diff --git a/src/Models/Operations/GetThumbImageResponse.php b/src/Models/Operations/GetThumbImageResponse.php index 786d061..c5b48cb 100644 --- a/src/Models/Operations/GetThumbImageResponse.php +++ b/src/Models/Operations/GetThumbImageResponse.php @@ -33,18 +33,18 @@ class GetThumbImageResponse public \Psr\Http\Message\ResponseInterface $rawResponse; /** - * Successful response returning an image + * $headers * - * @var ?string $bytes + * @var array> $headers */ - public ?string $bytes = null; + public array $headers; /** - * $headers + * Successful response returning an image * - * @var array> $headers + * @var ?string $bytes */ - public array $headers; + public ?string $bytes = null; /** * @param string $contentType diff --git a/src/Models/Operations/GetTokenByPinIdAuthPinContainer.php b/src/Models/Operations/GetTokenByPinIdAuthPinContainer.php index 1029b00..65678ee 100644 --- a/src/Models/Operations/GetTokenByPinIdAuthPinContainer.php +++ b/src/Models/Operations/GetTokenByPinIdAuthPinContainer.php @@ -33,14 +33,6 @@ class GetTokenByPinIdAuthPinContainer #[\Speakeasy\Serializer\Annotation\SerializedName('product')] public string $product; - /** - * - * @var ?bool $trusted - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('trusted')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $trusted = null; - /** * * @var string $qr @@ -65,15 +57,6 @@ class GetTokenByPinIdAuthPinContainer #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetTokenByPinIdGeoData')] public GetTokenByPinIdGeoData $location; - /** - * The number of seconds this pin expires, by default 900 seconds - * - * @var ?int $expiresIn - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('expiresIn')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?int $expiresIn = null; - /** * * @var \DateTime $createdAt @@ -105,6 +88,23 @@ class GetTokenByPinIdAuthPinContainer #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public mixed $newRegistration = null; + /** + * + * @var ?bool $trusted + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('trusted')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $trusted = null; + + /** + * The number of seconds this pin expires, by default 900 seconds + * + * @var ?int $expiresIn + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('expiresIn')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?int $expiresIn = null; + /** * @param int $id * @param string $code @@ -129,9 +129,9 @@ public function __construct(int $id, string $code, string $product, string $qr, $this->location = $location; $this->createdAt = $createdAt; $this->expiresAt = $expiresAt; - $this->trusted = $trusted; - $this->expiresIn = $expiresIn; $this->authToken = $authToken; $this->newRegistration = $newRegistration; + $this->trusted = $trusted; + $this->expiresIn = $expiresIn; } } \ No newline at end of file diff --git a/src/Models/Operations/GetTokenByPinIdGeoData.php b/src/Models/Operations/GetTokenByPinIdGeoData.php index 051e340..9e08d0a 100644 --- a/src/Models/Operations/GetTokenByPinIdGeoData.php +++ b/src/Models/Operations/GetTokenByPinIdGeoData.php @@ -44,15 +44,6 @@ class GetTokenByPinIdGeoData #[\Speakeasy\Serializer\Annotation\SerializedName('city')] public string $city; - /** - * Indicates if the country is a member of the European Union. - * - * @var ?bool $europeanUnionMember - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('european_union_member')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $europeanUnionMember = null; - /** * The time zone of the country. * @@ -69,6 +60,31 @@ class GetTokenByPinIdGeoData #[\Speakeasy\Serializer\Annotation\SerializedName('postal_code')] public string $postalCode; + /** + * The name of the primary administrative subdivision. + * + * @var string $subdivisions + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subdivisions')] + public string $subdivisions; + + /** + * The geographical coordinates (latitude, longitude) of the location. + * + * @var string $coordinates + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('coordinates')] + public string $coordinates; + + /** + * Indicates if the country is a member of the European Union. + * + * @var ?bool $europeanUnionMember + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('european_union_member')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $europeanUnionMember = null; + /** * Indicates if the country has privacy restrictions. * @@ -87,22 +103,6 @@ class GetTokenByPinIdGeoData #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $inPrivacyRestrictedRegion = null; - /** - * The name of the primary administrative subdivision. - * - * @var string $subdivisions - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subdivisions')] - public string $subdivisions; - - /** - * The geographical coordinates (latitude, longitude) of the location. - * - * @var string $coordinates - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('coordinates')] - public string $coordinates; - /** * @param string $code * @param string $continentCode diff --git a/src/Models/Operations/GetTokenByPinIdRequest.php b/src/Models/Operations/GetTokenByPinIdRequest.php index e5e9dbb..9d64a1a 100644 --- a/src/Models/Operations/GetTokenByPinIdRequest.php +++ b/src/Models/Operations/GetTokenByPinIdRequest.php @@ -22,10 +22,10 @@ class GetTokenByPinIdRequest /** * An opaque identifier unique to the client (UUID, serial number, or other unique device ID) * - * @var ?string $clientID + * @var string $clientID */ #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Client-Identifier')] - public ?string $clientID = null; + public string $clientID; /** * The name of the client application. (Plex Web, Plex Media Server, etc.) @@ -61,13 +61,13 @@ class GetTokenByPinIdRequest /** * @param int $pinID - * @param ?string $clientID + * @param string $clientID * @param ?string $clientName * @param ?string $deviceNickname * @param ?string $clientVersion * @param ?string $platform */ - public function __construct(int $pinID, ?string $clientID = null, ?string $clientName = null, ?string $deviceNickname = null, ?string $clientVersion = null, ?string $platform = null) + public function __construct(int $pinID, string $clientID, ?string $clientName = null, ?string $deviceNickname = null, ?string $clientVersion = null, ?string $platform = null) { $this->pinID = $pinID; $this->clientID = $clientID; diff --git a/src/Models/Operations/GetTokenDetailsSubscription.php b/src/Models/Operations/GetTokenDetailsSubscription.php index 1ecdc74..0f6279d 100644 --- a/src/Models/Operations/GetTokenDetailsSubscription.php +++ b/src/Models/Operations/GetTokenDetailsSubscription.php @@ -30,15 +30,6 @@ class GetTokenDetailsSubscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $active = null; - /** - * Date the account subscribed to Plex Pass - * - * @var ?string $subscribedAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $subscribedAt = null; - /** * String representation of subscriptionActive * @@ -49,6 +40,15 @@ class GetTokenDetailsSubscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?GetTokenDetailsAuthenticationResponseStatus $status = null; + /** + * Date the account subscribed to Plex Pass + * + * @var ?string $subscribedAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $subscribedAt = null; + /** * Payment service used for your Plex Pass subscription * diff --git a/src/Models/Operations/GetTokenDetailsUserPlexAccount.php b/src/Models/Operations/GetTokenDetailsUserPlexAccount.php index 10ca2a3..47a405c 100644 --- a/src/Models/Operations/GetTokenDetailsUserPlexAccount.php +++ b/src/Models/Operations/GetTokenDetailsUserPlexAccount.php @@ -13,206 +13,199 @@ class GetTokenDetailsUserPlexAccount { /** - * Unknown + * The account token * - * @var ?bool $adsConsent + * @var string $authToken */ - #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsent')] - public ?bool $adsConsent; + #[\Speakeasy\Serializer\Annotation\SerializedName('authToken')] + public string $authToken; /** + * The account country * - * @var ?int $adsConsentReminderAt + * @var string $country */ - #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentReminderAt')] - public ?int $adsConsentReminderAt; + #[\Speakeasy\Serializer\Annotation\SerializedName('country')] + public string $country; /** + * The account email address * - * @var ?int $adsConsentSetAt + * @var string $email */ - #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentSetAt')] - public ?int $adsConsentSetAt; + #[\Speakeasy\Serializer\Annotation\SerializedName('email')] + public string $email; /** - * Unknown + * Your account full name * - * @var ?bool $anonymous + * @var string $friendlyName */ - #[\Speakeasy\Serializer\Annotation\SerializedName('anonymous')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $anonymous = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('friendlyName')] + public string $friendlyName; /** - * The account token + * List of devices your allowed to use with this account * - * @var string $authToken + * @var array $entitlements */ - #[\Speakeasy\Serializer\Annotation\SerializedName('authToken')] - public string $authToken; + #[\Speakeasy\Serializer\Annotation\SerializedName('entitlements')] + #[\Speakeasy\Serializer\Annotation\Type('array')] + public array $entitlements; /** - * If the two-factor authentication backup codes have been created + * The number of accounts in the Plex Home * - * @var ?bool $backupCodesCreated + * @var int $homeSize */ - #[\Speakeasy\Serializer\Annotation\SerializedName('backupCodesCreated')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $backupCodesCreated = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('homeSize')] + public int $homeSize; /** - * If the account has been confirmed + * The Plex account ID * - * @var ?bool $confirmed + * @var int $id */ - #[\Speakeasy\Serializer\Annotation\SerializedName('confirmed')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $confirmed = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('id')] + public int $id; /** - * The account country + * Unix epoch datetime in seconds * - * @var string $country + * @var int $joinedAt */ - #[\Speakeasy\Serializer\Annotation\SerializedName('country')] - public string $country; + #[\Speakeasy\Serializer\Annotation\SerializedName('joinedAt')] + public int $joinedAt; /** - * The account email address + * Your current mailing list status (active or unsubscribed) * - * @var string $email + * @var MailingListStatus $mailingListStatus */ - #[\Speakeasy\Serializer\Annotation\SerializedName('email')] - public string $email; + #[\Speakeasy\Serializer\Annotation\SerializedName('mailingListStatus')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\MailingListStatus')] + public MailingListStatus $mailingListStatus; /** - * If login with email only is enabled + * The maximum number of accounts allowed in the Plex Home * - * @var ?bool $emailOnlyAuth + * @var int $maxHomeSize */ - #[\Speakeasy\Serializer\Annotation\SerializedName('emailOnlyAuth')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $emailOnlyAuth = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('maxHomeSize')] + public int $maxHomeSize; /** - * If experimental features are enabled * - * @var ?bool $experimentalFeatures + * @var UserProfile $profile */ - #[\Speakeasy\Serializer\Annotation\SerializedName('experimentalFeatures')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $experimentalFeatures = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('profile')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\UserProfile')] + public UserProfile $profile; /** - * Your account full name + * Unix epoch datetime in seconds * - * @var string $friendlyName + * @var int $rememberExpiresAt */ - #[\Speakeasy\Serializer\Annotation\SerializedName('friendlyName')] - public string $friendlyName; + #[\Speakeasy\Serializer\Annotation\SerializedName('rememberExpiresAt')] + public int $rememberExpiresAt; /** - * List of devices your allowed to use with this account + * Unknown * - * @var array $entitlements + * @var string $scrobbleTypes */ - #[\Speakeasy\Serializer\Annotation\SerializedName('entitlements')] - #[\Speakeasy\Serializer\Annotation\Type('array')] - public array $entitlements; + #[\Speakeasy\Serializer\Annotation\SerializedName('scrobbleTypes')] + public string $scrobbleTypes; /** - * If the account is a Plex Home guest user + * $services * - * @var ?bool $guest + * @var array $services */ - #[\Speakeasy\Serializer\Annotation\SerializedName('guest')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $guest = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('services')] + #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\Services>')] + public array $services; /** - * If the account has a password + * If the account’s Plex Pass subscription is active * - * @var ?bool $hasPassword + * @var Subscription $subscription */ - #[\Speakeasy\Serializer\Annotation\SerializedName('hasPassword')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $hasPassword = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('subscription')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\Subscription')] + public Subscription $subscription; /** - * If the account is a Plex Home user + * $subscriptions * - * @var ?bool $home + * @var array $subscriptions */ - #[\Speakeasy\Serializer\Annotation\SerializedName('home')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $home = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('subscriptions')] + #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetTokenDetailsSubscription>')] + public array $subscriptions; /** - * If the account is the Plex Home admin + * URL of the account thumbnail * - * @var ?bool $homeAdmin + * @var string $thumb */ - #[\Speakeasy\Serializer\Annotation\SerializedName('homeAdmin')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $homeAdmin = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('thumb')] + public string $thumb; /** - * The number of accounts in the Plex Home + * The title of the account (username or friendly name) * - * @var int $homeSize + * @var string $title */ - #[\Speakeasy\Serializer\Annotation\SerializedName('homeSize')] - public int $homeSize; + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; /** - * The Plex account ID + * The account username * - * @var int $id + * @var string $username */ - #[\Speakeasy\Serializer\Annotation\SerializedName('id')] - public int $id; + #[\Speakeasy\Serializer\Annotation\SerializedName('username')] + public string $username; /** - * Unix epoch datetime in seconds + * The account UUID * - * @var int $joinedAt + * @var string $uuid */ - #[\Speakeasy\Serializer\Annotation\SerializedName('joinedAt')] - public int $joinedAt; + #[\Speakeasy\Serializer\Annotation\SerializedName('uuid')] + public string $uuid; /** - * The account locale + * Unknown * - * @var ?string $locale + * @var ?bool $adsConsent */ - #[\Speakeasy\Serializer\Annotation\SerializedName('locale')] - public ?string $locale; + #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsent')] + public ?bool $adsConsent; /** - * If you are subscribed to the Plex newsletter * - * @var ?bool $mailingListActive + * @var ?int $adsConsentReminderAt */ - #[\Speakeasy\Serializer\Annotation\SerializedName('mailingListActive')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $mailingListActive = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentReminderAt')] + public ?int $adsConsentReminderAt; /** - * Your current mailing list status (active or unsubscribed) * - * @var MailingListStatus $mailingListStatus + * @var ?int $adsConsentSetAt */ - #[\Speakeasy\Serializer\Annotation\SerializedName('mailingListStatus')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\MailingListStatus')] - public MailingListStatus $mailingListStatus; + #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentSetAt')] + public ?int $adsConsentSetAt; /** - * The maximum number of accounts allowed in the Plex Home + * The account locale * - * @var int $maxHomeSize + * @var ?string $locale */ - #[\Speakeasy\Serializer\Annotation\SerializedName('maxHomeSize')] - public int $maxHomeSize; + #[\Speakeasy\Serializer\Annotation\SerializedName('locale')] + public ?string $locale; /** * [Might be removed] The hashed Plex Home PIN @@ -225,139 +218,146 @@ class GetTokenDetailsUserPlexAccount public ?string $pin = null; /** + * [Might be removed] List of account roles. Plexpass membership listed here * - * @var UserProfile $profile + * @var ?array $roles */ - #[\Speakeasy\Serializer\Annotation\SerializedName('profile')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\UserProfile')] - public UserProfile $profile; + #[\Speakeasy\Serializer\Annotation\SerializedName('roles')] + #[\Speakeasy\Serializer\Annotation\Type('array|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?array $roles = null; /** - * If the account has a Plex Home PIN enabled + * Description of the Plex Pass subscription * - * @var ?bool $protected + * @var ?string $subscriptionDescription */ - #[\Speakeasy\Serializer\Annotation\SerializedName('protected')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $protected = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('subscriptionDescription')] + public ?string $subscriptionDescription; /** - * Unix epoch datetime in seconds * - * @var int $rememberExpiresAt + * @var ?string $attributionPartner */ - #[\Speakeasy\Serializer\Annotation\SerializedName('rememberExpiresAt')] - public int $rememberExpiresAt; + #[\Speakeasy\Serializer\Annotation\SerializedName('attributionPartner')] + public ?string $attributionPartner; /** - * If the account is a Plex Home managed user + * If the two-factor authentication backup codes have been created * - * @var ?bool $restricted + * @var ?bool $backupCodesCreated */ - #[\Speakeasy\Serializer\Annotation\SerializedName('restricted')] + #[\Speakeasy\Serializer\Annotation\SerializedName('backupCodesCreated')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $restricted = null; + public ?bool $backupCodesCreated = null; /** - * [Might be removed] List of account roles. Plexpass membership listed here + * If the account has been confirmed * - * @var ?array $roles + * @var ?bool $confirmed */ - #[\Speakeasy\Serializer\Annotation\SerializedName('roles')] - #[\Speakeasy\Serializer\Annotation\Type('array|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('confirmed')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?array $roles = null; + public ?bool $confirmed = null; /** - * Unknown + * If login with email only is enabled * - * @var string $scrobbleTypes + * @var ?bool $emailOnlyAuth */ - #[\Speakeasy\Serializer\Annotation\SerializedName('scrobbleTypes')] - public string $scrobbleTypes; + #[\Speakeasy\Serializer\Annotation\SerializedName('emailOnlyAuth')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $emailOnlyAuth = null; /** - * $services + * If experimental features are enabled * - * @var array $services + * @var ?bool $experimentalFeatures */ - #[\Speakeasy\Serializer\Annotation\SerializedName('services')] - #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\Services>')] - public array $services; + #[\Speakeasy\Serializer\Annotation\SerializedName('experimentalFeatures')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $experimentalFeatures = null; /** - * If the account’s Plex Pass subscription is active + * If the account is a Plex Home guest user * - * @var Subscription $subscription + * @var ?bool $guest */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscription')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\Subscription')] - public Subscription $subscription; + #[\Speakeasy\Serializer\Annotation\SerializedName('guest')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $guest = null; /** - * Description of the Plex Pass subscription + * If the account has a password * - * @var ?string $subscriptionDescription + * @var ?bool $hasPassword */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscriptionDescription')] - public ?string $subscriptionDescription; + #[\Speakeasy\Serializer\Annotation\SerializedName('hasPassword')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $hasPassword = null; /** - * $subscriptions + * If the account is a Plex Home user * - * @var array $subscriptions + * @var ?bool $home */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscriptions')] - #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\GetTokenDetailsSubscription>')] - public array $subscriptions; + #[\Speakeasy\Serializer\Annotation\SerializedName('home')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $home = null; /** - * URL of the account thumbnail + * If the account is the Plex Home admin * - * @var string $thumb + * @var ?bool $homeAdmin */ - #[\Speakeasy\Serializer\Annotation\SerializedName('thumb')] - public string $thumb; + #[\Speakeasy\Serializer\Annotation\SerializedName('homeAdmin')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $homeAdmin = null; /** - * The title of the account (username or friendly name) + * If you are subscribed to the Plex newsletter * - * @var string $title + * @var ?bool $mailingListActive */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; + #[\Speakeasy\Serializer\Annotation\SerializedName('mailingListActive')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $mailingListActive = null; /** - * If two-factor authentication is enabled + * If the account has a Plex Home PIN enabled * - * @var ?bool $twoFactorEnabled + * @var ?bool $protected */ - #[\Speakeasy\Serializer\Annotation\SerializedName('twoFactorEnabled')] + #[\Speakeasy\Serializer\Annotation\SerializedName('protected')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $twoFactorEnabled = null; + public ?bool $protected = null; /** - * The account username + * If the account is a Plex Home managed user * - * @var string $username + * @var ?bool $restricted */ - #[\Speakeasy\Serializer\Annotation\SerializedName('username')] - public string $username; + #[\Speakeasy\Serializer\Annotation\SerializedName('restricted')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $restricted = null; /** - * The account UUID + * If two-factor authentication is enabled * - * @var string $uuid + * @var ?bool $twoFactorEnabled */ - #[\Speakeasy\Serializer\Annotation\SerializedName('uuid')] - public string $uuid; + #[\Speakeasy\Serializer\Annotation\SerializedName('twoFactorEnabled')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $twoFactorEnabled = null; /** + * Unknown * - * @var ?string $attributionPartner + * @var ?bool $anonymous */ - #[\Speakeasy\Serializer\Annotation\SerializedName('attributionPartner')] - public ?string $attributionPartner; + #[\Speakeasy\Serializer\Annotation\SerializedName('anonymous')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $anonymous = null; /** * @param string $authToken @@ -427,6 +427,11 @@ public function __construct(string $authToken, string $country, string $email, s $this->adsConsent = $adsConsent; $this->adsConsentReminderAt = $adsConsentReminderAt; $this->adsConsentSetAt = $adsConsentSetAt; + $this->locale = $locale; + $this->pin = $pin; + $this->roles = $roles; + $this->subscriptionDescription = $subscriptionDescription; + $this->attributionPartner = $attributionPartner; $this->backupCodesCreated = $backupCodesCreated; $this->confirmed = $confirmed; $this->emailOnlyAuth = $emailOnlyAuth; @@ -435,15 +440,10 @@ public function __construct(string $authToken, string $country, string $email, s $this->hasPassword = $hasPassword; $this->home = $home; $this->homeAdmin = $homeAdmin; - $this->locale = $locale; $this->mailingListActive = $mailingListActive; - $this->pin = $pin; $this->protected = $protected; $this->restricted = $restricted; - $this->roles = $roles; - $this->subscriptionDescription = $subscriptionDescription; $this->twoFactorEnabled = $twoFactorEnabled; - $this->attributionPartner = $attributionPartner; $this->anonymous = $anonymous; } } \ No newline at end of file diff --git a/src/Models/Operations/GetTopWatchedContentQueryParamType.php b/src/Models/Operations/GetTopWatchedContentQueryParamType.php index 5a35a0e..4ab19e1 100644 --- a/src/Models/Operations/GetTopWatchedContentQueryParamType.php +++ b/src/Models/Operations/GetTopWatchedContentQueryParamType.php @@ -26,4 +26,6 @@ enum GetTopWatchedContentQueryParamType: int case Season = 3; case Episode = 4; case Audio = 8; + case Album = 9; + case Track = 10; } diff --git a/src/Models/Operations/GetWatchListRequest.php b/src/Models/Operations/GetWatchListRequest.php index dcb7c89..c44a42c 100644 --- a/src/Models/Operations/GetWatchListRequest.php +++ b/src/Models/Operations/GetWatchListRequest.php @@ -19,6 +19,14 @@ class GetWatchListRequest #[SpeakeasyMetadata('pathParam:style=simple,explode=false,name=filter')] public Filter $filter; + /** + * An authentication token, obtained from plex.tv + * + * @var string $xPlexToken + */ + #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Token')] + public string $xPlexToken; + /** * In the format "field:dir". Available fields are "watchlistedAt" (Added At), * @@ -96,14 +104,6 @@ class GetWatchListRequest #[SpeakeasyMetadata('queryParam:style=form,explode=true,name=X-Plex-Container-Size')] public ?int $xPlexContainerSize = null; - /** - * An authentication token, obtained from plex.tv - * - * @var string $xPlexToken - */ - #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Token')] - public string $xPlexToken; - /** * @param Filter $filter * @param string $xPlexToken diff --git a/src/Models/Operations/Media.php b/src/Models/Operations/Media.php index c25dd47..67c5492 100644 --- a/src/Models/Operations/Media.php +++ b/src/Models/Operations/Media.php @@ -18,6 +18,22 @@ class Media #[\Speakeasy\Serializer\Annotation\SerializedName('id')] public int $id; + /** + * + * @var string $container + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('container')] + public string $container; + + /** + * $part + * + * @var array $part + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('Part')] + #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\Part>')] + public array $part; + /** * * @var ?int $duration @@ -98,13 +114,6 @@ class Media #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $videoResolution = null; - /** - * - * @var string $container - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('container')] - public string $container; - /** * * @var ?string $videoFrameRate @@ -129,15 +138,6 @@ class Media #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $hasVoiceActivity = null; - /** - * - * @var ?OptimizedForStreaming $optimizedForStreaming - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('optimizedForStreaming')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\OptimizedForStreaming|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?OptimizedForStreaming $optimizedForStreaming = null; - /** * * @var ?bool $has64bitOffsets @@ -147,13 +147,13 @@ class Media public ?bool $has64bitOffsets = null; /** - * $part * - * @var array $part + * @var ?OptimizedForStreaming $optimizedForStreaming */ - #[\Speakeasy\Serializer\Annotation\SerializedName('Part')] - #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\Part>')] - public array $part; + #[\Speakeasy\Serializer\Annotation\SerializedName('optimizedForStreaming')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\OptimizedForStreaming|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?OptimizedForStreaming $optimizedForStreaming = null; /** * @param int $id @@ -193,7 +193,7 @@ public function __construct(int $id, string $container, array $part, ?int $durat $this->videoFrameRate = $videoFrameRate; $this->videoProfile = $videoProfile; $this->hasVoiceActivity = $hasVoiceActivity; - $this->optimizedForStreaming = $optimizedForStreaming; $this->has64bitOffsets = $has64bitOffsets; + $this->optimizedForStreaming = $optimizedForStreaming; } } \ No newline at end of file diff --git a/src/Models/Operations/Part.php b/src/Models/Operations/Part.php index c25695d..da3b499 100644 --- a/src/Models/Operations/Part.php +++ b/src/Models/Operations/Part.php @@ -25,14 +25,6 @@ class Part #[\Speakeasy\Serializer\Annotation\SerializedName('key')] public string $key; - /** - * - * @var ?int $duration - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('duration')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?int $duration = null; - /** * * @var string $file @@ -57,6 +49,14 @@ class Part #[\Speakeasy\Serializer\Annotation\SerializedName('container')] public string $container; + /** + * + * @var ?int $duration + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('duration')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?int $duration = null; + /** * * @var ?string $audioProfile @@ -97,15 +97,6 @@ class Part #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?string $indexes = null; - /** - * - * @var ?HasThumbnail $hasThumbnail - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('hasThumbnail')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\HasThumbnail|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?HasThumbnail $hasThumbnail = null; - /** * $stream * @@ -116,6 +107,15 @@ class Part #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?array $stream = null; + /** + * + * @var ?HasThumbnail $hasThumbnail + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('hasThumbnail')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\HasThumbnail|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?HasThumbnail $hasThumbnail = null; + /** * @param int $id * @param string $key @@ -144,7 +144,7 @@ public function __construct(int $id, string $key, string $file, int $size, strin $this->optimizedForStreaming = $optimizedForStreaming; $this->videoProfile = $videoProfile; $this->indexes = $indexes; - $this->hasThumbnail = $hasThumbnail; $this->stream = $stream; + $this->hasThumbnail = $hasThumbnail; } } \ No newline at end of file diff --git a/src/Models/Operations/PastSubscription.php b/src/Models/Operations/PastSubscription.php index ecdef6a..9beb2c6 100644 --- a/src/Models/Operations/PastSubscription.php +++ b/src/Models/Operations/PastSubscription.php @@ -11,6 +11,29 @@ class PastSubscription { + /** + * + * @var string $type + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('type')] + public string $type; + + /** + * + * @var PostUsersSignInDataState $state + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('state')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataState')] + public PostUsersSignInDataState $state; + + /** + * + * @var Billing $billing + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('billing')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\Billing')] + public Billing $billing; + /** * * @var ?string $id @@ -39,6 +62,13 @@ class PastSubscription #[\Speakeasy\Serializer\Annotation\SerializedName('endsAt')] public ?int $endsAt; + /** + * + * @var ?string $transfer + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('transfer')] + public ?string $transfer; + /** * * @var ?bool $canceled @@ -95,36 +125,6 @@ class PastSubscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $canConvert = null; - /** - * - * @var string $type - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('type')] - public string $type; - - /** - * - * @var ?string $transfer - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('transfer')] - public ?string $transfer; - - /** - * - * @var PostUsersSignInDataState $state - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('state')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataState')] - public PostUsersSignInDataState $state; - - /** - * - * @var Billing $billing - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('billing')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\Billing')] - public Billing $billing; - /** * @param string $type * @param PostUsersSignInDataState $state @@ -151,6 +151,7 @@ public function __construct(string $type, PostUsersSignInDataState $state, Billi $this->mode = $mode; $this->renewsAt = $renewsAt; $this->endsAt = $endsAt; + $this->transfer = $transfer; $this->canceled = $canceled; $this->gracePeriod = $gracePeriod; $this->onHold = $onHold; @@ -158,6 +159,5 @@ public function __construct(string $type, PostUsersSignInDataState $state, Billi $this->canUpgrade = $canUpgrade; $this->canDowngrade = $canDowngrade; $this->canConvert = $canConvert; - $this->transfer = $transfer; } } \ No newline at end of file diff --git a/src/Models/Operations/PlexDevice.php b/src/Models/Operations/PlexDevice.php index de17bea..997d82b 100644 --- a/src/Models/Operations/PlexDevice.php +++ b/src/Models/Operations/PlexDevice.php @@ -32,27 +32,6 @@ class PlexDevice #[\Speakeasy\Serializer\Annotation\SerializedName('productVersion')] public string $productVersion; - /** - * - * @var ?string $platform - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('platform')] - public ?string $platform; - - /** - * - * @var ?string $platformVersion - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('platformVersion')] - public ?string $platformVersion; - - /** - * - * @var ?string $device - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('device')] - public ?string $device; - /** * * @var string $clientIdentifier @@ -81,21 +60,6 @@ class PlexDevice #[\Speakeasy\Serializer\Annotation\SerializedName('provides')] public string $provides; - /** - * ownerId is null when the device is owned by the token used to send the request - * - * @var ?int $ownerId - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('ownerId')] - public ?int $ownerId; - - /** - * - * @var ?string $sourceTitle - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('sourceTitle')] - public ?string $sourceTitle; - /** * * @var string $publicAddress @@ -182,6 +146,42 @@ class PlexDevice #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\Connections>')] public array $connections; + /** + * + * @var ?string $platform + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('platform')] + public ?string $platform; + + /** + * + * @var ?string $platformVersion + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('platformVersion')] + public ?string $platformVersion; + + /** + * + * @var ?string $device + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('device')] + public ?string $device; + + /** + * ownerId is null when the device is owned by the token used to send the request + * + * @var ?int $ownerId + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('ownerId')] + public ?int $ownerId; + + /** + * + * @var ?string $sourceTitle + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('sourceTitle')] + public ?string $sourceTitle; + /** * @param string $name * @param string $product diff --git a/src/Models/Operations/PostUsersSignInDataAuthenticationSubscription.php b/src/Models/Operations/PostUsersSignInDataAuthenticationSubscription.php index 78eaf64..cb51447 100644 --- a/src/Models/Operations/PostUsersSignInDataAuthenticationSubscription.php +++ b/src/Models/Operations/PostUsersSignInDataAuthenticationSubscription.php @@ -30,15 +30,6 @@ class PostUsersSignInDataAuthenticationSubscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $active = null; - /** - * Date the account subscribed to Plex Pass - * - * @var ?string $subscribedAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $subscribedAt = null; - /** * String representation of subscriptionActive * @@ -49,6 +40,15 @@ class PostUsersSignInDataAuthenticationSubscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?PostUsersSignInDataAuthenticationResponseStatus $status = null; + /** + * Date the account subscribed to Plex Pass + * + * @var ?string $subscribedAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $subscribedAt = null; + /** * Payment service used for your Plex Pass subscription * diff --git a/src/Models/Operations/PostUsersSignInDataRequest.php b/src/Models/Operations/PostUsersSignInDataRequest.php index 36953f8..93c0740 100644 --- a/src/Models/Operations/PostUsersSignInDataRequest.php +++ b/src/Models/Operations/PostUsersSignInDataRequest.php @@ -14,10 +14,10 @@ class PostUsersSignInDataRequest /** * An opaque identifier unique to the client (UUID, serial number, or other unique device ID) * - * @var ?string $clientID + * @var string $clientID */ #[SpeakeasyMetadata('header:style=simple,explode=false,name=X-Plex-Client-Identifier')] - public ?string $clientID = null; + public string $clientID; /** * The name of the client application. (Plex Web, Plex Media Server, etc.) @@ -60,14 +60,14 @@ class PostUsersSignInDataRequest public ?PostUsersSignInDataRequestBody $requestBody = null; /** - * @param ?string $clientID + * @param string $clientID * @param ?string $clientName * @param ?string $deviceNickname * @param ?string $clientVersion * @param ?string $platform * @param ?PostUsersSignInDataRequestBody $requestBody */ - public function __construct(?string $clientID = null, ?string $clientName = null, ?string $deviceNickname = null, ?string $clientVersion = null, ?string $platform = null, ?PostUsersSignInDataRequestBody $requestBody = null) + public function __construct(string $clientID, ?string $clientName = null, ?string $deviceNickname = null, ?string $clientVersion = null, ?string $platform = null, ?PostUsersSignInDataRequestBody $requestBody = null) { $this->clientID = $clientID; $this->clientName = $clientName; diff --git a/src/Models/Operations/PostUsersSignInDataRequestBody.php b/src/Models/Operations/PostUsersSignInDataRequestBody.php index d8c201b..3865d33 100644 --- a/src/Models/Operations/PostUsersSignInDataRequestBody.php +++ b/src/Models/Operations/PostUsersSignInDataRequestBody.php @@ -28,17 +28,17 @@ class PostUsersSignInDataRequestBody /** * - * @var ?bool $rememberMe + * @var ?string $verificationCode */ - #[SpeakeasyMetadata('form:name=rememberMe')] - public ?bool $rememberMe = null; + #[SpeakeasyMetadata('form:name=verificationCode')] + public ?string $verificationCode = null; /** * - * @var ?string $verificationCode + * @var ?bool $rememberMe */ - #[SpeakeasyMetadata('form:name=verificationCode')] - public ?string $verificationCode = null; + #[SpeakeasyMetadata('form:name=rememberMe')] + public ?bool $rememberMe = null; /** * @param string $login @@ -50,7 +50,7 @@ public function __construct(string $login, string $password, ?string $verificati { $this->login = $login; $this->password = $password; - $this->rememberMe = $rememberMe; $this->verificationCode = $verificationCode; + $this->rememberMe = $rememberMe; } } \ No newline at end of file diff --git a/src/Models/Operations/PostUsersSignInDataServices.php b/src/Models/Operations/PostUsersSignInDataServices.php index 0dea5fd..93ff6de 100644 --- a/src/Models/Operations/PostUsersSignInDataServices.php +++ b/src/Models/Operations/PostUsersSignInDataServices.php @@ -25,6 +25,14 @@ class PostUsersSignInDataServices #[\Speakeasy\Serializer\Annotation\SerializedName('endpoint')] public string $endpoint; + /** + * + * @var PostUsersSignInDataStatus $status + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('status')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataStatus')] + public PostUsersSignInDataStatus $status; + /** * * @var ?string $token @@ -39,14 +47,6 @@ class PostUsersSignInDataServices #[\Speakeasy\Serializer\Annotation\SerializedName('secret')] public ?string $secret; - /** - * - * @var PostUsersSignInDataStatus $status - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('status')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataStatus')] - public PostUsersSignInDataStatus $status; - /** * @param string $identifier * @param string $endpoint diff --git a/src/Models/Operations/PostUsersSignInDataSubscription.php b/src/Models/Operations/PostUsersSignInDataSubscription.php index 8728110..bcd032e 100644 --- a/src/Models/Operations/PostUsersSignInDataSubscription.php +++ b/src/Models/Operations/PostUsersSignInDataSubscription.php @@ -31,15 +31,6 @@ class PostUsersSignInDataSubscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $active = null; - /** - * Date the account subscribed to Plex Pass - * - * @var ?string $subscribedAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $subscribedAt = null; - /** * String representation of subscriptionActive * @@ -50,6 +41,15 @@ class PostUsersSignInDataSubscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?PostUsersSignInDataAuthenticationStatus $status = null; + /** + * Date the account subscribed to Plex Pass + * + * @var ?string $subscribedAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $subscribedAt = null; + /** * Payment service used for your Plex Pass subscription * diff --git a/src/Models/Operations/PostUsersSignInDataUserPlexAccount.php b/src/Models/Operations/PostUsersSignInDataUserPlexAccount.php index 6425d63..16f9623 100644 --- a/src/Models/Operations/PostUsersSignInDataUserPlexAccount.php +++ b/src/Models/Operations/PostUsersSignInDataUserPlexAccount.php @@ -12,37 +12,6 @@ /** PostUsersSignInDataUserPlexAccount - Returns the user account data with a valid auth token */ class PostUsersSignInDataUserPlexAccount { - /** - * Unknown - * - * @var ?bool $adsConsent - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsent')] - public ?bool $adsConsent; - - /** - * - * @var ?int $adsConsentReminderAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentReminderAt')] - public ?int $adsConsentReminderAt; - - /** - * - * @var ?int $adsConsentSetAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentSetAt')] - public ?int $adsConsentSetAt; - - /** - * Unknown - * - * @var ?bool $anonymous - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('anonymous')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $anonymous = null; - /** * The account token * @@ -51,24 +20,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\SerializedName('authToken')] public string $authToken; - /** - * If the two-factor authentication backup codes have been created - * - * @var ?bool $backupCodesCreated - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('backupCodesCreated')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $backupCodesCreated = null; - - /** - * If the account has been confirmed - * - * @var ?bool $confirmed - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('confirmed')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $confirmed = null; - /** * The account country * @@ -85,24 +36,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\SerializedName('email')] public string $email; - /** - * If login with email only is enabled - * - * @var ?bool $emailOnlyAuth - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('emailOnlyAuth')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $emailOnlyAuth = null; - - /** - * If experimental features are enabled - * - * @var ?bool $experimentalFeatures - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('experimentalFeatures')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $experimentalFeatures = null; - /** * Your account full name * @@ -120,42 +53,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\Type('array')] public array $entitlements; - /** - * If the account is a Plex Home guest user - * - * @var ?bool $guest - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('guest')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $guest = null; - - /** - * If the account has a password - * - * @var ?bool $hasPassword - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('hasPassword')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $hasPassword = null; - - /** - * If the account is a Plex Home user - * - * @var ?bool $home - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('home')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $home = null; - - /** - * If the account is the Plex Home admin - * - * @var ?bool $homeAdmin - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('homeAdmin')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $homeAdmin = null; - /** * The number of accounts in the Plex Home * @@ -180,23 +77,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\SerializedName('joinedAt')] public int $joinedAt; - /** - * The account locale - * - * @var ?string $locale - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('locale')] - public ?string $locale; - - /** - * If you are subscribed to the Plex newsletter - * - * @var ?bool $mailingListActive - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('mailingListActive')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $mailingListActive = null; - /** * Your current mailing list status (active or unsubscribed) * @@ -214,16 +94,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\SerializedName('maxHomeSize')] public int $maxHomeSize; - /** - * [Might be removed] The hashed Plex Home PIN - * - * @var ?string $pin - * @deprecated field: This will be removed in a future release, please migrate away from it as soon as possible. - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('pin')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $pin = null; - /** * * @var PostUsersSignInDataUserProfile $profile @@ -232,15 +102,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataUserProfile')] public PostUsersSignInDataUserProfile $profile; - /** - * If the account has a Plex Home PIN enabled - * - * @var ?bool $protected - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('protected')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $protected = null; - /** * Unix epoch datetime in seconds * @@ -249,25 +110,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\SerializedName('rememberExpiresAt')] public int $rememberExpiresAt; - /** - * If the account is a Plex Home managed user - * - * @var ?bool $restricted - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('restricted')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $restricted = null; - - /** - * [Might be removed] List of account roles. Plexpass membership listed here - * - * @var ?array $roles - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('roles')] - #[\Speakeasy\Serializer\Annotation\Type('array|null')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?array $roles = null; - /** * Unknown * @@ -294,14 +136,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\PostUsersSignInDataSubscription')] public PostUsersSignInDataSubscription $subscription; - /** - * Description of the Plex Pass subscription - * - * @var ?string $subscriptionDescription - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscriptionDescription')] - public ?string $subscriptionDescription; - /** * $subscriptions * @@ -327,15 +161,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\SerializedName('title')] public string $title; - /** - * If two-factor authentication is enabled - * - * @var ?bool $twoFactorEnabled - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('twoFactorEnabled')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $twoFactorEnabled = null; - /** * The account username * @@ -352,13 +177,6 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\SerializedName('uuid')] public string $uuid; - /** - * - * @var ?string $attributionPartner - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('attributionPartner')] - public ?string $attributionPartner; - /** * $pastSubscriptions * @@ -377,6 +195,188 @@ class PostUsersSignInDataUserPlexAccount #[\Speakeasy\Serializer\Annotation\Type('array<\LukeHagar\Plex_API\Models\Operations\Trials>')] public array $trials; + /** + * Unknown + * + * @var ?bool $adsConsent + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsent')] + public ?bool $adsConsent; + + /** + * + * @var ?int $adsConsentReminderAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentReminderAt')] + public ?int $adsConsentReminderAt; + + /** + * + * @var ?int $adsConsentSetAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('adsConsentSetAt')] + public ?int $adsConsentSetAt; + + /** + * The account locale + * + * @var ?string $locale + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('locale')] + public ?string $locale; + + /** + * [Might be removed] The hashed Plex Home PIN + * + * @var ?string $pin + * @deprecated field: This will be removed in a future release, please migrate away from it as soon as possible. + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('pin')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $pin = null; + + /** + * [Might be removed] List of account roles. Plexpass membership listed here + * + * @var ?array $roles + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('roles')] + #[\Speakeasy\Serializer\Annotation\Type('array|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?array $roles = null; + + /** + * Description of the Plex Pass subscription + * + * @var ?string $subscriptionDescription + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subscriptionDescription')] + public ?string $subscriptionDescription; + + /** + * + * @var ?string $attributionPartner + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('attributionPartner')] + public ?string $attributionPartner; + + /** + * If the two-factor authentication backup codes have been created + * + * @var ?bool $backupCodesCreated + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('backupCodesCreated')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $backupCodesCreated = null; + + /** + * If the account has been confirmed + * + * @var ?bool $confirmed + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('confirmed')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $confirmed = null; + + /** + * If login with email only is enabled + * + * @var ?bool $emailOnlyAuth + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('emailOnlyAuth')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $emailOnlyAuth = null; + + /** + * If experimental features are enabled + * + * @var ?bool $experimentalFeatures + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('experimentalFeatures')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $experimentalFeatures = null; + + /** + * If the account is a Plex Home guest user + * + * @var ?bool $guest + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('guest')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $guest = null; + + /** + * If the account has a password + * + * @var ?bool $hasPassword + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('hasPassword')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $hasPassword = null; + + /** + * If the account is a Plex Home user + * + * @var ?bool $home + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('home')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $home = null; + + /** + * If the account is the Plex Home admin + * + * @var ?bool $homeAdmin + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('homeAdmin')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $homeAdmin = null; + + /** + * If you are subscribed to the Plex newsletter + * + * @var ?bool $mailingListActive + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('mailingListActive')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $mailingListActive = null; + + /** + * If the account has a Plex Home PIN enabled + * + * @var ?bool $protected + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('protected')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $protected = null; + + /** + * If the account is a Plex Home managed user + * + * @var ?bool $restricted + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('restricted')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $restricted = null; + + /** + * If two-factor authentication is enabled + * + * @var ?bool $twoFactorEnabled + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('twoFactorEnabled')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $twoFactorEnabled = null; + + /** + * Unknown + * + * @var ?bool $anonymous + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('anonymous')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $anonymous = null; + /** * @param string $authToken * @param string $country @@ -449,6 +449,11 @@ public function __construct(string $authToken, string $country, string $email, s $this->adsConsent = $adsConsent; $this->adsConsentReminderAt = $adsConsentReminderAt; $this->adsConsentSetAt = $adsConsentSetAt; + $this->locale = $locale; + $this->pin = $pin; + $this->roles = $roles; + $this->subscriptionDescription = $subscriptionDescription; + $this->attributionPartner = $attributionPartner; $this->backupCodesCreated = $backupCodesCreated; $this->confirmed = $confirmed; $this->emailOnlyAuth = $emailOnlyAuth; @@ -457,15 +462,10 @@ public function __construct(string $authToken, string $country, string $email, s $this->hasPassword = $hasPassword; $this->home = $home; $this->homeAdmin = $homeAdmin; - $this->locale = $locale; $this->mailingListActive = $mailingListActive; - $this->pin = $pin; $this->protected = $protected; $this->restricted = $restricted; - $this->roles = $roles; - $this->subscriptionDescription = $subscriptionDescription; $this->twoFactorEnabled = $twoFactorEnabled; - $this->attributionPartner = $attributionPartner; $this->anonymous = $anonymous; } } \ No newline at end of file diff --git a/src/Models/Operations/PostUsersSignInDataUserProfile.php b/src/Models/Operations/PostUsersSignInDataUserProfile.php index 162b4e8..1e09383 100644 --- a/src/Models/Operations/PostUsersSignInDataUserProfile.php +++ b/src/Models/Operations/PostUsersSignInDataUserProfile.php @@ -11,15 +11,6 @@ class PostUsersSignInDataUserProfile { - /** - * If the account has automatically select audio and subtitle tracks enabled - * - * @var ?bool $autoSelectAudio - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('autoSelectAudio')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $autoSelectAudio = null; - /** * The preferred audio language for the account * @@ -36,6 +27,15 @@ class PostUsersSignInDataUserProfile #[\Speakeasy\Serializer\Annotation\SerializedName('defaultSubtitleLanguage')] public ?string $defaultSubtitleLanguage; + /** + * If the account has automatically select audio and subtitle tracks enabled + * + * @var ?bool $autoSelectAudio + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('autoSelectAudio')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $autoSelectAudio = null; + /** * * @var ?PostUsersSignInDataAutoSelectSubtitle $autoSelectSubtitle @@ -93,9 +93,9 @@ class PostUsersSignInDataUserProfile */ public function __construct(?string $defaultAudioLanguage = null, ?string $defaultSubtitleLanguage = null, ?bool $autoSelectAudio = true, ?PostUsersSignInDataAutoSelectSubtitle $autoSelectSubtitle = PostUsersSignInDataAutoSelectSubtitle::Disable, ?PostUsersSignInDataDefaultSubtitleAccessibility $defaultSubtitleAccessibility = PostUsersSignInDataDefaultSubtitleAccessibility::Disable, ?PostUsersSignInDataDefaultSubtitleForced $defaultSubtitleForced = PostUsersSignInDataDefaultSubtitleForced::Disable, ?PostUsersSignInDataWatchedIndicator $watchedIndicator = PostUsersSignInDataWatchedIndicator::Disable, ?PostUsersSignInDataMediaReviewsVisibility $mediaReviewsVisibility = PostUsersSignInDataMediaReviewsVisibility::Disable) { - $this->autoSelectAudio = $autoSelectAudio; $this->defaultAudioLanguage = $defaultAudioLanguage; $this->defaultSubtitleLanguage = $defaultSubtitleLanguage; + $this->autoSelectAudio = $autoSelectAudio; $this->autoSelectSubtitle = $autoSelectSubtitle; $this->defaultSubtitleAccessibility = $defaultSubtitleAccessibility; $this->defaultSubtitleForced = $defaultSubtitleForced; diff --git a/src/Models/Operations/QueryParamType.php b/src/Models/Operations/QueryParamType.php index 7e88dc7..3f8416d 100644 --- a/src/Models/Operations/QueryParamType.php +++ b/src/Models/Operations/QueryParamType.php @@ -26,4 +26,6 @@ enum QueryParamType: int case Season = 3; case Episode = 4; case Audio = 8; + case Album = 9; + case Track = 10; } diff --git a/src/Models/Operations/Services.php b/src/Models/Operations/Services.php index af5da1d..e2b40ec 100644 --- a/src/Models/Operations/Services.php +++ b/src/Models/Operations/Services.php @@ -25,6 +25,14 @@ class Services #[\Speakeasy\Serializer\Annotation\SerializedName('endpoint')] public string $endpoint; + /** + * + * @var GetTokenDetailsStatus $status + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('status')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetTokenDetailsStatus')] + public GetTokenDetailsStatus $status; + /** * * @var ?string $token @@ -39,14 +47,6 @@ class Services #[\Speakeasy\Serializer\Annotation\SerializedName('secret')] public ?string $secret; - /** - * - * @var GetTokenDetailsStatus $status - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('status')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\GetTokenDetailsStatus')] - public GetTokenDetailsStatus $status; - /** * @param string $identifier * @param string $endpoint diff --git a/src/Models/Operations/ShowOrdering.php b/src/Models/Operations/ShowOrdering.php index 7f18ca5..938c92b 100644 --- a/src/Models/Operations/ShowOrdering.php +++ b/src/Models/Operations/ShowOrdering.php @@ -10,20 +10,20 @@ /** - * Setting that indicates the episode ordering for the show + * Setting that indicates the episode ordering for the show * - * None = Library default, - * tmdbAiring = The Movie Database (Aired), - * aired = TheTVDB (Aired), - * dvd = TheTVDB (DVD), - * absolute = TheTVDB (Absolute)). + * None = Library default, + * tmdbAiring = The Movie Database (Aired), + * tvdbAiring = TheTVDB (Aired), + * tvdbDvd = TheTVDB (DVD), + * tvdbAbsolute = TheTVDB (Absolute)). * */ enum ShowOrdering: string { case None = 'None'; case TmdbAiring = 'tmdbAiring'; - case Aired = 'aired'; - case Dvd = 'dvd'; - case Absolute = 'absolute'; + case TvdbAiring = 'tvdbAiring'; + case TvdbDvd = 'tvdbDvd'; + case TvdbAbsolute = 'tvdbAbsolute'; } diff --git a/src/Models/Operations/Sort.php b/src/Models/Operations/Sort.php index e8e0832..68a4b1e 100644 --- a/src/Models/Operations/Sort.php +++ b/src/Models/Operations/Sort.php @@ -13,43 +13,33 @@ class Sort { /** * - * @var ?string $default + * @var string $key */ - #[\Speakeasy\Serializer\Annotation\SerializedName('default')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $default = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('key')] + public string $key; /** * - * @var ?bool $active + * @var string $title */ - #[\Speakeasy\Serializer\Annotation\SerializedName('active')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $active = null; + #[\Speakeasy\Serializer\Annotation\SerializedName('title')] + public string $title; /** - * The direction of the sort. Can be either `asc` or `desc`. * - * - * - * @var ?ActiveDirection $activeDirection + * @var ?string $default */ - #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\ActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('default')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?ActiveDirection $activeDirection = null; + public ?string $default = null; /** - * The direction of the sort. Can be either `asc` or `desc`. - * - * * - * @var ?DefaultDirection $defaultDirection + * @var ?bool $active */ - #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] - #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\DefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SerializedName('active')] #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?DefaultDirection $defaultDirection = null; + public ?bool $active = null; /** * @@ -68,18 +58,28 @@ class Sort public ?string $firstCharacterKey = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $key + * + * + * @var ?ActiveDirection $activeDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('key')] - public string $key; + #[\Speakeasy\Serializer\Annotation\SerializedName('activeDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\ActiveDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?ActiveDirection $activeDirection = null; /** + * The direction of the sort. Can be either `asc` or `desc`. * - * @var string $title + * + * + * @var ?DefaultDirection $defaultDirection */ - #[\Speakeasy\Serializer\Annotation\SerializedName('title')] - public string $title; + #[\Speakeasy\Serializer\Annotation\SerializedName('defaultDirection')] + #[\Speakeasy\Serializer\Annotation\Type('\LukeHagar\Plex_API\Models\Operations\DefaultDirection|null')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?DefaultDirection $defaultDirection = null; /** * @param string $key @@ -97,9 +97,9 @@ public function __construct(string $key, string $title, ?string $default = null, $this->title = $title; $this->default = $default; $this->active = $active; - $this->activeDirection = $activeDirection; - $this->defaultDirection = $defaultDirection; $this->descKey = $descKey; $this->firstCharacterKey = $firstCharacterKey; + $this->activeDirection = $activeDirection; + $this->defaultDirection = $defaultDirection; } } \ No newline at end of file diff --git a/src/Models/Operations/Stream.php b/src/Models/Operations/Stream.php index 71155dc..945f025 100644 --- a/src/Models/Operations/Stream.php +++ b/src/Models/Operations/Stream.php @@ -26,6 +26,22 @@ class Stream #[\Speakeasy\Serializer\Annotation\SerializedName('streamType')] public int $streamType; + /** + * Codec used by the stream + * + * @var string $codec + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('codec')] + public string $codec; + + /** + * The index of the stream + * + * @var int $index + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('index')] + public int $index; + /** * Indicates if this is the default stream * @@ -44,22 +60,6 @@ class Stream #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $selected = null; - /** - * Codec used by the stream - * - * @var string $codec - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('codec')] - public string $codec; - - /** - * The index of the stream - * - * @var int $index - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('index')] - public int $index; - /** * The bitrate of the stream in kbps * diff --git a/src/Models/Operations/Subscription.php b/src/Models/Operations/Subscription.php index 41eb4df..ad73d3a 100644 --- a/src/Models/Operations/Subscription.php +++ b/src/Models/Operations/Subscription.php @@ -31,15 +31,6 @@ class Subscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?bool $active = null; - /** - * Date the account subscribed to Plex Pass - * - * @var ?string $subscribedAt - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?string $subscribedAt = null; - /** * String representation of subscriptionActive * @@ -50,6 +41,15 @@ class Subscription #[\Speakeasy\Serializer\Annotation\SkipWhenNull] public ?GetTokenDetailsAuthenticationStatus $status = null; + /** + * Date the account subscribed to Plex Pass + * + * @var ?string $subscribedAt + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('subscribedAt')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?string $subscribedAt = null; + /** * Payment service used for your Plex Pass subscription * diff --git a/src/Models/Operations/Tag.php b/src/Models/Operations/Tag.php index 8870cfb..dc7dca1 100644 --- a/src/Models/Operations/Tag.php +++ b/src/Models/Operations/Tag.php @@ -31,4 +31,5 @@ enum Tag: string case Resolution = 'resolution'; case FirstCharacter = 'firstCharacter'; case Folder = 'folder'; + case Albums = 'albums'; } diff --git a/src/Models/Operations/Type.php b/src/Models/Operations/Type.php index f10e372..9158382 100644 --- a/src/Models/Operations/Type.php +++ b/src/Models/Operations/Type.php @@ -26,4 +26,6 @@ enum Type: int case Season = 3; case Episode = 4; case Audio = 8; + case Album = 9; + case Track = 10; } diff --git a/src/Models/Operations/UserProfile.php b/src/Models/Operations/UserProfile.php index 9d07ea0..549090b 100644 --- a/src/Models/Operations/UserProfile.php +++ b/src/Models/Operations/UserProfile.php @@ -11,15 +11,6 @@ class UserProfile { - /** - * If the account has automatically select audio and subtitle tracks enabled - * - * @var ?bool $autoSelectAudio - */ - #[\Speakeasy\Serializer\Annotation\SerializedName('autoSelectAudio')] - #[\Speakeasy\Serializer\Annotation\SkipWhenNull] - public ?bool $autoSelectAudio = null; - /** * The preferred audio language for the account * @@ -36,6 +27,15 @@ class UserProfile #[\Speakeasy\Serializer\Annotation\SerializedName('defaultSubtitleLanguage')] public ?string $defaultSubtitleLanguage; + /** + * If the account has automatically select audio and subtitle tracks enabled + * + * @var ?bool $autoSelectAudio + */ + #[\Speakeasy\Serializer\Annotation\SerializedName('autoSelectAudio')] + #[\Speakeasy\Serializer\Annotation\SkipWhenNull] + public ?bool $autoSelectAudio = null; + /** * * @var ?AutoSelectSubtitle $autoSelectSubtitle @@ -93,9 +93,9 @@ class UserProfile */ public function __construct(?string $defaultAudioLanguage = null, ?string $defaultSubtitleLanguage = null, ?bool $autoSelectAudio = true, ?AutoSelectSubtitle $autoSelectSubtitle = AutoSelectSubtitle::Disable, ?DefaultSubtitleAccessibility $defaultSubtitleAccessibility = DefaultSubtitleAccessibility::Disable, ?DefaultSubtitleForced $defaultSubtitleForced = DefaultSubtitleForced::Disable, ?WatchedIndicator $watchedIndicator = WatchedIndicator::Disable, ?MediaReviewsVisibility $mediaReviewsVisibility = MediaReviewsVisibility::Disable) { - $this->autoSelectAudio = $autoSelectAudio; $this->defaultAudioLanguage = $defaultAudioLanguage; $this->defaultSubtitleLanguage = $defaultSubtitleLanguage; + $this->autoSelectAudio = $autoSelectAudio; $this->autoSelectSubtitle = $autoSelectSubtitle; $this->defaultSubtitleAccessibility = $defaultSubtitleAccessibility; $this->defaultSubtitleForced = $defaultSubtitleForced; diff --git a/src/Playlists.php b/src/Playlists.php index 4bac2e7..bdca121 100644 --- a/src/Playlists.php +++ b/src/Playlists.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Playlists @@ -21,39 +23,86 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Create a Playlist + * Adding to a Playlist * - * Create a new playlist. By default the playlist is blank. To create a playlist along with a first item, pass: - * - `uri` - The content URI for what we're playing (e.g. `server://1234/com.plexapp.plugins.library/library/metadata/1`). - * - `playQueueID` - To create a playlist from an existing play queue. + * Adds a generator to a playlist, same parameters as the POST to create. With a dumb playlist, this adds the specified items to the playlist. + * With a smart playlist, passing a new `uri` parameter replaces the rules for the playlist. Returns the playlist. * * - * @param Operations\CreatePlaylistRequest $request - * @return Operations\CreatePlaylistResponse + * @param float $playlistID + * @param string $uri + * @param ?float $playQueueID + * @return Operations\AddPlaylistContentsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function createPlaylist(Operations\CreatePlaylistRequest $request): Operations\CreatePlaylistResponse + public function addPlaylistContents(float $playlistID, string $uri, ?float $playQueueID = null, ?Options $options = null): Operations\AddPlaylistContentsResponse { + $request = new Operations\AddPlaylistContentsRequest( + playlistID: $playlistID, + uri: $uri, + playQueueID: $playQueueID, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\CreatePlaylistRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); + $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}/items', Operations\AddPlaylistContentsRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\AddPlaylistContentsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); + $hookContext = new HookContext('addPlaylistContents', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\CreatePlaylistResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\CreatePlaylistResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\AddPlaylistContentsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\AddPlaylistContentsResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -65,8 +114,11 @@ public function createPlaylist(Operations\CreatePlaylistRequest $request): Opera } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\CreatePlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\AddPlaylistContentsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -74,8 +126,11 @@ public function createPlaylist(Operations\CreatePlaylistRequest $request): Opera } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\CreatePlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\AddPlaylistContentsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -89,52 +144,63 @@ public function createPlaylist(Operations\CreatePlaylistRequest $request): Opera } /** - * Get All Playlists + * Delete Playlist Contents * - * Get All Playlists given the specified filters. + * Clears a playlist, only works with dumb playlists. Returns the playlist. * - * @param ?Operations\PlaylistType $playlistType - * @param ?Operations\QueryParamSmart $smart - * @return Operations\GetPlaylistsResponse + * + * @param float $playlistID + * @return Operations\ClearPlaylistContentsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getPlaylists(?Operations\PlaylistType $playlistType = null, ?Operations\QueryParamSmart $smart = null): Operations\GetPlaylistsResponse + public function clearPlaylistContents(float $playlistID, ?Options $options = null): Operations\ClearPlaylistContentsResponse { - $request = new Operations\GetPlaylistsRequest( - playlistType: $playlistType, - smart: $smart, + $request = new Operations\ClearPlaylistContentsRequest( + playlistID: $playlistID, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetPlaylistsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}/items', Operations\ClearPlaylistContentsRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); + $hookContext = new HookContext('clearPlaylistContents', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetPlaylistsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetPlaylistsResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\ClearPlaylistContentsResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetPlaylistsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\ClearPlaylistContentsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -142,8 +208,11 @@ public function getPlaylists(?Operations\PlaylistType $playlistType = null, ?Ope } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetPlaylistsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\ClearPlaylistContentsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -157,38 +226,58 @@ public function getPlaylists(?Operations\PlaylistType $playlistType = null, ?Ope } /** - * Retrieve Playlist + * Create a Playlist * - * Gets detailed metadata for a playlist. A playlist for many purposes (rating, editing metadata, tagging), can be treated like a regular metadata item: - * Smart playlist details contain the `content` attribute. This is the content URI for the generator. This can then be parsed by a client to provide smart playlist editing. + * Create a new playlist. By default the playlist is blank. To create a playlist along with a first item, pass: + * - `uri` - The content URI for what we're playing (e.g. `server://1234/com.plexapp.plugins.library/library/metadata/1`). + * - `playQueueID` - To create a playlist from an existing play queue. * * - * @param float $playlistID - * @return Operations\GetPlaylistResponse + * @param Operations\CreatePlaylistRequest $request + * @return Operations\CreatePlaylistResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getPlaylist(float $playlistID): Operations\GetPlaylistResponse + public function createPlaylist(Operations\CreatePlaylistRequest $request, ?Options $options = null): Operations\CreatePlaylistResponse { - $request = new Operations\GetPlaylistRequest( - playlistID: $playlistID, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}', Operations\GetPlaylistRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/playlists'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\CreatePlaylistRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); + $hookContext = new HookContext('createPlaylist', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetPlaylistResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetPlaylistResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\CreatePlaylistResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\CreatePlaylistResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -200,8 +289,11 @@ public function getPlaylist(float $playlistID): Operations\GetPlaylistResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetPlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\CreatePlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -209,8 +301,11 @@ public function getPlaylist(float $playlistID): Operations\GetPlaylistResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetPlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\CreatePlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -233,24 +328,42 @@ public function getPlaylist(float $playlistID): Operations\GetPlaylistResponse * @return Operations\DeletePlaylistResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function deletePlaylist(float $playlistID): Operations\DeletePlaylistResponse + public function deletePlaylist(float $playlistID, ?Options $options = null): Operations\DeletePlaylistResponse { $request = new Operations\DeletePlaylistRequest( playlistID: $playlistID, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}', Operations\DeletePlaylistRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}', Operations\DeletePlaylistRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('deletePlaylist', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 204) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\DeletePlaylistResponse( statusCode: $statusCode, contentType: $contentType, @@ -258,8 +371,11 @@ public function deletePlaylist(float $playlistID): Operations\DeletePlaylistResp ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\DeletePlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\DeletePlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -267,8 +383,11 @@ public function deletePlaylist(float $playlistID): Operations\DeletePlaylistResp } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\DeletePlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\DeletePlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -282,47 +401,73 @@ public function deletePlaylist(float $playlistID): Operations\DeletePlaylistResp } /** - * Update a Playlist + * Retrieve Playlist * - * From PMS version 1.9.1 clients can also edit playlist metadata using this endpoint as they would via `PUT /library/metadata/{playlistID}` + * Gets detailed metadata for a playlist. A playlist for many purposes (rating, editing metadata, tagging), can be treated like a regular metadata item: + * Smart playlist details contain the `content` attribute. This is the content URI for the generator. This can then be parsed by a client to provide smart playlist editing. * * * @param float $playlistID - * @param ?string $title - * @param ?string $summary - * @return Operations\UpdatePlaylistResponse + * @return Operations\GetPlaylistResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function updatePlaylist(float $playlistID, ?string $title = null, ?string $summary = null): Operations\UpdatePlaylistResponse + public function getPlaylist(float $playlistID, ?Options $options = null): Operations\GetPlaylistResponse { - $request = new Operations\UpdatePlaylistRequest( + $request = new Operations\GetPlaylistRequest( playlistID: $playlistID, - title: $title, - summary: $summary, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}', Operations\UpdatePlaylistRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\UpdatePlaylistRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}', Operations\GetPlaylistRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getPlaylist', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\UpdatePlaylistResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetPlaylistResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetPlaylistResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\UpdatePlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetPlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -330,8 +475,11 @@ public function updatePlaylist(float $playlistID, ?string $title = null, ?string } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\UpdatePlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetPlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -358,29 +506,50 @@ public function updatePlaylist(float $playlistID, ?string $title = null, ?string * @return Operations\GetPlaylistContentsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getPlaylistContents(float $playlistID, Operations\GetPlaylistContentsQueryParamType $type): Operations\GetPlaylistContentsResponse + public function getPlaylistContents(float $playlistID, Operations\GetPlaylistContentsQueryParamType $type, ?Options $options = null): Operations\GetPlaylistContentsResponse { $request = new Operations\GetPlaylistContentsRequest( playlistID: $playlistID, type: $type, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}/items', Operations\GetPlaylistContentsRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetPlaylistContentsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}/items', Operations\GetPlaylistContentsRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetPlaylistContentsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getPlaylistContents', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetPlaylistContentsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetPlaylistContentsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetPlaylistContentsResponse( statusCode: $statusCode, contentType: $contentType, @@ -393,8 +562,11 @@ public function getPlaylistContents(float $playlistID, Operations\GetPlaylistCon } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetPlaylistContentsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetPlaylistContentsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -402,8 +574,11 @@ public function getPlaylistContents(float $playlistID, Operations\GetPlaylistCon } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetPlaylistContentsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetPlaylistContentsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -417,42 +592,76 @@ public function getPlaylistContents(float $playlistID, Operations\GetPlaylistCon } /** - * Delete Playlist Contents - * - * Clears a playlist, only works with dumb playlists. Returns the playlist. + * Get All Playlists * + * Get All Playlists given the specified filters. * - * @param float $playlistID - * @return Operations\ClearPlaylistContentsResponse + * @param ?Operations\PlaylistType $playlistType + * @param ?Operations\QueryParamSmart $smart + * @return Operations\GetPlaylistsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function clearPlaylistContents(float $playlistID): Operations\ClearPlaylistContentsResponse + public function getPlaylists(?Operations\PlaylistType $playlistType = null, ?Operations\QueryParamSmart $smart = null, ?Options $options = null): Operations\GetPlaylistsResponse { - $request = new Operations\ClearPlaylistContentsRequest( - playlistID: $playlistID, + $request = new Operations\GetPlaylistsRequest( + playlistType: $playlistType, + smart: $smart, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}/items', Operations\ClearPlaylistContentsRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/playlists'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetPlaylistsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getPlaylists', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\ClearPlaylistContentsResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetPlaylistsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetPlaylistsResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\ClearPlaylistContentsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetPlaylistsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -460,8 +669,11 @@ public function clearPlaylistContents(float $playlistID): Operations\ClearPlayli } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\ClearPlaylistContentsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetPlaylistsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -475,56 +687,70 @@ public function clearPlaylistContents(float $playlistID): Operations\ClearPlayli } /** - * Adding to a Playlist + * Update a Playlist * - * Adds a generator to a playlist, same parameters as the POST to create. With a dumb playlist, this adds the specified items to the playlist. - * With a smart playlist, passing a new `uri` parameter replaces the rules for the playlist. Returns the playlist. + * From PMS version 1.9.1 clients can also edit playlist metadata using this endpoint as they would via `PUT /library/metadata/{playlistID}` * * * @param float $playlistID - * @param string $uri - * @param ?float $playQueueID - * @return Operations\AddPlaylistContentsResponse + * @param ?string $title + * @param ?string $summary + * @return Operations\UpdatePlaylistResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function addPlaylistContents(float $playlistID, string $uri, ?float $playQueueID = null): Operations\AddPlaylistContentsResponse + public function updatePlaylist(float $playlistID, ?string $title = null, ?string $summary = null, ?Options $options = null): Operations\UpdatePlaylistResponse { - $request = new Operations\AddPlaylistContentsRequest( + $request = new Operations\UpdatePlaylistRequest( playlistID: $playlistID, - uri: $uri, - playQueueID: $playQueueID, + title: $title, + summary: $summary, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}/items', Operations\AddPlaylistContentsRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\AddPlaylistContentsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/playlists/{playlistID}', Operations\UpdatePlaylistRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\UpdatePlaylistRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); + $hookContext = new HookContext('updatePlaylist', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\AddPlaylistContentsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\AddPlaylistContentsResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\UpdatePlaylistResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\AddPlaylistContentsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\UpdatePlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -532,8 +758,11 @@ public function addPlaylistContents(float $playlistID, string $uri, ?float $play } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\AddPlaylistContentsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\UpdatePlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -558,7 +787,7 @@ public function addPlaylistContents(float $playlistID, string $uri, ?float $play * @return Operations\UploadPlaylistResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function uploadPlaylist(string $path, Operations\QueryParamForce $force, int $sectionID): Operations\UploadPlaylistResponse + public function uploadPlaylist(string $path, Operations\QueryParamForce $force, int $sectionID, ?Options $options = null): Operations\UploadPlaylistResponse { $request = new Operations\UploadPlaylistRequest( path: $path, @@ -567,18 +796,38 @@ public function uploadPlaylist(string $path, Operations\QueryParamForce $force, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/playlists/upload'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\UploadPlaylistRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); - + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\UploadPlaylistRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); + $hookContext = new HookContext('uploadPlaylist', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\UploadPlaylistResponse( statusCode: $statusCode, contentType: $contentType, @@ -586,8 +835,11 @@ public function uploadPlaylist(string $path, Operations\QueryParamForce $force, ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\UploadPlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\UploadPlaylistBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -595,8 +847,11 @@ public function uploadPlaylist(string $path, Operations\QueryParamForce $force, } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\UploadPlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\UploadPlaylistUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Plex.php b/src/Plex.php index 0b3b861..a2d75c6 100644 --- a/src/Plex.php +++ b/src/Plex.php @@ -8,16 +8,18 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Plex { - public const GET_COMPANIONS_DATA_SERVERS = [ + public const GET_SERVER_RESOURCES_SERVERS = [ 'https://plex.tv/api/v2', ]; - public const GET_USER_FRIENDS_SERVERS = [ + public const GET_COMPANIONS_DATA_SERVERS = [ 'https://plex.tv/api/v2', ]; @@ -25,15 +27,15 @@ class Plex 'https://plex.tv/api/v2', ]; - public const GET_SERVER_RESOURCES_SERVERS = [ + public const GET_PIN_SERVERS = [ 'https://plex.tv/api/v2', ]; - public const GET_PIN_SERVERS = [ + public const GET_TOKEN_BY_PIN_ID_SERVERS = [ 'https://plex.tv/api/v2', ]; - public const GET_TOKEN_BY_PIN_ID_SERVERS = [ + public const GET_USER_FRIENDS_SERVERS = [ 'https://plex.tv/api/v2', ]; @@ -45,43 +47,99 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Get Companions Data + * Get Server Resources * - * Get Companions Data + * Get Plex server access tokens and server connections * - * @param string $serverURL - * @return Operations\GetCompanionsDataResponse + * @param string $clientID + * @param ?Operations\IncludeHttps $includeHttps + * @param ?Operations\IncludeRelay $includeRelay + * @param ?Operations\IncludeIPv6 $includeIPv6 + * @param ?string $serverURL + * @return Operations\GetServerResourcesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getCompanionsData(?string $serverURL = null): Operations\GetCompanionsDataResponse + public function getServerResources(string $clientID, ?Operations\IncludeHttps $includeHttps = null, ?Operations\IncludeRelay $includeRelay = null, ?Operations\IncludeIPv6 $includeIPv6 = null, ?string $serverURL = null, ?Options $options = null): Operations\GetServerResourcesResponse { - $baseUrl = Utils\Utils::templateUrl(Plex::GET_COMPANIONS_DATA_SERVERS[0], [ + $request = new Operations\GetServerResourcesRequest( + clientID: $clientID, + includeHttps: $includeHttps, + includeRelay: $includeRelay, + includeIPv6: $includeIPv6, + ); + $baseUrl = Utils\Utils::templateUrl(Plex::GET_SERVER_RESOURCES_SERVERS[0], [ ]); if (! empty($serverURL)) { $baseUrl = $serverURL; } - $url = Utils\Utils::generateUrl($baseUrl, '/companions'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/resources'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetServerResourcesRequest::class, $request, $urlOverride); + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; + } + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('get-server-resources', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), 'array<\LukeHagar\Plex_API\Models\Operations\ResponseBody>', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetCompanionsDataResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, 'array<\LukeHagar\Plex_API\Models\Operations\PlexDevice>', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetServerResourcesResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, - responseBodies: $obj); + plexDevices: $obj); return $response; } else { @@ -89,8 +147,11 @@ public function getCompanionsData(?string $serverURL = null): Operations\GetComp } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetCompanionsDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerResourcesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -98,8 +159,11 @@ public function getCompanionsData(?string $serverURL = null): Operations\GetComp } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetCompanionsDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerResourcesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -113,41 +177,60 @@ public function getCompanionsData(?string $serverURL = null): Operations\GetComp } /** - * Get list of friends of the user logged in + * Get Companions Data * - * Get friends of provided auth token. + * Get Companions Data * - * @param string $serverURL - * @return Operations\GetUserFriendsResponse + * @param ?string $serverURL + * @return Operations\GetCompanionsDataResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getUserFriends(?string $serverURL = null): Operations\GetUserFriendsResponse + public function getCompanionsData(?string $serverURL = null, ?Options $options = null): Operations\GetCompanionsDataResponse { - $baseUrl = Utils\Utils::templateUrl(Plex::GET_USER_FRIENDS_SERVERS[0], [ + $baseUrl = Utils\Utils::templateUrl(Plex::GET_COMPANIONS_DATA_SERVERS[0], [ ]); if (! empty($serverURL)) { $baseUrl = $serverURL; } - $url = Utils\Utils::generateUrl($baseUrl, '/friends'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/companions'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getCompanionsData', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), 'array<\LukeHagar\Plex_API\Models\Operations\Friend>', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetUserFriendsResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, 'array<\LukeHagar\Plex_API\Models\Operations\ResponseBody>', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetCompanionsDataResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, - friends: $obj); + responseBodies: $obj); return $response; } else { @@ -155,8 +238,11 @@ public function getUserFriends(?string $serverURL = null): Operations\GetUserFri } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetUserFriendsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetCompanionsDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -164,8 +250,11 @@ public function getUserFriends(?string $serverURL = null): Operations\GetUserFri } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetUserFriendsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetCompanionsDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -183,11 +272,11 @@ public function getUserFriends(?string $serverURL = null): Operations\GetUserFri * * Returns the geolocation and locale data of the caller * - * @param string $serverURL + * @param ?string $serverURL * @return Operations\GetGeoDataResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getGeoData(?string $serverURL = null): Operations\GetGeoDataResponse + public function getGeoData(?string $serverURL = null, ?Options $options = null): Operations\GetGeoDataResponse { $baseUrl = Utils\Utils::templateUrl(Plex::GET_GEO_DATA_SERVERS[0], [ ]); @@ -195,18 +284,39 @@ public function getGeoData(?string $serverURL = null): Operations\GetGeoDataResp $baseUrl = $serverURL; } $url = Utils\Utils::generateUrl($baseUrl, '/geoip'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - $httpResponse = $this->sdkConfiguration->defaultClient->send($httpRequest, $options); + $hookContext = new HookContext('getGeoData', null, null); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetGeoDataGeoData', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetGeoDataGeoData', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetGeoDataResponse( statusCode: $statusCode, contentType: $contentType, @@ -219,8 +329,11 @@ public function getGeoData(?string $serverURL = null): Operations\GetGeoDataResp } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetGeoDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetGeoDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -228,8 +341,11 @@ public function getGeoData(?string $serverURL = null): Operations\GetGeoDataResp } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetGeoDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetGeoDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -250,24 +366,43 @@ public function getGeoData(?string $serverURL = null): Operations\GetGeoDataResp * @return Operations\GetHomeDataResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getHomeData(): Operations\GetHomeDataResponse + public function getHomeData(?Options $options = null): Operations\GetHomeDataResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/home'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getHomeData', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetHomeDataResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetHomeDataResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetHomeDataResponse( statusCode: $statusCode, contentType: $contentType, @@ -280,8 +415,11 @@ public function getHomeData(): Operations\GetHomeDataResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetHomeDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetHomeDataBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -289,8 +427,11 @@ public function getHomeData(): Operations\GetHomeDataResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetHomeDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetHomeDataUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -304,56 +445,68 @@ public function getHomeData(): Operations\GetHomeDataResponse } /** - * Get Server Resources + * Get a Pin * - * Get Plex server access tokens and server connections + * Retrieve a Pin ID from Plex.tv to use for authentication flows * - * @param ?Operations\IncludeHttps $includeHttps - * @param ?Operations\IncludeRelay $includeRelay - * @param ?Operations\IncludeIPv6 $includeIPv6 - * @param ?string $clientID - * @param string $serverURL - * @return Operations\GetServerResourcesResponse + * @param Operations\GetPinRequest $request + * @param ?string $serverURL + * @return Operations\GetPinResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getServerResources(?Operations\IncludeHttps $includeHttps = null, ?Operations\IncludeRelay $includeRelay = null, ?Operations\IncludeIPv6 $includeIPv6 = null, ?string $clientID = null, ?string $serverURL = null): Operations\GetServerResourcesResponse + public function getPin(Operations\GetPinRequest $request, ?string $serverURL = null, ?Options $options = null): Operations\GetPinResponse { - $request = new Operations\GetServerResourcesRequest( - includeHttps: $includeHttps, - includeRelay: $includeRelay, - includeIPv6: $includeIPv6, - clientID: $clientID, - ); - $baseUrl = Utils\Utils::templateUrl(Plex::GET_SERVER_RESOURCES_SERVERS[0], [ + $baseUrl = Utils\Utils::templateUrl(Plex::GET_PIN_SERVERS[0], [ ]); if (! empty($serverURL)) { $baseUrl = $serverURL; } - $url = Utils\Utils::generateUrl($baseUrl, '/resources'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetServerResourcesRequest::class, $request, $this->sdkConfiguration->globals)); - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; - } - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/pins'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetPinRequest::class, $request, $urlOverride); + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; + } + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); + $hookContext = new HookContext('getPin', null, null); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); - if ($statusCode == 200) { + if ($statusCode == 400 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } + if ($statusCode == 201) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), 'array<\LukeHagar\Plex_API\Models\Operations\PlexDevice>', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetServerResourcesResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetPinAuthPinContainer', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetPinResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, - plexDevices: $obj); + authPinContainer: $obj); return $response; } else { @@ -361,17 +514,11 @@ public function getServerResources(?Operations\IncludeHttps $includeHttps = null } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerResourcesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode == 401) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerResourcesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetPinBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -385,41 +532,61 @@ public function getServerResources(?Operations\IncludeHttps $includeHttps = null } /** - * Get a Pin + * Get Access Token by PinId * - * Retrieve a Pin ID from Plex.tv to use for authentication flows + * Retrieve an Access Token from Plex.tv after the Pin has been authenticated * - * @param ?Operations\GetPinRequest $request - * @param string $serverURL - * @return Operations\GetPinResponse + * @param Operations\GetTokenByPinIdRequest $request + * @param ?string $serverURL + * @return Operations\GetTokenByPinIdResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getPin(?Operations\GetPinRequest $request = null, ?string $serverURL = null): Operations\GetPinResponse + public function getTokenByPinId(Operations\GetTokenByPinIdRequest $request, ?string $serverURL = null, ?Options $options = null): Operations\GetTokenByPinIdResponse { - $baseUrl = Utils\Utils::templateUrl(Plex::GET_PIN_SERVERS[0], [ + $baseUrl = Utils\Utils::templateUrl(Plex::GET_TOKEN_BY_PIN_ID_SERVERS[0], [ ]); if (! empty($serverURL)) { $baseUrl = $serverURL; } - $url = Utils\Utils::generateUrl($baseUrl, '/pins'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetPinRequest::class, $request, $this->sdkConfiguration->globals)); - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; - } - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('POST', $url); - $httpResponse = $this->sdkConfiguration->defaultClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/pins/{pinID}', Operations\GetTokenByPinIdRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; + } + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getTokenByPinId', null, null); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); - if ($statusCode == 201) { + if ($statusCode == 400 || $statusCode == 404 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } + if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetPinAuthPinContainer', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetPinResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetTokenByPinIdAuthPinContainer', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetTokenByPinIdResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -431,8 +598,23 @@ public function getPin(?Operations\GetPinRequest $request = null, ?string $serve } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTokenByPinIdBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 404) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetPinBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTokenByPinIdResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -446,44 +628,60 @@ public function getPin(?Operations\GetPinRequest $request = null, ?string $serve } /** - * Get Access Token by PinId + * Get list of friends of the user logged in * - * Retrieve an Access Token from Plex.tv after the Pin has been authenticated + * Get friends of provided auth token. * - * @param Operations\GetTokenByPinIdRequest $request - * @param string $serverURL - * @return Operations\GetTokenByPinIdResponse + * @param ?string $serverURL + * @return Operations\GetUserFriendsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getTokenByPinId(Operations\GetTokenByPinIdRequest $request, ?string $serverURL = null): Operations\GetTokenByPinIdResponse + public function getUserFriends(?string $serverURL = null, ?Options $options = null): Operations\GetUserFriendsResponse { - $baseUrl = Utils\Utils::templateUrl(Plex::GET_TOKEN_BY_PIN_ID_SERVERS[0], [ + $baseUrl = Utils\Utils::templateUrl(Plex::GET_USER_FRIENDS_SERVERS[0], [ ]); if (! empty($serverURL)) { $baseUrl = $serverURL; } - $url = Utils\Utils::generateUrl($baseUrl, '/pins/{pinID}', Operations\GetTokenByPinIdRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; - } - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/friends'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - $httpResponse = $this->sdkConfiguration->defaultClient->send($httpRequest, $options); + $hookContext = new HookContext('getUserFriends', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetTokenByPinIdAuthPinContainer', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetTokenByPinIdResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, 'array<\LukeHagar\Plex_API\Models\Operations\Friend>', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetUserFriendsResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, - authPinContainer: $obj); + friends: $obj); return $response; } else { @@ -491,17 +689,23 @@ public function getTokenByPinId(Operations\GetTokenByPinIdRequest $request, ?str } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTokenByPinIdBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetUserFriendsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode == 404) { + } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTokenByPinIdResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetUserFriendsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/PlexAPI.php b/src/PlexAPI.php index d564f90..cda7d7f 100644 --- a/src/PlexAPI.php +++ b/src/PlexAPI.php @@ -232,5 +232,7 @@ public function __construct( $this->statistics = new Statistics($this->sdkConfiguration); $this->sessions = new Sessions($this->sdkConfiguration); $this->updater = new Updater($this->sdkConfiguration); + $this->sdkConfiguration->client = $this->sdkConfiguration->initHooks($this->sdkConfiguration->client); + } } \ No newline at end of file diff --git a/src/PlexAPIBuilder.php b/src/PlexAPIBuilder.php index 32c143f..785a8e1 100644 --- a/src/PlexAPIBuilder.php +++ b/src/PlexAPIBuilder.php @@ -8,6 +8,8 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Utils\Retry; + /** * PlexAPIBuilder is used to configure and build an instance of the SDK. */ @@ -26,7 +28,7 @@ public function __construct( */ public function setClient(\GuzzleHttp\ClientInterface $client): PlexAPIBuilder { - $this->sdkConfig->defaultClient = $client; + $this->sdkConfig->client = $client; return $this; } @@ -141,83 +143,10 @@ public function setPort(string $port): PlexAPIBuilder return $this; } - /** - * setClientID is used to configure the ClientID parameter for the SDK. - * - * @param string $clientID - * @return PlexAPIBuilder - */ - public function setClientID(string $clientID): PlexAPIBuilder - { - if (! array_key_exists('header', $this->sdkConfig->globals['parameters'])) { - $this->sdkConfig->globals['parameters']['header'] = []; - } - - $this->sdkConfig->globals['parameters']['header']['clientID'] = $clientID; - return $this; - } - /** - * setClientName is used to configure the ClientName parameter for the SDK. - * - * @param string $clientName - * @return PlexAPIBuilder - */ - public function setClientName(string $clientName): PlexAPIBuilder + public function setRetryConfig(Retry\RetryConfig $config): PlexAPIBuilder { - if (! array_key_exists('header', $this->sdkConfig->globals['parameters'])) { - $this->sdkConfig->globals['parameters']['header'] = []; - } - - $this->sdkConfig->globals['parameters']['header']['clientName'] = $clientName; - - return $this; - } - /** - * setClientVersion is used to configure the ClientVersion parameter for the SDK. - * - * @param string $clientVersion - * @return PlexAPIBuilder - */ - public function setClientVersion(string $clientVersion): PlexAPIBuilder - { - if (! array_key_exists('header', $this->sdkConfig->globals['parameters'])) { - $this->sdkConfig->globals['parameters']['header'] = []; - } - - $this->sdkConfig->globals['parameters']['header']['clientVersion'] = $clientVersion; - - return $this; - } - /** - * setPlatform is used to configure the Platform parameter for the SDK. - * - * @param string $platform - * @return PlexAPIBuilder - */ - public function setPlatform(string $platform): PlexAPIBuilder - { - if (! array_key_exists('header', $this->sdkConfig->globals['parameters'])) { - $this->sdkConfig->globals['parameters']['header'] = []; - } - - $this->sdkConfig->globals['parameters']['header']['platform'] = $platform; - - return $this; - } - /** - * setDeviceNickname is used to configure the DeviceNickname parameter for the SDK. - * - * @param string $deviceNickname - * @return PlexAPIBuilder - */ - public function setDeviceNickname(string $deviceNickname): PlexAPIBuilder - { - if (! array_key_exists('header', $this->sdkConfig->globals['parameters'])) { - $this->sdkConfig->globals['parameters']['header'] = []; - } - - $this->sdkConfig->globals['parameters']['header']['deviceNickname'] = $deviceNickname; + $this->sdkConfig->retryConfig = $config; return $this; } @@ -229,16 +158,13 @@ public function setDeviceNickname(string $deviceNickname): PlexAPIBuilder */ public function build(): PlexAPI { - if ($this->sdkConfig->defaultClient === null) { - $this->sdkConfig->defaultClient = new \GuzzleHttp\Client([ + if ($this->sdkConfig->client === null) { + $this->sdkConfig->client = new \GuzzleHttp\Client([ 'timeout' => 60, ]); } if ($this->sdkConfig->hasSecurity()) { - $this->sdkConfig->securityClient = Utils\Utils::configureSecurityClient($this->sdkConfig->defaultClient, $this->sdkConfig->getSecurity()); - } - if ($this->sdkConfig->securityClient === null) { - $this->sdkConfig->securityClient = $this->sdkConfig->defaultClient; + $this->sdkConfig->client = Utils\Utils::configureSecurityClient($this->sdkConfig->client, $this->sdkConfig->getSecurity()); } return new PlexAPI($this->sdkConfig); diff --git a/src/SDKConfiguration.php b/src/SDKConfiguration.php index 50b6365..ff881d3 100644 --- a/src/SDKConfiguration.php +++ b/src/SDKConfiguration.php @@ -7,18 +7,17 @@ declare(strict_types=1); namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Utils\Retry\RetryConfig; class SDKConfiguration { - public ?\GuzzleHttp\ClientInterface $defaultClient = null; - - public ?\GuzzleHttp\ClientInterface $securityClient = null; + public ?\GuzzleHttp\ClientInterface $client = null; + public Hooks\SDKHooks $hooks; public ?Models\Components\Security $security = null; /** @var pure-Closure(): string */ public ?\Closure $securitySource = null; - public string $serverUrl = ''; public int $serverIndex = 0; @@ -36,15 +35,18 @@ class SDKConfiguration public string $openapiDocVersion = '0.0.3'; - public string $sdkVersion = '0.11.1'; + public string $sdkVersion = '0.12.0'; - public string $genVersion = '2.457.9'; + public string $genVersion = '2.483.1'; - public string $userAgent = 'speakeasy-sdk/php 0.11.1 2.457.9 0.0.3 lukehagar/plex-api'; - /** @var array>> */ - public ?array $globals = [ - 'parameters' => [], - ]; + public string $userAgent = 'speakeasy-sdk/php 0.12.0 2.483.1 0.0.3 lukehagar/plex-api'; + + public ?RetryConfig $retryConfig = null; + + public function __construct() + { + $this->hooks = new Hooks\SDKHooks(); + } public function getServerUrl(): string { @@ -84,4 +86,40 @@ public function getSecurity(): ?Models\Components\Security return $this->security; } } -} \ No newline at end of file + + /** + * @return Utils\ServerDetails + */ + public function getServerDetails(): Utils\ServerDetails + { + if ($this->serverUrl !== null && $this->serverUrl !== '') { + return new Utils\ServerDetails(rtrim($this->serverUrl, '/'), []); + } + if ($this->serverIndex === null) { + $this->serverIndex = 0; + } + + return new Utils\ServerDetails(PlexAPI::SERVERS[$this->serverIndex], $this->serverDefaults[$this->serverIndex]); + + } + + public function getTemplatedServerUrl(): string + { + if ($this->serverUrl) { + return Utils\Utils::templateUrl($this->serverUrl.trim('/'), []); + } + + return Utils\Utils::templateUrl($this->getServerUrl(), $this->getServerDefaults()); + } + + public function initHooks(\GuzzleHttp\ClientInterface $client): \GuzzleHttp\ClientInterface + { + $preHooksUrl = $this->getTemplatedServerUrl(); + $ret = $this->hooks->sdkInit($preHooksUrl, $client); + if ($preHooksUrl != $ret->url) { + $this->serverUrl = $ret->url; + } + + return $ret->client; + } +} diff --git a/src/Search.php b/src/Search.php index 6d900f5..4fe2a37 100644 --- a/src/Search.php +++ b/src/Search.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Search @@ -21,60 +23,96 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } - /** - * Perform a search - * - * This endpoint performs a search across all library sections, or a single section, and returns matches as hubs, split up by type. It performs spell checking, looks for partial matches, and orders the hubs based on quality of results. In addition, based on matches, it will return other related matches (e.g. for a genre match, it may return movies in that genre, or for an actor match, movies with that actor). - * - * In the response's items, the following extra attributes are returned to further describe or disambiguate the result: - * - * - `reason`: The reason for the result, if not because of a direct search term match; can be either: - * - `section`: There are multiple identical results from different sections. - * - `originalTitle`: There was a search term match from the original title field (sometimes those can be very different or in a foreign language). - * - ``: If the reason for the result is due to a result in another hub, the source hub identifier is returned. For example, if the search is for "dylan" then Bob Dylan may be returned as an artist result, an a few of his albums returned as album results with a reason code of `artist` (the identifier of that particular hub). Or if the search is for "arnold", there might be movie results returned with a reason of `actor` - * - `reasonTitle`: The string associated with the reason code. For a section reason, it'll be the section name; For a hub identifier, it'll be a string associated with the match (e.g. `Arnold Schwarzenegger` for movies which were returned because the search was for "arnold"). - * - `reasonID`: The ID of the item associated with the reason for the result. This might be a section ID, a tag ID, an artist ID, or a show ID. + * @param string $baseUrl + * @param array $urlVariables * - * This request is intended to be very fast, and called as the user types. + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } + + /** + * Get Search Results * + * This will search the database for the string provided. * * @param string $query - * @param ?float $sectionId - * @param ?float $limit - * @return Operations\PerformSearchResponse + * @return Operations\GetSearchResultsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function performSearch(string $query, ?float $sectionId = null, ?float $limit = null): Operations\PerformSearchResponse + public function getSearchResults(string $query, ?Options $options = null): Operations\GetSearchResultsResponse { - $request = new Operations\PerformSearchRequest( + $request = new Operations\GetSearchResultsRequest( query: $query, - sectionId: $sectionId, - limit: $limit, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/hubs/search'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\PerformSearchRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/search'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetSearchResultsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getSearchResults', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\PerformSearchResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetSearchResultsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetSearchResultsResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\PerformSearchBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSearchResultsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -82,8 +120,11 @@ public function performSearch(string $query, ?float $sectionId = null, ?float $l } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\PerformSearchUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSearchResultsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -97,50 +138,81 @@ public function performSearch(string $query, ?float $sectionId = null, ?float $l } /** - * Perform a voice search + * Perform a search * - * This endpoint performs a search specifically tailored towards voice or other imprecise input which may work badly with the substring and spell-checking heuristics used by the `/hubs/search` endpoint. - * It uses a [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) heuristic to search titles, and as such is much slower than the other search endpoint. - * Whenever possible, clients should limit the search to the appropriate type. - * Results, as well as their containing per-type hubs, contain a `distance` attribute which can be used to judge result quality. + * This endpoint performs a search across all library sections, or a single section, and returns matches as hubs, split up by type. It performs spell checking, looks for partial matches, and orders the hubs based on quality of results. In addition, based on matches, it will return other related matches (e.g. for a genre match, it may return movies in that genre, or for an actor match, movies with that actor). + * + * In the response's items, the following extra attributes are returned to further describe or disambiguate the result: + * + * - `reason`: The reason for the result, if not because of a direct search term match; can be either: + * - `section`: There are multiple identical results from different sections. + * - `originalTitle`: There was a search term match from the original title field (sometimes those can be very different or in a foreign language). + * - ``: If the reason for the result is due to a result in another hub, the source hub identifier is returned. For example, if the search is for "dylan" then Bob Dylan may be returned as an artist result, an a few of his albums returned as album results with a reason code of `artist` (the identifier of that particular hub). Or if the search is for "arnold", there might be movie results returned with a reason of `actor` + * - `reasonTitle`: The string associated with the reason code. For a section reason, it'll be the section name; For a hub identifier, it'll be a string associated with the match (e.g. `Arnold Schwarzenegger` for movies which were returned because the search was for "arnold"). + * - `reasonID`: The ID of the item associated with the reason for the result. This might be a section ID, a tag ID, an artist ID, or a show ID. + * + * This request is intended to be very fast, and called as the user types. * * * @param string $query * @param ?float $sectionId * @param ?float $limit - * @return Operations\PerformVoiceSearchResponse + * @return Operations\PerformSearchResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function performVoiceSearch(string $query, ?float $sectionId = null, ?float $limit = null): Operations\PerformVoiceSearchResponse + public function performSearch(string $query, ?float $sectionId = null, ?float $limit = null, ?Options $options = null): Operations\PerformSearchResponse { - $request = new Operations\PerformVoiceSearchRequest( + $request = new Operations\PerformSearchRequest( query: $query, sectionId: $sectionId, limit: $limit, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/hubs/search/voice'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\PerformVoiceSearchRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/hubs/search'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\PerformSearchRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('performSearch', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\PerformVoiceSearchResponse( + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + return new Operations\PerformSearchResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\PerformVoiceSearchBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\PerformSearchBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -148,8 +220,11 @@ public function performVoiceSearch(string $query, ?float $sectionId = null, ?flo } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\PerformVoiceSearchUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\PerformSearchUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -163,50 +238,73 @@ public function performVoiceSearch(string $query, ?float $sectionId = null, ?flo } /** - * Get Search Results + * Perform a voice search + * + * This endpoint performs a search specifically tailored towards voice or other imprecise input which may work badly with the substring and spell-checking heuristics used by the `/hubs/search` endpoint. + * It uses a [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) heuristic to search titles, and as such is much slower than the other search endpoint. + * Whenever possible, clients should limit the search to the appropriate type. + * Results, as well as their containing per-type hubs, contain a `distance` attribute which can be used to judge result quality. * - * This will search the database for the string provided. * * @param string $query - * @return Operations\GetSearchResultsResponse + * @param ?float $sectionId + * @param ?float $limit + * @return Operations\PerformVoiceSearchResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getSearchResults(string $query): Operations\GetSearchResultsResponse + public function performVoiceSearch(string $query, ?float $sectionId = null, ?float $limit = null, ?Options $options = null): Operations\PerformVoiceSearchResponse { - $request = new Operations\GetSearchResultsRequest( + $request = new Operations\PerformVoiceSearchRequest( query: $query, + sectionId: $sectionId, + limit: $limit, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/search'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetSearchResultsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/hubs/search/voice'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\PerformVoiceSearchRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('performVoiceSearch', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetSearchResultsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetSearchResultsResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\PerformVoiceSearchResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSearchResultsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\PerformVoiceSearchBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -214,8 +312,11 @@ public function getSearchResults(string $query): Operations\GetSearchResultsResp } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSearchResultsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\PerformVoiceSearchUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Server.php b/src/Server.php index 8d0a03f..ed44630 100644 --- a/src/Server.php +++ b/src/Server.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Server @@ -21,34 +23,81 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Get Server Capabilities + * Get Media Providers * - * Get Server Capabilities + * Retrieves media providers and their features from the Plex server. * - * @return Operations\GetServerCapabilitiesResponse + * @param string $xPlexToken + * @return Operations\GetMediaProvidersResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getServerCapabilities(): Operations\GetServerCapabilitiesResponse + public function getMediaProviders(string $xPlexToken, ?Options $options = null): Operations\GetMediaProvidersResponse { + $request = new Operations\GetMediaProvidersRequest( + xPlexToken: $xPlexToken, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/media/providers'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; + } + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('get-media-providers', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetServerCapabilitiesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetServerCapabilitiesResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetMediaProvidersResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetMediaProvidersResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -60,8 +109,11 @@ public function getServerCapabilities(): Operations\GetServerCapabilitiesRespons } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerCapabilitiesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMediaProvidersBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -69,8 +121,11 @@ public function getServerCapabilities(): Operations\GetServerCapabilitiesRespons } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerCapabilitiesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMediaProvidersUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -84,32 +139,51 @@ public function getServerCapabilities(): Operations\GetServerCapabilitiesRespons } /** - * Get Server Preferences + * Get Server Identity * - * Get Server Preferences + * This request is useful to determine if the server is online or offline * - * @return Operations\GetServerPreferencesResponse + * @return Operations\GetServerIdentityResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getServerPreferences(): Operations\GetServerPreferencesResponse + public function getServerIdentity(?Options $options = null): Operations\GetServerIdentityResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/:/prefs'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/identity'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('get-server-identity', null, null); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 408 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetServerPreferencesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetServerPreferencesResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetServerIdentityResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetServerIdentityResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -119,19 +193,13 @@ public function getServerPreferences(): Operations\GetServerPreferencesResponse } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode == 400) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerPreferencesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $obj->rawResponse = $httpResponse; - throw $obj->toException(); - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } - } elseif ($statusCode == 401) { + } elseif ($statusCode == 408) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerPreferencesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerIdentityRequestTimeout', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -152,24 +220,43 @@ public function getServerPreferences(): Operations\GetServerPreferencesResponse * @return Operations\GetAvailableClientsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getAvailableClients(): Operations\GetAvailableClientsResponse + public function getAvailableClients(?Options $options = null): Operations\GetAvailableClientsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/clients'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getAvailableClients', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetAvailableClientsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetAvailableClientsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetAvailableClientsResponse( statusCode: $statusCode, contentType: $contentType, @@ -182,8 +269,11 @@ public function getAvailableClients(): Operations\GetAvailableClientsResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetAvailableClientsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetAvailableClientsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -191,8 +281,11 @@ public function getAvailableClients(): Operations\GetAvailableClientsResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetAvailableClientsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetAvailableClientsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -213,24 +306,43 @@ public function getAvailableClients(): Operations\GetAvailableClientsResponse * @return Operations\GetDevicesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getDevices(): Operations\GetDevicesResponse + public function getDevices(?Options $options = null): Operations\GetDevicesResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/devices'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getDevices', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetDevicesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetDevicesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetDevicesResponse( statusCode: $statusCode, contentType: $contentType, @@ -243,8 +355,11 @@ public function getDevices(): Operations\GetDevicesResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetDevicesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetDevicesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -252,8 +367,11 @@ public function getDevices(): Operations\GetDevicesResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetDevicesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetDevicesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -267,30 +385,51 @@ public function getDevices(): Operations\GetDevicesResponse } /** - * Get Server Identity + * Get MyPlex Account * - * This request is useful to determine if the server is online or offline + * Returns MyPlex Account Information * - * @return Operations\GetServerIdentityResponse + * @return Operations\GetMyPlexAccountResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getServerIdentity(): Operations\GetServerIdentityResponse + public function getMyPlexAccount(?Options $options = null): Operations\GetMyPlexAccountResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/identity'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/myplex/account'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - $httpResponse = $this->sdkConfiguration->defaultClient->send($httpRequest, $options); + $hookContext = new HookContext('getMyPlexAccount', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetServerIdentityResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetServerIdentityResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetMyPlexAccountResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetMyPlexAccountResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -300,10 +439,25 @@ public function getServerIdentity(): Operations\GetServerIdentityResponse } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode == 408) { + } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerIdentityRequestTimeout', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMyPlexAccountBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $obj->rawResponse = $httpResponse; + throw $obj->toException(); + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } + } elseif ($statusCode == 401) { + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetMyPlexAccountUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -317,45 +471,63 @@ public function getServerIdentity(): Operations\GetServerIdentityResponse } /** - * Get MyPlex Account + * Get a Resized Photo * - * Returns MyPlex Account Information + * Plex's Photo transcoder is used throughout the service to serve images at specified sizes. * - * @return Operations\GetMyPlexAccountResponse + * + * @param Operations\GetResizedPhotoRequest $request + * @return Operations\GetResizedPhotoResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getMyPlexAccount(): Operations\GetMyPlexAccountResponse + public function getResizedPhoto(Operations\GetResizedPhotoRequest $request, ?Options $options = null): Operations\GetResizedPhotoResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/myplex/account'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/photo/:/transcode'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetResizedPhotoRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getResizedPhoto', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetMyPlexAccountResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetMyPlexAccountResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\GetResizedPhotoResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMyPlexAccountBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetResizedPhotoBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -363,8 +535,11 @@ public function getMyPlexAccount(): Operations\GetMyPlexAccountResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMyPlexAccountUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetResizedPhotoUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -378,40 +553,67 @@ public function getMyPlexAccount(): Operations\GetMyPlexAccountResponse } /** - * Get a Resized Photo - * - * Plex's Photo transcoder is used throughout the service to serve images at specified sizes. + * Get Server Capabilities * + * Get Server Capabilities * - * @param Operations\GetResizedPhotoRequest $request - * @return Operations\GetResizedPhotoResponse + * @return Operations\GetServerCapabilitiesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getResizedPhoto(Operations\GetResizedPhotoRequest $request): Operations\GetResizedPhotoResponse + public function getServerCapabilities(?Options $options = null): Operations\GetServerCapabilitiesResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/photo/:/transcode'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetResizedPhotoRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getServerCapabilities', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\GetResizedPhotoResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetServerCapabilitiesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetServerCapabilitiesResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetResizedPhotoBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerCapabilitiesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -419,8 +621,11 @@ public function getResizedPhoto(Operations\GetResizedPhotoRequest $request): Ope } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetResizedPhotoUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerCapabilitiesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -434,40 +639,51 @@ public function getResizedPhoto(Operations\GetResizedPhotoRequest $request): Ope } /** - * Get Media Providers + * Get Server List * - * Retrieves media providers and their features from the Plex server. + * Get Server List * - * @param string $xPlexToken - * @return Operations\GetMediaProvidersResponse + * @return Operations\GetServerListResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getMediaProviders(string $xPlexToken): Operations\GetMediaProvidersResponse + public function getServerList(?Options $options = null): Operations\GetServerListResponse { - $request = new Operations\GetMediaProvidersRequest( - xPlexToken: $xPlexToken, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/media/providers'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; - } - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/servers'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getServerList', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetMediaProvidersResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetMediaProvidersResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetServerListResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetServerListResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -479,8 +695,11 @@ public function getMediaProviders(string $xPlexToken): Operations\GetMediaProvid } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMediaProvidersBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerListBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -488,8 +707,11 @@ public function getMediaProviders(string $xPlexToken): Operations\GetMediaProvid } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetMediaProvidersUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerListUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -503,32 +725,51 @@ public function getMediaProviders(string $xPlexToken): Operations\GetMediaProvid } /** - * Get Server List + * Get Server Preferences * - * Get Server List + * Get Server Preferences * - * @return Operations\GetServerListResponse + * @return Operations\GetServerPreferencesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getServerList(): Operations\GetServerListResponse + public function getServerPreferences(?Options $options = null): Operations\GetServerPreferencesResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/servers'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/:/prefs'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getServerPreferences', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetServerListResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetServerListResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetServerPreferencesResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetServerPreferencesResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -540,8 +781,11 @@ public function getServerList(): Operations\GetServerListResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerListBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerPreferencesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -549,8 +793,11 @@ public function getServerList(): Operations\GetServerListResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetServerListUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetServerPreferencesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Sessions.php b/src/Sessions.php index 232da4b..9527ae4 100644 --- a/src/Sessions.php +++ b/src/Sessions.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Sessions @@ -21,34 +23,86 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Get Active Sessions + * Get Session History * - * This will retrieve the "Now Playing" Information of the PMS. + * This will Retrieve a listing of all history views. * - * @return Operations\GetSessionsResponse + * @param ?string $sort + * @param ?int $accountId + * @param ?Operations\QueryParamFilter $filter + * @param ?int $librarySectionID + * @return Operations\GetSessionHistoryResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getSessions(): Operations\GetSessionsResponse + public function getSessionHistory(?string $sort = null, ?int $accountId = null, ?Operations\QueryParamFilter $filter = null, ?int $librarySectionID = null, ?Options $options = null): Operations\GetSessionHistoryResponse { + $request = new Operations\GetSessionHistoryRequest( + sort: $sort, + accountId: $accountId, + filter: $filter, + librarySectionID: $librarySectionID, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/status/sessions'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/status/sessions/history/all'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetSessionHistoryRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getSessionHistory', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetSessionsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetSessionsResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetSessionHistoryResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetSessionHistoryResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -60,8 +114,11 @@ public function getSessions(): Operations\GetSessionsResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSessionsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSessionHistoryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -69,8 +126,11 @@ public function getSessions(): Operations\GetSessionsResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSessionsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSessionHistoryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -84,43 +144,51 @@ public function getSessions(): Operations\GetSessionsResponse } /** - * Get Session History + * Get Active Sessions * - * This will Retrieve a listing of all history views. + * This will retrieve the "Now Playing" Information of the PMS. * - * @param ?string $sort - * @param ?int $accountId - * @param ?Operations\QueryParamFilter $filter - * @param ?int $librarySectionID - * @return Operations\GetSessionHistoryResponse + * @return Operations\GetSessionsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getSessionHistory(?string $sort = null, ?int $accountId = null, ?Operations\QueryParamFilter $filter = null, ?int $librarySectionID = null): Operations\GetSessionHistoryResponse + public function getSessions(?Options $options = null): Operations\GetSessionsResponse { - $request = new Operations\GetSessionHistoryRequest( - sort: $sort, - accountId: $accountId, - filter: $filter, - librarySectionID: $librarySectionID, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/status/sessions/history/all'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetSessionHistoryRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/status/sessions'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getSessions', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetSessionHistoryResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetSessionHistoryResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetSessionsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetSessionsResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -132,8 +200,11 @@ public function getSessionHistory(?string $sort = null, ?int $accountId = null, } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSessionHistoryBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSessionsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -141,8 +212,11 @@ public function getSessionHistory(?string $sort = null, ?int $accountId = null, } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetSessionHistoryUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetSessionsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -163,24 +237,43 @@ public function getSessionHistory(?string $sort = null, ?int $accountId = null, * @return Operations\GetTranscodeSessionsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getTranscodeSessions(): Operations\GetTranscodeSessionsResponse + public function getTranscodeSessions(?Options $options = null): Operations\GetTranscodeSessionsResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/transcode/sessions'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('getTranscodeSessions', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetTranscodeSessionsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetTranscodeSessionsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetTranscodeSessionsResponse( statusCode: $statusCode, contentType: $contentType, @@ -193,8 +286,11 @@ public function getTranscodeSessions(): Operations\GetTranscodeSessionsResponse } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTranscodeSessionsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTranscodeSessionsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -202,8 +298,11 @@ public function getTranscodeSessions(): Operations\GetTranscodeSessionsResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTranscodeSessionsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTranscodeSessionsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -225,24 +324,42 @@ public function getTranscodeSessions(): Operations\GetTranscodeSessionsResponse * @return Operations\StopTranscodeSessionResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function stopTranscodeSession(string $sessionKey): Operations\StopTranscodeSessionResponse + public function stopTranscodeSession(string $sessionKey, ?Options $options = null): Operations\StopTranscodeSessionResponse { $request = new Operations\StopTranscodeSessionRequest( sessionKey: $sessionKey, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/transcode/sessions/{sessionKey}', Operations\StopTranscodeSessionRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $url = Utils\Utils::generateUrl($baseUrl, '/transcode/sessions/{sessionKey}', Operations\StopTranscodeSessionRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('DELETE', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('stopTranscodeSession', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 204) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\StopTranscodeSessionResponse( statusCode: $statusCode, contentType: $contentType, @@ -250,8 +367,11 @@ public function stopTranscodeSession(string $sessionKey): Operations\StopTransco ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StopTranscodeSessionBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StopTranscodeSessionBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -259,8 +379,11 @@ public function stopTranscodeSession(string $sessionKey): Operations\StopTransco } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StopTranscodeSessionUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StopTranscodeSessionUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Statistics.php b/src/Statistics.php index eb89456..7bee57a 100644 --- a/src/Statistics.php +++ b/src/Statistics.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Statistics @@ -21,39 +23,80 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Get Media Statistics + * Get Bandwidth Statistics * - * This will return the media statistics for the server + * This will return the bandwidth statistics for the server * * @param ?int $timespan - * @return Operations\GetStatisticsResponse + * @return Operations\GetBandwidthStatisticsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getStatistics(?int $timespan = null): Operations\GetStatisticsResponse + public function getBandwidthStatistics(?int $timespan = null, ?Options $options = null): Operations\GetBandwidthStatisticsResponse { - $request = new Operations\GetStatisticsRequest( + $request = new Operations\GetBandwidthStatisticsRequest( timespan: $timespan, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/statistics/media'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetStatisticsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/statistics/bandwidth'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetBandwidthStatisticsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getBandwidthStatistics', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetStatisticsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetStatisticsResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetBandwidthStatisticsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetBandwidthStatisticsResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -65,8 +108,11 @@ public function getStatistics(?int $timespan = null): Operations\GetStatisticsRe } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetStatisticsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetBandwidthStatisticsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -74,8 +120,11 @@ public function getStatistics(?int $timespan = null): Operations\GetStatisticsRe } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetStatisticsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetBandwidthStatisticsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -97,28 +146,49 @@ public function getStatistics(?int $timespan = null): Operations\GetStatisticsRe * @return Operations\GetResourcesStatisticsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getResourcesStatistics(?int $timespan = null): Operations\GetResourcesStatisticsResponse + public function getResourcesStatistics(?int $timespan = null, ?Options $options = null): Operations\GetResourcesStatisticsResponse { $request = new Operations\GetResourcesStatisticsRequest( timespan: $timespan, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/statistics/resources'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetResourcesStatisticsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetResourcesStatisticsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getResourcesStatistics', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetResourcesStatisticsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetResourcesStatisticsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetResourcesStatisticsResponse( statusCode: $statusCode, contentType: $contentType, @@ -131,8 +201,11 @@ public function getResourcesStatistics(?int $timespan = null): Operations\GetRes } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetResourcesStatisticsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetResourcesStatisticsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -140,8 +213,11 @@ public function getResourcesStatistics(?int $timespan = null): Operations\GetRes } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetResourcesStatisticsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetResourcesStatisticsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -155,37 +231,58 @@ public function getResourcesStatistics(?int $timespan = null): Operations\GetRes } /** - * Get Bandwidth Statistics + * Get Media Statistics * - * This will return the bandwidth statistics for the server + * This will return the media statistics for the server * * @param ?int $timespan - * @return Operations\GetBandwidthStatisticsResponse + * @return Operations\GetStatisticsResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getBandwidthStatistics(?int $timespan = null): Operations\GetBandwidthStatisticsResponse + public function getStatistics(?int $timespan = null, ?Options $options = null): Operations\GetStatisticsResponse { - $request = new Operations\GetBandwidthStatisticsRequest( + $request = new Operations\GetStatisticsRequest( timespan: $timespan, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/statistics/bandwidth'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetBandwidthStatisticsRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/statistics/media'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetStatisticsRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getStatistics', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetBandwidthStatisticsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetBandwidthStatisticsResponse( + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetStatisticsResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetStatisticsResponse( statusCode: $statusCode, contentType: $contentType, rawResponse: $httpResponse, @@ -197,8 +294,11 @@ public function getBandwidthStatistics(?int $timespan = null): Operations\GetBan } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetBandwidthStatisticsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetStatisticsBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -206,8 +306,11 @@ public function getBandwidthStatistics(?int $timespan = null): Operations\GetBan } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetBandwidthStatisticsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetStatisticsUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Updater.php b/src/Updater.php index 04bb114..542f062 100644 --- a/src/Updater.php +++ b/src/Updater.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Updater @@ -21,47 +23,90 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** - * Querying status of updates + * Apply Updates * - * Querying status of updates + * Note that these two parameters are effectively mutually exclusive. The `tonight` parameter takes precedence and `skip` will be ignored if `tonight` is also passed * - * @return Operations\GetUpdateStatusResponse + * + * @param ?Operations\Tonight $tonight + * @param ?Operations\Skip $skip + * @return Operations\ApplyUpdatesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getUpdateStatus(): Operations\GetUpdateStatusResponse + public function applyUpdates(?Operations\Tonight $tonight = null, ?Operations\Skip $skip = null, ?Options $options = null): Operations\ApplyUpdatesResponse { + $request = new Operations\ApplyUpdatesRequest( + tonight: $tonight, + skip: $skip, + ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/updater/status'); - $options = ['http_errors' => false]; - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $url = Utils\Utils::generateUrl($baseUrl, '/updater/apply'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\ApplyUpdatesRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); + $hookContext = new HookContext('applyUpdates', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode == 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - if (Utils\Utils::matchContentType($contentType, 'application/json')) { - $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetUpdateStatusResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); - $response = new Operations\GetUpdateStatusResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse, - object: $obj); + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); - return $response; - } else { - throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); - } + return new Operations\ApplyUpdatesResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse + ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetUpdateStatusBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\ApplyUpdatesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -69,14 +114,17 @@ public function getUpdateStatus(): Operations\GetUpdateStatusResponse } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetUpdateStatusUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\ApplyUpdatesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode == 500 || $statusCode >= 500 && $statusCode < 600) { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); @@ -92,25 +140,45 @@ public function getUpdateStatus(): Operations\GetUpdateStatusResponse * @return Operations\CheckForUpdatesResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function checkForUpdates(?Operations\Download $download = null): Operations\CheckForUpdatesResponse + public function checkForUpdates(?Operations\Download $download = null, ?Options $options = null): Operations\CheckForUpdatesResponse { $request = new Operations\CheckForUpdatesRequest( download: $download, ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/updater/check'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\CheckForUpdatesRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); - + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\CheckForUpdatesRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); + $hookContext = new HookContext('checkForUpdates', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\CheckForUpdatesResponse( statusCode: $statusCode, contentType: $contentType, @@ -118,8 +186,11 @@ public function checkForUpdates(?Operations\Download $download = null): Operatio ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\CheckForUpdatesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\CheckForUpdatesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -127,8 +198,11 @@ public function checkForUpdates(?Operations\Download $download = null): Operatio } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\CheckForUpdatesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\CheckForUpdatesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -142,45 +216,67 @@ public function checkForUpdates(?Operations\Download $download = null): Operatio } /** - * Apply Updates - * - * Note that these two parameters are effectively mutually exclusive. The `tonight` parameter takes precedence and `skip` will be ignored if `tonight` is also passed + * Querying status of updates * + * Querying status of updates * - * @param ?Operations\Tonight $tonight - * @param ?Operations\Skip $skip - * @return Operations\ApplyUpdatesResponse + * @return Operations\GetUpdateStatusResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function applyUpdates(?Operations\Tonight $tonight = null, ?Operations\Skip $skip = null): Operations\ApplyUpdatesResponse + public function getUpdateStatus(?Options $options = null): Operations\GetUpdateStatusResponse { - $request = new Operations\ApplyUpdatesRequest( - tonight: $tonight, - skip: $skip, - ); $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); - $url = Utils\Utils::generateUrl($baseUrl, '/updater/apply'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\ApplyUpdatesRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('PUT', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $url = Utils\Utils::generateUrl($baseUrl, '/updater/status'); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getUpdateStatus', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { - return new Operations\ApplyUpdatesResponse( - statusCode: $statusCode, - contentType: $contentType, - rawResponse: $httpResponse - ); + if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + + $serializer = Utils\JSON::createSerializer(); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetUpdateStatusResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $response = new Operations\GetUpdateStatusResponse( + statusCode: $statusCode, + contentType: $contentType, + rawResponse: $httpResponse, + object: $obj); + + return $response; + } else { + throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); + } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\ApplyUpdatesBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetUpdateStatusBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -188,14 +284,17 @@ public function applyUpdates(?Operations\Tonight $tonight = null, ?Operations\Sk } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\ApplyUpdatesUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetUpdateStatusUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown content type received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } - } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode == 500 || $statusCode >= 500 && $statusCode < 600) { + } elseif ($statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('API error occurred', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); } else { throw new \LukeHagar\Plex_API\Models\Errors\SDKException('Unknown status code received', $statusCode, $httpResponse->getBody()->getContents(), $httpResponse); diff --git a/src/Utils/Options.php b/src/Utils/Options.php new file mode 100644 index 0000000..1d64734 --- /dev/null +++ b/src/Utils/Options.php @@ -0,0 +1,67 @@ +|null $retryCodes + */ + public ?array $retryCodes = null; + + public static function builder(): OptionsBuilder + { + return new OptionsBuilder(); + } +} + +class OptionsBuilder +{ + public Options $options; + + public function __construct() + { + $this->options = new Options(); + } + + /** + * Sets the configuration to use for retries. + * + * @param RetryConfig $config + * @return OptionsBuilder + */ + public function setRetryConfig(RetryConfig $config): OptionsBuilder + { + $this->options->retryConfig = $config; + + return $this; + } + + /** + * Specifies which HTTP status codes should be retried. + * + * @param array $codes + * @return OptionsBuilder + */ + public function setRetryCodes(array $codes): OptionsBuilder + { + $this->options->retryCodes = $codes; + + return $this; + } + + public function build(): Options + { + return $this->options; + } +} diff --git a/src/Utils/QueryParameters.php b/src/Utils/QueryParameters.php index 9f60b47..de9cebb 100644 --- a/src/Utils/QueryParameters.php +++ b/src/Utils/QueryParameters.php @@ -8,6 +8,7 @@ namespace LukeHagar\Plex_API\Utils; +use Psr\Http\Message\RequestInterface; use ReflectionProperty; class QueryParameters @@ -15,10 +16,11 @@ class QueryParameters /** * @param string $type * @param mixed $queryParams + * @param array $urlOverride * @param array>>|null $globals - * @return ?string + * @return array */ - public function parseQueryParams(string $type, mixed $queryParams, ?array $globals = null): ?string + public function parseQueryParams(string $type, mixed $queryParams, array $urlOverride, ?array $globals = null): array { $parts = []; @@ -44,28 +46,29 @@ public function parseQueryParams(string $type, mixed $queryParams, ?array $globa if ($metadata === null) { continue; } - if (! empty($metadata->serialization)) { - $parts[] = $this->parseSerializationParams($metadata, $value); + $parts = array_merge($parts, $this->parseSerializationParams($metadata, $value)); } else { match ($metadata->style) { - 'deepObject' => $parts[] = $this->parseDeepObjectParams($metadata, $value), - 'form' => $parts[] = $this->parseDelimitedParams($metadata, $value, ','), - 'pipeDelimited' => $parts[] = $this->parseDelimitedParams($metadata, $value, '|'), + 'deepObject' => $parts = array_merge_recursive($parts, $this->parseDeepObjectParams($metadata, $value)), + 'form' => $parts = array_merge_recursive($parts, $this->parseDelimitedParams($metadata, $value, ',')), + 'pipeDelimited' => $parts = array_merge_recursive($parts, $this->parseDelimitedParams($metadata, $value, '|')), default => throw new \RuntimeException('Unsupported style '.$metadata->style), }; } } - return empty($parts) ? null : implode('&', $parts); + $parts = array_merge($parts, $urlOverride); + + return $parts; } /** * @param ParamsMetadata $metadata * @param mixed $value - * @return string + * @return array */ - private function parseSerializationParams(ParamsMetadata $metadata, mixed $value): string + private function parseSerializationParams(ParamsMetadata $metadata, mixed $value): array { $queryParams = []; @@ -78,15 +81,15 @@ private function parseSerializationParams(ParamsMetadata $metadata, mixed $value throw new \Exception('Unsupported serialization: '.$metadata->serialization); } - return http_build_query($queryParams); + return $queryParams; } /** * @param ParamsMetadata $metadata * @param mixed $value - * @return string + * @return array|string> */ - private function parseDeepObjectParams(ParamsMetadata $metadata, mixed $value): string + private function parseDeepObjectParams(ParamsMetadata $metadata, mixed $value): array { $queryParams = []; @@ -146,16 +149,16 @@ private function parseDeepObjectParams(ParamsMetadata $metadata, mixed $value): break; } - return $this->buildQueryString($queryParams); + return $queryParams; } /** * @param ParamsMetadata $metadata * @param mixed $value * @param string $delimiter - * @return string + * @return array|string> */ - private function parseDelimitedParams(ParamsMetadata $metadata, mixed $value, string $delimiter): string + private function parseDelimitedParams(ParamsMetadata $metadata, mixed $value, string $delimiter): array { $queryParams = []; @@ -230,30 +233,45 @@ private function parseDelimitedParams(ParamsMetadata $metadata, mixed $value, st $queryParams[$metadata->name] = valToString($value, ['dateTimeFormat' => $dateTimeFormat]); } - return $this->buildQueryString($queryParams); + return $queryParams; } /** - * @param array|string> $queryParams + * @param array> $queryParams + * @return string */ - private function buildQueryString(array $queryParams): string + private static function recursivelyBuildQueryString(array $queryParams): string { - ksort($queryParams); - $parts = []; + foreach ($queryParams as $key => $value) { - if (is_array($value)) { - foreach ($value as $item) { - $parts[] = urlencode($key).'='.urlencode($item); - } + if (is_array($value) && array_is_list($value)) { + $parts = array_merge($parts, array_map(fn ($v) => self::buildQueryString($key, $v), $value)); + } elseif (is_array($value)) { + $res = self::recursivelyBuildQueryString($value); + $parts[] = self::buildQueryString($key, $res); } else { - $parts[] = urlencode($key).'='.urlencode($value); + $parts[] = self::buildQueryString($key, $value); } } return implode('&', $parts); } + /** + * @param string|int $queryParamKey + * @param string $queryParamValue + * @return string + */ + private static function buildQueryString(string|int $queryParamKey, string $queryParamValue): string + { + if (is_int($queryParamKey)) { + $queryParamKey = (string) $queryParamKey; + } + + return implode('=', [urlencode($queryParamKey), urlencode($queryParamValue)]); + } + private function parseQueryParamsMetadata(ReflectionProperty $property): ?ParamsMetadata { $metadataStr = SpeakeasyMetadata::find($property->getAttributes(SpeakeasyMetadata::class), 'queryParam'); @@ -268,5 +286,21 @@ private function parseQueryParamsMetadata(ReflectionProperty $property): ?Params return $metadata; } -} + /** + * @param RequestInterface $httpRequest + * @param array $queryParams + * @return string + */ + public static function standardizeQueryParams(RequestInterface $httpRequest, array $queryParams): string + { + $uri = $httpRequest->getUri(); + $query = $uri->getQuery(); + $requestQueryParams = Utils::proper_parse_str($query); + + $allParams = array_merge($queryParams, $requestQueryParams); + $uri = $uri->withQuery(QueryParameters::recursivelyBuildQueryString($allParams)); + + return $uri->getQuery(); + } +} diff --git a/src/Utils/RequestBodies.php b/src/Utils/RequestBodies.php index 658712f..70ccc45 100644 --- a/src/Utils/RequestBodies.php +++ b/src/Utils/RequestBodies.php @@ -105,7 +105,7 @@ private function serializeMultipart(mixed $value): array } if ($metadata->file) { - $options['multipart'][] = $this->serializeMultipartFile($val); + $options['multipart'][] = $this->serializeMultipartFile($metadata->name, $val); } elseif ($metadata->json) { $serializer = JSON::createSerializer(); $options['multipart'][] = [ @@ -138,16 +138,16 @@ private function serializeMultipart(mixed $value): array } /** + * @param string $fieldName * @param mixed $value * @return array */ - private function serializeMultipartFile(mixed $value): array + private function serializeMultipartFile(string $fieldName, mixed $value): array { if (gettype($value) != 'object') { throw new \Exception('Invalid type for multipart/form-data file'); } - $name = ''; $filename = ''; $content = ''; @@ -164,17 +164,16 @@ private function serializeMultipartFile(mixed $value): array if ($metadata->content) { $content = $val; } else { - $name = $metadata->name; $filename = $val; } } - if (empty($name) || empty($filename) || empty($content)) { + if (empty($filename) || empty($content)) { throw new \Exception('Invalid multipart/form-data file'); } return [ - 'name' => $name, + 'name' => $fieldName, 'contents' => $content, 'filename' => $filename, ]; diff --git a/src/Utils/Retry/PermanentError.php b/src/Utils/Retry/PermanentError.php new file mode 100644 index 0000000..3de4721 --- /dev/null +++ b/src/Utils/Retry/PermanentError.php @@ -0,0 +1,17 @@ +initialInterval = $initialIntervalMs; + $this->maxInterval = $maxIntervalMs; + $this->exponent = $exponent; + $this->maxElapsedTime = $maxElapsedTimeMs; + $this->retryConnectionErrors = $retryConnectionErrors; + } +} diff --git a/src/Utils/Retry/RetryConfigNone.php b/src/Utils/Retry/RetryConfigNone.php new file mode 100644 index 0000000..c9bd379 --- /dev/null +++ b/src/Utils/Retry/RetryConfigNone.php @@ -0,0 +1,15 @@ + $statusCodesToRetry + * @return ResponseInterface + */ + public static function retryWrapper(callable $fn, RetryConfig $config, array $statusCodesToRetry): ResponseInterface + { + $retryCount = 0; + $start = LocalDateTime::now(TimeZone::utc()); + while (true) { + try { + $httpResponse = $fn(); + if ($config->strategy !== RetryStrategy::NONE && RetryUtils::isRetryableResponse($httpResponse, $statusCodesToRetry)) { + throw new TemporaryError('Response failed with retryable status code', response: $httpResponse); + } + + return $httpResponse; + } catch (\Exception $e) { + if ($e instanceof PermanentError) { + throw $e->getPrevious(); + } + if ($config instanceof RetryConfigNone) { + throw $e->getPrevious(); + } elseif ($config instanceof RetryConfigBackoff) { + $elapsed = 1000 * (LocalDateTime::now(TimeZone::utc())->getTime()->toSecondOfDay() - $start->getTime()->toSecondOfDay()); + if ($elapsed > $config->maxElapsedTime) { + if ($e instanceof TemporaryError) { + return $e->response; + } + throw $e; + } + $retryInterval = 0; + if ($e instanceof TemporaryError) { + $retryInterval = RetryUtils::retryInterval($e->response); + } + if ($retryInterval <= 0) { + $retryInterval = $config->initialInterval * pow($retryCount, $config->exponent) + (rand(0, 1) * 1000); + } + + $d = min($retryInterval, $config->maxInterval); + + usleep((int) $d * 1000); + + $retryCount++; + } + } + } + } + + public static function retryInterval(?ResponseInterface $response): int + { + if ($response == null) { + return 0; + } + $retryAfter = $response->getHeader('Retry-After'); + if (count($retryAfter) == 0) { + return 0; + } + $retryAfter = $retryAfter[0]; + if ((string) (int) $retryAfter == $retryAfter) { + return (int) $retryAfter * 1000; + } + + try { + $parsedDate = LocalDateTime::parse($retryAfter); + $deltaMS = ($parsedDate->getNano() * 1000) - (LocalDateTime::now(TimeZone::utc())->getNano() * 1000); + + return $deltaMS > 0 ? (int) ceil($deltaMS) : 0; + } catch (DateTimeParseException|DateTimeException $e) { + return 0; + } + } + + /** + * @param ResponseInterface $response + * @param array $statusCodes + * @return bool + */ + public static function isRetryableResponse(ResponseInterface $response, array $statusCodes): bool + { + $actual = (string) $response->getStatusCode(); + + $final = false; + foreach ($statusCodes as $code) { + $matches = []; + if (! preg_match('/^[0-9]xx$/', $code, $matches)) { + return $code === $actual; + } + + $expectFamily = mb_substr($code, 0, 1); + if (! $expectFamily) { + throw new \Exception('Invalid status code range'); + } + + $actualFamily = mb_substr($actual, 0, 1); + if (! $actualFamily) { + throw new \Exception('Invalid response status code: {$actual}'); + } + + if ($actualFamily === $expectFamily) { + $final = true; + } + } + + return $final; + } +} diff --git a/src/Utils/Retry/TemporaryError.php b/src/Utils/Retry/TemporaryError.php new file mode 100644 index 0000000..b570ddd --- /dev/null +++ b/src/Utils/Retry/TemporaryError.php @@ -0,0 +1,21 @@ +response = $response; + } +} diff --git a/src/Utils/SecurityClient.php b/src/Utils/SecurityClient.php index 1208f33..c61f4ca 100644 --- a/src/Utils/SecurityClient.php +++ b/src/Utils/SecurityClient.php @@ -92,7 +92,7 @@ private function addClientOptions(array $options): array } if (count($this->clientOptions['headers']) > 0) { - $options['headers'] = array_merge_recursive($options['headers'], $this->clientOptions['headers']); + $options['headers'] = array_merge($this->clientOptions['headers'], $options['headers']); } if (count($this->clientOptions['query']) > 0) { diff --git a/src/Utils/ServerDetails.php b/src/Utils/ServerDetails.php new file mode 100644 index 0000000..b7759e5 --- /dev/null +++ b/src/Utils/ServerDetails.php @@ -0,0 +1,29 @@ + options + */ + public array $options; + + /** + * @param string $baseUrl + * @param array $options + */ + public function __construct(string $baseUrl, array $options) + { + $this->baseUrl = $baseUrl; + $this->options = $options; + } +} \ No newline at end of file diff --git a/src/Utils/Utils.php b/src/Utils/Utils.php index eeeed41..cf11102 100644 --- a/src/Utils/Utils.php +++ b/src/Utils/Utils.php @@ -9,6 +9,7 @@ namespace LukeHagar\Plex_API\Utils; use GuzzleHttp\ClientInterface; +use Psr\Http\Message\RequestInterface; class Utils { @@ -141,20 +142,25 @@ public static function serializeRequestBody(mixed $request, string $requestField * @param array>>|null $globals * @return array */ - public static function getQueryParams(string $type, mixed $queryParams, ?array $globals = null): array + public static function getQueryParams(string $type, mixed $queryParams, ?string $urlOverride, ?array $globals = null): array { $qp = new QueryParameters(); $globals ??= []; - $query = $qp->parseQueryParams($type, $queryParams, $globals); + $parsedUrl = []; + if ($urlOverride != null) { + $splitUrl = explode('?', $urlOverride); + if (count($splitUrl) > 1) { + $parsedUrl = self::proper_parse_str($splitUrl[1]); + } + } + $query = $qp->parseQueryParams($type, $queryParams, $parsedUrl, $globals); if ($query === null) { return []; } - return [ - 'query' => $query, - ]; + return $query; } /** @@ -174,6 +180,182 @@ public static function getHeaders(mixed $headers, ?array $globals = null): array 'headers' => $headers, ]; } + + /** + * The builtin php parse_str function does not + * properly implement query param parsing (specifically it doesn't handle + * multiple values from the same key) This function is a bit more correct + * @param string $str + * @return array + */ + public static function proper_parse_str($str) + { + $arr = []; + + if (empty($str)) { + return $arr; + } + + $pairs = explode('&', $str); + + foreach ($pairs as $i) { + [$name,$value] = explode('=', $i, 2); + + // if name already exists + if (isset($arr[$name])) { + // stick multiple values into an array + if (is_array($arr[$name])) { + $arr[$name][] = $value; + } else { + $arr[$name] = [$arr[$name], $value]; + } + } else { + // else treat as scalar + $arr[$name] = $value; + } + } + + return $arr; + } + + /** + * convertHeadersToOptions will convert the headers from a request to options for a client. + * + * @param RequestInterface $request + * @param array $options + * @return array + */ + public static function convertHeadersToOptions(RequestInterface $request, array $options): array + { + $headers = $request->getHeaders(); + foreach ($request->getHeaders() as $name => $values) { + $options['headers'][$name] = $values; + } + + return $options; + } + + /** + * removeHeaders will remove all headers from a request + * + * @param RequestInterface $request + * @return RequestInterface + */ + public static function removeHeaders(RequestInterface $request): RequestInterface + { + $headers = $request->getHeaders(); + foreach ($request->getHeaders() as $name => $values) { + $request = $request->withoutHeader($name); + } + + return $request; + } + + /** + * urljoin joins a base URL and a relative URL. + * this is a PHP port of the Python urllib.urljoin function + * + * @param string $base + * @param string $rel + * @return string + */ + public static function urljoin(string $base, string $rel): string + { + $pbase = parse_url($base); + if ($pbase === false) { + throw new \InvalidArgumentException('Invalid base URL: '.$base); + } else { + $pbase = (array) $pbase; + } + $prel = parse_url($rel); + if ($prel === false) { + throw new \InvalidArgumentException('Invalid relative URL: '.$rel); + } else { + $prel = (array) $prel; + } + + $merged = array_merge($pbase, $prel); + if (array_key_exists('path', $pbase) && array_key_exists('path', $prel) && $prel['path'][0] != '/') { + // Relative path + $dir = preg_replace('@/[^/]*$@', '', $pbase['path']); + $merged['path'] = $dir.'/'.$prel['path']; + } elseif (array_key_exists('path', $pbase)) { + $merged['path'] = $pbase['path']; + } elseif (array_key_exists('path', $prel)) { + $merged['path'] = $prel['path']; + } else { + $merged['path'] = ''; + } + + // Get the path components, and remove the initial empty one + $pathParts = explode('/', $merged['path']); + array_shift($pathParts); + + $path = []; + $prevPart = ''; + foreach ($pathParts as $part) { + if ($part == '..' && count($path) > 0) { + // Cancel out the parent directory (if there's a parent to cancel) + $parent = array_pop($path); + // But if it was also a parent directory, leave it in + if ($parent == '..') { + array_push($path, $parent); + array_push($path, $part); + } + } elseif ($prevPart != '' || ($part != '.' && $part != '')) { + // Don't include empty or current-directory components + if ($part == '.') { + $part = ''; + } + array_push($path, $part); + } + $prevPart = $part; + } + $merged['path'] = '/'.implode('/', $path); + + $ret = ''; + if (isset($merged['scheme'])) { + $ret .= $merged['scheme'].':'; + } + + if (isset($merged['scheme']) || isset($merged['host'])) { + $ret .= '//'; + } + + if (isset($prel['host'])) { + $hostSource = $prel; + } else { + $hostSource = $pbase; + } + + // username, password, and port are associated with the hostname, not merged + if (isset($hostSource['host'])) { + if (isset($hostSource['user'])) { + $ret .= $hostSource['user']; + if (isset($hostSource['pass'])) { + $ret .= ':'.$hostSource['pass']; + } + $ret .= '@'; + } + $ret .= $hostSource['host']; + if (isset($hostSource['port'])) { + $ret .= ':'.$hostSource['port']; + } + } + + $ret .= $merged['path']; + + if (isset($prel['query'])) { + $ret .= '?'.$prel['query']; + } + + if (isset($prel['fragment'])) { + $ret .= '#'.$prel['fragment']; + } + + return $ret; + } + } function removePrefix(string $text, string $prefix): string @@ -242,6 +424,7 @@ function valToString(mixed $val, array $extras): string default: return var_export($val, true); } + } /** diff --git a/src/Video.php b/src/Video.php index f70d8ad..5df2025 100644 --- a/src/Video.php +++ b/src/Video.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Video @@ -21,6 +23,26 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** * Get the timeline for a media item @@ -31,22 +53,42 @@ public function __construct(public SDKConfiguration $sdkConfig) * @return Operations\GetTimelineResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getTimeline(Operations\GetTimelineRequest $request): Operations\GetTimelineResponse + public function getTimeline(Operations\GetTimelineRequest $request, ?Options $options = null): Operations\GetTimelineResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/:/timeline'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetTimelineRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\GetTimelineRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('getTimeline', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\GetTimelineResponse( statusCode: $statusCode, contentType: $contentType, @@ -54,8 +96,11 @@ public function getTimeline(Operations\GetTimelineRequest $request): Operations\ ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTimelineBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTimelineBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -63,8 +108,11 @@ public function getTimeline(Operations\GetTimelineRequest $request): Operations\ } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetTimelineUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetTimelineUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -86,22 +134,42 @@ public function getTimeline(Operations\GetTimelineRequest $request): Operations\ * @return Operations\StartUniversalTranscodeResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function startUniversalTranscode(Operations\StartUniversalTranscodeRequest $request): Operations\StartUniversalTranscodeResponse + public function startUniversalTranscode(Operations\StartUniversalTranscodeRequest $request, ?Options $options = null): Operations\StartUniversalTranscodeResponse { $baseUrl = Utils\Utils::templateUrl($this->sdkConfiguration->getServerUrl(), $this->sdkConfiguration->getServerDefaults()); $url = Utils\Utils::generateUrl($baseUrl, '/video/:/transcode/universal/start.mpd'); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\StartUniversalTranscodeRequest::class, $request, $this->sdkConfiguration->globals)); - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; - $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $qp = Utils\Utils::getQueryParams(Operations\StartUniversalTranscodeRequest::class, $request, $urlOverride); + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); + $hookContext = new HookContext('startUniversalTranscode', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + return new Operations\StartUniversalTranscodeResponse( statusCode: $statusCode, contentType: $contentType, @@ -109,8 +177,11 @@ public function startUniversalTranscode(Operations\StartUniversalTranscodeReques ); } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StartUniversalTranscodeBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StartUniversalTranscodeBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -118,8 +189,11 @@ public function startUniversalTranscode(Operations\StartUniversalTranscodeReques } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\StartUniversalTranscodeUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\StartUniversalTranscodeUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { diff --git a/src/Watchlist.php b/src/Watchlist.php index 2cad3a6..ad33140 100644 --- a/src/Watchlist.php +++ b/src/Watchlist.php @@ -8,7 +8,9 @@ namespace LukeHagar\Plex_API; +use LukeHagar\Plex_API\Hooks\HookContext; use LukeHagar\Plex_API\Models\Operations; +use LukeHagar\Plex_API\Utils\Options; use Speakeasy\Serializer\DeserializationContext; class Watchlist @@ -25,6 +27,26 @@ public function __construct(public SDKConfiguration $sdkConfig) { $this->sdkConfiguration = $sdkConfig; } + /** + * @param string $baseUrl + * @param array $urlVariables + * + * @return string + */ + public function getUrl(string $baseUrl, array $urlVariables): string + { + $serverDetails = $this->sdkConfiguration->getServerDetails(); + + if ($baseUrl == null) { + $baseUrl = $serverDetails->baseUrl; + } + + if ($urlVariables == null) { + $urlVariables = $serverDetails->options; + } + + return Utils\Utils::templateUrl($baseUrl, $urlVariables); + } /** * Get User Watchlist @@ -32,37 +54,58 @@ public function __construct(public SDKConfiguration $sdkConfig) * Get User Watchlist * * @param Operations\GetWatchListRequest $request - * @param string $serverURL + * @param ?string $serverURL * @return Operations\GetWatchListResponse * @throws \LukeHagar\Plex_API\Models\Errors\SDKException */ - public function getWatchList(Operations\GetWatchListRequest $request, ?string $serverURL = null): Operations\GetWatchListResponse + public function getWatchList(Operations\GetWatchListRequest $request, ?string $serverURL = null, ?Options $options = null): Operations\GetWatchListResponse { $baseUrl = Utils\Utils::templateUrl(Watchlist::GET_WATCH_LIST_SERVERS[0], [ ]); if (! empty($serverURL)) { $baseUrl = $serverURL; } - $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/watchlist/{filter}', Operations\GetWatchListRequest::class, $request, $this->sdkConfiguration->globals); - $options = ['http_errors' => false]; - $options = array_merge_recursive($options, Utils\Utils::getQueryParams(Operations\GetWatchListRequest::class, $request, $this->sdkConfiguration->globals)); - $options = array_merge_recursive($options, Utils\Utils::getHeaders($request, $this->sdkConfiguration->globals)); - if (! array_key_exists('headers', $options)) { - $options['headers'] = []; + $url = Utils\Utils::generateUrl($baseUrl, '/library/sections/watchlist/{filter}', Operations\GetWatchListRequest::class, $request); + $urlOverride = null; + $httpOptions = ['http_errors' => false]; + + $qp = Utils\Utils::getQueryParams(Operations\GetWatchListRequest::class, $request, $urlOverride); + $httpOptions = array_merge_recursive($httpOptions, Utils\Utils::getHeaders($request)); + if (! array_key_exists('headers', $httpOptions)) { + $httpOptions['headers'] = []; } - $options['headers']['Accept'] = 'application/json'; - $options['headers']['user-agent'] = $this->sdkConfiguration->userAgent; + $httpOptions['headers']['Accept'] = 'application/json'; + $httpOptions['headers']['user-agent'] = $this->sdkConfiguration->userAgent; $httpRequest = new \GuzzleHttp\Psr7\Request('GET', $url); - - - $httpResponse = $this->sdkConfiguration->securityClient->send($httpRequest, $options); + $hookContext = new HookContext('get-watch-list', null, $this->sdkConfiguration->securitySource); + $httpRequest = $this->sdkConfiguration->hooks->beforeRequest(new Hooks\BeforeRequestContext($hookContext), $httpRequest); + $httpOptions['query'] = Utils\QueryParameters::standardizeQueryParams($httpRequest, $qp); + $httpOptions = Utils\Utils::convertHeadersToOptions($httpRequest, $httpOptions); + $httpRequest = Utils\Utils::removeHeaders($httpRequest); + try { + $httpResponse = $this->sdkConfiguration->client->send($httpRequest, $httpOptions); + } catch (\GuzzleHttp\Exception\GuzzleException $error) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), null, $error); + if ($res !== null) { + $httpResponse = $res; + } + } $contentType = $httpResponse->getHeader('Content-Type')[0] ?? ''; $statusCode = $httpResponse->getStatusCode(); + if ($statusCode == 400 || $statusCode == 401 || $statusCode >= 400 && $statusCode < 500 || $statusCode >= 500 && $statusCode < 600) { + $res = $this->sdkConfiguration->hooks->afterError(new Hooks\AfterErrorContext($hookContext), $httpResponse, null); + if ($res !== null) { + $httpResponse = $res; + } + } if ($statusCode == 200) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Operations\GetWatchListResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Operations\GetWatchListResponseBody', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $response = new Operations\GetWatchListResponse( statusCode: $statusCode, contentType: $contentType, @@ -75,8 +118,11 @@ public function getWatchList(Operations\GetWatchListRequest $request, ?string $s } } elseif ($statusCode == 400) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetWatchListBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetWatchListBadRequest', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else { @@ -84,8 +130,11 @@ public function getWatchList(Operations\GetWatchListRequest $request, ?string $s } } elseif ($statusCode == 401) { if (Utils\Utils::matchContentType($contentType, 'application/json')) { + $httpResponse = $this->sdkConfiguration->hooks->afterSuccess(new Hooks\AfterSuccessContext($hookContext), $httpResponse); + $serializer = Utils\JSON::createSerializer(); - $obj = $serializer->deserialize((string) $httpResponse->getBody(), '\LukeHagar\Plex_API\Models\Errors\GetWatchListUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); + $responseData = (string) $httpResponse->getBody(); + $obj = $serializer->deserialize($responseData, '\LukeHagar\Plex_API\Models\Errors\GetWatchListUnauthorized', 'json', DeserializationContext::create()->setRequireAllRequiredProperties(true)); $obj->rawResponse = $httpResponse; throw $obj->toException(); } else {