diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 22b4865..a197a8c 100755 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: dfa99515-01c0-42eb-9be5-ee212fd03eb3 management: - docChecksum: 14b35829d4be91a88269761c3ed01426 + docChecksum: 7dec92ab9151a1b5a35df5faa81811ba docVersion: 0.0.3 - speakeasyVersion: 1.484.1 - generationVersion: 2.503.2 - releaseVersion: 0.17.4 - configChecksum: 03b930c277a60bb2913235285cab5b77 + speakeasyVersion: 1.487.0 + generationVersion: 2.506.0 + releaseVersion: 0.18.0 + configChecksum: 2c67410bd5eed3f54f23e32506d938ab repoURL: https://github.com/LukeHagar/plexgo.git repoSubDirectory: . installationURL: https://github.com/LukeHagar/plexgo @@ -14,8 +14,8 @@ management: features: go: additionalDependencies: 0.1.0 - constsAndDefaults: 0.1.6 - core: 3.6.12 + constsAndDefaults: 0.1.7 + core: 3.7.0 defaultEnabledRetries: 0.2.0 deprecations: 2.81.2 downloadStreams: 0.1.2 @@ -98,6 +98,7 @@ generatedFiles: - /models/operations/gettransienttoken.go - /models/operations/getupdatestatus.go - /models/operations/getuserfriends.go + - /models/operations/getusers.go - /models/operations/getwatchlist.go - /models/operations/logline.go - /models/operations/logmultiline.go @@ -175,6 +176,7 @@ generatedFiles: - /models/sdkerrors/gettransienttoken.go - /models/sdkerrors/getupdatestatus.go - /models/sdkerrors/getuserfriends.go + - /models/sdkerrors/getusers.go - /models/sdkerrors/getwatchlist.go - /models/sdkerrors/logline.go - /models/sdkerrors/logmultiline.go @@ -206,6 +208,12 @@ generatedFiles: - docs/models/operations/addplaylistcontentsrequest.md - docs/models/operations/addplaylistcontentsresponse.md - docs/models/operations/addplaylistcontentsresponsebody.md + - docs/models/operations/alllibraries.md + - docs/models/operations/allowcameraupload.md + - docs/models/operations/allowchannels.md + - docs/models/operations/allowsubtitleadmin.md + - docs/models/operations/allowsync.md + - docs/models/operations/allowtuners.md - docs/models/operations/applyupdatesrequest.md - docs/models/operations/applyupdatesresponse.md - docs/models/operations/autoselectsubtitle.md @@ -568,6 +576,7 @@ generatedFiles: - docs/models/operations/gettopwatchedcontentresponse.md - docs/models/operations/gettopwatchedcontentresponsebody.md - docs/models/operations/gettopwatchedcontentrole.md + - docs/models/operations/gettopwatchedcontentuser.md - docs/models/operations/gettranscodesessionsmediacontainer.md - docs/models/operations/gettranscodesessionsresponse.md - docs/models/operations/gettranscodesessionsresponsebody.md @@ -578,11 +587,17 @@ generatedFiles: - docs/models/operations/getupdatestatusresponse.md - docs/models/operations/getupdatestatusresponsebody.md - docs/models/operations/getuserfriendsresponse.md + - docs/models/operations/getusersmediacontainer.md + - docs/models/operations/getusersrequest.md + - docs/models/operations/getusersresponse.md + - docs/models/operations/getusersresponsebody.md + - docs/models/operations/getusersserver.md - docs/models/operations/getwatchlistrequest.md - docs/models/operations/getwatchlistresponse.md - docs/models/operations/getwatchlistresponsebody.md - docs/models/operations/guids.md - docs/models/operations/hasthumbnail.md + - docs/models/operations/home.md - docs/models/operations/hub.md - docs/models/operations/image.md - docs/models/operations/includecollections.md @@ -619,9 +634,11 @@ generatedFiles: - docs/models/operations/operator.md - docs/models/operations/optimizedforstreaming.md - docs/models/operations/option.md + - docs/models/operations/owned.md - docs/models/operations/part.md - docs/models/operations/pastsubscription.md - docs/models/operations/pathparamtaskname.md + - docs/models/operations/pending.md - docs/models/operations/performsearchrequest.md - docs/models/operations/performsearchresponse.md - docs/models/operations/performvoicesearchrequest.md @@ -649,6 +666,7 @@ generatedFiles: - docs/models/operations/postuserssignindatauserprofile.md - docs/models/operations/postuserssignindatawatchedindicator.md - docs/models/operations/producer.md + - docs/models/operations/protected.md - docs/models/operations/protocol.md - docs/models/operations/provider.md - docs/models/operations/queryparamfilter.md @@ -662,6 +680,7 @@ generatedFiles: - docs/models/operations/ratings.md - docs/models/operations/release.md - docs/models/operations/responsebody.md + - docs/models/operations/restricted.md - docs/models/operations/role.md - docs/models/operations/scope.md - docs/models/operations/searchresult.md @@ -946,6 +965,10 @@ generatedFiles: - docs/models/sdkerrors/getuserfriendserrors.md - docs/models/sdkerrors/getuserfriendsplexerrors.md - docs/models/sdkerrors/getuserfriendsunauthorized.md + - docs/models/sdkerrors/getusersbadrequest.md + - docs/models/sdkerrors/getuserserrors.md + - docs/models/sdkerrors/getusersunauthorized.md + - docs/models/sdkerrors/getusersuserserrors.md - docs/models/sdkerrors/getwatchlistbadrequest.md - docs/models/sdkerrors/getwatchlisterrors.md - docs/models/sdkerrors/getwatchlistunauthorized.md @@ -1029,6 +1052,7 @@ generatedFiles: - docs/sdks/sessions/README.md - docs/sdks/statistics/README.md - docs/sdks/updater/README.md + - docs/sdks/users/README.md - docs/sdks/video/README.md - docs/sdks/watchlist/README.md - docs/types/date.md @@ -1065,6 +1089,7 @@ generatedFiles: - types/decimal.go - types/pointers.go - updater.go + - users.go - video.go - watchlist.go examples: @@ -2077,5 +2102,29 @@ examples: application/json: {"errors": [{"code": 1000, "message": "X-Plex-Client-Identifier is missing", "status": 400}, {"code": 1000, "message": "X-Plex-Client-Identifier is missing", "status": 400}]} "401": application/json: {"errors": [{"code": 1001, "message": "User could not be authenticated", "status": 401}, {"code": 1001, "message": "User could not be authenticated", "status": 401}, {"code": 1001, "message": "User could not be authenticated", "status": 401}]} + get-users: + "": + parameters: + header: + X-Plex-Client-Identifier: "3381b62b-9ab7-4e37-827b-203e9809eb58" + X-Plex-Product: "Plex for Roku" + X-Plex-Device: "Roku 3" + X-Plex-Device-Name: "Chrome" + X-Plex-Device-Screen-Resolution: "1487x1165,2560x1440" + X-Plex-Version: "2.4.1" + X-Plex-Platform: "Roku" + X-Plex-Features: "external-media,indirect-media,hub-style-list" + X-Plex-Model: "4200X" + X-Plex-Session-Id: "97e136ef-4ddd-4ff3-89a7-a5820c96c2ca" + X-Plex-Language: "en" + X-Plex-Platform-Version: "4.3 build 1057" + X-Plex-Token: "CV5xoxjTpFKUzBTShsaf" + responses: + "200": + application/xml: "0xa9CdebeF9E" + "400": + application/json: {"errors": [{"code": 1000, "message": "X-Plex-Client-Identifier is missing", "status": 400}, {"code": 1000, "message": "X-Plex-Client-Identifier is missing", "status": 400}]} + "401": + application/json: {"errors": [{"code": 1001, "message": "User could not be authenticated", "status": 401}, {"code": 1001, "message": "User could not be authenticated", "status": 401}]} examplesVersion: 1.0.0 generatedTests: {} diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index b6261c2..d09c286 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -13,7 +13,7 @@ generation: oAuth2ClientCredentialsEnabled: true oAuth2PasswordEnabled: false go: - version: 0.17.4 + version: 0.18.0 additionalDependencies: {} allowUnknownFieldsInWeakUnions: false clientServerStatusCodesAsErrors: true diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index cda5ed4..9c75b2f 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,4 +1,4 @@ -speakeasyVersion: 1.484.1 +speakeasyVersion: 1.487.0 sources: my-source: sourceNamespace: my-source @@ -9,19 +9,19 @@ sources: - main plexapi: sourceNamespace: plexapi - sourceRevisionDigest: sha256:0b88c8bfc41def63e19e91fdd4d51bab07cb947cc3d39d2b44e8523a209cec10 - sourceBlobDigest: sha256:89d5b8427d4fb61b25751aebbaf71f9613958e9e91073fc084fed2c2ec62ce55 + sourceRevisionDigest: sha256:e6ab335dd91a4165f4510e4a3af8a55819c6310b7e66251266d2384376f3ccae + sourceBlobDigest: sha256:89d1b1133e400c89f0d06efe5e5168f5ba25a413e1ab8380d442d6b233e2e5a9 tags: - latest - - speakeasy-sdk-regen-1738800558 + - speakeasy-sdk-regen-1738886963 targets: plexgo: source: plexapi sourceNamespace: plexapi - sourceRevisionDigest: sha256:0b88c8bfc41def63e19e91fdd4d51bab07cb947cc3d39d2b44e8523a209cec10 - sourceBlobDigest: sha256:89d5b8427d4fb61b25751aebbaf71f9613958e9e91073fc084fed2c2ec62ce55 + sourceRevisionDigest: sha256:e6ab335dd91a4165f4510e4a3af8a55819c6310b7e66251266d2384376f3ccae + sourceBlobDigest: sha256:89d1b1133e400c89f0d06efe5e5168f5ba25a413e1ab8380d442d6b233e2e5a9 codeSamplesNamespace: code-samples-go-plexgo - codeSamplesRevisionDigest: sha256:56fbdcee207bdfb0340ee02eaeacfb389357affe2899881837f41fa2b7b5b043 + codeSamplesRevisionDigest: sha256:e556c9b714f159036257d9405e7e72e55f72c2ad96b306a7ccaa287d4d33829c workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/README.md b/README.md index 191916d..fa5e086 100644 --- a/README.md +++ b/README.md @@ -226,6 +226,10 @@ func main() { * [CheckForUpdates](docs/sdks/updater/README.md#checkforupdates) - Checking for updates * [ApplyUpdates](docs/sdks/updater/README.md#applyupdates) - Apply Updates +### [Users](docs/sdks/users/README.md) + +* [GetUsers](docs/sdks/users/README.md#getusers) - Get list of all connected users + ### [Video](docs/sdks/video/README.md) * [GetTimeline](docs/sdks/video/README.md#gettimeline) - Get the timeline for a media item diff --git a/RELEASES.md b/RELEASES.md index b6c9619..386033d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1022,4 +1022,14 @@ Based on: ### Generated - [go v0.17.4] . ### Releases -- [Go v0.17.4] https://github.com/LukeHagar/plexgo/releases/tag/v0.17.4 - . \ No newline at end of file +- [Go v0.17.4] https://github.com/LukeHagar/plexgo/releases/tag/v0.17.4 - . + +## 2025-02-07 00:09:08 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.487.0 (2.506.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [go v0.18.0] . +### Releases +- [Go v0.18.0] https://github.com/LukeHagar/plexgo/releases/tag/v0.18.0 - . \ No newline at end of file diff --git a/codeSamples.yaml b/codeSamples.yaml index ba62cb0..8108686 100644 --- a/codeSamples.yaml +++ b/codeSamples.yaml @@ -459,6 +459,12 @@ actions: - lang: go label: getTokenDetails source: "package main\n\nimport(\n\t\"context\"\n\t\"github.com/LukeHagar/plexgo\"\n\t\"log\"\n)\n\nfunc main() {\n ctx := context.Background()\n \n s := plexgo.New(\n plexgo.WithSecurity(\"\"),\n )\n\n res, err := s.Authentication.GetTokenDetails(ctx)\n if err != nil {\n log.Fatal(err)\n }\n if res.UserPlexAccount != nil {\n // handle response\n }\n}" + - target: $["paths"]["/users"]["get"] + update: + x-codeSamples: + - lang: go + label: users + source: "package main\n\nimport(\n\t\"context\"\n\t\"github.com/LukeHagar/plexgo\"\n\t\"github.com/LukeHagar/plexgo/models/operations\"\n\t\"log\"\n)\n\nfunc main() {\n ctx := context.Background()\n \n s := plexgo.New()\n\n res, err := s.Users.GetUsers(ctx, operations.GetUsersRequest{\n ClientID: \"3381b62b-9ab7-4e37-827b-203e9809eb58\",\n ClientName: plexgo.String(\"Plex for Roku\"),\n DeviceNickname: plexgo.String(\"Roku 3\"),\n DeviceName: plexgo.String(\"Chrome\"),\n DeviceScreenResolution: plexgo.String(\"1487x1165,2560x1440\"),\n ClientVersion: plexgo.String(\"2.4.1\"),\n Platform: plexgo.String(\"Roku\"),\n ClientFeatures: plexgo.String(\"external-media,indirect-media,hub-style-list\"),\n Model: plexgo.String(\"4200X\"),\n XPlexSessionID: plexgo.String(\"97e136ef-4ddd-4ff3-89a7-a5820c96c2ca\"),\n XPlexLanguage: plexgo.String(\"en\"),\n PlatformVersion: plexgo.String(\"4.3 build 1057\"),\n XPlexToken: \"CV5xoxjTpFKUzBTShsaf\",\n })\n if err != nil {\n log.Fatal(err)\n }\n if res.Body != nil {\n // handle response\n }\n}" - target: $["paths"]["/users/signin"]["post"] update: x-codeSamples: diff --git a/docs/models/operations/alllibraries.md b/docs/models/operations/alllibraries.md new file mode 100644 index 0000000..642aca4 --- /dev/null +++ b/docs/models/operations/alllibraries.md @@ -0,0 +1,11 @@ +# AllLibraries + +Indicates if the user has access to all libraries. + + +## Values + +| Name | Value | +| --------------------- | --------------------- | +| `AllLibrariesDisable` | 0 | +| `AllLibrariesEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/allowcameraupload.md b/docs/models/operations/allowcameraupload.md new file mode 100644 index 0000000..ca0bb2a --- /dev/null +++ b/docs/models/operations/allowcameraupload.md @@ -0,0 +1,11 @@ +# AllowCameraUpload + +Indicates if the user is allowed to upload from a camera. + + +## Values + +| Name | Value | +| -------------------------- | -------------------------- | +| `AllowCameraUploadDisable` | 0 | +| `AllowCameraUploadEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/allowchannels.md b/docs/models/operations/allowchannels.md new file mode 100644 index 0000000..11d6c75 --- /dev/null +++ b/docs/models/operations/allowchannels.md @@ -0,0 +1,11 @@ +# AllowChannels + +Indicates if the user has access to channels. + + +## Values + +| Name | Value | +| ---------------------- | ---------------------- | +| `AllowChannelsDisable` | 0 | +| `AllowChannelsEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/allowsubtitleadmin.md b/docs/models/operations/allowsubtitleadmin.md new file mode 100644 index 0000000..d794ec0 --- /dev/null +++ b/docs/models/operations/allowsubtitleadmin.md @@ -0,0 +1,11 @@ +# AllowSubtitleAdmin + +Indicates if the user can manage subtitles. + + +## Values + +| Name | Value | +| --------------------------- | --------------------------- | +| `AllowSubtitleAdminDisable` | 0 | +| `AllowSubtitleAdminEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/allowsync.md b/docs/models/operations/allowsync.md new file mode 100644 index 0000000..30e7fad --- /dev/null +++ b/docs/models/operations/allowsync.md @@ -0,0 +1,11 @@ +# AllowSync + +Indicates if the user is allowed to sync media. + + +## Values + +| Name | Value | +| ------------------ | ------------------ | +| `AllowSyncDisable` | 0 | +| `AllowSyncEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/allowtuners.md b/docs/models/operations/allowtuners.md new file mode 100644 index 0000000..2df5873 --- /dev/null +++ b/docs/models/operations/allowtuners.md @@ -0,0 +1,11 @@ +# AllowTuners + +Indicates if the user is allowed to use tuners. + + +## Values + +| Name | Value | +| -------------------- | -------------------- | +| `AllowTunersDisable` | 0 | +| `AllowTunersEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/gettopwatchedcontentmetadata.md b/docs/models/operations/gettopwatchedcontentmetadata.md index 3954c57..e37274b 100644 --- a/docs/models/operations/gettopwatchedcontentmetadata.md +++ b/docs/models/operations/gettopwatchedcontentmetadata.md @@ -36,4 +36,4 @@ | `Country` | [][operations.GetTopWatchedContentCountry](../../models/operations/gettopwatchedcontentcountry.md) | :heavy_minus_sign: | N/A | | | `Guids` | [][operations.GetTopWatchedContentGuids](../../models/operations/gettopwatchedcontentguids.md) | :heavy_minus_sign: | N/A | | | `Role` | [][operations.GetTopWatchedContentRole](../../models/operations/gettopwatchedcontentrole.md) | :heavy_minus_sign: | N/A | | -| `User` | [][operations.User](../../models/operations/user.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file +| `User` | [][operations.GetTopWatchedContentUser](../../models/operations/gettopwatchedcontentuser.md) | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/models/operations/gettopwatchedcontentuser.md b/docs/models/operations/gettopwatchedcontentuser.md new file mode 100644 index 0000000..9dda37e --- /dev/null +++ b/docs/models/operations/gettopwatchedcontentuser.md @@ -0,0 +1,8 @@ +# GetTopWatchedContentUser + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `ID` | **int* | :heavy_minus_sign: | N/A | 220 | \ No newline at end of file diff --git a/docs/models/operations/getusersmediacontainer.md b/docs/models/operations/getusersmediacontainer.md new file mode 100644 index 0000000..625d8b9 --- /dev/null +++ b/docs/models/operations/getusersmediacontainer.md @@ -0,0 +1,15 @@ +# GetUsersMediaContainer + +Container holding user and server details. + + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `FriendlyName` | *string* | :heavy_check_mark: | The friendly name of the Plex instance. | myPlex | +| `Identifier` | *string* | :heavy_check_mark: | N/A | com.plexapp.plugins.myplex | +| `MachineIdentifier` | *string* | :heavy_check_mark: | Unique Machine identifier of the Plex server. | 3dff4c4da3b1229a649aa574a9e2b419a684a20e | +| `TotalSize` | *int64* | :heavy_check_mark: | Total number of users. | 30 | +| `Size` | *int64* | :heavy_check_mark: | Number of users in the current response. | 30 | +| `User` | [][operations.User](../../models/operations/user.md) | :heavy_check_mark: | List of users with access to the Plex server. | | \ No newline at end of file diff --git a/docs/models/operations/getusersrequest.md b/docs/models/operations/getusersrequest.md new file mode 100644 index 0000000..cc529c0 --- /dev/null +++ b/docs/models/operations/getusersrequest.md @@ -0,0 +1,20 @@ +# GetUsersRequest + + +## Fields + +| 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 | +| `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 | +| `DeviceName` | **string* | :heavy_minus_sign: | The name of the device the client application is running on. This is used to track the client application and its usage. (Chrome, Safari, etc.) | Chrome | +| `DeviceScreenResolution` | **string* | :heavy_minus_sign: | The resolution of the device the client application is running on. This is used to track the client application and its usage. (1487x1165,2560x1440) | 1487x1165,2560x1440 | +| `ClientVersion` | **string* | :heavy_minus_sign: | The version of the client application. | 2.4.1 | +| `Platform` | **string* | :heavy_minus_sign: | The platform of the client application. | Roku | +| `ClientFeatures` | **string* | :heavy_minus_sign: | The features of the client application. This is used to track the client application and its usage. (external-media,indirect-media,hub-style-list) | external-media,indirect-media,hub-style-list | +| `Model` | **string* | :heavy_minus_sign: | A potentially less friendly identifier for the device model | 4200X | +| `XPlexSessionID` | **string* | :heavy_minus_sign: | The session ID of the client application. This is used to track the client application and its usage. (97e136ef-4ddd-4ff3-89a7-a5820c96c2ca) | 97e136ef-4ddd-4ff3-89a7-a5820c96c2ca | +| `XPlexLanguage` | **string* | :heavy_minus_sign: | The language of the client application. | en | +| `PlatformVersion` | **string* | :heavy_minus_sign: | The version of the platform | 4.3 build 1057 | +| `XPlexToken` | *string* | :heavy_check_mark: | An authentication token, obtained from plex.tv | CV5xoxjTpFKUzBTShsaf | \ No newline at end of file diff --git a/docs/models/operations/getusersresponse.md b/docs/models/operations/getusersresponse.md new file mode 100644 index 0000000..0d9d0fe --- /dev/null +++ b/docs/models/operations/getusersresponse.md @@ -0,0 +1,11 @@ +# GetUsersResponse + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | +| `ContentType` | *string* | :heavy_check_mark: | HTTP response content type for this operation | +| `StatusCode` | *int* | :heavy_check_mark: | HTTP response status code for this operation | +| `RawResponse` | [*http.Response](https://pkg.go.dev/net/http#Response) | :heavy_check_mark: | Raw HTTP response; suitable for custom response parsing | +| `Body` | *[]byte* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/operations/getusersresponsebody.md b/docs/models/operations/getusersresponsebody.md new file mode 100644 index 0000000..2a7b98b --- /dev/null +++ b/docs/models/operations/getusersresponsebody.md @@ -0,0 +1,10 @@ +# GetUsersResponseBody + +Successful response with media container data in XML + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| `MediaContainer` | [*operations.GetUsersMediaContainer](../../models/operations/getusersmediacontainer.md) | :heavy_minus_sign: | Container holding user and server details. | \ No newline at end of file diff --git a/docs/models/operations/getusersserver.md b/docs/models/operations/getusersserver.md new file mode 100644 index 0000000..a7b3ec3 --- /dev/null +++ b/docs/models/operations/getusersserver.md @@ -0,0 +1,16 @@ +# GetUsersServer + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `ID` | *int64* | :heavy_check_mark: | Unique ID of the server of the connected user | 907759180 | +| `ServerID` | *int64* | :heavy_check_mark: | ID of the actual Plex server. | 9999999 | +| `MachineIdentifier` | *string* | :heavy_check_mark: | Machine identifier of the Plex server. | fbb8aa6be6e0c997c6268bc2b4431c8807f70a3 | +| `Name` | *string* | :heavy_check_mark: | Name of the Plex server of the connected user. | ConnectedUserFlix | +| `LastSeenAt` | *int64* | :heavy_check_mark: | N/A | 1556281940 | +| `NumLibraries` | *int64* | :heavy_check_mark: | Number of libraries in the server this user has access to. | 16 | +| `AllLibraries` | [*operations.AllLibraries](../../models/operations/alllibraries.md) | :heavy_minus_sign: | N/A | 1 | +| `Owned` | [*operations.Owned](../../models/operations/owned.md) | :heavy_minus_sign: | N/A | 1 | +| `Pending` | [*operations.Pending](../../models/operations/pending.md) | :heavy_minus_sign: | N/A | 1 | \ No newline at end of file diff --git a/docs/models/operations/home.md b/docs/models/operations/home.md new file mode 100644 index 0000000..d5a389b --- /dev/null +++ b/docs/models/operations/home.md @@ -0,0 +1,11 @@ +# Home + +Indicates if the user is part of a home group. + + +## Values + +| Name | Value | +| ------------- | ------------- | +| `HomeDisable` | 0 | +| `HomeEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/owned.md b/docs/models/operations/owned.md new file mode 100644 index 0000000..e989d43 --- /dev/null +++ b/docs/models/operations/owned.md @@ -0,0 +1,11 @@ +# Owned + +Indicates if the user owns the server. + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `OwnedDisable` | 0 | +| `OwnedEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/pending.md b/docs/models/operations/pending.md new file mode 100644 index 0000000..7d8772f --- /dev/null +++ b/docs/models/operations/pending.md @@ -0,0 +1,11 @@ +# Pending + +Indicates if the server is pending approval. + + +## Values + +| Name | Value | +| ---------------- | ---------------- | +| `PendingDisable` | 0 | +| `PendingEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/protected.md b/docs/models/operations/protected.md new file mode 100644 index 0000000..05f5e78 --- /dev/null +++ b/docs/models/operations/protected.md @@ -0,0 +1,11 @@ +# Protected + +Indicates whether the account is protected. + + +## Values + +| Name | Value | +| ------------------ | ------------------ | +| `ProtectedDisable` | 0 | +| `ProtectedEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/restricted.md b/docs/models/operations/restricted.md new file mode 100644 index 0000000..861f407 --- /dev/null +++ b/docs/models/operations/restricted.md @@ -0,0 +1,11 @@ +# Restricted + +Indicates if the user has restricted access. + + +## Values + +| Name | Value | +| ------------------- | ------------------- | +| `RestrictedDisable` | 0 | +| `RestrictedEnable` | 1 | \ No newline at end of file diff --git a/docs/models/operations/user.md b/docs/models/operations/user.md index 5e970bb..ceec634 100644 --- a/docs/models/operations/user.md +++ b/docs/models/operations/user.md @@ -3,6 +3,25 @@ ## Fields -| Field | Type | Required | Description | Example | -| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | -| `ID` | **int* | :heavy_minus_sign: | N/A | 220 | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| `ID` | *int64* | :heavy_check_mark: | User's unique ID. | 22526914 | +| `Title` | *string* | :heavy_check_mark: | User's display name. | Plex User | +| `Username` | *string* | :heavy_check_mark: | User's username. | zgfuc7krcqfimrmb9lsl5j | +| `Email` | *string* | :heavy_check_mark: | User's email address. | zgfuc7krcqfimrmb9lsl5j@protonmail.com | +| `RecommendationsPlaylistID` | **string* | :heavy_minus_sign: | ID of the user's recommendation playlist. | | +| `Thumb` | *string* | :heavy_check_mark: | URL to the user's avatar image. | https://plex.tv/users/3346028014e93acd/avatar?c=1731605021 | +| `Protected` | [*operations.Protected](../../models/operations/protected.md) | :heavy_minus_sign: | N/A | 1 | +| `Home` | [*operations.Home](../../models/operations/home.md) | :heavy_minus_sign: | N/A | 1 | +| `AllowTuners` | [*operations.AllowTuners](../../models/operations/allowtuners.md) | :heavy_minus_sign: | N/A | 1 | +| `AllowSync` | [*operations.AllowSync](../../models/operations/allowsync.md) | :heavy_minus_sign: | N/A | 1 | +| `AllowCameraUpload` | [*operations.AllowCameraUpload](../../models/operations/allowcameraupload.md) | :heavy_minus_sign: | N/A | 1 | +| `AllowChannels` | [*operations.AllowChannels](../../models/operations/allowchannels.md) | :heavy_minus_sign: | N/A | 1 | +| `AllowSubtitleAdmin` | [*operations.AllowSubtitleAdmin](../../models/operations/allowsubtitleadmin.md) | :heavy_minus_sign: | N/A | 1 | +| `FilterAll` | **string* | :heavy_minus_sign: | Filters applied for all content. | | +| `FilterMovies` | **string* | :heavy_minus_sign: | Filters applied for movies. | | +| `FilterMusic` | **string* | :heavy_minus_sign: | Filters applied for music. | | +| `FilterPhotos` | **string* | :heavy_minus_sign: | Filters applied for photos. | | +| `FilterTelevision` | **string* | :heavy_minus_sign: | Filters applied for television. | | +| `Restricted` | [*operations.Restricted](../../models/operations/restricted.md) | :heavy_minus_sign: | N/A | 1 | +| `Server` | [][operations.GetUsersServer](../../models/operations/getusersserver.md) | :heavy_check_mark: | List of servers owned by the user. | | \ No newline at end of file diff --git a/docs/models/sdkerrors/getusersbadrequest.md b/docs/models/sdkerrors/getusersbadrequest.md new file mode 100644 index 0000000..7395603 --- /dev/null +++ b/docs/models/sdkerrors/getusersbadrequest.md @@ -0,0 +1,11 @@ +# GetUsersBadRequest + +Bad Request - A parameter was not specified, or was specified incorrectly. + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `Errors` | [][sdkerrors.GetUsersErrors](../../models/sdkerrors/getuserserrors.md) | :heavy_minus_sign: | N/A | +| `RawResponse` | [*http.Response](https://pkg.go.dev/net/http#Response) | :heavy_minus_sign: | Raw HTTP response; suitable for custom response parsing | \ No newline at end of file diff --git a/docs/models/sdkerrors/getuserserrors.md b/docs/models/sdkerrors/getuserserrors.md new file mode 100644 index 0000000..8ef7e64 --- /dev/null +++ b/docs/models/sdkerrors/getuserserrors.md @@ -0,0 +1,10 @@ +# GetUsersErrors + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | ----------------------------------- | +| `Code` | **int* | :heavy_minus_sign: | N/A | 1000 | +| `Message` | **string* | :heavy_minus_sign: | N/A | X-Plex-Client-Identifier is missing | +| `Status` | **int* | :heavy_minus_sign: | N/A | 400 | \ No newline at end of file diff --git a/docs/models/sdkerrors/getusersunauthorized.md b/docs/models/sdkerrors/getusersunauthorized.md new file mode 100644 index 0000000..04aa34c --- /dev/null +++ b/docs/models/sdkerrors/getusersunauthorized.md @@ -0,0 +1,11 @@ +# GetUsersUnauthorized + +Unauthorized - Returned if the X-Plex-Token is missing from the header or query. + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| `Errors` | [][sdkerrors.GetUsersUsersErrors](../../models/sdkerrors/getusersuserserrors.md) | :heavy_minus_sign: | N/A | +| `RawResponse` | [*http.Response](https://pkg.go.dev/net/http#Response) | :heavy_minus_sign: | Raw HTTP response; suitable for custom response parsing | \ No newline at end of file diff --git a/docs/models/sdkerrors/getusersuserserrors.md b/docs/models/sdkerrors/getusersuserserrors.md new file mode 100644 index 0000000..71d8b31 --- /dev/null +++ b/docs/models/sdkerrors/getusersuserserrors.md @@ -0,0 +1,10 @@ +# GetUsersUsersErrors + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | ------------------------------- | +| `Code` | **int* | :heavy_minus_sign: | N/A | 1001 | +| `Message` | **string* | :heavy_minus_sign: | N/A | User could not be authenticated | +| `Status` | **int* | :heavy_minus_sign: | N/A | 401 | \ No newline at end of file diff --git a/docs/sdks/users/README.md b/docs/sdks/users/README.md new file mode 100644 index 0000000..251e0f0 --- /dev/null +++ b/docs/sdks/users/README.md @@ -0,0 +1,73 @@ +# Users +(*Users*) + +## Overview + +### Available Operations + +* [GetUsers](#getusers) - Get list of all connected users + +## GetUsers + +Get list of all users that are friends and have library access with the provided Plex authentication token + +### Example Usage + +```go +package main + +import( + "context" + "github.com/LukeHagar/plexgo" + "github.com/LukeHagar/plexgo/models/operations" + "log" +) + +func main() { + ctx := context.Background() + + s := plexgo.New() + + res, err := s.Users.GetUsers(ctx, operations.GetUsersRequest{ + ClientID: "3381b62b-9ab7-4e37-827b-203e9809eb58", + ClientName: plexgo.String("Plex for Roku"), + DeviceNickname: plexgo.String("Roku 3"), + DeviceName: plexgo.String("Chrome"), + DeviceScreenResolution: plexgo.String("1487x1165,2560x1440"), + ClientVersion: plexgo.String("2.4.1"), + Platform: plexgo.String("Roku"), + ClientFeatures: plexgo.String("external-media,indirect-media,hub-style-list"), + Model: plexgo.String("4200X"), + XPlexSessionID: plexgo.String("97e136ef-4ddd-4ff3-89a7-a5820c96c2ca"), + XPlexLanguage: plexgo.String("en"), + PlatformVersion: plexgo.String("4.3 build 1057"), + XPlexToken: "CV5xoxjTpFKUzBTShsaf", + }) + if err != nil { + log.Fatal(err) + } + if res.Body != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | +| `request` | [operations.GetUsersRequest](../../models/operations/getusersrequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `opts` | [][operations.Option](../../models/operations/option.md) | :heavy_minus_sign: | The options for this request. | + +### Response + +**[*operations.GetUsersResponse](../../models/operations/getusersresponse.md), error** + +### Errors + +| Error Type | Status Code | Content Type | +| ------------------------------ | ------------------------------ | ------------------------------ | +| sdkerrors.GetUsersBadRequest | 400 | application/json | +| sdkerrors.GetUsersUnauthorized | 401 | application/json | +| sdkerrors.SDKError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/internal/utils/queryparams.go b/internal/utils/queryparams.go index 369d98d..9931c9f 100644 --- a/internal/utils/queryparams.go +++ b/internal/utils/queryparams.go @@ -65,6 +65,12 @@ func populateQueryParams(queryParams interface{}, globals interface{}, values ur continue } + constValue := parseConstTag(fieldType) + if constValue != nil { + values.Add(qpTag.ParamName, *constValue) + continue + } + if globals != nil { var globalFound bool fieldType, valType, globalFound = populateFromGlobals(fieldType, valType, queryParamTagKey, globals) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 031a71a..49cba6d 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -96,6 +96,16 @@ func AsSecuritySource(security interface{}) func(context.Context) (interface{}, } } +func parseConstTag(field reflect.StructField) *string { + value := field.Tag.Get("const") + + if value == "" { + return nil + } + + return &value +} + func parseStructTag(tagKey string, field reflect.StructField) map[string]string { tag := field.Tag.Get(tagKey) if tag == "" { diff --git a/models/operations/gettopwatchedcontent.go b/models/operations/gettopwatchedcontent.go index c848905..928dce1 100644 --- a/models/operations/gettopwatchedcontent.go +++ b/models/operations/gettopwatchedcontent.go @@ -201,11 +201,11 @@ func (o *GetTopWatchedContentRole) GetThumb() *string { return o.Thumb } -type User struct { +type GetTopWatchedContentUser struct { ID *int `json:"id,omitempty"` } -func (o *User) GetID() *int { +func (o *GetTopWatchedContentUser) GetID() *int { if o == nil { return nil } @@ -244,7 +244,7 @@ type GetTopWatchedContentMetadata struct { Country []GetTopWatchedContentCountry `json:"Country,omitempty"` Guids []GetTopWatchedContentGuids `json:"Guid,omitempty"` Role []GetTopWatchedContentRole `json:"Role,omitempty"` - User []User `json:"User,omitempty"` + User []GetTopWatchedContentUser `json:"User,omitempty"` } func (g GetTopWatchedContentMetadata) MarshalJSON() ([]byte, error) { @@ -475,7 +475,7 @@ func (o *GetTopWatchedContentMetadata) GetRole() []GetTopWatchedContentRole { return o.Role } -func (o *GetTopWatchedContentMetadata) GetUser() []User { +func (o *GetTopWatchedContentMetadata) GetUser() []GetTopWatchedContentUser { if o == nil { return nil } diff --git a/models/operations/getusers.go b/models/operations/getusers.go new file mode 100644 index 0000000..621e9ff --- /dev/null +++ b/models/operations/getusers.go @@ -0,0 +1,816 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "encoding/json" + "fmt" + "github.com/LukeHagar/plexgo/internal/utils" + "net/http" +) + +var GetUsersServerList = []string{ + "https://plex.tv/api", +} + +type GetUsersRequest struct { + // An opaque identifier unique to the client (UUID, serial number, or other unique device ID) + ClientID string `header:"style=simple,explode=false,name=X-Plex-Client-Identifier"` + // The name of the client application. (Plex Web, Plex Media Server, etc.) + ClientName *string `header:"style=simple,explode=false,name=X-Plex-Product"` + // A relatively friendly name for the client device + DeviceNickname *string `header:"style=simple,explode=false,name=X-Plex-Device"` + // The name of the device the client application is running on. This is used to track the client application and its usage. (Chrome, Safari, etc.) + DeviceName *string `header:"style=simple,explode=false,name=X-Plex-Device-Name"` + // The resolution of the device the client application is running on. This is used to track the client application and its usage. (1487x1165,2560x1440) + DeviceScreenResolution *string `header:"style=simple,explode=false,name=X-Plex-Device-Screen-Resolution"` + // The version of the client application. + ClientVersion *string `header:"style=simple,explode=false,name=X-Plex-Version"` + // The platform of the client application. + Platform *string `header:"style=simple,explode=false,name=X-Plex-Platform"` + // The features of the client application. This is used to track the client application and its usage. (external-media,indirect-media,hub-style-list) + ClientFeatures *string `header:"style=simple,explode=false,name=X-Plex-Features"` + // A potentially less friendly identifier for the device model + Model *string `header:"style=simple,explode=false,name=X-Plex-Model"` + // The session ID of the client application. This is used to track the client application and its usage. (97e136ef-4ddd-4ff3-89a7-a5820c96c2ca) + XPlexSessionID *string `header:"style=simple,explode=false,name=X-Plex-Session-Id"` + // The language of the client application. + XPlexLanguage *string `header:"style=simple,explode=false,name=X-Plex-Language"` + // The version of the platform + PlatformVersion *string `header:"style=simple,explode=false,name=X-Plex-Platform-Version"` + // An authentication token, obtained from plex.tv + XPlexToken string `header:"style=simple,explode=false,name=X-Plex-Token"` +} + +func (o *GetUsersRequest) GetClientID() string { + if o == nil { + return "" + } + return o.ClientID +} + +func (o *GetUsersRequest) GetClientName() *string { + if o == nil { + return nil + } + return o.ClientName +} + +func (o *GetUsersRequest) GetDeviceNickname() *string { + if o == nil { + return nil + } + return o.DeviceNickname +} + +func (o *GetUsersRequest) GetDeviceName() *string { + if o == nil { + return nil + } + return o.DeviceName +} + +func (o *GetUsersRequest) GetDeviceScreenResolution() *string { + if o == nil { + return nil + } + return o.DeviceScreenResolution +} + +func (o *GetUsersRequest) GetClientVersion() *string { + if o == nil { + return nil + } + return o.ClientVersion +} + +func (o *GetUsersRequest) GetPlatform() *string { + if o == nil { + return nil + } + return o.Platform +} + +func (o *GetUsersRequest) GetClientFeatures() *string { + if o == nil { + return nil + } + return o.ClientFeatures +} + +func (o *GetUsersRequest) GetModel() *string { + if o == nil { + return nil + } + return o.Model +} + +func (o *GetUsersRequest) GetXPlexSessionID() *string { + if o == nil { + return nil + } + return o.XPlexSessionID +} + +func (o *GetUsersRequest) GetXPlexLanguage() *string { + if o == nil { + return nil + } + return o.XPlexLanguage +} + +func (o *GetUsersRequest) GetPlatformVersion() *string { + if o == nil { + return nil + } + return o.PlatformVersion +} + +func (o *GetUsersRequest) GetXPlexToken() string { + if o == nil { + return "" + } + return o.XPlexToken +} + +// Protected - Indicates whether the account is protected. +type Protected int + +const ( + ProtectedDisable Protected = 0 + ProtectedEnable Protected = 1 +) + +func (e Protected) ToPointer() *Protected { + return &e +} +func (e *Protected) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Protected(v) + return nil + default: + return fmt.Errorf("invalid value for Protected: %v", v) + } +} + +// Home - Indicates if the user is part of a home group. +type Home int + +const ( + HomeDisable Home = 0 + HomeEnable Home = 1 +) + +func (e Home) ToPointer() *Home { + return &e +} +func (e *Home) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Home(v) + return nil + default: + return fmt.Errorf("invalid value for Home: %v", v) + } +} + +// AllowTuners - Indicates if the user is allowed to use tuners. +type AllowTuners int + +const ( + AllowTunersDisable AllowTuners = 0 + AllowTunersEnable AllowTuners = 1 +) + +func (e AllowTuners) ToPointer() *AllowTuners { + return &e +} +func (e *AllowTuners) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = AllowTuners(v) + return nil + default: + return fmt.Errorf("invalid value for AllowTuners: %v", v) + } +} + +// AllowSync - Indicates if the user is allowed to sync media. +type AllowSync int + +const ( + AllowSyncDisable AllowSync = 0 + AllowSyncEnable AllowSync = 1 +) + +func (e AllowSync) ToPointer() *AllowSync { + return &e +} +func (e *AllowSync) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = AllowSync(v) + return nil + default: + return fmt.Errorf("invalid value for AllowSync: %v", v) + } +} + +// AllowCameraUpload - Indicates if the user is allowed to upload from a camera. +type AllowCameraUpload int + +const ( + AllowCameraUploadDisable AllowCameraUpload = 0 + AllowCameraUploadEnable AllowCameraUpload = 1 +) + +func (e AllowCameraUpload) ToPointer() *AllowCameraUpload { + return &e +} +func (e *AllowCameraUpload) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = AllowCameraUpload(v) + return nil + default: + return fmt.Errorf("invalid value for AllowCameraUpload: %v", v) + } +} + +// AllowChannels - Indicates if the user has access to channels. +type AllowChannels int + +const ( + AllowChannelsDisable AllowChannels = 0 + AllowChannelsEnable AllowChannels = 1 +) + +func (e AllowChannels) ToPointer() *AllowChannels { + return &e +} +func (e *AllowChannels) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = AllowChannels(v) + return nil + default: + return fmt.Errorf("invalid value for AllowChannels: %v", v) + } +} + +// AllowSubtitleAdmin - Indicates if the user can manage subtitles. +type AllowSubtitleAdmin int + +const ( + AllowSubtitleAdminDisable AllowSubtitleAdmin = 0 + AllowSubtitleAdminEnable AllowSubtitleAdmin = 1 +) + +func (e AllowSubtitleAdmin) ToPointer() *AllowSubtitleAdmin { + return &e +} +func (e *AllowSubtitleAdmin) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = AllowSubtitleAdmin(v) + return nil + default: + return fmt.Errorf("invalid value for AllowSubtitleAdmin: %v", v) + } +} + +// Restricted - Indicates if the user has restricted access. +type Restricted int + +const ( + RestrictedDisable Restricted = 0 + RestrictedEnable Restricted = 1 +) + +func (e Restricted) ToPointer() *Restricted { + return &e +} +func (e *Restricted) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Restricted(v) + return nil + default: + return fmt.Errorf("invalid value for Restricted: %v", v) + } +} + +// AllLibraries - Indicates if the user has access to all libraries. +type AllLibraries int + +const ( + AllLibrariesDisable AllLibraries = 0 + AllLibrariesEnable AllLibraries = 1 +) + +func (e AllLibraries) ToPointer() *AllLibraries { + return &e +} +func (e *AllLibraries) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = AllLibraries(v) + return nil + default: + return fmt.Errorf("invalid value for AllLibraries: %v", v) + } +} + +// Owned - Indicates if the user owns the server. +type Owned int + +const ( + OwnedDisable Owned = 0 + OwnedEnable Owned = 1 +) + +func (e Owned) ToPointer() *Owned { + return &e +} +func (e *Owned) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Owned(v) + return nil + default: + return fmt.Errorf("invalid value for Owned: %v", v) + } +} + +// Pending - Indicates if the server is pending approval. +type Pending int + +const ( + PendingDisable Pending = 0 + PendingEnable Pending = 1 +) + +func (e Pending) ToPointer() *Pending { + return &e +} +func (e *Pending) UnmarshalJSON(data []byte) error { + var v int + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case 0: + fallthrough + case 1: + *e = Pending(v) + return nil + default: + return fmt.Errorf("invalid value for Pending: %v", v) + } +} + +type GetUsersServer struct { + // Unique ID of the server of the connected user + ID int64 + // ID of the actual Plex server. + ServerID int64 + // Machine identifier of the Plex server. + MachineIdentifier string + // Name of the Plex server of the connected user. + Name string + LastSeenAt int64 + // Number of libraries in the server this user has access to. + NumLibraries int64 + AllLibraries *AllLibraries `default:"0"` + Owned *Owned `default:"0"` + Pending *Pending `default:"0"` +} + +func (g GetUsersServer) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(g, "", false) +} + +func (g *GetUsersServer) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &g, "", false, false); err != nil { + return err + } + return nil +} + +func (o *GetUsersServer) GetID() int64 { + if o == nil { + return 0 + } + return o.ID +} + +func (o *GetUsersServer) GetServerID() int64 { + if o == nil { + return 0 + } + return o.ServerID +} + +func (o *GetUsersServer) GetMachineIdentifier() string { + if o == nil { + return "" + } + return o.MachineIdentifier +} + +func (o *GetUsersServer) GetName() string { + if o == nil { + return "" + } + return o.Name +} + +func (o *GetUsersServer) GetLastSeenAt() int64 { + if o == nil { + return 0 + } + return o.LastSeenAt +} + +func (o *GetUsersServer) GetNumLibraries() int64 { + if o == nil { + return 0 + } + return o.NumLibraries +} + +func (o *GetUsersServer) GetAllLibraries() *AllLibraries { + if o == nil { + return nil + } + return o.AllLibraries +} + +func (o *GetUsersServer) GetOwned() *Owned { + if o == nil { + return nil + } + return o.Owned +} + +func (o *GetUsersServer) GetPending() *Pending { + if o == nil { + return nil + } + return o.Pending +} + +type User struct { + // User's unique ID. + ID int64 + // User's display name. + Title string + // User's username. + Username string + // User's email address. + Email string + // ID of the user's recommendation playlist. + RecommendationsPlaylistID *string + // URL to the user's avatar image. + Thumb string + Protected *Protected `default:"0"` + Home *Home `default:"0"` + AllowTuners *AllowTuners `default:"0"` + AllowSync *AllowSync `default:"0"` + AllowCameraUpload *AllowCameraUpload `default:"0"` + AllowChannels *AllowChannels `default:"0"` + AllowSubtitleAdmin *AllowSubtitleAdmin `default:"0"` + // Filters applied for all content. + FilterAll *string + // Filters applied for movies. + FilterMovies *string + // Filters applied for music. + FilterMusic *string + // Filters applied for photos. + FilterPhotos *string + // Filters applied for television. + FilterTelevision *string + Restricted *Restricted `default:"0"` + // List of servers owned by the user. + Server []GetUsersServer +} + +func (u User) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(u, "", false) +} + +func (u *User) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &u, "", false, false); err != nil { + return err + } + return nil +} + +func (o *User) GetID() int64 { + if o == nil { + return 0 + } + return o.ID +} + +func (o *User) GetTitle() string { + if o == nil { + return "" + } + return o.Title +} + +func (o *User) GetUsername() string { + if o == nil { + return "" + } + return o.Username +} + +func (o *User) GetEmail() string { + if o == nil { + return "" + } + return o.Email +} + +func (o *User) GetRecommendationsPlaylistID() *string { + if o == nil { + return nil + } + return o.RecommendationsPlaylistID +} + +func (o *User) GetThumb() string { + if o == nil { + return "" + } + return o.Thumb +} + +func (o *User) GetProtected() *Protected { + if o == nil { + return nil + } + return o.Protected +} + +func (o *User) GetHome() *Home { + if o == nil { + return nil + } + return o.Home +} + +func (o *User) GetAllowTuners() *AllowTuners { + if o == nil { + return nil + } + return o.AllowTuners +} + +func (o *User) GetAllowSync() *AllowSync { + if o == nil { + return nil + } + return o.AllowSync +} + +func (o *User) GetAllowCameraUpload() *AllowCameraUpload { + if o == nil { + return nil + } + return o.AllowCameraUpload +} + +func (o *User) GetAllowChannels() *AllowChannels { + if o == nil { + return nil + } + return o.AllowChannels +} + +func (o *User) GetAllowSubtitleAdmin() *AllowSubtitleAdmin { + if o == nil { + return nil + } + return o.AllowSubtitleAdmin +} + +func (o *User) GetFilterAll() *string { + if o == nil { + return nil + } + return o.FilterAll +} + +func (o *User) GetFilterMovies() *string { + if o == nil { + return nil + } + return o.FilterMovies +} + +func (o *User) GetFilterMusic() *string { + if o == nil { + return nil + } + return o.FilterMusic +} + +func (o *User) GetFilterPhotos() *string { + if o == nil { + return nil + } + return o.FilterPhotos +} + +func (o *User) GetFilterTelevision() *string { + if o == nil { + return nil + } + return o.FilterTelevision +} + +func (o *User) GetRestricted() *Restricted { + if o == nil { + return nil + } + return o.Restricted +} + +func (o *User) GetServer() []GetUsersServer { + if o == nil { + return []GetUsersServer{} + } + return o.Server +} + +// GetUsersMediaContainer - Container holding user and server details. +type GetUsersMediaContainer struct { + // The friendly name of the Plex instance. + FriendlyName string + Identifier string + // Unique Machine identifier of the Plex server. + MachineIdentifier string + // Total number of users. + TotalSize int64 + // Number of users in the current response. + Size int64 + // List of users with access to the Plex server. + User []User +} + +func (o *GetUsersMediaContainer) GetFriendlyName() string { + if o == nil { + return "" + } + return o.FriendlyName +} + +func (o *GetUsersMediaContainer) GetIdentifier() string { + if o == nil { + return "" + } + return o.Identifier +} + +func (o *GetUsersMediaContainer) GetMachineIdentifier() string { + if o == nil { + return "" + } + return o.MachineIdentifier +} + +func (o *GetUsersMediaContainer) GetTotalSize() int64 { + if o == nil { + return 0 + } + return o.TotalSize +} + +func (o *GetUsersMediaContainer) GetSize() int64 { + if o == nil { + return 0 + } + return o.Size +} + +func (o *GetUsersMediaContainer) GetUser() []User { + if o == nil { + return []User{} + } + return o.User +} + +// GetUsersResponseBody - Successful response with media container data in XML +type GetUsersResponseBody struct { + // Container holding user and server details. + MediaContainer *GetUsersMediaContainer +} + +func (o *GetUsersResponseBody) GetMediaContainer() *GetUsersMediaContainer { + if o == nil { + return nil + } + return o.MediaContainer +} + +type GetUsersResponse struct { + // HTTP response content type for this operation + ContentType string + // HTTP response status code for this operation + StatusCode int + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response + Body []byte +} + +func (o *GetUsersResponse) GetContentType() string { + if o == nil { + return "" + } + return o.ContentType +} + +func (o *GetUsersResponse) GetStatusCode() int { + if o == nil { + return 0 + } + return o.StatusCode +} + +func (o *GetUsersResponse) GetRawResponse() *http.Response { + if o == nil { + return nil + } + return o.RawResponse +} + +func (o *GetUsersResponse) GetBody() []byte { + if o == nil { + return nil + } + return o.Body +} diff --git a/models/operations/options.go b/models/operations/options.go index 41bc494..a965e83 100644 --- a/models/operations/options.go +++ b/models/operations/options.go @@ -23,6 +23,7 @@ type AcceptHeaderEnum string const ( AcceptHeaderEnumApplicationJson AcceptHeaderEnum = "application/json" AcceptHeaderEnumImageJpeg AcceptHeaderEnum = "image/jpeg" + AcceptHeaderEnumApplicationXml AcceptHeaderEnum = "application/xml" ) func (e AcceptHeaderEnum) ToPointer() *AcceptHeaderEnum { diff --git a/models/sdkerrors/getusers.go b/models/sdkerrors/getusers.go new file mode 100644 index 0000000..f84a439 --- /dev/null +++ b/models/sdkerrors/getusers.go @@ -0,0 +1,90 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "net/http" +) + +type GetUsersUsersErrors struct { + Code *int `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *int `json:"status,omitempty"` +} + +func (o *GetUsersUsersErrors) GetCode() *int { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetUsersUsersErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetUsersUsersErrors) GetStatus() *int { + if o == nil { + return nil + } + return o.Status +} + +// GetUsersUnauthorized - Unauthorized - Returned if the X-Plex-Token is missing from the header or query. +type GetUsersUnauthorized struct { + Errors []GetUsersUsersErrors `json:"errors,omitempty"` + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response `json:"-"` +} + +var _ error = &GetUsersUnauthorized{} + +func (e *GetUsersUnauthorized) Error() string { + data, _ := json.Marshal(e) + return string(data) +} + +type GetUsersErrors struct { + Code *int `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Status *int `json:"status,omitempty"` +} + +func (o *GetUsersErrors) GetCode() *int { + if o == nil { + return nil + } + return o.Code +} + +func (o *GetUsersErrors) GetMessage() *string { + if o == nil { + return nil + } + return o.Message +} + +func (o *GetUsersErrors) GetStatus() *int { + if o == nil { + return nil + } + return o.Status +} + +// GetUsersBadRequest - Bad Request - A parameter was not specified, or was specified incorrectly. +type GetUsersBadRequest struct { + Errors []GetUsersErrors `json:"errors,omitempty"` + // Raw HTTP response; suitable for custom response parsing + RawResponse *http.Response `json:"-"` +} + +var _ error = &GetUsersBadRequest{} + +func (e *GetUsersBadRequest) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/plexapi.go b/plexapi.go index ee467f7..f0a9b4b 100644 --- a/plexapi.go +++ b/plexapi.go @@ -154,6 +154,7 @@ type PlexAPI struct { // Updates to the status can be observed via the Event API. // Updater *Updater + Users *Users sdkConfiguration sdkConfiguration } @@ -298,9 +299,9 @@ func New(opts ...SDKOption) *PlexAPI { sdkConfiguration: sdkConfiguration{ Language: "go", OpenAPIDocVersion: "0.0.3", - SDKVersion: "0.17.4", - GenVersion: "2.503.2", - UserAgent: "speakeasy-sdk/go 0.17.4 2.503.2 0.0.3 github.com/LukeHagar/plexgo", + SDKVersion: "0.18.0", + GenVersion: "2.506.0", + UserAgent: "speakeasy-sdk/go 0.18.0 2.506.0 0.0.3 github.com/LukeHagar/plexgo", ServerDefaults: []map[string]string{ { "protocol": "https", @@ -359,5 +360,7 @@ func New(opts ...SDKOption) *PlexAPI { sdk.Updater = newUpdater(sdk.sdkConfiguration) + sdk.Users = newUsers(sdk.sdkConfiguration) + return sdk } diff --git a/users.go b/users.go new file mode 100644 index 0000000..f5be043 --- /dev/null +++ b/users.go @@ -0,0 +1,262 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package plexgo + +import ( + "bytes" + "context" + "fmt" + "github.com/LukeHagar/plexgo/internal/hooks" + "github.com/LukeHagar/plexgo/internal/utils" + "github.com/LukeHagar/plexgo/models/operations" + "github.com/LukeHagar/plexgo/models/sdkerrors" + "github.com/LukeHagar/plexgo/retry" + "net/http" + "net/url" +) + +type Users struct { + sdkConfiguration sdkConfiguration +} + +func newUsers(sdkConfig sdkConfiguration) *Users { + return &Users{ + sdkConfiguration: sdkConfig, + } +} + +// GetUsers - Get list of all connected users +// Get list of all users that are friends and have library access with the provided Plex authentication token +func (s *Users) GetUsers(ctx context.Context, request operations.GetUsersRequest, opts ...operations.Option) (*operations.GetUsersResponse, error) { + hookCtx := hooks.HookContext{ + Context: ctx, + OperationID: "get-users", + OAuth2Scopes: []string{}, + SecuritySource: nil, + } + + o := operations.Options{} + supportedOptions := []string{ + operations.SupportedOptionRetries, + operations.SupportedOptionTimeout, + } + + for _, opt := range opts { + if err := opt(&o, supportedOptions...); err != nil { + return nil, fmt.Errorf("error applying option: %w", err) + } + } + + baseURL := utils.ReplaceParameters(operations.GetUsersServerList[0], map[string]string{}) + if o.ServerURL != nil { + baseURL = *o.ServerURL + } + + opURL, err := url.JoinPath(baseURL, "/users") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + timeout := o.Timeout + if timeout == nil { + timeout = s.sdkConfiguration.Timeout + } + + if timeout != nil { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, *timeout) + defer cancel() + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/xml") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + utils.PopulateHeaders(ctx, req, request, nil) + + for k, v := range o.SetHeaders { + req.Header.Set(k, v) + } + + globalRetryConfig := s.sdkConfiguration.RetryConfig + retryConfig := o.Retries + if retryConfig == nil { + if globalRetryConfig != nil { + retryConfig = globalRetryConfig + } + } + + var httpRes *http.Response + if retryConfig != nil { + httpRes, err = utils.Retry(ctx, utils.Retries{ + Config: retryConfig, + StatusCodes: []string{ + "429", + "500", + "502", + "503", + "504", + }, + }, func() (*http.Response, error) { + if req.Body != nil { + copyBody, err := req.GetBody() + if err != nil { + return nil, err + } + req.Body = copyBody + } + + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + if retry.IsPermanentError(err) || retry.IsTemporaryError(err) { + return nil, err + } + + return nil, retry.Permanent(err) + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + } + return httpRes, err + }) + + if err != nil { + return nil, err + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } else { + req, err = s.sdkConfiguration.Hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err = s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"400", "401", "4XX", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.sdkConfiguration.Hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.sdkConfiguration.Hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } + + res := &operations.GetUsersResponse{ + StatusCode: httpRes.StatusCode, + ContentType: httpRes.Header.Get("Content-Type"), + RawResponse: httpRes, + } + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/xml`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + res.Body = rawBody + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 400: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.GetUsersBadRequest + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + out.RawResponse = httpRes + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.GetUsersUnauthorized + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + out.RawResponse = httpRes + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewSDKError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewSDKError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewSDKError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } + + return res, nil + +}