├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ └── default.md ├── dependabot.yml └── workflows │ ├── cicd.yaml │ └── docs.yaml ├── .gitignore ├── .vscode ├── csharp.code-snippets └── settings.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SpotifyAPI.Docs ├── .gitignore ├── .prettierrc.json ├── .vscode │ └── settings.json ├── README.md ├── docs.sh ├── docs │ ├── 5_to_6.md │ ├── auth_introduction.md │ ├── authorization_code.md │ ├── client_credentials.md │ ├── configuration.md │ ├── error_handling.md │ ├── example_asp.md │ ├── example_blazor.md │ ├── example_blazor_wasm.md │ ├── example_cli_custom_html.md │ ├── example_cli_persistent_config.md │ ├── example_token_swap.md │ ├── example_uwp.md │ ├── getting_started.md │ ├── implicit_grant.md │ ├── introduction.md │ ├── iplayableitem.md │ ├── logging.md │ ├── pagination.md │ ├── pkce.md │ ├── proxy.md │ ├── retry_handling.md │ ├── showcase.md │ ├── token_swap.md │ └── unit_testing.md ├── docusaurus.config.js ├── package.json ├── pnpm-lock.yaml ├── reference.md ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ ├── install_instructions.js │ └── pages │ │ ├── index.js │ │ └── styles.module.css ├── static │ └── img │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── asp_blazor_example_home.png │ │ ├── asp_example_home.png │ │ ├── asp_example_profile.png │ │ ├── auth_comparison.png │ │ ├── auth_protocol_handlers.png │ │ ├── blazorwasm_homepage.png │ │ ├── blazorwasm_network_tools.png │ │ ├── cli_custom_html.jpeg │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── logo.svg │ │ ├── mitmproxy.png │ │ ├── undraw_Devices_e67q.svg │ │ ├── undraw_QA_engineers_dg5p.svg │ │ ├── undraw_preferences_uuo2.svg │ │ └── undraw_project_completed_w0oq.svg ├── versioned_docs │ └── version-5.1.1 │ │ ├── auth │ │ ├── authorization_code.md │ │ ├── client_credentials.md │ │ ├── getting_started.md │ │ ├── implicit_grant.md │ │ └── token_swap.md │ │ ├── home.md │ │ └── web │ │ ├── albums.md │ │ ├── artists.md │ │ ├── browse.md │ │ ├── follow.md │ │ ├── getting_started.md │ │ ├── library.md │ │ ├── personalization.md │ │ ├── player.md │ │ ├── playlists.md │ │ ├── profiles.md │ │ ├── proxy.md │ │ ├── search.md │ │ ├── tracks.md │ │ └── utilities.md ├── versioned_sidebars │ └── version-5.1.1-sidebars.json └── versions.json ├── SpotifyAPI.Web.Auth ├── AssemblyInfo.cs ├── AuthException.cs ├── BrowserUtil.cs ├── EmbedIOAuthServer.cs ├── IAuthServer.cs ├── Models │ └── Response │ │ ├── AuthorizationCodeResponse.cs │ │ └── ImplicitGrantResponse.cs ├── Resources │ ├── auth_assets │ │ ├── logo.svg │ │ ├── main.css │ │ └── main.js │ └── default_site │ │ ├── favicon.ico │ │ └── index.html └── SpotifyAPI.Web.Auth.csproj ├── SpotifyAPI.Web.Examples ├── Example.ASP │ ├── Example.ASP.csproj │ ├── Pages │ │ ├── Error.cshtml │ │ ├── Error.cshtml.cs │ │ ├── Index.cshtml │ │ ├── Index.cshtml.cs │ │ ├── Profile.cs │ │ ├── Profile.cshtml │ │ ├── Shared │ │ │ └── _Layout.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ ├── Program.cs │ ├── SpotifyClientBuilder.cs │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ │ ├── css │ │ └── site.css │ │ ├── favicon.ico │ │ └── js │ │ └── site.js ├── Example.ASPBlazor │ ├── App.razor │ ├── Data │ │ ├── WeatherForecast.cs │ │ └── WeatherForecastService.cs │ ├── Example.ASPBlazor.csproj │ ├── Pages │ │ ├── Error.razor │ │ ├── Index.razor │ │ └── _Host.cshtml │ ├── Program.cs │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── NavMenu.razor │ │ └── SurveyPrompt.razor │ ├── Startup.cs │ ├── _Imports.razor │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ │ ├── css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ │ ├── css │ │ │ │ └── open-iconic-bootstrap.min.css │ │ │ │ └── fonts │ │ │ │ ├── open-iconic.eot │ │ │ │ ├── open-iconic.otf │ │ │ │ ├── open-iconic.svg │ │ │ │ ├── open-iconic.ttf │ │ │ │ └── open-iconic.woff │ │ └── site.css │ │ └── favicon.ico ├── Example.BlazorWASM │ ├── .gitignore │ ├── App.razor │ ├── Example.BlazorWASM.csproj │ ├── Pages │ │ └── Index.razor │ ├── Program.cs │ ├── Shared │ │ ├── MainLayout.razor │ │ └── NavMenu.razor │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ └── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ │ ├── favicon.ico │ │ ├── index.html │ │ └── sample-data │ │ └── weather.json ├── Example.CLI.CustomHTML │ ├── Example.CLI.CustomHTML.csproj │ ├── Program.cs │ └── Resources │ │ └── custom_site │ │ └── index.html ├── Example.CLI.PersistentConfig │ ├── .gitignore │ ├── .vscode │ │ ├── launch.json │ │ └── tasks.json │ ├── Example.CLI.PersistentConfig.csproj │ └── Program.cs ├── Example.TokenSwap │ ├── Client │ │ ├── Client.csproj │ │ └── Program.cs │ └── Server │ │ ├── .gitignore │ │ ├── index.js │ │ ├── package.json │ │ └── yarn.lock └── Example.UWP │ ├── App.xaml │ ├── App.xaml.cs │ ├── Assets │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ └── Wide310x150Logo.scale-200.png │ ├── CoreApp.cs │ ├── Example.UWP.csproj │ ├── Package.appxmanifest │ ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml │ ├── TokenPublisherService.cs │ ├── ViewModels │ ├── LoginViewModel.cs │ └── PlaylistsListViewModel.cs │ └── Views │ ├── LoginView.xaml │ ├── LoginView.xaml.cs │ ├── PlaylistsListView.xaml │ └── PlaylistsListView.xaml.cs ├── SpotifyAPI.Web.Tests ├── Clients │ ├── BrowseClientTest.cs │ ├── FollowClientTest.cs │ ├── SpotifyClientConfigTest.cs │ ├── SpotifyClientTest.cs │ └── UserProfileClientTest.cs ├── Fixtures │ └── full_playlist_response.json ├── Http │ ├── APIConnectorTest.cs │ ├── NewtonsoftJSONSerializerTest.cs │ └── TokenAuthenticatorTest.cs ├── Models │ ├── PlayableItemConverterTest.cs │ └── RequestParamsTest.cs ├── RetryHandlers │ └── SimpleRetryHandlerTest.cs ├── SpotifyAPI.Web.Tests.csproj └── UtilTests │ ├── Base64UtilTest.cs │ ├── URIExtensionTest.cs │ └── URIParameterFormatProviderTest.cs ├── SpotifyAPI.Web ├── Assembly.cs ├── Authenticators │ ├── AuthorizationCodeAuthenticator.cs │ ├── ClientCredentialsAuthenticator.cs │ ├── IAuthenticator.cs │ ├── PKCEAuthenticator.cs │ └── TokenAuthenticator.cs ├── Clients │ ├── APIClient.cs │ ├── AlbumsClient.cs │ ├── ArtistsClient.cs │ ├── AudiobooksClient.cs │ ├── BrowseClient.cs │ ├── ChaptersClient.cs │ ├── EpisodesClient.cs │ ├── FollowClient.cs │ ├── Interfaces │ │ ├── IAlbumsClient.cs │ │ ├── IArtistsClient.cs │ │ ├── IAudiobooksClient.cs │ │ ├── IBrowseClient.cs │ │ ├── IChaptersClient.cs │ │ ├── IEpisodesClient.cs │ │ ├── IFollowClient.cs │ │ ├── ILibraryClient.cs │ │ ├── IMarketsClient.cs │ │ ├── IOAuthClient.cs │ │ ├── IPaginator.cs │ │ ├── IPersonalizationClient.cs │ │ ├── IPlayerClient.cs │ │ ├── IPlaylistsClient.cs │ │ ├── ISearchClient.cs │ │ ├── IShowsClient.cs │ │ ├── ISpotifyClient.cs │ │ ├── ITracksClient.cs │ │ └── IUserProfileClient.cs │ ├── LibraryClient.cs │ ├── MarketsClient.cs │ ├── OAuthClient.cs │ ├── PersonalizationClient.cs │ ├── PlayerClient.cs │ ├── PlaylistsClient.cs │ ├── SearchClient.cs │ ├── ShowsClient.cs │ ├── SimplePaginator.cs │ ├── SpotifyClient.cs │ ├── SpotifyClientConfig.cs │ ├── TracksClient.cs │ └── UserProfileClient.cs ├── Exceptions │ ├── APIException.cs │ ├── APIPagingException.cs │ ├── APITooManyRequestsException.cs │ └── APIUnauthorizedException.cs ├── Http │ ├── APIConnector.cs │ ├── APIResponse.cs │ ├── Interfaces │ │ ├── IAPIConnector.cs │ │ ├── IAPIResponse.cs │ │ ├── IHTTPLogger.cs │ │ ├── IHttpClient.cs │ │ ├── IJSONSerializer.cs │ │ ├── IProxyConfig.cs │ │ ├── IRequest.cs │ │ └── IResponse.cs │ ├── NetHttpClient.cs │ ├── NewtonsoftJSONSerializer.cs │ ├── ProxyConfig.cs │ ├── Request.cs │ ├── Response.cs │ └── SimpleConsoleHTTPLogger.cs ├── Models │ ├── Converters │ │ ├── DoubleToIntConverter.cs │ │ └── PlayableItemConverter.cs │ ├── IPaginatable.cs │ ├── Request │ │ ├── AlbumRequest.cs │ │ ├── AlbumTracksRequest.cs │ │ ├── AlbumsRequest.cs │ │ ├── ArtistRequest.cs │ │ ├── ArtistsAlbumsRequest.cs │ │ ├── ArtistsRelatedArtistsRequest.cs │ │ ├── ArtistsRequest.cs │ │ ├── ArtistsTopTracksRequest.cs │ │ ├── AudiobookChaptersRequest.cs │ │ ├── AudiobookRequest.cs │ │ ├── AudiobooksRequest.cs │ │ ├── AuthorizationCodeRefreshRequest.cs │ │ ├── AuthorizationCodeTokenRequest.cs │ │ ├── CategoriesRequest.cs │ │ ├── CategoryPlaylistsRequest.cs │ │ ├── CategoryRequest.cs │ │ ├── ChapterRequest.cs │ │ ├── ChaptersRequest.cs │ │ ├── ClientCredentialsRequest.cs │ │ ├── EpisodeRequest.cs │ │ ├── EpisodesRequest.cs │ │ ├── FeaturedPlaylistsRequest.cs │ │ ├── FollowCheckCurrentUserRequest.cs │ │ ├── FollowCheckPlaylistRequest.cs │ │ ├── FollowGetCurrentUserRequest.cs │ │ ├── FollowPlaylistRequest.cs │ │ ├── FollowRequest.cs │ │ ├── LibraryAlbumsRequest.cs │ │ ├── LibraryAudiobooksRequest.cs │ │ ├── LibraryCheckAlbumsRequest.cs │ │ ├── LibraryCheckAudiobooksRequest.cs │ │ ├── LibraryCheckEpisodesRequest.cs │ │ ├── LibraryCheckShowsRequest.cs │ │ ├── LibraryCheckTracksRequest.cs │ │ ├── LibraryEpisodesRequest.cs │ │ ├── LibraryRemoveAlbumsRequest.cs │ │ ├── LibraryRemoveAudiobooksRequest.cs │ │ ├── LibraryRemoveEpisodesRequest copy.cs │ │ ├── LibraryRemoveShowsRequest.cs │ │ ├── LibraryRemoveTracksRequest.cs │ │ ├── LibrarySaveAlbumsRequest.cs │ │ ├── LibrarySaveAudiobooksRequest.cs │ │ ├── LibrarySaveEpisodesRequest.cs │ │ ├── LibrarySaveShowsRequest.cs │ │ ├── LibrarySaveTracksRequest.cs │ │ ├── LibraryShowsRequest.cs │ │ ├── LibraryTracksRequest.cs │ │ ├── LoginRequest.cs │ │ ├── NewReleasesRequest.cs │ │ ├── PKCETokenRefreshRequest.cs │ │ ├── PKCETokenRequest.cs │ │ ├── PersonalizationTopRequest.cs │ │ ├── PlayerAddToQueueRequest.cs │ │ ├── PlayerCurrentPlaybackRequest.cs │ │ ├── PlayerCurrentlyPlayingRequest.cs │ │ ├── PlayerGetQueueRequest.cs │ │ ├── PlayerPausePlaybackRequest.cs │ │ ├── PlayerRecentlyPlayedRequest.cs │ │ ├── PlayerResumePlaybackRequest.cs │ │ ├── PlayerSeekToRequest.cs │ │ ├── PlayerSetRepeatRequest.cs │ │ ├── PlayerShuffleRequest.cs │ │ ├── PlayerSkipNextRequest.cs │ │ ├── PlayerSkipPreviousRequest.cs │ │ ├── PlayerTransferPlaybackRequest.cs │ │ ├── PlayerVolumeRequest.cs │ │ ├── PlaylistAddItemsRequest.cs │ │ ├── PlaylistChangeDetailsRequest.cs │ │ ├── PlaylistCreateRequest.cs │ │ ├── PlaylistCurrentUsersRequest.cs │ │ ├── PlaylistGetItemsRequest.cs │ │ ├── PlaylistGetRequest.cs │ │ ├── PlaylistGetUsersRequest.cs │ │ ├── PlaylistRemoveItemsRequest.cs │ │ ├── PlaylistReorderItemsRequest.cs │ │ ├── PlaylistReplaceItemsRequest.cs │ │ ├── RecommendationsRequest.cs │ │ ├── RequestParams.cs │ │ ├── SearchRequest.cs │ │ ├── ShowEpisodesRequest.cs │ │ ├── ShowRequest.cs │ │ ├── ShowsRequest.cs │ │ ├── TokenSwapRefreshRequest.cs │ │ ├── TokenSwapTokenRequest.cs │ │ ├── TrackRequest.cs │ │ ├── TracksAudioFeaturesRequest.cs │ │ ├── TracksRequest.cs │ │ ├── UnfollowRequest.cs │ │ └── UsersTopItemsRequest.cs │ ├── Response │ │ ├── Actions.cs │ │ ├── AlbumsResponse.cs │ │ ├── ArtistsRelatedArtistsResponse.cs │ │ ├── ArtistsResponse.cs │ │ ├── ArtistsTopTracksResponse.cs │ │ ├── AudiobooksResponse.cs │ │ ├── Author.cs │ │ ├── AuthorizationCodeRefreshResponse.cs │ │ ├── AuthorizationCodeTokenResponse.cs │ │ ├── AvailableMarketsResponse.cs │ │ ├── CategoriesResponse.cs │ │ ├── Category.cs │ │ ├── CategoryPlaylistsResponse.cs │ │ ├── ChaptersResponse.cs │ │ ├── ClientCredentialsTokenResponse.cs │ │ ├── Context.cs │ │ ├── Copyright.cs │ │ ├── CurrentlyPlaying.cs │ │ ├── CurrentlyPlayingContext.cs │ │ ├── Cursor.cs │ │ ├── CursorPaging.cs │ │ ├── Device.cs │ │ ├── DeviceResponse.cs │ │ ├── EpisodesResponse.cs │ │ ├── FeaturedPlaylistsResponse.cs │ │ ├── FollowedArtistsResponse.cs │ │ ├── Followers.cs │ │ ├── FullAlbum.cs │ │ ├── FullArtist.cs │ │ ├── FullAudiobook.cs │ │ ├── FullAudiobookChapter.cs │ │ ├── FullEpisode.cs │ │ ├── FullPlaylist.cs │ │ ├── FullShow.cs │ │ ├── FullTrack.cs │ │ ├── Image.cs │ │ ├── Interfaces │ │ │ ├── IPlaylistElement.cs │ │ │ ├── IRefreshableToken.cs │ │ │ ├── IToken.cs │ │ │ └── IUserToken.cs │ │ ├── LinkedTrack.cs │ │ ├── Narrator.cs │ │ ├── NewReleasesResponse.cs │ │ ├── PKCETokenResponse.cs │ │ ├── Paging.cs │ │ ├── PlayHistoryItem.cs │ │ ├── PlaylistTrack.cs │ │ ├── PrivateUser.cs │ │ ├── PublicUser.cs │ │ ├── QueueResponse.cs │ │ ├── RecommendationGenresResponse.cs │ │ ├── RecommendationSeed.cs │ │ ├── RecommendationsResponse.cs │ │ ├── ResumePointObject.cs │ │ ├── SavedAlbum.cs │ │ ├── SavedEpisodes.cs │ │ ├── SavedShow.cs │ │ ├── SavedTrack.cs │ │ ├── SearchResponse.cs │ │ ├── Section.cs │ │ ├── Segment.cs │ │ ├── ShowsResponse.cs │ │ ├── SimpleAlbum.cs │ │ ├── SimpleArtist.cs │ │ ├── SimpleAudiobook.cs │ │ ├── SimpleAudiobookChapter.cs │ │ ├── SimpleEpisode.cs │ │ ├── SimpleShow.cs │ │ ├── SimpleTrack.cs │ │ ├── SnapshotResponse.cs │ │ ├── TimeInterval.cs │ │ ├── TrackAudio.cs │ │ ├── TrackAudioAnalysis.cs │ │ ├── TrackAudioFeatures.cs │ │ ├── TrackMeta.cs │ │ ├── TracksAudioFeaturesResponse.cs │ │ ├── TracksResponse.cs │ │ └── UsersTopArtistsResponse.cs │ └── Scopes.cs ├── RetryHandlers │ ├── IRetryHandler.cs │ └── SimpleRetryHandler.cs ├── SpotifyAPI.Web.csproj ├── SpotifyUrls.cs └── Util │ ├── Base64Util.cs │ ├── Ensure.cs │ ├── HTTP.cs │ ├── PKCEUtil.cs │ ├── StringAttribute.cs │ ├── URIExtension.cs │ └── URIParameterFormatProvider.cs ├── SpotifyAPI.sln ├── donate.svg ├── omnisharp.json └── publish.sh /.github/ISSUE_TEMPLATE/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: default 3 | about: Default Issue Template 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "nuget" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | 13 | - package-ecosystem: "npm" # See documentation for possible values 14 | directory: "/" # Location of package manifests 15 | schedule: 16 | interval: "weekly" 17 | -------------------------------------------------------------------------------- /.github/workflows/docs.yaml: -------------------------------------------------------------------------------- 1 | name: Build/Deploy Documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build-deploy-docs: 10 | runs-on: ubuntu-20.04 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | fetch-tags: true 17 | - uses: pnpm/action-setup@v2 18 | with: 19 | version: 9 20 | - name: Use Node.JS 21 | uses: actions/setup-node@v3 22 | with: 23 | node-version: 22.x 24 | cache: "pnpm" 25 | cache-dependency-path: | 26 | SpotifyAPI.Docs/pnpm-lock.yaml 27 | - name: Setup GitHub Deploy SSH Key 28 | uses: webfactory/ssh-agent@v0.4.1 29 | with: 30 | ssh-private-key: ${{ secrets.GH_DEPLOY_SSH_KEY }} 31 | - name: Build & Deploy Documentation 32 | run: ./SpotifyAPI.Docs/docs.sh 33 | -------------------------------------------------------------------------------- /.vscode/csharp.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "class-model": { 3 | "scope": "csharp", 4 | "prefix": "class-model", 5 | "body": [ 6 | "namespace SpotifyAPI.Web", 7 | "{", 8 | " public class $TM_FILENAME_BASE", 9 | " {", 10 | " public ${2:string} ${3:Name} { get; set; }", 11 | "", 12 | " $4", 13 | " }", 14 | "}" 15 | ], 16 | "description": "Creates a new model" 17 | }, 18 | "class-request": { 19 | "scope": "csharp", 20 | "prefix": "class-request", 21 | "body": [ 22 | "namespace SpotifyAPI.Web", 23 | "{", 24 | " public class $TM_FILENAME_BASE : RequestParams", 25 | " {", 26 | " [QueryParam(\"${3:Name}\")]", 27 | " public ${2:string} ${3:Name} { get; set; }", 28 | "", 29 | " $4", 30 | " }", 31 | "}" 32 | ], 33 | "description": "Creates a new request" 34 | }, 35 | "reqcomment": { 36 | "scope": "csharp", 37 | "prefix": "reqcomment", 38 | "body": "The request-model which contains required and optional parameters.", 39 | "description": "Creates a new request comment for XAML" 40 | }, 41 | "remark": { 42 | "scope": "csharp", 43 | "prefix": "remark", 44 | "body": [ 45 | "", 46 | "/// $1", 47 | "/// " 48 | ], 49 | "description": "Creates a new request comment for XAML" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.detectIndentation": false, 3 | "editor.insertSpaces": true, 4 | "editor.tabSize": 2, 5 | "omnisharp.enableEditorConfigSupport": true, 6 | "files.associations": { 7 | "*.md": "mdx" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 Jonas Dellinger 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "printWidth": 120, 6 | "tabWidth": 2, 7 | "endOfLine": "auto" 8 | } 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[javascript]": { 3 | "editor.codeActionsOnSave": { 4 | "source.organizeImports": false 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ pnpm 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ pnpm start 15 | ``` 16 | 17 | This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ pnpm build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | ``` 30 | $ GIT_USER= USE_SSH=true pnpm deploy 31 | ``` 32 | 33 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 34 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Building docs..." 6 | 7 | export LATEST_VERSION="$(git tag --sort=committerdate | grep -E '[0-9]' | tail -1)" 8 | 9 | echo "Set LATEST_VERSION to ${LATEST_VERSION}" 10 | 11 | git config --global user.email "jonas@dellinger.dev" 12 | git config --global user.name "GH Actions Docs Builder" 13 | 14 | cd ./SpotifyAPI.Docs 15 | pnpm i --frozen-lockfile 16 | 17 | USE_SSH=true GIT_USER=JohnnyCrazy pnpm run deploy 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/auth_introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: auth_introduction 3 | title: Introduction 4 | --- 5 | 6 | import useBaseUrl from '@docusaurus/useBaseUrl'; 7 | 8 | Spotify does not allow unauthorized access to the API. Thus, you need an access token to make requests. This access token can be gathered via multiple schemes, all following the OAuth2 spec. Since it's important to choose the correct scheme for your usecase, make sure you have a grasp of the following terminology/docs: 9 | 10 | - OAuth2 11 | - [Spotify Authorization Flows](https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow) 12 | 13 | Since every auth flow also needs an application in the [Spotify dashboard](https://developer.spotify.com/dashboard/), make sure you have the necessary values (like `Client Id` and `Client Secret`). 14 | 15 | Then, continue with the docs of the specific auth flows: 16 | 17 | - [Client Credentials](client_credentials.md) 18 | - [Implicit Grant](implicit_grant.md) 19 | - [Authorization Code](authorization_code.md) 20 | - [PKCE](pkce.md) 21 | - [(Token Swap)](token_swap.md) 22 | 23 | auth comparison 24 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/example_asp.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: example_asp 3 | title: ASP.NET 4 | --- 5 | 6 | import useBaseUrl from '@docusaurus/useBaseUrl'; 7 | 8 | ## Description 9 | 10 | This example is based on ASP .NET Core. It uses `Authorization Code` under the hood with the help of [`AspNet.Security.OAuth.Spotify`](https://www.nuget.org/packages/AspNet.Security.OAuth.Spotify/). It stores the access token in the current user session (cookie-based) and allows to refresh tokens when they expire. Two pages are implemented: 11 | 12 | * Home shows your current playlists via pagination 13 | * Profile shows your current profile information 14 | 15 | ASP Example - Home 16 | ASP Example - Profile 17 | 18 | ## Run it 19 | 20 | Before running it, make sure you created an app in your [spotify dashboard](https://developer.spotify.com/dashboard/) and `https://localhost:5543` is a redirect uri of it. 21 | 22 | ```bash 23 | # Assumes linux and current working directory is the cloned repository 24 | cd SpotifyAPI.Web.Examples/Example.ASP 25 | dotnet restore 26 | 27 | SPOTIFY_CLIENT_ID=YourClientId SPOTIFY_CLIENT_SECRET=YourClientSecret dotnet run 28 | 29 | # Visit https://localhost:5543 30 | ``` 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/example_blazor.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: example_blazor 3 | title: Blazor ServerSide 4 | --- 5 | 6 | import useBaseUrl from '@docusaurus/useBaseUrl'; 7 | 8 | ## Description 9 | 10 | Very similar to the [Blazor WASM Example](example_blazor_wasm.md), but runs code on the server side and pushes view updates to the client. 11 | 12 | ASP Blazor Example - Home 13 | 14 | ## Run it 15 | 16 | Before running it, make sure you created an app in your [spotify dashboard](https://developer.spotify.com/dashboard/) and `https://localhost:5543` is a redirect uri of it. 17 | 18 | ```bash 19 | # Assumes linux and current working directory is the cloned repository 20 | cd SpotifyAPI.Web.Examples/Example.ASPBlazor 21 | dotnet restore 22 | 23 | SPOTIFY_CLIENT_ID=YourClientId SPOTIFY_CLIENT_SECRET=YourClientSecret dotnet run 24 | 25 | # Visit https://localhost:5543 26 | ``` 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/example_cli_custom_html.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: example_cli_custom_html 3 | title: CLI - Custom HTML 4 | --- 5 | 6 | import useBaseUrl from '@docusaurus/useBaseUrl'; 7 | 8 | ## Description 9 | 10 | An example to show how you can display your own HTML resource after the user went through the authentication process of either [Implicit Grant](implicit_grant.md), [Authorization Code](authorization_code.md) or [PKCE](pkce.md). 11 | 12 | CLI Custom HTML Example 13 | 14 | ## Run it 15 | 16 | Before running it, make sure you created an app in your [spotify dashboard](https://developer.spotify.com/dashboard/) and `https://localhost:5543` is a redirect uri of it. 17 | 18 | ```bash 19 | # Assumes linux and current working directory is the cloned repository 20 | cd SpotifyAPI.Web.Examples/Example.CLI.CustomHTML 21 | dotnet restore 22 | 23 | SPOTIFY_CLIENT_ID=YourClientId SPOTIFY_CLIENT_SECRET=YourClientSecret dotnet run 24 | # A browser window should appear 25 | ``` 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/example_cli_persistent_config.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: example_cli_persistent_config 3 | title: CLI - Persistent Config 4 | --- 5 | 6 | ## Description 7 | 8 | An example to show how an obtained access and refresh token can be stored persistently and re-used across application restarts. This results in fewer requests to spotifys authentication endpoints and a faster experience for the user. The example uses [PKCE](pkce.md) in combination with the `PKCEAuthenticator`, which automatically refreshes expired tokens. 9 | 10 | The access and refresh token is saved in a `credentials.json` file of the current working directory. 11 | 12 | ## Run it 13 | 14 | Before running it, make sure you created an app in your [spotify dashboard](https://developer.spotify.com/dashboard/) and `https://localhost:5543` is a redirect uri of it. 15 | 16 | ```bash 17 | # Assumes linux and current working directory is the cloned repository 18 | cd SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig 19 | dotnet restore 20 | 21 | SPOTIFY_CLIENT_ID=YourClientId dotnet run 22 | # A browser window should appear 23 | # Restarting the process should NOT open a new authentication window 24 | # Instead, the local `crendentials.json` file is used 25 | SPOTIFY_CLIENT_ID=YourClientId dotnet run 26 | ``` 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/example_token_swap.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: example_token_swap 3 | title: Token Swap 4 | --- 5 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/example_uwp.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: example_uwp 3 | title: UWP 4 | --- 5 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: introduction 3 | title: Introduction 4 | --- 5 | 6 | This open source library for the Spotify Web API provides an easy to use interface for .NET based languages, like C# and VisualBasic .NET. By using it you can query general spotify catalog information (tracks, albums and playlists), manage user-related content ("My Library", create and edit playlists) and control the users music players (play, stop, transfer playback, play specific track). 7 | 8 | ## Features 9 | 10 | From version 6 onwards, the library was built with the following features included: 11 | 12 | - ✅ Typed responses and requests to over 74 endpoints. Complete and always up to date. 13 | - ✅ Supports `.NET 5.0` and `.NET Standard 2.X`, which includes all major platforms, including mobile: 14 | - `.NET Framework` 15 | - `UWP` 16 | - `.NET Core` 17 | - `Xamarin.Forms` 18 | - ✅ Included `HTTPClient`, but feel free to bring your own! 19 | - ✅ Logging supported 20 | - ✅ Retry Handlers supported 21 | - ✅ Proxy support 22 | - ✅ Pagination support 23 | - ✅ All OAuth2 Authentications supported for use in `ASP .NET` **and** `CLI` apps 24 | - ✅ Modular structure, for easy unit testing 25 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/logging.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: logging 3 | title: Logging 4 | --- 5 | 6 | The library provides a way to inject your own, custom HTTP Logger. By default, no logging is performed. 7 | 8 | ```csharp 9 | var config = SpotifyClientConfig 10 | .CreateDefault("YourAccessToken") 11 | .WithHTTPLogger(new YourHTTPLogger()); 12 | 13 | var spotify = new SpotifyClient(config); 14 | ``` 15 | 16 | The `IHTTPLogger` interface can be found [here](https://github.com/JohnnyCrazy/SpotifyAPI-NET/blob/master/SpotifyAPI.Web/Http/Interfaces/IHTTPLogger.cs). 17 | 18 | ## SimpleConsoleHTTPLogger 19 | 20 | The library ships with a simple console-based logger. 21 | 22 | ```csharp 23 | var config = SpotifyClientConfig 24 | .CreateDefault("YourAccessToken") 25 | .WithHTTPLogger(new SimpleConsoleHTTPLogger()); 26 | 27 | var spotify = new SpotifyClient(config); 28 | ``` 29 | 30 | This logger produces a simple console output for debugging purposes: 31 | 32 | ```text 33 | GET tracks/NotAnid [] 34 | --> BadRequest application/json { "error" : { "status" : 400, "message" : " 35 | 36 | GET tracks/6YlOxoHWLjH6uVQvxUIUug [] 37 | --> OK application/json { "album" : { "album_type" : "album", "arti 38 | ``` 39 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/proxy.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: proxy 3 | title: Proxy 4 | --- 5 | 6 | import useBaseUrl from '@docusaurus/useBaseUrl'; 7 | 8 | The included `HTTPClient` has full proxy configuration support: 9 | 10 | ```csharp 11 | var httpClient = new NetHttpClient(new ProxyConfig("localhost", 8080) 12 | { 13 | User = "", 14 | Password = "", 15 | SkipSSLCheck = false, 16 | }); 17 | var config = SpotifyClientConfig 18 | .CreateDefault() 19 | .WithHTTPClient(httpClient); 20 | 21 | var spotify = new SpotifyClient(config); 22 | ``` 23 | 24 | As an example, [mitmproxy](https://mitmproxy.org/) can be used to inspect the requests and responses: 25 | 26 | mitmproxy 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/docs/unit_testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: unit_testing 3 | title: Unit Testing 4 | --- 5 | 6 | The modular structure of the library makes it easy to mock the API when unit testing. Consider the following method: 7 | 8 | ```csharp 9 | public static async Task IsAdmin(IUserProfileClient userProfileClient) 10 | { 11 | // get logged in user 12 | var user = await userProfileClient.Current(); 13 | 14 | // only my user id is an admin 15 | return user.Id == "1122095781"; 16 | } 17 | ``` 18 | 19 | Using `Moq`, this can be tested without doing any network requests: 20 | 21 | ```csharp 22 | [Test] 23 | public async Task IsAdmin_SuccessTest() 24 | { 25 | var userProfileClient = new Mock(); 26 | userProfileClient.Setup(u => u.Current()).Returns( 27 | Task.FromResult(new PrivateUser 28 | { 29 | Id = "1122095781" 30 | }) 31 | ); 32 | 33 | Assert.AreEqual(true, await IsAdmin(userProfileClient.Object)); 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spotify-api-docs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "docusaurus start --no-open", 7 | "build": "docusaurus build", 8 | "swizzle": "docusaurus swizzle", 9 | "deploy": "docusaurus deploy" 10 | }, 11 | "importSort": { 12 | ".js, .jsx, .ts, .tsx": { 13 | "style": "module" 14 | } 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "^3.1.1", 18 | "@docusaurus/preset-classic": "^3.1.1", 19 | "@mdx-js/react": "^3.0.0", 20 | "classnames": "^2.5.1", 21 | "react": "^18.2.0", 22 | "react-dom": "^18.2.0", 23 | "react-github-btn": "^1.2.0" 24 | }, 25 | "browserslist": { 26 | "production": [ 27 | ">0.2%", 28 | "not dead", 29 | "not op_mini all" 30 | ], 31 | "development": [ 32 | "last 1 chrome version", 33 | "last 1 firefox version", 34 | "last 1 safari version" 35 | ] 36 | }, 37 | "devDependencies": { 38 | "import-sort-style-module": "^6.0.0", 39 | "prettier": "^3.2.5", 40 | "prettier-plugin-import-sort": "^0.0.7" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | docs: { 3 | 'SpotifyAPI-NET': [ 4 | 'introduction', 5 | 'getting_started', 6 | { 7 | type: 'category', 8 | label: 'Guides', 9 | items: [ 10 | 'error_handling', 11 | 'configuration', 12 | 'logging', 13 | 'proxy', 14 | 'pagination', 15 | 'retry_handling', 16 | 'iplayableitem', 17 | 'unit_testing', 18 | ], 19 | }, 20 | { 21 | type: 'category', 22 | label: 'Authentication Guides', 23 | items: [ 24 | 'auth_introduction', 25 | 'client_credentials', 26 | 'implicit_grant', 27 | 'authorization_code', 28 | 'pkce', 29 | 'token_swap', 30 | ], 31 | }, 32 | 'showcase', 33 | { 34 | type: 'category', 35 | label: 'Examples', 36 | items: [ 37 | 'example_asp', 38 | 'example_blazor_wasm', 39 | 'example_blazor', 40 | 'example_cli_custom_html', 41 | 'example_cli_persistent_config', 42 | 'example_token_swap', 43 | 'example_uwp', 44 | ], 45 | }, 46 | { 47 | type: 'category', 48 | label: 'Migration Guides', 49 | items: ['5_to_6'], 50 | }, 51 | ], 52 | }, 53 | }; 54 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | :root { 10 | --ifm-color-primary: #1db954; 11 | --ifm-color-primary-dark: #1aa74c; 12 | --ifm-color-primary-darker: #199d47; 13 | --ifm-color-primary-darkest: #14823b; 14 | --ifm-color-primary-light: #20cb5c; 15 | --ifm-color-primary-lighter: #21d561; 16 | --ifm-color-primary-lightest: #37e072; 17 | --ifm-code-font-size: 95%; 18 | } 19 | 20 | .docusaurus-highlight-code-line { 21 | background-color: rgb(72, 77, 91); 22 | display: block; 23 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 24 | padding: 0 var(--ifm-pre-padding); 25 | } 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/src/pages/styles.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * CSS files with the .module.css suffix will be treated as CSS modules 4 | * and scoped locally. 5 | */ 6 | 7 | .heroBanner { 8 | padding : 4rem 0; 9 | text-align: center; 10 | position : relative; 11 | overflow : hidden; 12 | } 13 | 14 | .exampleCode { 15 | margin-top: 20px; 16 | text-align: left; 17 | } 18 | 19 | @media screen and (max-width: 966px) { 20 | .heroBanner { 21 | padding: 2rem; 22 | } 23 | } 24 | 25 | .buttons { 26 | display : flex; 27 | align-items : center; 28 | justify-content: center; 29 | } 30 | 31 | .features { 32 | display : flex; 33 | align-items: center; 34 | padding : 2rem 0; 35 | width : 100%; 36 | } 37 | 38 | .featureImage { 39 | height: 200px; 40 | width : 200px; 41 | } 42 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/android-chrome-192x192.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/android-chrome-512x512.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/apple-touch-icon.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/asp_blazor_example_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/asp_blazor_example_home.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/asp_example_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/asp_example_home.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/asp_example_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/asp_example_profile.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/auth_comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/auth_comparison.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/auth_protocol_handlers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/auth_protocol_handlers.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/blazorwasm_homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/blazorwasm_homepage.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/blazorwasm_network_tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/blazorwasm_network_tools.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/cli_custom_html.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/cli_custom_html.jpeg -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/favicon-16x16.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/favicon-32x32.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/favicon.ico -------------------------------------------------------------------------------- /SpotifyAPI.Docs/static/img/mitmproxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Docs/static/img/mitmproxy.png -------------------------------------------------------------------------------- /SpotifyAPI.Docs/versioned_docs/version-5.1.1/auth/client_credentials.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: client_credentials 3 | title: Client Credentials 4 | --- 5 | 6 | With this approach, you make a POST Request with a base64 encoded string (consists of ClientId + ClientSecret). You will directly get the token (Without a local HTTP Server), but it will expire and can't be refreshed. 7 | If you want to use it securely, you would need to do it all server-side. 8 | **NOTE:** You will only be able to query non-user-related information e.g search for a Track. 9 | 10 | More info: [here](https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow) 11 | 12 | ```csharp 13 | CredentialsAuth auth = new CredentialsAuth(_clientId, _secretId); 14 | Token token = await auth.GetToken(); 15 | SpotifyWebAPI api = new SpotifyWebAPI() 16 | { 17 | TokenType = token.TokenType, 18 | AccessToken = token.AccessToken 19 | }; 20 | ``` 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/versioned_docs/version-5.1.1/auth/implicit_grant.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: implicit_grant 3 | title: Implicit Grant 4 | sidebar_label: Implicit Grant 5 | --- 6 | 7 | This way is **recommended** and the only auth-process which does not need a server-side exchange of keys. With this approach, you directly get a Token object after the user authed your application. 8 | You won't be able to refresh the token. If you want to use the internal Http server, please add "http://localhost:YOURPORT" to your application redirect URIs. 9 | 10 | More info: [here](https://developer.spotify.com/documentation/general/guides/authorization-guide/#implicit-grant-flow) 11 | 12 | ```csharp 13 | static async void Main(string[] args) 14 | { 15 | ImplicitGrantAuth auth = new ImplicitGrantAuth( 16 | _clientId, 17 | "http://localhost:4002", 18 | "http://localhost:4002", 19 | Scope.UserReadPrivate 20 | ); 21 | auth.AuthReceived += async (sender, payload) => 22 | { 23 | auth.Stop(); // `sender` is also the auth instance 24 | SpotifyWebAPI api = new SpotifyWebAPI() 25 | { 26 | TokenType = payload.TokenType, 27 | AccessToken = payload.AccessToken 28 | }; 29 | // Do requests with API client 30 | }; 31 | auth.Start(); // Starts an internal HTTP Server 32 | auth.OpenBrowser(); 33 | } 34 | ``` 35 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/versioned_docs/version-5.1.1/web/profiles.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: profiles 3 | title: Profiles 4 | sidebar_label: Profiles 5 | --- 6 | 7 | ## GetPrivateProfile 8 | 9 | > Get detailed profile information about the current user (including the current user’s username). 10 | 11 | **Parameters** 12 | 13 | |Name|Description|Example| 14 | |--------------|-------------------------|-------------------------| 15 | 16 | Returns a [PrivateProfile](https://developer.spotify.com/web-api/object-model/#user-object-private) 17 | 18 | **Usage** 19 | ```csharp 20 | PrivateUser user = _spotify.GetPrivateProfile(); 21 | Console.WriteLine(user.DisplayName); 22 | ``` 23 | 24 | --- 25 | 26 | ## GetPublicProfile 27 | 28 | > Get public profile information about a Spotify user. 29 | 30 | **Parameters** 31 | 32 | |Name|Description|Example| 33 | |--------------|-------------------------|-------------------------| 34 | |userId| The user's Spotify user ID. | EXAMPLE 35 | 36 | Returns a [PublicProfile](https://developer.spotify.com/web-api/object-model/#user-object-public) 37 | 38 | **Usage** 39 | ```csharp 40 | ``` 41 | 42 | --- 43 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/versioned_docs/version-5.1.1/web/proxy.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: proxy 3 | title: Proxy Settings 4 | sidebar_label: Proxy Settings 5 | --- 6 | 7 | You can forward your proxy settings to the web api by using a field in the `SpotifyLocalAPIConfig`. 8 | 9 | ```csharp 10 | ProxyConfig proxyConfig = new ProxyConfig() 11 | { 12 | Host = "127.0.0.1", 13 | Port = 8080 14 | // Additional values like Username and Password are available 15 | }; 16 | 17 | SpotifyWebAPI api = new SpotifyWebAPI(proxyConfig); 18 | ``` 19 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/versioned_docs/version-5.1.1/web/utilities.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: utilities 3 | title: Utilities 4 | sidebar_label: Utilities 5 | --- 6 | 7 | ## Paging-Methods 8 | 9 | The `SpotifyWebAPI` features two paging-helper Methods, `GetNextPage(Paging page)` and `GetPreviousPage(Paging page)`. 10 | Both are an easy way to receive the next/previous page of a Paging-Object. 11 | 12 | Sample: 13 | ````csharp 14 | var playlistTracks = _spotify.GetPlaylistTracks("1122095781", "4EcNf2l8rXInbJOf3tQdgU", "", 50); 15 | while (true) 16 | { 17 | Console.WriteLine(playlistTracks.Items.Count); 18 | if (!playlistTracks.HasNextPage()) 19 | break; 20 | playlistTracks = _spotify.GetNextPage(playlistTracks); 21 | } 22 | ```` 23 | -------------------------------------------------------------------------------- /SpotifyAPI.Docs/versions.json: -------------------------------------------------------------------------------- 1 | ["5.1.1"] 2 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: InternalsVisibleTo("SpotifyAPI.Web.Tests")] 5 | [assembly: CLSCompliant(true)] 6 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/AuthException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace SpotifyAPI.Web.Auth 5 | { 6 | [Serializable] 7 | public class AuthException : Exception 8 | { 9 | public AuthException(string? error, string? state) 10 | { 11 | Error = error; 12 | State = state; 13 | } 14 | public AuthException(string message) : base(message) { } 15 | public AuthException(string message, Exception inner) : base(message, inner) { } 16 | 17 | #if NET8_0_OR_GREATER 18 | [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")] 19 | #endif 20 | protected AuthException(SerializationInfo info, StreamingContext context) : base(info, context) { } 21 | 22 | public string? Error { get; set; } 23 | public string? State { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/BrowserUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace SpotifyAPI.Web.Auth 6 | { 7 | public static class BrowserUtil 8 | { 9 | public static void Open(Uri uri) 10 | { 11 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) 12 | { 13 | var uriStr = uri.ToString().Replace("&", "^&"); 14 | Process.Start(new ProcessStartInfo($"cmd", $"/c start {uriStr}")); 15 | } 16 | else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) 17 | { 18 | Process.Start("xdg-open", uri.ToString()); 19 | } 20 | else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) 21 | { 22 | Process.Start("open", uri.ToString()); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/IAuthServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace SpotifyAPI.Web.Auth 5 | { 6 | public interface IAuthServer : IDisposable 7 | { 8 | event Func AuthorizationCodeReceived; 9 | 10 | event Func ImplictGrantReceived; 11 | 12 | Task Start(); 13 | Task Stop(); 14 | 15 | Uri BaseUri { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/Models/Response/AuthorizationCodeResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web.Auth 2 | { 3 | public class AuthorizationCodeResponse 4 | { 5 | public AuthorizationCodeResponse(string code) 6 | { 7 | Ensure.ArgumentNotNullOrEmptyString(code, nameof(code)); 8 | 9 | Code = code; 10 | } 11 | 12 | public string Code { get; set; } = default!; 13 | public string? State { get; set; } = default!; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/Models/Response/ImplicitGrantResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web.Auth 4 | { 5 | public class ImplictGrantResponse 6 | { 7 | public ImplictGrantResponse(string accessToken, string tokenType, int expiresIn) 8 | { 9 | Ensure.ArgumentNotNullOrEmptyString(accessToken, nameof(accessToken)); 10 | Ensure.ArgumentNotNullOrEmptyString(tokenType, nameof(tokenType)); 11 | 12 | AccessToken = accessToken; 13 | TokenType = tokenType; 14 | ExpiresIn = expiresIn; 15 | } 16 | 17 | public string AccessToken { get; set; } = default!; 18 | public string TokenType { get; set; } = default!; 19 | public int ExpiresIn { get; set; } 20 | public string? State { get; set; } = default!; 21 | 22 | /// 23 | /// Auto-Initalized to UTC Now 24 | /// 25 | /// 26 | public DateTime CreatedAt { get; set; } = DateTime.UtcNow; 27 | 28 | public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/Resources/auth_assets/main.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | width: 100%; 4 | height: 100%; 5 | } 6 | 7 | body { 8 | color: #f5f6fa; 9 | background-color: #353b48; 10 | width: 100%; 11 | height: 100%; 12 | background-attachment: fixed; 13 | } 14 | 15 | main { 16 | text-align: center; 17 | margin-top: 100px; 18 | } 19 | 20 | .logo { 21 | margin-bottom: 50px; 22 | } 23 | 24 | .hidden { 25 | visibility: hidden; 26 | } 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Auth/Resources/default_site/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Auth/Resources/default_site/favicon.ico -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Example.ASP.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | da29eac4-4c22-4a7f-b393-379e83b60998 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to the Development environment displays detailed information about the error that occurred. 20 |

21 |

22 | The Development environment shouldn't be enabled for deployed applications. 23 | It can result in displaying sensitive information from exceptions to end users. 24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 25 | and restarting the app. 26 |

27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.AspNetCore.Mvc.RazorPages; 4 | 5 | namespace Example.ASP.Pages 6 | { 7 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 8 | public class ErrorModel : PageModel 9 | { 10 | public string RequestId { get; set; } 11 | 12 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 13 | 14 | public ErrorModel() { } 15 | 16 | public void OnGet() 17 | { 18 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Pages/Index.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model IndexModel 3 | @inject SpotifyClientBuilder spotifyBuilder 4 | @{ 5 | ViewData["Title"] = "Home"; 6 | ViewData["Page"] = "index"; 7 | } 8 | 9 |
10 |

11 | Welcome, 12 |

13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | @{ 23 | foreach (var item in Model.Playlists.Items) 24 | { 25 | 26 | 31 | 34 | 35 | } 36 | } 37 | 38 |
ImageName
27 | @if(item.Images.Any()) { 28 | 29 | } 30 | 32 | @item.Name 33 |
39 | @if(Model.Previous != null) { 40 | Previous 41 | } 42 | @if(Model.Next != null) { 43 | Next 44 | } 45 |
46 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Pages/Profile.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.AspNetCore.Authentication; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.AspNetCore.Mvc.RazorPages; 5 | using SpotifyAPI.Web; 6 | 7 | namespace Example.ASP.Pages 8 | { 9 | public class ProfileModel : PageModel 10 | { 11 | private readonly SpotifyClientBuilder _spotifyClientBuilder; 12 | public ProfileModel(SpotifyClientBuilder spotifyClientBuilder) 13 | { 14 | _spotifyClientBuilder = spotifyClientBuilder; 15 | } 16 | 17 | public PrivateUser Me { get; set; } 18 | 19 | public async Task OnGet() 20 | { 21 | var spotify = await _spotifyClientBuilder.BuildClient(); 22 | 23 | Me = await spotify.UserProfile.Current(); 24 | } 25 | 26 | public async Task OnPost() 27 | { 28 | await HttpContext.SignOutAsync(); 29 | return Redirect("https://google.com"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Pages/Profile.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ProfileModel 3 | @{ 4 | ViewData["Title"] = "Profile"; 5 | ViewData["Page"] = "profile"; 6 | ViewData["Description"] = "Have a look at your spotify info and logout of your account"; 7 | } 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
KeyValue
Id@Model.Me.Id
Uri@Model.Me.Uri
DisplayName@Model.Me.DisplayName
Country@Model.Me.Country
Product@Model.Me.Product
E-Mail (unverfied)@Model.Me.Email
41 | 42 |
43 | 44 |
45 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Example.ASP 2 | @namespace Example.ASP.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Pages/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | 5 | namespace Example.ASP 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | CreateHostBuilder(args).Build().Run(); 12 | } 13 | 14 | public static IHostBuilder CreateHostBuilder(string[] args) => 15 | Host.CreateDefaultBuilder(args) 16 | .ConfigureWebHostDefaults(webBuilder => 17 | { 18 | webBuilder.UseStartup(); 19 | }) 20 | .ConfigureAppConfiguration((httpContext, builder) => 21 | { 22 | builder.AddUserSecrets(); 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/SpotifyClientBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Microsoft.AspNetCore.Authentication; 3 | using Microsoft.AspNetCore.Http; 4 | using SpotifyAPI.Web; 5 | 6 | namespace Example.ASP 7 | { 8 | public class SpotifyClientBuilder 9 | { 10 | private readonly IHttpContextAccessor _httpContextAccessor; 11 | private readonly SpotifyClientConfig _spotifyClientConfig; 12 | 13 | public SpotifyClientBuilder(IHttpContextAccessor httpContextAccessor, SpotifyClientConfig spotifyClientConfig) 14 | { 15 | _httpContextAccessor = httpContextAccessor; 16 | _spotifyClientConfig = spotifyClientConfig; 17 | } 18 | 19 | public async Task BuildClient() 20 | { 21 | var token = await _httpContextAccessor.HttpContext.GetTokenAsync("Spotify", "access_token"); 22 | 23 | return new SpotifyClient(_spotifyClientConfig.WithToken(token)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.ASP/wwwroot/favicon.ico -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASP/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | (function (window, document) { 2 | 3 | var layout = document.getElementById('layout'), 4 | menu = document.getElementById('menu'), 5 | menuLink = document.getElementById('menuLink'); 6 | 7 | function toggleClass(element, className) { 8 | var classes = element.className.split(/\s+/), 9 | length = classes.length, 10 | i = 0; 11 | 12 | for (; i < length; i++) { 13 | if (classes[i] === className) { 14 | classes.splice(i, 1); 15 | break; 16 | } 17 | } 18 | // The className is not found 19 | if (length === classes.length) { 20 | classes.push(className); 21 | } 22 | 23 | element.className = classes.join(' '); 24 | } 25 | 26 | function toggleAll(e) { 27 | var active = 'active'; 28 | 29 | e.preventDefault(); 30 | toggleClass(layout, active); 31 | toggleClass(menu, active); 32 | toggleClass(menuLink, active); 33 | } 34 | 35 | function handleEvent(e) { 36 | if (e.target.id === menuLink.id) { 37 | return toggleAll(e); 38 | } 39 | 40 | if (menu.className.indexOf('active') !== -1) { 41 | return toggleAll(e); 42 | } 43 | } 44 | 45 | document.addEventListener('click', handleEvent); 46 | 47 | }(this, this.document)); 48 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 |

Sorry, there's nothing at this address.

8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Data/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Example.ASPBlazor.Data 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Data/WeatherForecastService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | 5 | namespace Example.ASPBlazor.Data 6 | { 7 | public class WeatherForecastService 8 | { 9 | private static readonly string[] Summaries = new[] 10 | { 11 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 12 | }; 13 | 14 | public Task GetForecastAsync(DateTime startDate) 15 | { 16 | var rng = new Random(); 17 | return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast 18 | { 19 | Date = startDate.AddDays(index), 20 | TemperatureC = rng.Next(-20, 55), 21 | Summary = Summaries[rng.Next(Summaries.Length)] 22 | }).ToArray()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Example.ASPBlazor.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Pages/Error.razor: -------------------------------------------------------------------------------- 1 | @page "/error" 2 | 3 | 4 |

Error.

5 |

An error occurred while processing your request.

6 | 7 |

Development Mode

8 |

9 | Swapping to Development environment will display more detailed information about the error that occurred. 10 |

11 |

12 | The Development environment shouldn't be enabled for deployed applications. 13 | It can result in displaying sensitive information from exceptions to end users. 14 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 15 | and restarting the app. 16 |

-------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace Example.ASPBlazor.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | @{ 5 | Layout = null; 6 | } 7 | 8 | 9 | 10 | 11 | 12 | 13 | Example.ASPBlazor 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | An error has occurred. This application may no longer respond until reloaded. 26 | 27 | 28 | An unhandled exception has occurred. See browser dev tools for details. 29 | 30 | Reload 31 | 🗙 32 |
33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace Example.ASPBlazor 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | CreateHostBuilder(args).Build().Run(); 11 | } 12 | 13 | public static IHostBuilder CreateHostBuilder(string[] args) => 14 | Host.CreateDefaultBuilder(args) 15 | .ConfigureWebHostDefaults(webBuilder => 16 | { 17 | webBuilder.UseStartup(); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | 16 |
17 | 18 | @code { 19 | private bool collapseNavMenu = true; 20 | 21 | private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 22 | 23 | private void ToggleNavMenu() 24 | { 25 | collapseNavMenu = !collapseNavMenu; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |  11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string Title { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Authorization 3 | @using Microsoft.AspNetCore.Components.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.JSInterop 8 | @using Example.ASPBlazor 9 | @using Example.ASPBlazor.Shared 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.ASPBlazor/wwwroot/favicon.ico -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/.gitignore: -------------------------------------------------------------------------------- 1 | wwwroot/appsettings.json 2 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Sorry, there's nothing at this address.

8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/Example.BlazorWASM.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Http; 3 | using System.Threading.Tasks; 4 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Example.BlazorWASM 8 | { 9 | public class Program 10 | { 11 | public static async Task Main(string[] args) 12 | { 13 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 14 | builder.RootComponents.Add("app"); 15 | 16 | builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 17 | 18 | await builder.Build().RunAsync(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 6 | 7 |
8 |
9 | About 10 |
11 | 12 |
13 | @Body 14 |
15 |
16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  7 | 8 |
9 | 16 |
17 | 18 | @code { 19 | private bool collapseNavMenu = true; 20 | 21 | private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 22 | 23 | private void ToggleNavMenu() 24 | { 25 | collapseNavMenu = !collapseNavMenu; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 7 | @using Microsoft.JSInterop 8 | @using Example.BlazorWASM 9 | @using Example.BlazorWASM.Shared 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/favicon.ico -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Example.BlazorWASM 8 | 9 | 10 | 11 | 12 | 13 | 14 | Loading... 15 | 16 |
17 | An unhandled error has occurred. 18 | Reload 19 | 🗙 20 |
21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.BlazorWASM/wwwroot/sample-data/weather.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2018-05-06", 4 | "temperatureC": 1, 5 | "summary": "Freezing" 6 | }, 7 | { 8 | "date": "2018-05-07", 9 | "temperatureC": 14, 10 | "summary": "Bracing" 11 | }, 12 | { 13 | "date": "2018-05-08", 14 | "temperatureC": -13, 15 | "summary": "Freezing" 16 | }, 17 | { 18 | "date": "2018-05-09", 19 | "temperatureC": -16, 20 | "summary": "Balmy" 21 | }, 22 | { 23 | "date": "2018-05-10", 24 | "temperatureC": -2, 25 | "summary": "Chilly" 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.CLI.CustomHTML/Example.CLI.CustomHTML.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | net7.0 10 | Exe 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/.gitignore: -------------------------------------------------------------------------------- 1 | credentials.json 2 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | // Use IntelliSense to find out which attributes exist for C# debugging 6 | // Use hover for the description of the existing attributes 7 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 8 | "name": ".NET Core Launch (console)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/bin/Debug/net6.0/Example.CLI.PersistentConfig.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}", 16 | // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console 17 | "console": "internalConsole", 18 | "stopAtEntry": false 19 | }, 20 | { 21 | "name": ".NET Core Attach", 22 | "type": "coreclr", 23 | "request": "attach" 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/Example.CLI.PersistentConfig.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/Example.CLI.PersistentConfig.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "--project", 36 | "${workspaceFolder}/Example.CLI.PersistentConfig.csproj" 37 | ], 38 | "problemMatcher": "$msCompile" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.CLI.PersistentConfig/Example.CLI.PersistentConfig.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | 9.0 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.TokenSwap/Client/Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | net7.0 10 | Exe 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.TokenSwap/Server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.TokenSwap/Server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Server", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "dependencies": { 10 | "axios": "^1.7.4", 11 | "body-parser": "^1.20.3", 12 | "express": "^4.20.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | Hello World! 8 | 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MvvmCross; 3 | using MvvmCross.Platforms.Uap.Core; 4 | using MvvmCross.Platforms.Uap.Views; 5 | using Windows.ApplicationModel; 6 | using Windows.ApplicationModel.Activation; 7 | using Windows.UI.Popups; 8 | using Windows.UI.Xaml; 9 | using Windows.UI.Xaml.Controls; 10 | using Windows.UI.Xaml.Navigation; 11 | 12 | namespace Example.UWP 13 | { 14 | public abstract class ExampleApp : MvxApplication, CoreApp> 15 | { 16 | } 17 | 18 | /// 19 | /// Provides application-specific behavior to supplement the default Application class. 20 | /// 21 | public sealed partial class App 22 | { 23 | /// 24 | /// Initializes the singleton application object. This is the first line of authored code 25 | /// executed, and as such is the logical equivalent of main() or WinMain(). 26 | /// 27 | public App() 28 | { 29 | InitializeComponent(); 30 | } 31 | 32 | protected override void OnActivated(IActivatedEventArgs args) 33 | { 34 | if (args.Kind == ActivationKind.Protocol) 35 | { 36 | ProtocolActivatedEventArgs eventArgs = args as ProtocolActivatedEventArgs; 37 | var publisher = Mvx.IoCProvider.Resolve(); 38 | publisher.ReceiveToken(eventArgs.Uri); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.UWP/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.UWP/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.UWP/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.UWP/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.UWP/Assets/StoreLogo.png -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnnyCrazy/SpotifyAPI-NET/8293f6419b298c0ef7303064003edd474e314a3a/SpotifyAPI.Web.Examples/Example.UWP/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/CoreApp.cs: -------------------------------------------------------------------------------- 1 | using Example.UWP.ViewModels; 2 | using MvvmCross.IoC; 3 | using MvvmCross.ViewModels; 4 | 5 | namespace Example.UWP 6 | { 7 | public class CoreApp : MvxApplication 8 | { 9 | public override void Initialize() 10 | { 11 | CreatableTypes() 12 | .EndingWith("Service") 13 | .AsInterfaces() 14 | .RegisterAsLazySingleton(); 15 | 16 | RegisterAppStart(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Example.UWP")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Example.UWP")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/TokenPublisherService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Example.UWP 8 | { 9 | public interface ITokenPublisherService 10 | { 11 | event EventHandler TokenReceived; 12 | void ReceiveToken(Uri uri); 13 | } 14 | public class TokenPublisherService : ITokenPublisherService 15 | { 16 | public event EventHandler TokenReceived; 17 | 18 | public void ReceiveToken(Uri uri) 19 | { 20 | if(string.IsNullOrEmpty(uri.Fragment)) 21 | { 22 | throw new Exception($"Received weird URI: {uri}"); 23 | } 24 | var arguments = uri.Fragment.Substring(1).Split("&") 25 | .Select(param => param.Split("=")) 26 | .ToDictionary(param => param[0], param => param[1]); 27 | 28 | if(arguments["access_token"] == null) 29 | { 30 | throw new Exception($"No access token found in URI: {uri}"); 31 | } 32 | 33 | TokenReceived?.Invoke(this, arguments["access_token"]); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/ViewModels/PlaylistsListViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MvvmCross.ViewModels; 7 | using SpotifyAPI.Web; 8 | 9 | namespace Example.UWP.ViewModels 10 | { 11 | /// 12 | /// Spotify Token is the parameter 13 | /// 14 | public class PlaylistsListViewModel : MvxViewModel 15 | { 16 | private SpotifyClient _spotify; 17 | 18 | private IList _playlists; 19 | public IList Playlists 20 | { 21 | get => _playlists ?? (_playlists = new List()); 22 | set => SetProperty(ref _playlists, value); 23 | } 24 | 25 | public override void Prepare(string token) 26 | { 27 | _spotify = new SpotifyClient(SpotifyClientConfig.CreateDefault(token)); 28 | } 29 | 30 | public override async Task Initialize() 31 | { 32 | await base.Initialize(); 33 | 34 | Playlists = await _spotify.PaginateAll(await _spotify.Playlists.CurrentUsers()); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Views/LoginView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Example.UWP.ViewModels; 2 | using MvvmCross.Platforms.Uap.Presenters.Attributes; 3 | using MvvmCross.Platforms.Uap.Views; 4 | using MvvmCross.ViewModels; 5 | 6 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 7 | 8 | namespace Example.UWP.Views 9 | { 10 | /// 11 | /// An empty page that can be used on its own or navigated to within a Frame. 12 | /// 13 | [MvxViewFor(typeof(LoginViewModel))] 14 | [MvxPagePresentation] 15 | public sealed partial class LoginView : LoginViewPage 16 | { 17 | public LoginView() 18 | { 19 | InitializeComponent(); 20 | } 21 | } 22 | 23 | public abstract class LoginViewPage : MvxWindowsPage 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Examples/Example.UWP/Views/PlaylistsListView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Example.UWP.ViewModels; 7 | using MvvmCross.Platforms.Uap.Presenters.Attributes; 8 | using MvvmCross.Platforms.Uap.Views; 9 | using MvvmCross.ViewModels; 10 | using Windows.Foundation; 11 | using Windows.Foundation.Collections; 12 | using Windows.UI.Xaml; 13 | using Windows.UI.Xaml.Controls; 14 | using Windows.UI.Xaml.Controls.Primitives; 15 | using Windows.UI.Xaml.Data; 16 | using Windows.UI.Xaml.Input; 17 | using Windows.UI.Xaml.Media; 18 | using Windows.UI.Xaml.Navigation; 19 | 20 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238 21 | 22 | namespace Example.UWP.Views 23 | { 24 | /// 25 | /// An empty page that can be used on its own or navigated to within a Frame. 26 | /// 27 | [MvxViewFor(typeof(PlaylistsListViewModel))] 28 | [MvxPagePresentation] 29 | public sealed partial class PlaylistsListView : PlaylistsListViewPage 30 | { 31 | public PlaylistsListView() 32 | { 33 | InitializeComponent(); 34 | } 35 | } 36 | 37 | public abstract class PlaylistsListViewPage : MvxWindowsPage 38 | { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Tests/Clients/BrowseClientTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using Moq; 5 | using NUnit.Framework; 6 | using SpotifyAPI.Web.Http; 7 | 8 | namespace SpotifyAPI.Web.Tests 9 | { 10 | [TestFixture] 11 | public class BrowseClientTest 12 | { 13 | [Test] 14 | public async Task GetRecommendationGenres_UsesCorrectURL() 15 | { 16 | var api = new Mock(); 17 | var client = new BrowseClient(api.Object); 18 | 19 | await client.GetRecommendationGenres(); 20 | 21 | api.Verify(a => a.Get( 22 | It.Is((uri) => uri.ToString().Contains("recommendations/available-genre-seeds")), 23 | It.IsAny() 24 | )); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Tests/Clients/FollowClientTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using Moq; 5 | using NUnit.Framework; 6 | using SpotifyAPI.Web.Http; 7 | 8 | namespace SpotifyAPI.Web.Tests 9 | { 10 | [TestFixture] 11 | public class FollowClientTest 12 | { 13 | [Test] 14 | public async Task OfCurrentUser_PassesQueryParams() 15 | { 16 | var api = new Mock(); 17 | var client = new FollowClient(api.Object); 18 | 19 | var request = new FollowOfCurrentUserRequest(FollowOfCurrentUserRequest.Type.Artist); 20 | await client.OfCurrentUser(request); 21 | 22 | api.Verify(a => a.Get( 23 | SpotifyUrls.CurrentUserFollower(), 24 | It.Is>(val => val.ContainsKey("type")), 25 | It.IsAny() 26 | )); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Tests/Http/TokenAuthenticatorTest.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Collections.Generic; 3 | using Moq; 4 | using NUnit.Framework; 5 | using SpotifyAPI.Web.Http; 6 | 7 | namespace SpotifyAPI.Web.Tests 8 | { 9 | [TestFixture] 10 | public class TokenAuthenticatorTest 11 | { 12 | [Test] 13 | public void Apply_AddsCorrectHeader() 14 | { 15 | var authenticator = new TokenAuthenticator("MyToken", "Bearer"); 16 | var request = new Mock(); 17 | var apiConnector = new Mock(); 18 | 19 | request.SetupGet(r => r.Headers).Returns(new Dictionary()); 20 | 21 | authenticator.Apply(request.Object, apiConnector.Object); 22 | Assert.That(request.Object.Headers["Authorization"], Is.EqualTo("Bearer MyToken")); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Tests/Models/PlayableItemConverterTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | using Newtonsoft.Json; 4 | using NUnit.Framework; 5 | 6 | namespace SpotifyAPI.Web.Tests 7 | { 8 | [TestFixture] 9 | public class PPlayableItemConverterTest 10 | { 11 | [Test] 12 | public void PlayableItemConverter_CanSerialize() 13 | { 14 | var context = new CurrentlyPlayingContext { Item = new FullTrack() }; 15 | 16 | Assert.DoesNotThrow(() => 17 | { 18 | var serialized = JsonConvert.SerializeObject(context); 19 | }); 20 | } 21 | 22 | [Test] 23 | public async Task PlayableItemConverter_Reserialize() 24 | { 25 | // This has lowercase field names since it's a spotify response 26 | var fixture = await File.ReadAllTextAsync( 27 | Path.Join(TestContext.CurrentContext.TestDirectory, "Fixtures/full_playlist_response.json") 28 | ); 29 | 30 | var fullPlaylist = JsonConvert.DeserializeObject(fixture); 31 | // This whill have uppercase field names since we use default JsonConvert settings 32 | var serialized = JsonConvert.SerializeObject(fullPlaylist); 33 | 34 | Assert.DoesNotThrow(() => 35 | { 36 | var deserialized = JsonConvert.DeserializeObject(serialized); 37 | }); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Tests/SpotifyAPI.Web.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0;net7.0;net6.0 5 | 9.0 6 | false 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Always 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Tests/UtilTests/Base64UtilTest.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using NUnit.Framework; 3 | 4 | namespace SpotifyAPI.Web.Tests 5 | { 6 | [TestFixture] 7 | public class Base64UtilTest 8 | { 9 | [Test] 10 | public void Base64UrlDecode_Works() 11 | { 12 | var encoded = "SGVsbG9Xb3JsZA"; 13 | 14 | Assert.That("HelloWorld", Is.EqualTo(Encoding.UTF8.GetString(Base64Util.UrlDecode(encoded)))); 15 | } 16 | 17 | [Test] 18 | public void Base64UrlEncode_Works() 19 | { 20 | var decoded = "HelloWorld"; 21 | 22 | Assert.That("SGVsbG9Xb3JsZA", Is.EqualTo(Base64Util.UrlEncode(Encoding.UTF8.GetBytes(decoded)))); 23 | } 24 | 25 | [Test] 26 | public void Base64UrlEncode_WorksSpecialChars() 27 | { 28 | var bytes = new byte[] { 0x04, 0x9f, 0x9c, 0xff, 0x3f, 0x0a }; 29 | 30 | // normal base64: BJ+c/z8K 31 | Assert.That("BJ-c_z8K", Is.EqualTo(Base64Util.UrlEncode(bytes))); 32 | } 33 | 34 | [Test] 35 | public void Base64UrlDecode_WorksSpecialChars() 36 | { 37 | var bytes = new byte[] { 0x04, 0x9f, 0x9c, 0xff, 0x3f, 0x0a }; 38 | 39 | // normal base64: BJ+c/z8K 40 | Assert.That(bytes, Is.EqualTo(Base64Util.UrlDecode("BJ-c_z8K"))); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SpotifyAPI.Web.Tests/UtilTests/URIParameterFormatProviderTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | 4 | namespace SpotifyAPI.Web.Tests 5 | { 6 | [TestFixture] 7 | public class URIParameterFormatProviderTest 8 | { 9 | [Test] 10 | public void Format_NormalParameters() 11 | { 12 | var expected = "/users/wizzler"; 13 | 14 | var user = "wizzler"; 15 | var formatter = new URIParameterFormatProvider(); 16 | string func(FormattableString str) => str.ToString(formatter); 17 | 18 | Assert.That(expected, Is.EqualTo(func($"/users/{user}"))); 19 | } 20 | 21 | [Test] 22 | public void Format_EscapedParameters() 23 | { 24 | var expected = "/users/++wizzler"; 25 | 26 | var user = " wizzler"; 27 | var formatter = new URIParameterFormatProvider(); 28 | string func(FormattableString str) => str.ToString(formatter); 29 | 30 | Assert.That(expected, Is.EqualTo(func($"/users/{user}"))); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Assembly.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | [assembly: InternalsVisibleTo("SpotifyAPI.Web.Tests")] 5 | [assembly: CLSCompliant(true)] 6 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Authenticators/IAuthenticator.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using SpotifyAPI.Web.Http; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | public interface IAuthenticator 7 | { 8 | Task Apply(IRequest request, IAPIConnector apiConnector); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Authenticators/TokenAuthenticator.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using SpotifyAPI.Web.Http; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | public class TokenAuthenticator : IAuthenticator 7 | { 8 | public TokenAuthenticator(string token, string tokenType) 9 | { 10 | Token = token; 11 | TokenType = tokenType; 12 | } 13 | 14 | public string Token { get; set; } 15 | 16 | public string TokenType { get; set; } 17 | 18 | public Task Apply(IRequest request, IAPIConnector apiConnector) 19 | { 20 | Ensure.ArgumentNotNull(request, nameof(request)); 21 | 22 | request.Headers["Authorization"] = $"{TokenType} {Token}"; 23 | return Task.CompletedTask; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Clients/APIClient.cs: -------------------------------------------------------------------------------- 1 | using SpotifyAPI.Web.Http; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public abstract class APIClient 6 | { 7 | protected APIClient(IAPIConnector apiConnector) 8 | { 9 | Ensure.ArgumentNotNull(apiConnector, nameof(apiConnector)); 10 | 11 | API = apiConnector; 12 | } 13 | 14 | protected IAPIConnector API { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Clients/ChaptersClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using SpotifyAPI.Web.Http; 4 | using URLs = SpotifyAPI.Web.SpotifyUrls; 5 | 6 | namespace SpotifyAPI.Web 7 | { 8 | public class ChaptersClient : APIClient, IChaptersClient 9 | { 10 | public ChaptersClient(IAPIConnector apiConnector) : base(apiConnector) { } 11 | 12 | public Task Get(string chapterId, CancellationToken cancel = default) 13 | { 14 | Ensure.ArgumentNotNullOrEmptyString(chapterId, nameof(chapterId)); 15 | 16 | return API.Get(URLs.Chapter(chapterId), cancel); 17 | } 18 | 19 | public Task Get(string chapterId, ChapterRequest request, CancellationToken cancel = default) 20 | { 21 | Ensure.ArgumentNotNullOrEmptyString(chapterId, nameof(chapterId)); 22 | Ensure.ArgumentNotNull(request, nameof(request)); 23 | 24 | return API.Get(URLs.Chapter(chapterId), request.BuildQueryParams(), cancel); 25 | } 26 | 27 | public Task GetSeveral(ChaptersRequest request, CancellationToken cancel = default) 28 | { 29 | Ensure.ArgumentNotNull(request, nameof(request)); 30 | 31 | return API.Get(URLs.Chapters(), request.BuildQueryParams(), cancel); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Clients/EpisodesClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using SpotifyAPI.Web.Http; 4 | using URLs = SpotifyAPI.Web.SpotifyUrls; 5 | 6 | namespace SpotifyAPI.Web 7 | { 8 | public class EpisodesClient : APIClient, IEpisodesClient 9 | { 10 | public EpisodesClient(IAPIConnector apiConnector) : base(apiConnector) { } 11 | 12 | public Task Get(string episodeId, CancellationToken cancel = default) 13 | { 14 | Ensure.ArgumentNotNullOrEmptyString(episodeId, nameof(episodeId)); 15 | 16 | return API.Get(URLs.Episode(episodeId), cancel); 17 | } 18 | 19 | public Task Get(string episodeId, EpisodeRequest request, CancellationToken cancel = default) 20 | { 21 | Ensure.ArgumentNotNullOrEmptyString(episodeId, nameof(episodeId)); 22 | Ensure.ArgumentNotNull(request, nameof(request)); 23 | 24 | return API.Get(URLs.Episode(episodeId), request.BuildQueryParams(), cancel); 25 | } 26 | 27 | public Task GetSeveral(EpisodesRequest request, CancellationToken cancel = default) 28 | { 29 | Ensure.ArgumentNotNull(request, nameof(request)); 30 | 31 | return API.Get(URLs.Episodes(), request.BuildQueryParams(), cancel); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Clients/Interfaces/IMarketsClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | /// 7 | /// Markets Endpoints 8 | /// 9 | public interface IMarketsClient 10 | { 11 | /// 12 | /// Get the list of markets where Spotify is available. 13 | /// 14 | /// The cancellation-token to allow to cancel the request. 15 | /// 16 | /// https://developer.spotify.com/documentation/web-api/reference/#/operations/get-available-markets 17 | /// 18 | /// 19 | Task AvailableMarkets(CancellationToken cancel = default); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Clients/Interfaces/ISearchClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | /// 7 | /// Search Endpoints 8 | /// 9 | public interface ISearchClient 10 | { 11 | /// 12 | /// Get Spotify Catalog information about albums, artists, playlists, 13 | /// tracks, shows or episodes that match a keyword string. 14 | /// 15 | /// The request-model which contains required and optional parameters. 16 | /// The cancellation-token to allow to cancel the request. 17 | /// 18 | /// https://developer.spotify.com/documentation/web-api/reference-beta/#endpoint-search 19 | /// 20 | /// 21 | Task Item(SearchRequest request, CancellationToken cancel = default); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Clients/MarketsClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using SpotifyAPI.Web.Http; 4 | using URLs = SpotifyAPI.Web.SpotifyUrls; 5 | 6 | namespace SpotifyAPI.Web 7 | { 8 | public class MarketsClient : APIClient, IMarketsClient 9 | { 10 | public MarketsClient(IAPIConnector apiConnector) : base(apiConnector) { } 11 | 12 | public Task AvailableMarkets(CancellationToken cancel = default) 13 | { 14 | return API.Get(URLs.Markets(), cancel); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Clients/SearchClient.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using SpotifyAPI.Web.Http; 4 | using URLs = SpotifyAPI.Web.SpotifyUrls; 5 | 6 | namespace SpotifyAPI.Web 7 | { 8 | public class SearchClient : APIClient, ISearchClient 9 | { 10 | public SearchClient(IAPIConnector apiConnector) : base(apiConnector) { } 11 | 12 | public Task Item(SearchRequest request, CancellationToken cancel = default) 13 | { 14 | Ensure.ArgumentNotNull(request, nameof(request)); 15 | 16 | return API.Get(URLs.Search(), request.BuildQueryParams(), cancel); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Exceptions/APIPagingException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Runtime.Serialization; 4 | using SpotifyAPI.Web.Http; 5 | 6 | namespace SpotifyAPI.Web 7 | { 8 | [Serializable] 9 | public class APIPagingException : APIException 10 | { 11 | public TimeSpan RetryAfter { get; } 12 | 13 | public APIPagingException(IResponse response) : base(response) 14 | { 15 | Ensure.ArgumentNotNull(response, nameof(response)); 16 | 17 | if (response.Headers.TryGetValue("Retry-After", out string? retryAfter)) 18 | { 19 | RetryAfter = TimeSpan.FromSeconds(int.Parse(retryAfter, CultureInfo.InvariantCulture)); 20 | } 21 | } 22 | 23 | public APIPagingException() { } 24 | 25 | public APIPagingException(string message) : base(message) { } 26 | 27 | public APIPagingException(string message, Exception innerException) : base(message, innerException) { } 28 | 29 | #if NET8_0_OR_GREATER 30 | [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")] 31 | #endif 32 | protected APIPagingException(SerializationInfo info, StreamingContext context) : base(info, context) { } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Exceptions/APITooManyRequestsException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Runtime.Serialization; 4 | using SpotifyAPI.Web.Http; 5 | 6 | namespace SpotifyAPI.Web 7 | { 8 | [Serializable] 9 | public class APITooManyRequestsException : APIException 10 | { 11 | public TimeSpan RetryAfter { get; } 12 | 13 | public APITooManyRequestsException(IResponse response) : base(response) 14 | { 15 | Ensure.ArgumentNotNull(response, nameof(response)); 16 | 17 | if (response.Headers.TryGetValue("Retry-After", out string? retryAfter)) 18 | { 19 | RetryAfter = TimeSpan.FromSeconds(int.Parse(retryAfter, CultureInfo.InvariantCulture)); 20 | } 21 | } 22 | 23 | public APITooManyRequestsException() { } 24 | 25 | public APITooManyRequestsException(string message) : base(message) { } 26 | 27 | public APITooManyRequestsException(string message, Exception innerException) : base(message, innerException) { } 28 | 29 | #if NET8_0_OR_GREATER 30 | [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")] 31 | #endif 32 | protected APITooManyRequestsException(SerializationInfo info, StreamingContext context) : base(info, context) { } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Exceptions/APIUnauthorizedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using SpotifyAPI.Web.Http; 4 | 5 | namespace SpotifyAPI.Web 6 | { 7 | [Serializable] 8 | public class APIUnauthorizedException : APIException 9 | { 10 | public APIUnauthorizedException(IResponse response) : base(response) { } 11 | 12 | public APIUnauthorizedException() { } 13 | 14 | public APIUnauthorizedException(string message) : base(message) { } 15 | 16 | public APIUnauthorizedException(string message, Exception innerException) : base(message, innerException) { } 17 | 18 | #if NET8_0_OR_GREATER 19 | [Obsolete("This API supports obsolete formatter-based serialization. It should not be called or extended by application code.")] 20 | #endif 21 | protected APIUnauthorizedException(SerializationInfo info, StreamingContext context) : base(info, context) { } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/APIResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web.Http 2 | { 3 | public class APIResponse : IAPIResponse 4 | { 5 | public APIResponse(IResponse response, T? body = default) 6 | { 7 | Ensure.ArgumentNotNull(response, nameof(response)); 8 | 9 | Body = body; 10 | Response = response; 11 | } 12 | 13 | public T? Body { get; set; } 14 | 15 | public IResponse Response { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Interfaces/IAPIResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web.Http 2 | { 3 | public interface IAPIResponse 4 | { 5 | T? Body { get; } 6 | 7 | IResponse Response { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Interfaces/IHTTPLogger.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web.Http 2 | { 3 | public interface IHTTPLogger 4 | { 5 | void OnRequest(IRequest request); 6 | void OnResponse(IResponse response); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Interfaces/IHttpClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | 5 | namespace SpotifyAPI.Web.Http 6 | { 7 | public interface IHTTPClient : IDisposable 8 | { 9 | Task DoRequest(IRequest request, CancellationToken cancel = default); 10 | void SetRequestTimeout(TimeSpan timeout); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Interfaces/IJSONSerializer.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web.Http 2 | { 3 | public interface IJSONSerializer 4 | { 5 | void SerializeRequest(IRequest request); 6 | IAPIResponse DeserializeResponse(IResponse response); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Interfaces/IProxyConfig.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public interface IProxyConfig 4 | { 5 | string Host { get; } 6 | int Port { get; } 7 | string? User { get; } 8 | string? Password { get; } 9 | bool SkipSSLCheck { get; } 10 | /// 11 | /// Whether to bypass the proxy server for local addresses. 12 | /// 13 | bool BypassProxyOnLocal { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Interfaces/IRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | 5 | namespace SpotifyAPI.Web.Http 6 | { 7 | public interface IRequest 8 | { 9 | Uri BaseAddress { get; } 10 | 11 | Uri Endpoint { get; } 12 | 13 | IDictionary Headers { get; } 14 | 15 | IDictionary Parameters { get; } 16 | 17 | HttpMethod Method { get; } 18 | 19 | object? Body { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Interfaces/IResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net; 3 | 4 | namespace SpotifyAPI.Web.Http 5 | { 6 | public interface IResponse 7 | { 8 | object? Body { get; } 9 | 10 | IReadOnlyDictionary Headers { get; } 11 | 12 | HttpStatusCode StatusCode { get; } 13 | 14 | string? ContentType { get; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/ProxyConfig.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ProxyConfig : IProxyConfig 4 | { 5 | public ProxyConfig(string host, int port) 6 | { 7 | Ensure.ArgumentNotNullOrEmptyString(host, nameof(host)); 8 | 9 | Host = host; 10 | Port = port; 11 | } 12 | 13 | public string Host { get; } 14 | public int Port { get; } 15 | public string? User { get; set; } 16 | public string? Password { get; set; } 17 | public bool BypassProxyOnLocal { get; set; } 18 | public bool SkipSSLCheck { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/Response.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | using System.Net; 4 | 5 | namespace SpotifyAPI.Web.Http 6 | { 7 | public class Response : IResponse 8 | { 9 | public Response(IDictionary headers) 10 | { 11 | Ensure.ArgumentNotNull(headers, nameof(headers)); 12 | 13 | Headers = new ReadOnlyDictionary(headers); 14 | } 15 | 16 | public object? Body { get; set; } 17 | 18 | public IReadOnlyDictionary Headers { get; set; } 19 | 20 | public HttpStatusCode StatusCode { get; set; } 21 | 22 | public string? ContentType { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Http/SimpleConsoleHTTPLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace SpotifyAPI.Web.Http 5 | { 6 | public class SimpleConsoleHTTPLogger : IHTTPLogger 7 | { 8 | private const string OnRequestFormat = "\n{0} {1} [{2}] {3}"; 9 | 10 | public void OnRequest(IRequest request) 11 | { 12 | Ensure.ArgumentNotNull(request, nameof(request)); 13 | 14 | string? parameters = null; 15 | if (request.Parameters != null) 16 | { 17 | parameters = string.Join(",", 18 | request.Parameters.Select(kv => kv.Key + "=" + kv.Value)?.ToArray() ?? Array.Empty() 19 | ); 20 | } 21 | 22 | Console.WriteLine(OnRequestFormat, request.Method, request.Endpoint, parameters, request.Body); 23 | } 24 | 25 | public void OnResponse(IResponse response) 26 | { 27 | Ensure.ArgumentNotNull(response, nameof(response)); 28 | #if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER 29 | string? body = response.Body?.ToString()?.Replace("\n", "", StringComparison.InvariantCulture); 30 | #else 31 | string? body = response.Body?.ToString()?.Replace("\n", ""); 32 | #endif 33 | body = body?.Substring(0, Math.Min(50, body.Length)); 34 | Console.WriteLine("--> {0} {1} {2}\n", response.StatusCode, response.ContentType, body); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Converters/DoubleToIntConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | using Newtonsoft.Json; 5 | 6 | namespace SpotifyAPI.Web 7 | { 8 | public class DoubleToIntConverter : JsonConverter 9 | { 10 | public override void WriteJson(JsonWriter? writer, int value, JsonSerializer serializer) 11 | { 12 | writer?.WriteValue(value); 13 | } 14 | 15 | public override int ReadJson(JsonReader? reader, Type objectType, int existingValue, bool hasExistingValue, 16 | JsonSerializer serializer) 17 | { 18 | return reader != null ? Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture) : 0; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/IPaginatable.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public interface IPaginatable 6 | { 7 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")] 8 | string? Next { get; set; } 9 | 10 | List? Items { get; set; } 11 | } 12 | 13 | public interface IPaginatable 14 | { 15 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716")] 16 | string? Next { get; set; } 17 | 18 | List? Items { get; set; } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/AlbumRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class AlbumRequest : RequestParams 4 | { 5 | /// 6 | /// The market you’d like to request. Synonym for country. 7 | /// 8 | /// 9 | [QueryParam("market")] 10 | public string? Market { get; set; } 11 | 12 | /// 13 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 14 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 15 | /// Provide this parameter if you want the category strings returned in a particular language. 16 | /// Note that, if locale is not supplied, or if the specified language is not available, 17 | /// the category strings returned will be in the Spotify default language (American English). 18 | /// 19 | /// 20 | [QueryParam("locale")] 21 | public string? Locale { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ArtistRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ArtistRequest : RequestParams 4 | { 5 | /// 6 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 7 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 8 | /// Provide this parameter if you want the category strings returned in a particular language. 9 | /// Note that, if locale is not supplied, or if the specified language is not available, 10 | /// the category strings returned will be in the Spotify default language (American English). 11 | /// 12 | /// 13 | [QueryParam("locale")] 14 | public string? Locale { get; set; } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ArtistsRelatedArtistsRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ArtistsRelatedArtistsRequest : RequestParams 4 | { 5 | /// 6 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 7 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 8 | /// Provide this parameter if you want the category strings returned in a particular language. 9 | /// Note that, if locale is not supplied, or if the specified language is not available, 10 | /// the category strings returned will be in the Spotify default language (American English). 11 | /// 12 | /// 13 | [QueryParam("locale")] 14 | public string? Locale { get; set; } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ArtistsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class ArtistsRequest : RequestParams 6 | { 7 | /// 8 | /// ArtistsRequest 9 | /// 10 | /// A comma-separated list of the Spotify IDs for the artists. Maximum: 50 IDs. 11 | public ArtistsRequest(IList ids) 12 | { 13 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 14 | 15 | Ids = ids; 16 | } 17 | 18 | /// 19 | /// A comma-separated list of the Spotify IDs for the artists. Maximum: 50 IDs. 20 | /// 21 | /// 22 | [QueryParam("ids")] 23 | public IList Ids { get; } 24 | 25 | /// 26 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 27 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 28 | /// Provide this parameter if you want the category strings returned in a particular language. 29 | /// Note that, if locale is not supplied, or if the specified language is not available, 30 | /// the category strings returned will be in the Spotify default language (American English). 31 | /// 32 | /// 33 | [QueryParam("locale")] 34 | public string? Locale { get; set; } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ArtistsTopTracksRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ArtistsTopTracksRequest : RequestParams 4 | { 5 | /// 6 | /// An ISO 3166-1 alpha-2 country code or the string from_token. Synonym for country. 7 | /// 8 | /// 9 | public ArtistsTopTracksRequest(string market) 10 | { 11 | Ensure.ArgumentNotNullOrEmptyString(market, nameof(market)); 12 | 13 | Market = market; 14 | } 15 | 16 | /// 17 | /// An ISO 3166-1 alpha-2 country code or the string from_token. Synonym for country. 18 | /// 19 | /// 20 | [QueryParam("market")] 21 | public string Market { get; } 22 | 23 | /// 24 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 25 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 26 | /// Provide this parameter if you want the category strings returned in a particular language. 27 | /// Note that, if locale is not supplied, or if the specified language is not available, 28 | /// the category strings returned will be in the Spotify default language (American English). 29 | /// 30 | /// 31 | [QueryParam("locale")] 32 | public string? Locale { get; set; } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/AudiobookRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class AudiobookRequest : RequestParams 4 | { 5 | /// 6 | /// The market you’d like to request. Synonym for country. 7 | /// 8 | /// 9 | [QueryParam("market")] 10 | public string? Market { get; set; } 11 | 12 | /// 13 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 14 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 15 | /// Provide this parameter if you want the category strings returned in a particular language. 16 | /// Note that, if locale is not supplied, or if the specified language is not available, 17 | /// the category strings returned will be in the Spotify default language (American English). 18 | /// 19 | /// 20 | [QueryParam("locale")] 21 | public string? Locale { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/CategoryRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class CategoryRequest : RequestParams 4 | { 5 | /// 6 | /// A country: an ISO 3166-1 alpha-2 country code. 7 | /// Provide this parameter to ensure that the category exists for a particular country. 8 | /// 9 | /// 10 | [QueryParam("country")] 11 | public string? Country { get; set; } 12 | 13 | /// 14 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 15 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 16 | /// Provide this parameter if you want the category strings returned in a particular language. 17 | /// Note that, if locale is not supplied, or if the specified language is not available, 18 | /// the category strings returned will be in the Spotify default language (American English). 19 | /// 20 | /// 21 | [QueryParam("locale")] 22 | public string? Locale { get; set; } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ChapterRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ChapterRequest : RequestParams 4 | { 5 | /// 6 | /// The market you’d like to request. Synonym for country. 7 | /// 8 | /// 9 | [QueryParam("market")] 10 | public string? Market { get; set; } 11 | 12 | /// 13 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 14 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 15 | /// Provide this parameter if you want the category strings returned in a particular language. 16 | /// Note that, if locale is not supplied, or if the specified language is not available, 17 | /// the category strings returned will be in the Spotify default language (American English). 18 | /// 19 | /// 20 | [QueryParam("locale")] 21 | public string? Locale { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ClientCredentialsRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | /// 4 | /// Used when requesting a token from spotify oauth services (Client Credentials Auth) 5 | /// 6 | public class ClientCredentialsRequest 7 | { 8 | /// 9 | /// 10 | /// 11 | /// The Client ID of your Spotify Application (See Spotify Dev Dashboard) 12 | /// The Client Secret of your Spotify Application (See Spotify Dev Dashboard) 13 | public ClientCredentialsRequest(string clientId, string clientSecret) 14 | { 15 | Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId)); 16 | Ensure.ArgumentNotNullOrEmptyString(clientSecret, nameof(clientSecret)); 17 | 18 | ClientId = clientId; 19 | ClientSecret = clientSecret; 20 | } 21 | 22 | /// 23 | /// The Client ID of your Spotify Application (See Spotify Dev Dashboard) 24 | /// 25 | /// 26 | public string ClientId { get; } 27 | 28 | /// 29 | /// The Client Secret of your Spotify Application (See Spotify Dev Dashboard) 30 | /// 31 | /// 32 | public string ClientSecret { get; } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/FollowCheckPlaylistRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class FollowCheckPlaylistRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of Spotify User IDs ; 12 | /// the ids of the users that you want to check to see if they follow the playlist. 13 | /// Maximum: 5 ids. 14 | /// 15 | public FollowCheckPlaylistRequest(IList ids) 16 | { 17 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 18 | 19 | Ids = ids; 20 | } 21 | 22 | /// 23 | /// A comma-separated list of Spotify User IDs ; 24 | /// the ids of the users that you want to check to see if they follow the playlist. 25 | /// Maximum: 5 ids. 26 | /// 27 | /// 28 | [QueryParam("ids")] 29 | public IList Ids { get; } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/FollowPlaylistRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class FollowPlaylistRequest : RequestParams 4 | { 5 | /// 6 | /// Defaults to true. If true the playlist will be included in user’s public playlists, 7 | /// if false it will remain private. To be able to follow playlists privately, 8 | /// the user must have granted the playlist-modify-private scope. 9 | /// 10 | /// 11 | [BodyParam("public")] 12 | public bool? Public { get; set; } 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryCheckAlbumsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryCheckAlbumsRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of the Spotify IDs for the albums. Maximum: 50 IDs. 12 | /// 13 | public LibraryCheckAlbumsRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNull(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of the Spotify IDs for the albums. Maximum: 50 IDs. 22 | /// 23 | /// 24 | [QueryParam("ids")] 25 | public IList Ids { get; } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryCheckAudiobooksRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryCheckAudiobooksRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 ids. 11 | public LibraryCheckAudiobooksRequest(IList ids) 12 | { 13 | Ensure.ArgumentNotNull(ids, nameof(ids)); 14 | 15 | Ids = ids; 16 | } 17 | 18 | /// 19 | /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 ids. 20 | /// 21 | /// 22 | [QueryParam("ids")] 23 | public IList Ids { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryCheckEpisodesRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryCheckEpisodesRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 ids. 11 | public LibraryCheckEpisodesRequest(IList ids) 12 | { 13 | Ensure.ArgumentNotNull(ids, nameof(ids)); 14 | 15 | Ids = ids; 16 | } 17 | 18 | /// 19 | /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 ids. 20 | /// 21 | /// 22 | [QueryParam("ids")] 23 | public IList Ids { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryCheckShowsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryCheckShowsRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 ids. 11 | public LibraryCheckShowsRequest(IList ids) 12 | { 13 | Ensure.ArgumentNotNull(ids, nameof(ids)); 14 | 15 | Ids = ids; 16 | } 17 | 18 | /// 19 | /// A comma-separated list of the Spotify IDs for the shows. Maximum: 50 ids. 20 | /// 21 | /// 22 | [QueryParam("ids")] 23 | public IList Ids { get; } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryCheckTracksRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryCheckTracksRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of the Spotify IDs for the tracks. Maximum: 50 IDs. 12 | /// 13 | public LibraryCheckTracksRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNull(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of the Spotify IDs for the tracks. Maximum: 50 IDs. 22 | /// 23 | /// 24 | [QueryParam("ids")] 25 | public IList Ids { get; } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryRemoveAlbumsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryRemoveAlbumsRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of the Spotify IDs. 11 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 12 | /// 13 | public LibraryRemoveAlbumsRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of the Spotify IDs. 22 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 23 | /// 24 | /// 25 | [QueryParam("ids")] 26 | public IList Ids { get; } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryRemoveAudiobooksRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryRemoveAudiobooksRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of Spotify IDs for the shows to be deleted from the user’s library. 12 | /// 13 | public LibraryRemoveAudiobooksRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of Spotify IDs for the shows to be deleted from the user’s library. 22 | /// 23 | /// 24 | [QueryParam("ids")] 25 | public IList Ids { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryRemoveEpisodesRequest copy.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryRemoveEpisodesRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of Spotify IDs for the shows to be deleted from the user’s library. 12 | /// 13 | public LibraryRemoveEpisodesRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of Spotify IDs for the shows to be deleted from the user’s library. 22 | /// 23 | /// 24 | [QueryParam("ids")] 25 | public IList Ids { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryRemoveShowsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryRemoveShowsRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of Spotify IDs for the shows to be deleted from the user’s library. 12 | /// 13 | public LibraryRemoveShowsRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of Spotify IDs for the shows to be deleted from the user’s library. 22 | /// 23 | /// 24 | [QueryParam("ids")] 25 | public IList Ids { get; } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryRemoveTracksRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibraryRemoveTracksRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of the Spotify IDs. For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. 12 | /// Maximum: 20 IDs. 13 | /// 14 | public LibraryRemoveTracksRequest(IList ids) 15 | { 16 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 17 | 18 | Ids = ids; 19 | } 20 | 21 | /// 22 | /// A comma-separated list of the Spotify IDs. For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. 23 | /// Maximum: 20 IDs. 24 | /// 25 | /// 26 | [QueryParam("ids")] 27 | public IList Ids { get; } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibrarySaveAlbumsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibrarySaveAlbumsRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of the Spotify IDs. 11 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 12 | /// 13 | public LibrarySaveAlbumsRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of the Spotify IDs. 22 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 23 | /// 24 | /// 25 | [QueryParam("ids")] 26 | public IList Ids { get; } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibrarySaveAudiobooksRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibrarySaveAudiobooksRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of the Spotify IDs. 11 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 12 | /// 13 | public LibrarySaveAudiobooksRequest(IList ids) 14 | { 15 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 16 | 17 | Ids = ids; 18 | } 19 | 20 | /// 21 | /// A comma-separated list of the Spotify IDs. 22 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 23 | /// 24 | /// 25 | [QueryParam("ids")] 26 | public IList Ids { get; } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibrarySaveEpisodesRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibrarySaveEpisodesRequest : RequestParams 6 | { 7 | /// 8 | /// Request for SaveEpisodes. 9 | /// 10 | /// 11 | public LibrarySaveEpisodesRequest(IList ids) 12 | { 13 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 14 | 15 | Ids = ids; 16 | } 17 | 18 | /// 19 | /// A comma-separated list of the Spotify IDs. 20 | /// Maximum: 50 IDs. 21 | /// 22 | /// 23 | [QueryParam("ids")] 24 | public IList Ids { get; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibrarySaveShowsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibrarySaveShowsRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of Spotify IDs for the shows to be added to the user’s library. 11 | public LibrarySaveShowsRequest(IList ids) 12 | { 13 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 14 | 15 | Ids = ids; 16 | } 17 | 18 | /// 19 | /// A comma-separated list of Spotify IDs for the shows to be added to the user’s library. 20 | /// 21 | /// 22 | [QueryParam("ids")] 23 | public IList Ids { get; } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibrarySaveTracksRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class LibrarySaveTracksRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of the Spotify IDs. 12 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 13 | /// 14 | public LibrarySaveTracksRequest(IList ids) 15 | { 16 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 17 | 18 | Ids = ids; 19 | } 20 | 21 | /// 22 | /// A comma-separated list of the Spotify IDs. 23 | /// For example: ids=4iV5W9uYEdYUVa79Axb7Rh,1301WleyT98MSxVHPZCA6M. Maximum: 50 IDs. 24 | /// 25 | /// 26 | [QueryParam("ids")] 27 | public IList Ids { get; } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/LibraryShowsRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class LibraryShowsRequest : RequestParams 4 | { 5 | /// 6 | /// The maximum number of shows to return. Default: 20. Minimum: 1. Maximum: 50 7 | /// 8 | /// 9 | [QueryParam("limit")] 10 | public int? Limit { get; set; } 11 | 12 | /// 13 | /// The index of the first show to return. Default: 0 (the first object). 14 | /// Use with limit to get the next set of shows. 15 | /// 16 | /// 17 | [QueryParam("offset")] 18 | public int? Offset { get; set; } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PKCETokenRefreshRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PKCETokenRefreshRequest 4 | { 5 | /// 6 | /// Request model for refreshing a access token via PKCE Token 7 | /// 8 | /// The Client ID of your Spotify Application (See Spotify Dev Dashboard). 9 | /// The received refresh token. Expires after one refresh 10 | public PKCETokenRefreshRequest(string clientId, string refreshToken) 11 | { 12 | Ensure.ArgumentNotNullOrEmptyString(clientId, nameof(clientId)); 13 | Ensure.ArgumentNotNullOrEmptyString(refreshToken, nameof(refreshToken)); 14 | 15 | ClientId = clientId; 16 | RefreshToken = refreshToken; 17 | } 18 | 19 | /// 20 | /// The Client ID of your Spotify Application (See Spotify Dev Dashboard). 21 | /// 22 | /// 23 | public string ClientId { get; } 24 | 25 | /// 26 | /// The received refresh token. 27 | /// 28 | /// 29 | public string RefreshToken { get; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerAddToQueueRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerAddToQueueRequest : RequestParams 4 | { 5 | /// 6 | /// 7 | /// 8 | /// The uri of the item to add to the queue. Must be a track or an episode uri. 9 | public PlayerAddToQueueRequest(string uri) 10 | { 11 | Ensure.ArgumentNotNullOrEmptyString(uri, nameof(uri)); 12 | 13 | Uri = uri; 14 | } 15 | 16 | /// 17 | /// The uri of the item to add to the queue. Must be a track or an episode uri. 18 | /// 19 | /// 20 | [QueryParam("uri")] 21 | public string Uri { get; } 22 | 23 | /// 24 | /// The id of the device this command is targeting. 25 | /// If not supplied, the user’s currently active device is the target. 26 | /// 27 | /// 28 | [QueryParam("device_id")] 29 | public string? DeviceId { get; set; } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerGetQueueRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerGetQueueRequest : RequestParams 4 | { 5 | /// 6 | /// An ISO 3166-1 alpha-2 country code or the string from_token. 7 | /// Provide this parameter if you want to apply Track Relinking. 8 | /// 9 | /// 10 | [QueryParam("market")] 11 | public string? Market { get; set; } 12 | 13 | /// 14 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 15 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 16 | /// Provide this parameter if you want the category strings returned in a particular language. 17 | /// Note that, if locale is not supplied, or if the specified language is not available, 18 | /// the category strings returned will be in the Spotify default language (American English). 19 | /// 20 | /// 21 | [QueryParam("locale")] 22 | public string? Locale { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerPausePlaybackRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerPausePlaybackRequest : RequestParams 4 | { 5 | /// 6 | /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. 7 | /// 8 | /// 9 | [QueryParam("device_id")] 10 | public string? DeviceId { get; set; } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerSeekToRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerSeekToRequest : RequestParams 4 | { 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// The position in milliseconds to seek to. Must be a positive number. 10 | /// Passing in a position that is greater than the length of the track will 11 | /// cause the player to start playing the next song. 12 | /// 13 | public PlayerSeekToRequest(long positionMs) 14 | { 15 | PositonMs = positionMs; 16 | } 17 | 18 | /// 19 | /// The position in milliseconds to seek to. Must be a positive number. 20 | /// Passing in a position that is greater than the length of the track will cause 21 | /// the player to start playing the next song. 22 | /// 23 | /// 24 | [QueryParam("position_ms")] 25 | public long PositonMs { get; } 26 | 27 | /// 28 | /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. 29 | /// 30 | /// 31 | [QueryParam("device_id")] 32 | public string? DeviceId { get; set; } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerSetRepeatRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerSetRepeatRequest : RequestParams 4 | { 5 | /// 6 | /// 7 | /// track, context or off. track will repeat the current track. context will repeat the current context. 8 | /// off will turn repeat off. 9 | /// 10 | public PlayerSetRepeatRequest(State state) 11 | { 12 | Ensure.ArgumentNotNull(state, nameof(state)); 13 | 14 | StateParam = state; 15 | } 16 | 17 | /// 18 | /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. 19 | /// 20 | /// 21 | [QueryParam("device_id")] 22 | public string? DeviceId { get; set; } 23 | 24 | /// 25 | /// track, context or off. track will repeat the current track. context will repeat the current context. 26 | /// off will turn repeat off. 27 | /// 28 | /// 29 | [QueryParam("state")] 30 | public State StateParam { get; } 31 | 32 | public enum State 33 | { 34 | [String("track")] 35 | Track, 36 | 37 | [String("context")] 38 | Context, 39 | 40 | [String("off")] 41 | Off 42 | } 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerShuffleRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerShuffleRequest : RequestParams 4 | { 5 | /// 6 | /// 7 | /// 8 | /// true : Shuffle user’s playback false : Do not shuffle user’s playback. 9 | public PlayerShuffleRequest(bool state) 10 | { 11 | State = state; 12 | } 13 | 14 | /// 15 | /// true : Shuffle user’s playback false : Do not shuffle user’s playback. 16 | /// 17 | /// 18 | [QueryParam("state")] 19 | public bool State { get; } 20 | 21 | /// 22 | /// The id of the device this command is targeting. If not supplied, 23 | /// the user’s currently active device is the target. 24 | /// 25 | /// 26 | [QueryParam("device_id")] 27 | public string? DeviceId { get; set; } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerSkipNextRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerSkipNextRequest : RequestParams 4 | { 5 | /// 6 | /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. 7 | /// 8 | /// 9 | [QueryParam("device_id")] 10 | public string? DeviceId { get; set; } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerSkipPreviousRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerSkipPreviousRequest : RequestParams 4 | { 5 | /// 6 | /// The id of the device this command is targeting. 7 | /// If not supplied, the user’s currently active device is the target. 8 | /// 9 | /// 10 | [QueryParam("device_id")] 11 | public string? DeviceId { get; set; } 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlayerVolumeRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlayerVolumeRequest : RequestParams 4 | { 5 | /// 6 | /// 7 | /// 8 | /// The volume to set. Must be a value from 0 to 100 inclusive. 9 | public PlayerVolumeRequest(int volumePercent) 10 | { 11 | VolumePercent = volumePercent; 12 | } 13 | 14 | /// 15 | /// The volume to set. Must be a value from 0 to 100 inclusive. 16 | /// 17 | /// 18 | [QueryParam("volume_percent")] 19 | public int VolumePercent { get; } 20 | 21 | /// 22 | /// The id of the device this command is targeting. If not supplied, the user’s currently active device is the target. 23 | /// 24 | /// 25 | [QueryParam("device_id")] 26 | public string? DeviceId { get; set; } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlaylistChangeDetailsRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlaylistChangeDetailsRequest : RequestParams 4 | { 5 | /// 6 | /// The new name for the playlist, for example "My New Playlist Title" 7 | /// 8 | /// 9 | [BodyParam("name")] 10 | public string? Name { get; set; } 11 | 12 | /// 13 | /// If true the playlist will be public, if false it will be private. 14 | /// 15 | /// 16 | [BodyParam("public")] 17 | public bool? Public { get; set; } 18 | 19 | /// 20 | /// If true , the playlist will become collaborative and other users will be able to modify the 21 | /// playlist in their Spotify client. Note: You can only set collaborative to true on non-public playlists. 22 | /// 23 | /// 24 | [BodyParam("collaborative")] 25 | public bool? Collaborative { get; set; } 26 | 27 | /// 28 | /// Value for playlist description as displayed in Spotify Clients and in the Web API. 29 | /// 30 | /// 31 | [BodyParam("description")] 32 | public string? Description { get; set; } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlaylistCurrentUsersRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlaylistCurrentUsersRequest : RequestParams 4 | { 5 | /// 6 | /// The maximum number of playlists to return. Default: 20. Minimum: 1. Maximum: 50. 7 | /// 8 | /// 9 | [QueryParam("limit")] 10 | public int? Limit { get; set; } 11 | 12 | /// 13 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 14 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 15 | /// Provide this parameter if you want the category strings returned in a particular language. 16 | /// Note that, if locale is not supplied, or if the specified language is not available, 17 | /// the category strings returned will be in the Spotify default language (American English). 18 | /// 19 | /// 20 | [QueryParam("locale")] 21 | public string? Locale { get; set; } 22 | 23 | /// 24 | /// The index of the first playlist to return. 25 | /// Default: 0 (the first object). Maximum offset: 100.000. Use with limit to get the next set of playlists. 26 | /// 27 | /// 28 | [QueryParam("offset")] 29 | public int? Offset { get; set; } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlaylistGetUsersRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class PlaylistGetUsersRequest : RequestParams 4 | { 5 | /// 6 | /// The maximum number of playlists to return. Default: 20. Minimum: 1. Maximum: 50. 7 | /// 8 | /// 9 | [QueryParam("limit")] 10 | public int? Limit { get; set; } 11 | 12 | /// 13 | /// The index of the first playlist to return. Default: 0 (the first object). 14 | /// Maximum offset: 100.000. Use with limit to get the next set of playlists. 15 | /// 16 | /// 17 | [QueryParam("offset")] 18 | public int? Offset { get; set; } 19 | 20 | /// 21 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 22 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 23 | /// Provide this parameter if you want the category strings returned in a particular language. 24 | /// Note that, if locale is not supplied, or if the specified language is not available, 25 | /// the category strings returned will be in the Spotify default language (American English). 26 | /// 27 | /// 28 | [QueryParam("locale")] 29 | public string? Locale { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/PlaylistReplaceItemsRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class PlaylistReplaceItemsRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// A comma-separated list of Spotify URIs to set, can be track or episode URIs. 12 | /// A maximum of 100 items can be set in one request. 13 | /// 14 | public PlaylistReplaceItemsRequest(List uris) 15 | { 16 | Ensure.ArgumentNotNull(uris, nameof(uris)); 17 | 18 | Uris = uris; 19 | } 20 | 21 | /// 22 | /// A comma-separated list of Spotify URIs to set, can be track or episode URIs. 23 | /// A maximum of 100 items can be set in one request. 24 | /// 25 | /// 26 | [BodyParam("uris")] 27 | public IList Uris { get; } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ShowEpisodesRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ShowEpisodesRequest : RequestParams 4 | { 5 | /// 6 | /// The maximum number of episodes to return. Default: 20. Minimum: 1. Maximum: 50. 7 | /// 8 | /// 9 | [QueryParam("limit")] 10 | public int? Limit { get; set; } 11 | 12 | /// 13 | /// The index of the first episode to return. 14 | /// Default: 0 (the first object). Use with limit to get the next set of episodes. 15 | /// 16 | /// 17 | [QueryParam("offset")] 18 | public int? Offset { get; set; } 19 | 20 | /// 21 | /// An ISO 3166-1 alpha-2 country code. If a country code is specified, only shows and episodes 22 | /// that are available in that market will be returned. 23 | /// If a valid user access token is specified in the request header, 24 | /// the country associated with the user account will take priority over this parameter. 25 | /// Note: If neither market or user country are provided, the content is considered unavailable for the client. 26 | /// Users can view the country that is associated with their account in the account settings. 27 | /// 28 | /// 29 | [QueryParam("market")] 30 | public string? Market { get; set; } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/ShowRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ShowRequest : RequestParams 4 | { 5 | /// 6 | /// An ISO 3166-1 alpha-2 country code. If a country code is specified, 7 | /// only shows and episodes that are available in that market will be returned. 8 | /// If a valid user access token is specified in the request header, 9 | /// the country associated with the user account will take priority over this parameter. 10 | /// Note: If neither market or user country are provided, the content 11 | /// is considered unavailable for the client. 12 | /// Users can view the country that is associated with their account in the account settings. 13 | /// 14 | /// 15 | [QueryParam("market")] 16 | public string? Market { get; set; } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/TokenSwapRefreshRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class TokenSwapRefreshRequest 6 | { 7 | public TokenSwapRefreshRequest(Uri refreshUri, string refreshToken) 8 | { 9 | Ensure.ArgumentNotNull(refreshUri, nameof(refreshUri)); 10 | Ensure.ArgumentNotNullOrEmptyString(refreshToken, nameof(refreshToken)); 11 | 12 | RefreshUri = refreshUri; 13 | RefreshToken = refreshToken; 14 | } 15 | 16 | public string RefreshToken { get; } 17 | 18 | public Uri RefreshUri { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/TokenSwapTokenRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class TokenSwapTokenRequest 6 | { 7 | public TokenSwapTokenRequest(Uri tokenUri, string code) 8 | { 9 | Ensure.ArgumentNotNull(tokenUri, nameof(tokenUri)); 10 | Ensure.ArgumentNotNullOrEmptyString(code, nameof(code)); 11 | 12 | TokenUri = tokenUri; 13 | Code = code; 14 | } 15 | 16 | public string Code { get; } 17 | 18 | public Uri TokenUri { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/TrackRequest.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class TrackRequest : RequestParams 4 | { 5 | /// 6 | /// An ISO 3166-1 alpha-2 country code or the string from_token. 7 | /// Provide this parameter if you want to apply Track Relinking. 8 | /// 9 | /// 10 | [QueryParam("market")] 11 | public string? Market { get; set; } 12 | 13 | /// 14 | /// The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, 15 | /// joined by an underscore. For example: es_MX, meaning "Spanish (Mexico)". 16 | /// Provide this parameter if you want the category strings returned in a particular language. 17 | /// Note that, if locale is not supplied, or if the specified language is not available, 18 | /// the category strings returned will be in the Spotify default language (American English). 19 | /// 20 | /// 21 | [QueryParam("locale")] 22 | public string? Locale { get; set; } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Request/TracksAudioFeaturesRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class TracksAudioFeaturesRequest : RequestParams 6 | { 7 | /// 8 | /// 9 | /// 10 | /// A comma-separated list of the Spotify IDs for the tracks. Maximum: 100 IDs. 11 | public TracksAudioFeaturesRequest(IList ids) 12 | { 13 | Ensure.ArgumentNotNullOrEmptyList(ids, nameof(ids)); 14 | 15 | Ids = ids; 16 | } 17 | 18 | /// 19 | /// A comma-separated list of the Spotify IDs for the tracks. Maximum: 100 IDs. 20 | /// 21 | /// 22 | [QueryParam("ids")] 23 | public IList Ids { get; } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Actions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class Actions 6 | { 7 | public Dictionary Disallows { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/AlbumsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class AlbumsResponse 6 | { 7 | public List Albums { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/ArtistsRelatedArtistsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class ArtistsRelatedArtistsResponse 6 | { 7 | public List Artists { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/ArtistsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class ArtistsResponse 6 | { 7 | public List Artists { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/ArtistsTopTracksResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class ArtistsTopTracksResponse 6 | { 7 | public List Tracks { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/AudiobooksResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class AudiobooksResponse 6 | { 7 | public List Audiobooks { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Author.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class Author 4 | { 5 | public string Name { get; set; } = default!; 6 | 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/AuthorizationCodeRefreshResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class AuthorizationCodeRefreshResponse : IRefreshableToken 6 | { 7 | public string AccessToken { get; set; } = default!; 8 | public string TokenType { get; set; } = default!; 9 | public int ExpiresIn { get; set; } 10 | public string Scope { get; set; } = default!; 11 | public string RefreshToken { get; set; } = default!; 12 | 13 | /// 14 | /// Auto-Initalized to UTC Now 15 | /// 16 | /// 17 | public DateTime CreatedAt { get; set; } = DateTime.UtcNow; 18 | 19 | public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/AuthorizationCodeTokenResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class AuthorizationCodeTokenResponse : IRefreshableToken 6 | { 7 | public string AccessToken { get; set; } = default!; 8 | public string TokenType { get; set; } = default!; 9 | public int ExpiresIn { get; set; } 10 | public string Scope { get; set; } = default!; 11 | public string RefreshToken { get; set; } = default!; 12 | 13 | /// 14 | /// Auto-Initalized to UTC Now 15 | /// 16 | /// 17 | public DateTime CreatedAt { get; set; } = DateTime.UtcNow; 18 | 19 | public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/AvailableMarketsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class AvailableMarketsResponse 6 | { 7 | public List Markets { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/CategoriesResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class CategoriesResponse 4 | { 5 | public Paging Categories { get; set; } = default!; 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class Category 6 | { 7 | public string Href { get; set; } = default!; 8 | public List Icons { get; set; } = default!; 9 | public string Id { get; set; } = default!; 10 | public string Name { get; set; } = default!; 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/CategoryPlaylistsResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class CategoryPlaylistsResponse 4 | { 5 | public Paging Playlists { get; set; } = default!; 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/ChaptersResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class ChaptersResponse 6 | { 7 | public List Chapters { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/ClientCredentialsTokenResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class ClientCredentialsTokenResponse : IToken 6 | { 7 | public string AccessToken { get; set; } = default!; 8 | public string TokenType { get; set; } = default!; 9 | public int ExpiresIn { get; set; } 10 | 11 | /// 12 | /// Auto-Initalized to UTC Now 13 | /// 14 | /// 15 | public DateTime CreatedAt { get; set; } = DateTime.UtcNow; 16 | 17 | public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; } 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Context.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class Context 6 | { 7 | public Dictionary ExternalUrls { get; set; } = default!; 8 | public string Href { get; set; } = default!; 9 | public string Type { get; set; } = default!; 10 | public string Uri { get; set; } = default!; 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Copyright.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class Copyright 4 | { 5 | public string Text { get; set; } = default!; 6 | public string Type { get; set; } = default!; 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/CurrentlyPlaying.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class CurrentlyPlaying 6 | { 7 | public Context Context { get; set; } = default!; 8 | public string CurrentlyPlayingType { get; set; } = default!; 9 | public bool IsPlaying { get; set; } 10 | 11 | /// 12 | /// Can be a FullTrack or FullEpisode 13 | /// 14 | /// 15 | [JsonConverter(typeof(PlayableItemConverter))] 16 | public IPlayableItem Item { get; set; } = default!; 17 | public int? ProgressMs { get; set; } 18 | public long Timestamp { get; set; } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/CurrentlyPlayingContext.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class CurrentlyPlayingContext 6 | { 7 | public Device Device { get; set; } = default!; 8 | public string RepeatState { get; set; } = default!; 9 | public bool ShuffleState { get; set; } 10 | public Context Context { get; set; } = default!; 11 | public long Timestamp { get; set; } 12 | public int ProgressMs { get; set; } 13 | public bool IsPlaying { get; set; } 14 | 15 | /// 16 | /// Can be a FullTrack or FullEpisode 17 | /// 18 | /// 19 | [JsonConverter(typeof(PlayableItemConverter))] 20 | public IPlayableItem Item { get; set; } = default!; 21 | 22 | public string CurrentlyPlayingType { get; set; } = default!; 23 | public Actions Actions { get; set; } = default!; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Cursor.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class Cursor 4 | { 5 | public string Before { get; set; } = default!; 6 | public string After { get; set; } = default!; 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/CursorPaging.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class CursorPaging : IPaginatable 6 | { 7 | public string Href { get; set; } = default!; 8 | public List? Items { get; set; } = default!; 9 | public int Limit { get; set; } 10 | public string? Next { get; set; } = default!; 11 | public Cursor Cursors { get; set; } = default!; 12 | public int Total { get; set; } 13 | } 14 | 15 | public class CursorPaging : IPaginatable 16 | { 17 | public string Href { get; set; } = default!; 18 | public List? Items { get; set; } = default!; 19 | public int Limit { get; set; } 20 | public string? Next { get; set; } = default!; 21 | public Cursor Cursors { get; set; } = default!; 22 | public int Total { get; set; } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Device.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class Device 4 | { 5 | public string Id { get; set; } = default!; 6 | public bool IsActive { get; set; } 7 | public bool IsPrivateSession { get; set; } 8 | public bool IsRestricted { get; set; } 9 | public string Name { get; set; } = default!; 10 | public bool SupportsVolume { get; set; } 11 | public string Type { get; set; } = default!; 12 | public int? VolumePercent { get; set; } 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/DeviceResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class DeviceResponse 6 | { 7 | public List Devices { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/EpisodesResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class EpisodesResponse 6 | { 7 | public List Episodes { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FeaturedPlaylistsResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class FeaturedPlaylistsResponse 4 | { 5 | public string Message { get; set; } = default!; 6 | public Paging Playlists { get; set; } = default!; 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FollowedArtistsResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class FollowedArtistsResponse 4 | { 5 | public CursorPaging Artists { get; set; } = default!; 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Followers.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class Followers 6 | { 7 | public string Href { get; set; } = default!; 8 | 9 | [JsonConverter(typeof(DoubleToIntConverter))] 10 | public int Total { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FullAlbum.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class FullAlbum 6 | { 7 | public string AlbumType { get; set; } = default!; 8 | public List Artists { get; set; } = default!; 9 | public List AvailableMarkets { get; set; } = default!; 10 | public List Copyrights { get; set; } = default!; 11 | public Dictionary ExternalIds { get; set; } = default!; 12 | public Dictionary ExternalUrls { get; set; } = default!; 13 | public List Genres { get; set; } = default!; 14 | public string Href { get; set; } = default!; 15 | public string Id { get; set; } = default!; 16 | public List Images { get; set; } = default!; 17 | public string Label { get; set; } = default!; 18 | public string Name { get; set; } = default!; 19 | public int Popularity { get; set; } 20 | public string ReleaseDate { get; set; } = default!; 21 | public string ReleaseDatePrecision { get; set; } = default!; 22 | public Dictionary Restrictions { get; set; } = default!; 23 | public int TotalTracks { get; set; } 24 | public Paging Tracks { get; set; } = default!; 25 | public string Type { get; set; } = default!; 26 | public string Uri { get; set; } = default!; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FullArtist.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | public class FullArtist 7 | { 8 | public Dictionary ExternalUrls { get; set; } = default!; 9 | public Followers Followers { get; set; } = default!; 10 | public List Genres { get; set; } = default!; 11 | public string Href { get; set; } = default!; 12 | public string Id { get; set; } = default!; 13 | public List Images { get; set; } = default!; 14 | public string Name { get; set; } = default!; 15 | [JsonConverter(typeof(DoubleToIntConverter))] 16 | public int Popularity { get; set; } 17 | public string Type { get; set; } = default!; 18 | public string Uri { get; set; } = default!; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FullAudiobook.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class FullAudiobook : SimpleAudiobook 4 | { 5 | public Paging Chapters { get; set; } = default!; 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FullAudiobookChapter.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class FullAudiobookChapter : SimpleAudiobookChapter 4 | { 5 | public SimpleAudiobook Audiobook { get; set; } = default!; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FullEpisode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace SpotifyAPI.Web 6 | { 7 | public class FullEpisode : IPlayableItem 8 | { 9 | public string AudioPreviewUrl { get; set; } = default!; 10 | public string Description { get; set; } = default!; 11 | public string HtmlDescription { get; set; } = default!; 12 | public int DurationMs { get; set; } 13 | public bool Explicit { get; set; } 14 | public Dictionary ExternalUrls { get; set; } = default!; 15 | public string Href { get; set; } = default!; 16 | public string Id { get; set; } = default!; 17 | public List Images { get; set; } = default!; 18 | public bool IsExternallyHosted { get; set; } 19 | public bool IsPlayable { get; set; } 20 | public List Languages { get; set; } = default!; 21 | public string Name { get; set; } = default!; 22 | public string ReleaseDate { get; set; } = default!; 23 | public string ReleaseDatePrecision { get; set; } = default!; 24 | public ResumePoint ResumePoint { get; set; } = default!; 25 | public SimpleShow Show { get; set; } = default!; 26 | 27 | [JsonConverter(typeof(StringEnumConverter))] 28 | public ItemType Type { get; set; } 29 | public string Uri { get; set; } = default!; 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FullPlaylist.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | namespace SpotifyAPI.Web 3 | { 4 | public class FullPlaylist 5 | { 6 | public bool? Collaborative { get; set; } 7 | public string? Description { get; set; } = default!; 8 | public Dictionary? ExternalUrls { get; set; } = default!; 9 | public Followers Followers { get; set; } = default!; 10 | public string? Href { get; set; } = default!; 11 | public string? Id { get; set; } = default!; 12 | public List? Images { get; set; } = default!; 13 | public string? Name { get; set; } = default!; 14 | public PublicUser? Owner { get; set; } = default!; 15 | public bool? Public { get; set; } 16 | public string? SnapshotId { get; set; } = default!; 17 | 18 | /// 19 | /// A list of PlaylistTracks, which items can be a FullTrack or FullEpisode 20 | /// 21 | /// 22 | public Paging>? Tracks { get; set; } = default!; 23 | public string? Type { get; set; } = default!; 24 | public string? Uri { get; set; } = default!; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/FullShow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class FullShow 6 | { 7 | public List AvailableMarkets { get; set; } = default!; 8 | public List Copyrights { get; set; } = default!; 9 | public string Description { get; set; } = default!; 10 | public string HtmlDescription { get; set; } = default!; 11 | public Paging Episodes { get; set; } = default!; 12 | public bool Explicit { get; set; } 13 | public Dictionary ExternalUrls { get; set; } = default!; 14 | public string Href { get; set; } = default!; 15 | public string Id { get; set; } = default!; 16 | public List Images { get; set; } = default!; 17 | public bool IsExternallyHosted { get; set; } 18 | public List Languages { get; set; } = default!; 19 | public string MediaType { get; set; } = default!; 20 | public string Name { get; set; } = default!; 21 | public string Publisher { get; set; } = default!; 22 | public string Type { get; set; } = default!; 23 | public string Uri { get; set; } = default!; 24 | public int TotalEpisodes { get; set; } = default!; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Image.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class Image 6 | { 7 | [JsonConverter(typeof(DoubleToIntConverter))] 8 | public int Height { get; set; } 9 | [JsonConverter(typeof(DoubleToIntConverter))] 10 | public int Width { get; set; } 11 | public string Url { get; set; } = default!; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Interfaces/IPlaylistElement.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | public enum ItemType 7 | { 8 | Track, 9 | Episode, 10 | Chapter 11 | } 12 | 13 | public interface IPlayableItem 14 | { 15 | [JsonConverter(typeof(StringEnumConverter))] 16 | ItemType Type { get; } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Interfaces/IRefreshableToken.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | /// 4 | /// An user token, which can be refreshed 5 | /// 6 | public interface IRefreshableToken : IUserToken 7 | { 8 | /// 9 | /// Refresh token 10 | /// 11 | public string RefreshToken { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Interfaces/IToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | /// 6 | /// A token to access the Spotify API 7 | /// 8 | public interface IToken 9 | { 10 | /// 11 | /// Access token string 12 | /// 13 | public string AccessToken { get; set; } 14 | 15 | /// 16 | /// Type of this token (eg. Bearer) 17 | /// 18 | public string TokenType { get; set; } 19 | 20 | /// 21 | /// Auto-Initalized to UTC Now 22 | /// 23 | public DateTime CreatedAt { get; set; } 24 | 25 | /// 26 | /// Is the token still valid? 27 | /// 28 | public bool IsExpired { get; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Interfaces/IUserToken.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | /// 4 | /// A token which allows you to access the API as user 5 | /// 6 | public interface IUserToken : IToken 7 | { 8 | /// 9 | /// Comma-Seperated list of scopes 10 | /// 11 | public string Scope { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/LinkedTrack.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | namespace SpotifyAPI.Web 3 | { 4 | public class LinkedTrack 5 | { 6 | public Dictionary ExternalUrls { get; set; } = default!; 7 | public string Href { get; set; } = default!; 8 | public string Id { get; set; } = default!; 9 | public string Type { get; set; } = default!; 10 | public string Uri { get; set; } = default!; 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Narrator.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class Narrator 4 | { 5 | public string Name { get; set; } = default!; 6 | 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/NewReleasesResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class NewReleasesResponse 4 | { 5 | public string Message { get; set; } = default!; 6 | public Paging Albums { get; set; } = default!; 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/PKCETokenResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class PKCETokenResponse : IRefreshableToken 6 | { 7 | public string AccessToken { get; set; } = default!; 8 | public string TokenType { get; set; } = default!; 9 | public int ExpiresIn { get; set; } 10 | public string Scope { get; set; } = default!; 11 | public string RefreshToken { get; set; } = default!; 12 | 13 | /// 14 | /// Auto-Initalized to UTC Now 15 | /// 16 | /// 17 | public DateTime CreatedAt { get; set; } = DateTime.UtcNow; 18 | 19 | public bool IsExpired { get => CreatedAt.AddSeconds(ExpiresIn) <= DateTime.UtcNow; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Paging.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class Paging : IPaginatable 6 | { 7 | public string? Href { get; set; } = default!; 8 | public List? Items { get; set; } = default!; 9 | public int? Limit { get; set; } = default!; 10 | public string? Next { get; set; } = default!; 11 | public int? Offset { get; set; } = default!; 12 | public string? Previous { get; set; } = default!; 13 | public int? Total { get; set; } = default!; 14 | } 15 | 16 | public class Paging : IPaginatable 17 | { 18 | public string? Href { get; set; } = default!; 19 | public List? Items { get; set; } = default!; 20 | public int? Limit { get; set; } = default!; 21 | public string? Next { get; set; } = default!; 22 | public int? Offset { get; set; } = default!; 23 | public string? Previous { get; set; } = default!; 24 | public int? Total { get; set; } = default!; 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/PlayHistoryItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace SpotifyAPI.Web 3 | { 4 | public class PlayHistoryItem 5 | { 6 | public FullTrack Track { get; set; } = default!; 7 | public DateTime PlayedAt { get; set; } 8 | public Context Context { get; set; } = default!; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/PlaylistTrack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | public class PlaylistTrack 7 | { 8 | public DateTime? AddedAt { get; set; } 9 | public PublicUser AddedBy { get; set; } = default!; 10 | public bool IsLocal { get; set; } 11 | 12 | [JsonConverter(typeof(PlayableItemConverter))] 13 | public T Track { get; set; } = default!; 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/PrivateUser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class PrivateUser 6 | { 7 | public string Country { get; set; } = default!; 8 | public string DisplayName { get; set; } = default!; 9 | public string Email { get; set; } = default!; 10 | public Dictionary ExternalUrls { get; set; } = default!; 11 | public Followers Followers { get; set; } = default!; 12 | public string Href { get; set; } = default!; 13 | public string Id { get; set; } = default!; 14 | public List Images { get; set; } = default!; 15 | public string Product { get; set; } = default!; 16 | public string Type { get; set; } = default!; 17 | public string Uri { get; set; } = default!; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/PublicUser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class PublicUser 6 | { 7 | public string DisplayName { get; set; } = default!; 8 | public Dictionary ExternalUrls { get; set; } = default!; 9 | public Followers Followers { get; set; } = default!; 10 | public string Href { get; set; } = default!; 11 | public string Id { get; set; } = default!; 12 | public List Images { get; set; } = default!; 13 | public string Type { get; set; } = default!; 14 | public string Uri { get; set; } = default!; 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/QueueResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace SpotifyAPI.Web 5 | { 6 | public class QueueResponse 7 | { 8 | [JsonConverter(typeof(PlayableItemConverter))] 9 | public IPlayableItem CurrentlyPlaying { get; set; } = default!; 10 | [JsonProperty(ItemConverterType = typeof(PlayableItemConverter))] 11 | public List Queue { get; set; } = default!; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/RecommendationGenresResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class RecommendationGenresResponse 6 | { 7 | public List Genres { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/RecommendationSeed.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class RecommendationSeed 6 | { 7 | [JsonProperty("afterFilteringSize")] 8 | public int AfterFiliteringSize { get; set; } 9 | 10 | [JsonProperty("afterRelinkingSize")] 11 | public int AfterRelinkingSize { get; set; } 12 | public string Href { get; set; } = default!; 13 | public string Id { get; set; } = default!; 14 | [JsonProperty("initialPoolSize")] 15 | public int InitialPoolSize { get; set; } 16 | public string Type { get; set; } = default!; 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/RecommendationsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class RecommendationsResponse 6 | { 7 | public List Seeds { get; set; } = default!; 8 | public List Tracks { get; set; } = default!; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/ResumePointObject.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class ResumePoint 4 | { 5 | public bool FullyPlayed { get; set; } 6 | public int ResumePositionMs { get; set; } 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SavedAlbum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SavedAlbum 6 | { 7 | public DateTime AddedAt { get; set; } 8 | public FullAlbum Album { get; set; } = default!; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SavedEpisodes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SavedEpisodes 6 | { 7 | public DateTime AddedAt { get; set; } 8 | public FullEpisode Episode { get; set; } = default!; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SavedShow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SavedShow 6 | { 7 | public DateTime AddedAt { get; set; } 8 | public FullShow Show { get; set; } = default!; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SavedTrack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SavedTrack 6 | { 7 | public DateTime AddedAt { get; set; } 8 | public FullTrack Track { get; set; } = default!; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SearchResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class SearchResponse 4 | { 5 | public Paging Artists { get; set; } = default!; 6 | public Paging Albums { get; set; } = default!; 7 | public Paging Tracks { get; set; } = default!; 8 | public Paging Shows { get; set; } = default!; 9 | public Paging Episodes { get; set; } = default!; 10 | public Paging Playlists { get; set; } = default!; 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Section.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class Section 4 | { 5 | public float Start { get; set; } 6 | public float Duration { get; set; } 7 | public float Confidence { get; set; } 8 | public float Loudness { get; set; } 9 | public float Tempo { get; set; } 10 | public float TempoConfidence { get; set; } 11 | public int Key { get; set; } 12 | public float KeyConfidence { get; set; } 13 | public int Mode { get; set; } 14 | public float ModeConfidence { get; set; } 15 | public int TimeSignature { get; set; } 16 | public float TimeSignatureConfidence { get; set; } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/Segment.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class Segment 6 | { 7 | public float Start { get; set; } 8 | public float Duration { get; set; } 9 | public float Confidence { get; set; } 10 | public float LoudnessStart { get; set; } 11 | public float LoudnessMax { get; set; } 12 | public float LoudnessMaxTime { get; set; } 13 | public float LoudnessEnd { get; set; } 14 | public List Pitches { get; set; } = default!; 15 | public List Timbre { get; set; } = default!; 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/ShowsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class ShowsResponse 6 | { 7 | public List Shows { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SimpleAlbum.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SimpleAlbum 6 | { 7 | public string AlbumGroup { get; set; } = default!; 8 | public string AlbumType { get; set; } = default!; 9 | public List Artists { get; set; } = default!; 10 | public List AvailableMarkets { get; set; } = default!; 11 | public Dictionary ExternalUrls { get; set; } = default!; 12 | public string Href { get; set; } = default!; 13 | public string Id { get; set; } = default!; 14 | public List Images { get; set; } = default!; 15 | public string Name { get; set; } = default!; 16 | public string ReleaseDate { get; set; } = default!; 17 | public string ReleaseDatePrecision { get; set; } = default!; 18 | public Dictionary Restrictions { get; set; } = default!; 19 | public int TotalTracks { get; set; } 20 | public string Type { get; set; } = default!; 21 | public string Uri { get; set; } = default!; 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SimpleArtist.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | namespace SpotifyAPI.Web 3 | { 4 | public class SimpleArtist 5 | { 6 | public Dictionary ExternalUrls { get; set; } = default!; 7 | public string Href { get; set; } = default!; 8 | public string Id { get; set; } = default!; 9 | public string Name { get; set; } = default!; 10 | public string Type { get; set; } = default!; 11 | public string Uri { get; set; } = default!; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SimpleAudiobook.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SimpleAudiobook 6 | { 7 | public List Authors { get; set; } = default!; 8 | public List AvailableMarkets { get; set; } = default!; 9 | public List Copyrights { get; set; } = default!; 10 | public string Description { get; set; } = default!; 11 | public string HtmlDescription { get; set; } = default!; 12 | public string Edition { get; set; } = default!; 13 | public bool Explicit { get; set; } = default!; 14 | public Dictionary ExternalUrls { get; set; } = default!; 15 | public string Href { get; set; } = default!; 16 | public string Id { get; set; } = default!; 17 | public List Images { get; set; } = default!; 18 | public List Languages { get; set; } = default!; 19 | public string MediaType { get; set; } = default!; 20 | public string Name { get; set; } = default!; 21 | public List Narrators { get; set; } = default!; 22 | public string Publisher { get; set; } = default!; 23 | public string Type { get; set; } = default!; 24 | public string Uri { get; set; } = default!; 25 | public int TotalChapters { get; set; } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SimpleAudiobookChapter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SimpleAudiobookChapter 6 | { 7 | public string? AudioPreviewUrl { get; set; } 8 | public List AvailableMarkets { get; set; } = default!; 9 | public int ChapterNumber { get; set; } 10 | public string Description { get; set; } = default!; 11 | public string HtmlDescription { get; set; } = default!; 12 | public int DurationMs { get; set; } = default!; 13 | public bool Explicit { get; set; } = default!; 14 | public Dictionary ExternalUrls { get; set; } = default!; 15 | public string Href { get; set; } = default!; 16 | public string Id { get; set; } = default!; 17 | public List Images { get; set; } = default!; 18 | public bool IsPlayable { get; set; } = default!; 19 | public List Languages { get; set; } = default!; 20 | public string Name { get; set; } = default!; 21 | public string ReleaseDate { get; set; } = default!; 22 | public string ReleaseDatePrecision { get; set; } = default!; 23 | public ResumePoint ResumePoint { get; set; } = default!; 24 | public string Type { get; set; } = default!; 25 | public string Uri { get; set; } = default!; 26 | public Dictionary Restrictions { get; set; } = default!; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SimpleShow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class SimpleShow 6 | { 7 | public List AvailableMarkets { get; set; } = default!; 8 | public List Copyrights { get; set; } = default!; 9 | public string Description { get; set; } = default!; 10 | public string HtmlDescription { get; set; } = default!; 11 | public bool Explicit { get; set; } 12 | public Dictionary ExternalUrls { get; set; } = default!; 13 | public string Href { get; set; } = default!; 14 | public string Id { get; set; } = default!; 15 | public List Images { get; set; } = default!; 16 | public bool IsExternallyHosted { get; set; } 17 | public List Languages { get; set; } = default!; 18 | public string MediaType { get; set; } = default!; 19 | public string Name { get; set; } = default!; 20 | public string Publisher { get; set; } = default!; 21 | public string Type { get; set; } = default!; 22 | public string Uri { get; set; } = default!; 23 | public int TotalEpisodes { get; set; } = default!; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SimpleTrack.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace SpotifyAPI.Web 6 | { 7 | public class SimpleTrack 8 | { 9 | public List Artists { get; set; } = default!; 10 | public List AvailableMarkets { get; set; } = default!; 11 | public int DiscNumber { get; set; } 12 | public int DurationMs { get; set; } 13 | public bool Explicit { get; set; } 14 | public Dictionary ExternalUrls { get; set; } = default!; 15 | public string Href { get; set; } = default!; 16 | public string Id { get; set; } = default!; 17 | public bool IsPlayable { get; set; } 18 | public LinkedTrack LinkedFrom { get; set; } = default!; 19 | public string Name { get; set; } = default!; 20 | public string PreviewUrl { get; set; } = default!; 21 | public int TrackNumber { get; set; } 22 | 23 | [JsonConverter(typeof(StringEnumConverter))] 24 | public ItemType Type { get; set; } 25 | public string Uri { get; set; } = default!; 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/SnapshotResponse.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class SnapshotResponse 4 | { 5 | public string SnapshotId { get; set; } = default!; 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/TimeInterval.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class TimeInterval 4 | { 5 | public float Start { get; set; } 6 | public float Duration { get; set; } 7 | public float Confidence { get; set; } 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/TrackAudio.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class TrackAudio 4 | { 5 | public float Duration { get; set; } 6 | public string SampleMd5 { get; set; } = default!; 7 | public int OffsetSeconds { get; set; } 8 | public int WindowSeconds { get; set; } 9 | public int AnalysisSampleRate { get; set; } 10 | public int AnalysisChannels { get; set; } 11 | public float EndOfFadeIn { get; set; } 12 | public float StartOfFadeOut { get; set; } 13 | public float Loudness { get; set; } 14 | public float Tempo { get; set; } 15 | public float TempConfidence { get; set; } 16 | public int TimeSignature { get; set; } 17 | public float TimeSignatureConfidence { get; set; } 18 | public int Key { get; set; } 19 | public float KeyConfidence { get; set; } 20 | public int Mode { get; set; } 21 | public float ModeConfidence { get; set; } 22 | public string Codestring { get; set; } = default!; 23 | public float CodeVersion { get; set; } 24 | public string Echoprintstring { get; set; } = default!; 25 | public float EchoprintVersion { get; set; } 26 | public string Synchstring { get; set; } = default!; 27 | public float SynchVersion { get; set; } 28 | public string Rhythmstring { get; set; } = default!; 29 | public float RhythmVersion { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/TrackAudioAnalysis.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class TrackAudioAnalysis 6 | { 7 | public List Bars { get; set; } = default!; 8 | public List Beats { get; set; } = default!; 9 | public List
Sections { get; set; } = default!; 10 | public List Segments { get; set; } = default!; 11 | public List Tatums { get; set; } = default!; 12 | public TrackAudio Track { get; set; } = default!; 13 | public TrackMeta Meta { get; set; } = default!; 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/TrackAudioFeatures.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class TrackAudioFeatures 4 | { 5 | public float Acousticness { get; set; } 6 | public string AnalysisUrl { get; set; } = default!; 7 | public float Danceability { get; set; } 8 | public int DurationMs { get; set; } 9 | public float Energy { get; set; } 10 | public string Id { get; set; } = default!; 11 | public float Instrumentalness { get; set; } 12 | public int Key { get; set; } 13 | public float Liveness { get; set; } 14 | public float Loudness { get; set; } 15 | public int Mode { get; set; } 16 | public float Speechiness { get; set; } 17 | public float Tempo { get; set; } 18 | public int TimeSignature { get; set; } 19 | public string TrackHref { get; set; } = default!; 20 | public string Type { get; set; } = default!; 21 | public string Uri { get; set; } = default!; 22 | public float Valence { get; set; } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/TrackMeta.cs: -------------------------------------------------------------------------------- 1 | namespace SpotifyAPI.Web 2 | { 3 | public class TrackMeta 4 | { 5 | public float AnalysisTime { get; set; } 6 | public string AnalyzerVersion { get; set; } = default!; 7 | public string DetailedStatus { get; set; } = default!; 8 | public string InputProcess { get; set; } = default!; 9 | public string Platform { get; set; } = default!; 10 | public int StatusCode { get; set; } = default!; 11 | public long Timestamp { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/TracksAudioFeaturesResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class TracksAudioFeaturesResponse 6 | { 7 | public List AudioFeatures { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/TracksResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class TracksResponse 6 | { 7 | public List Tracks { get; set; } = default!; 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Models/Response/UsersTopArtistsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | public class UsersTopArtistsResponse 6 | { 7 | public string Href { get; set; } = default!; 8 | public int Limit { get; set; } 9 | public string Next { get; set; } = default!; 10 | public int Offset { get; set; } 11 | public string Previous { get; set; } = default!; 12 | public int Total { get; set; } = default!; 13 | public List Items { get; set; } = default!; 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/RetryHandlers/IRetryHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | 4 | namespace SpotifyAPI.Web.Http 5 | { 6 | /// 7 | /// The Retry Handler will be directly called after the response is retrived and before errors and body are processed. 8 | /// 9 | public interface IRetryHandler 10 | { 11 | delegate Task RetryFunc(IRequest request, CancellationToken cancel = default); 12 | 13 | Task HandleRetry(IRequest request, IResponse response, RetryFunc retry, CancellationToken cancel = default); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Util/HTTP.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace SpotifyAPI.Web 4 | { 5 | internal static class HTTPUtil 6 | { 7 | public static bool StatusCodeIsSuccess(HttpStatusCode statusCode) 8 | { 9 | return ((int)statusCode >= 200) && ((int)statusCode <= 299); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Util/StringAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | #if !NETSTANDARD2_0 3 | using System.Diagnostics.CodeAnalysis; 4 | #endif 5 | using System.Linq; 6 | using System.Reflection; 7 | 8 | namespace SpotifyAPI.Web 9 | { 10 | [AttributeUsage(AttributeTargets.Field)] 11 | public sealed class StringAttribute : Attribute 12 | { 13 | public StringAttribute(string value) 14 | { 15 | Value = value; 16 | } 17 | 18 | public string Value { get; } 19 | 20 | #if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER 21 | public static bool GetValue(Type enumType, Enum enumValue, [NotNullWhen(true)] out string? result) 22 | #else 23 | public static bool GetValue(Type enumType, Enum enumValue, out string? result) 24 | #endif 25 | { 26 | Ensure.ArgumentNotNull(enumType, nameof(enumType)); 27 | Ensure.ArgumentNotNull(enumValue, nameof(enumValue)); 28 | 29 | if (enumType 30 | .GetMember(enumValue.ToString())[0] 31 | .GetCustomAttributes(typeof(StringAttribute)) 32 | .FirstOrDefault() is StringAttribute stringAttr) 33 | { 34 | result = stringAttr.Value; 35 | return true; 36 | } 37 | result = null; 38 | return false; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Util/URIExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | using System.Linq; 5 | using System.Web; 6 | 7 | namespace SpotifyAPI.Web 8 | { 9 | public static class URIExtensions 10 | { 11 | public static Uri ApplyParameters(this Uri uri, IDictionary parameters) 12 | { 13 | Ensure.ArgumentNotNull(uri, nameof(uri)); 14 | 15 | if (parameters == null || !parameters.Any()) 16 | { 17 | return uri; 18 | } 19 | 20 | var newParameters = new Dictionary(); 21 | NameValueCollection existingParameters = HttpUtility.ParseQueryString(uri.Query); 22 | foreach (string key in existingParameters) 23 | { 24 | newParameters.Add(key, existingParameters[key]!); 25 | } 26 | foreach (KeyValuePair parameter in parameters) 27 | { 28 | newParameters.Add(parameter.Key, HttpUtility.UrlEncode(parameter.Value)); 29 | } 30 | 31 | var queryString = string.Join("&", newParameters.Select((parameter) => $"{parameter.Key}={parameter.Value}")); 32 | var query = string.IsNullOrEmpty(queryString) ? null : queryString; 33 | 34 | var uriBuilder = new UriBuilder(uri) 35 | { 36 | Query = query 37 | }; 38 | 39 | return uriBuilder.Uri; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SpotifyAPI.Web/Util/URIParameterFormatProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | namespace SpotifyAPI.Web 4 | { 5 | public class URIParameterFormatProvider : IFormatProvider 6 | { 7 | private readonly URIParameterFormatter _formatter; 8 | 9 | public URIParameterFormatProvider() 10 | { 11 | _formatter = new URIParameterFormatter(); 12 | } 13 | 14 | public object? GetFormat(Type? formatType) 15 | { 16 | return formatType == typeof(ICustomFormatter) ? _formatter : null; 17 | } 18 | 19 | private class URIParameterFormatter : ICustomFormatter 20 | { 21 | public string Format(string? format, object? arg, IFormatProvider? formatProvider) 22 | { 23 | return HttpUtility.UrlEncode(arg?.ToString()) ?? string.Empty; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /omnisharp.json: -------------------------------------------------------------------------------- 1 | { 2 | "RoslynExtensionsOptions": { 3 | "enableAnalyzersSupport": true 4 | }, 5 | "FormattingOptions": { 6 | "enableEditorConfigSupport": true, 7 | "OrganizeImports": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Publishing..." 6 | 7 | cd ./SpotifyAPI.Web 8 | dotnet pack -c Release SpotifyAPI.Web.csproj -p:PackageVersion="$RELEASE_VERSION" 9 | nuget push "./bin/Release/SpotifyAPI.Web.$RELEASE_VERSION.nupkg"\ 10 | -ApiKey "$NUGET_TOKEN"\ 11 | -NonInteractive\ 12 | -Source https://www.nuget.org/api/v2/package 13 | 14 | cd ../SpotifyAPI.Web.Auth 15 | dotnet pack -c Release SpotifyAPI.Web.Auth.csproj -p:PackageVersion="$RELEASE_VERSION" 16 | nuget push "./bin/Release/SpotifyAPI.Web.Auth.$RELEASE_VERSION.nupkg"\ 17 | -ApiKey "$NUGET_TOKEN"\ 18 | -NonInteractive\ 19 | -Source https://www.nuget.org/api/v2/package 20 | 21 | cd .. 22 | --------------------------------------------------------------------------------