├── .gitignore ├── CodingChick.BeatsMusicAPI ├── .nuget │ ├── NuGet.Config │ ├── NuGet.exe │ └── NuGet.targets ├── CodingChick.BeatsMusic.WPFSample │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── BeatsPlayer │ │ └── BeatsMusicPlayer.html │ ├── CodingChick.BeatsMusic.WPFSample.csproj │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── SoundManager │ │ ├── HTMLAudioPlayer.html │ │ ├── UpgradeBrowserToIE11.reg │ │ ├── script │ │ │ ├── soundmanager2-jsmin.js │ │ │ ├── soundmanager2-nodebug-jsmin.js │ │ │ ├── soundmanager2-nodebug.js │ │ │ └── soundmanager2.js │ │ ├── src │ │ │ ├── SoundManager2.as │ │ │ ├── SoundManager2_AS3.as │ │ │ ├── SoundManager2_SMSound_AS3.as │ │ │ ├── make-flash8.bat │ │ │ ├── make-flash8.sh │ │ │ ├── make-flash9.bat │ │ │ └── make-flash9.sh │ │ └── swf │ │ │ ├── soundmanager2.swf │ │ │ ├── soundmanager2_debug.swf │ │ │ ├── soundmanager2_flash9.swf │ │ │ ├── soundmanager2_flash9_debug.swf │ │ │ └── soundmanager2_flash_xdomain.zip │ ├── WindowExtensions.cs │ └── packages.config ├── CodingChick.BeatsMusicAPI.Core │ ├── Base │ │ ├── Authorization.cs │ │ ├── BeatsHttpData.cs │ │ ├── BeatsMusicManager.cs │ │ ├── HttpBeatsMusicEngine.cs │ │ ├── HttpClientAccessor.cs │ │ ├── IBeatsHttpData.cs │ │ ├── IBeatsMusicManager.cs │ │ ├── IHttpBeatsMusicEngine.cs │ │ ├── IHttpClientAccessor.cs │ │ ├── IJsonBeatsMusicEngine.cs │ │ ├── JsonBeatsMusicEngine.cs │ │ └── JsonHelpers │ │ │ ├── BaseDataConverter.cs │ │ │ ├── JsonCreationConverter.cs │ │ │ └── UnderscoreResolver.cs │ ├── BeatsMusicClient.cs │ ├── CodingChick.BeatsMusicAPI.Core.csproj │ ├── Data │ │ ├── Activities │ │ │ └── ActivityData.cs │ │ ├── Albums │ │ │ ├── AlbumData.cs │ │ │ └── AlbumRefs.cs │ │ ├── Artists │ │ │ ├── ArtistData.cs │ │ │ └── ArtistRefs.cs │ │ ├── Audio │ │ │ ├── AudioData.cs │ │ │ └── AudioRefs.cs │ │ ├── BaseData.cs │ │ ├── Content │ │ │ ├── ContentData.cs │ │ │ └── ContentRefs.cs │ │ ├── Genres │ │ │ └── GenreData.cs │ │ ├── Info.cs │ │ ├── Me │ │ │ └── MeData.cs │ │ ├── MultipleRootObject.cs │ │ ├── Player │ │ │ └── PlayerCode.html │ │ ├── Playlists │ │ │ ├── PlaylistData.cs │ │ │ └── PlaylistsRefs.cs │ │ ├── Ratings │ │ │ └── RatingData.cs │ │ ├── RefTypeInfo.cs │ │ ├── Reviews │ │ │ └── ReviewData.cs │ │ ├── RootObject.cs │ │ ├── Search │ │ │ ├── Related.cs │ │ │ └── SearchData.cs │ │ ├── SingleRootObject.cs │ │ ├── Tracks │ │ │ ├── TrackData.cs │ │ │ └── TrackRefs.cs │ │ └── Users │ │ │ └── UserData.cs │ ├── Endpoints │ │ ├── ActivitiesEndpoint.cs │ │ ├── AlbumsEndpoint.cs │ │ ├── ArtistsEndpoint.cs │ │ ├── AudioEndpoint.cs │ │ ├── BaseEndpoint.cs │ │ ├── DataFilters │ │ │ └── StreamabilityFilters.cs │ │ ├── Enums │ │ │ ├── AccessPrivilege.cs │ │ │ ├── AlbumRefType.cs │ │ │ ├── AlbumsOrderBy.cs │ │ │ ├── ArtistOrderBy.cs │ │ │ ├── FollowType.cs │ │ │ ├── ImageSize.cs │ │ │ ├── PlaylistRefType.cs │ │ │ ├── PlaylistsOrderBy.cs │ │ │ ├── Rating.cs │ │ │ ├── ResponseType.cs │ │ │ ├── TracksOrderByData.cs │ │ │ └── TracksRefType.cs │ │ ├── FollowEndpoint.cs │ │ ├── GenreEndpoint.cs │ │ ├── HighlightsEndpoint.cs │ │ ├── ImagesEndpoint.cs │ │ ├── MeEndoint.cs │ │ ├── PlaylistsEndpoint.cs │ │ ├── RatingsEndpoint.cs │ │ ├── SearchEndpoint.cs │ │ └── TracksEndpoint.cs │ ├── Helpers │ │ ├── EnumHelper.cs │ │ ├── FileHelper.cs │ │ ├── HttpUtilityHelper.cs │ │ ├── ParamValueAttribute.cs │ │ └── ParamValueAttributeHelper.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── CodingChick.BeatsMusicAPI.Tests │ ├── ArtistsTests.cs │ ├── AudioTests.cs │ ├── BaseTest.cs │ ├── CodingChick.BeatsMusicAPI.Tests.csproj │ ├── FollowTests.cs │ ├── GenreTests.cs │ ├── HightlightsTests.cs │ ├── ImagesTests.cs │ ├── PlaylistTests.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RatingTests.cs │ ├── SearchTests.cs │ ├── TracksTest.cs │ ├── app.config │ └── packages.config ├── CodingChick.BeatsMusicAPI.sln └── UpgradeLog.htm ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/BaseTest.cs 110 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coding-chick/BeatsMusicCSharp/148aff4d992e75f30b4e91b83e394c1bc76b5d4f/CodingChick.BeatsMusicAPI/.nuget/NuGet.exe -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | 32 | 33 | 34 | 35 | $(SolutionDir).nuget 36 | 37 | 38 | 39 | packages.$(MSBuildProjectName.Replace(' ', '_')).config 40 | 41 | 42 | 43 | 44 | 45 | $(PackagesProjectConfig) 46 | 47 | 48 | 49 | 50 | packages.config 51 | 52 | 53 | 54 | 55 | 56 | 57 | $(NuGetToolsPath)\NuGet.exe 58 | @(PackageSource) 59 | 60 | "$(NuGetExePath)" 61 | mono --runtime=v4.0.30319 $(NuGetExePath) 62 | 63 | $(TargetDir.Trim('\\')) 64 | 65 | -RequireConsent 66 | -NonInteractive 67 | 68 | "$(SolutionDir) " 69 | "$(SolutionDir)" 70 | 71 | 72 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) 73 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols 74 | 75 | 76 | 77 | RestorePackages; 78 | $(BuildDependsOn); 79 | 80 | 81 | 82 | 83 | $(BuildDependsOn); 84 | BuildPackage; 85 | 86 | 87 | 88 | 89 | 90 | 91 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | 113 | 115 | 116 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace CodingChick.BeatsMusic.WPFSample 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/BeatsPlayer/BeatsMusicPlayer.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | My Beats Music Player 4 | 5 | 6 | 7 | 48 | 49 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Web; 11 | using System.Windows; 12 | using System.Windows.Controls; 13 | using System.Windows.Data; 14 | using System.Windows.Documents; 15 | using System.Windows.Input; 16 | using System.Windows.Media; 17 | using System.Windows.Media.Imaging; 18 | using System.Windows.Navigation; 19 | using System.Windows.Shapes; 20 | using CodingChick.BeatsMusicAPI.Core; 21 | using CodingChick.BeatsMusicAPI.Core.Base; 22 | using CodingChick.BeatsMusicAPI.Core.Data; 23 | using CodingChick.BeatsMusicAPI.Core.Data.Audio; 24 | using CodingChick.BeatsMusicAPI.Core.Data.Me; 25 | using CodingChick.BeatsMusicAPI.Core.Data.Playlists; 26 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 27 | using CodingChick.BeatsMusicAPI.Core.Endpoints.DataFilters; 28 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 29 | 30 | namespace CodingChick.BeatsMusic.WPFSample 31 | { 32 | /// 33 | /// Interaction logic for MainWindow.xaml 34 | /// 35 | public partial class MainWindow : Window 36 | { 37 | private BeatsMusicClient client; 38 | 39 | public MainWindow() 40 | { 41 | InitializeComponent(); 42 | this.StretchToMaximum(); 43 | 44 | // *** Fill your Beats Music app details here! *** 45 | //this.ClientId = ""; 46 | //this.ClientSecret = ""; 47 | //this.RedirectUrl = ""; 48 | 49 | // Create the beats music API client that will call all services, can be called with ClientSecret for enhanced long term security, 50 | // or without for short term limited security. More infomation on types of security @ https://developer.beatsmusic.com/docs/read/getting_started/Client_Side_Applications 51 | // and https://developer.beatsmusic.com/docs/read/getting_started/Web_Server_Applications 52 | client = new BeatsMusicClient(ClientId, RedirectUrl); 53 | 54 | // Get the address the web browser needs to navigate for OAuth 2.0 protocol authentication. 55 | var addressString = client.UriAddressToNavigateForPermissions(); 56 | // Navigate to the BeatsMusic OAuth page. 57 | BeatsMusicWebBrowser.Source = new Uri(addressString); 58 | BeatsMusicWebBrowser.Navigating += BeatsMusicWebBrowser_Navigating; 59 | } 60 | 61 | public string ClientId { get; set; } 62 | public string ClientSecret { get; set; } 63 | public string RedirectUrl { get; set; } 64 | 65 | public async void BeatsMusicWebBrowser_Navigating(object sender, NavigatingCancelEventArgs e) 66 | { 67 | // A check that the OAuth page has redirected to the redirected url provided. 68 | //if (e.Uri != null && e.Uri.AbsoluteUri.Contains("insert part of redirected url here")) 69 | if (e.Uri != null && e.Uri.AbsoluteUri.Contains("codingchick")) 70 | { 71 | NameValueCollection queryStringParams = HttpUtility.ParseQueryString(e.Uri.Query); 72 | 73 | // The first (commented) if statement is the key required for Client Side application (lower security), 74 | // the second (uncommented) if is for Web Server applications (higher security). 75 | 76 | if (queryStringParams.AllKeys.Contains("access_token")) 77 | //if (queryStringParams.AllKeys.Contains("code")) 78 | { 79 | BeatsMusicWebBrowser.NavigateToString(@""); 80 | 81 | // The first (commented) if statement is the key required for Client Side application (lower security), 82 | // the second (uncommented) if is for Web Server applications (higher security). 83 | 84 | client.SetClientAccessTokenFromRedirectUri(queryStringParams.GetValues("access_token").FirstOrDefault(), int.Parse(queryStringParams.GetValues("expires_in").FirstOrDefault())); 85 | //client.ServerCode = queryStringParams.GetValues("code").FirstOrDefault(); 86 | 87 | // This is an example of calling the BeatsMusic API, this call will get an information about the user currently logged into this app. 88 | SingleRootObject meResult = await client.Me.GetMeInfo(); 89 | 90 | var search = await client.Search.SearchByArtist("Cat Stevens"); 91 | 92 | //*************************************************************************************************************** 93 | // This is an example of using streaming, this call will get an audio track info required for streaming. 94 | // Calling this method with the aquire set to true just to make sure this works every time. 95 | // more info @https://developer.beatsmusic.com/docs/read/audio/Playback 96 | SingleRootObject trackResult = await client.Audio.GetAudioStreamingInfo("tr61032803", Bitrate.Highest, true); 97 | 98 | 99 | // To demonstrate how the information can be used, I'm using an OS web music player- SoundManager 2 (from @http://www.schillmania.com/projects/soundmanager2/) to play this file. 100 | // The files required and the HTML file are included in this project under the SoundManager directory. 101 | // SoundManager directory is hosted on local iis due to security issues with flash, js and soundmanager when running the local file. 102 | // If SoundManager retunes an exception try refreshing the page and/or update the WebBrowser version to a newer IE version by running the UpgradeBrowserToIE11.reg file included. 103 | //BeatsMusicWebBrowser.Navigate(new Uri(String.Format("http://localhost:8081/soundManager/SoundManager/HTMLAudioPlayer.html?&trackId={0}&trackUrl={1}&serverUrl={2}", 104 | // trackResult.Data.Refs.Track.Id, trackResult.Data.Resource, trackResult.Data.Location))); 105 | 106 | //*************************************************************************************************************** 107 | // Alternatly, you can use the BeatsMusic default web player, and play a track with it (@https://developer.beatsmusic.com/docs/read/web_playback_api/Getting_Started) 108 | // you can obtain the base js code from the C# BeatsMusicClient, or get the parameters from the client seperetly and write your own js. 109 | string beatsPlayer = await client.GetBeatsMusicPlayerCode("tr61032803"); 110 | 111 | // You can save the string to file, navigate, play etc. 112 | } 113 | } 114 | } 115 | 116 | } 117 | 118 | 119 | } 120 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("CodingChick.BeatsMusic.WPFSample")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("CodingChick.BeatsMusic.WPFSample")] 15 | [assembly: AssemblyCopyright("Copyright © 2014")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18449 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CodingChick.BeatsMusic.WPFSample.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CodingChick.BeatsMusic.WPFSample.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18449 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace CodingChick.BeatsMusic.WPFSample.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/HTMLAudioPlayer.html: -------------------------------------------------------------------------------- 1 |  2 | 26 | 27 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/UpgradeBrowserToIE11.reg: -------------------------------------------------------------------------------- 1 | Windows Registry Editor Version 5.00 2 | 3 | [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION] 4 | "CodingChick.BeatsMusic.WPFSample.exe"=dword:2af9 5 | 6 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION] 7 | "CodingChick.BeatsMusic.WPFSample.exe"=dword:2af9 8 | 9 | [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION] 10 | "CodingChick.BeatsMusic.WPFSample.vshost.exe"=dword:2af9 11 | 12 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION] 13 | "CodingChick.BeatsMusic.WPFSample.vshost.exe"=dword:2af9 -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/src/make-flash8.bat: -------------------------------------------------------------------------------- 1 | @REM this builds the soundmanager 2 SWF from source 2 | 3 | mtasc -swf ../swf/soundmanager2_debug.swf -main -header 16:16:30 SoundManager2.as -version 8 4 | @pause 5 | 6 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/src/make-flash8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | /Applications/mtasc/mtasc -swf ../swf/soundmanager2_debug.swf -main -header 16:16:30 SoundManager2.as -version 8 3 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/src/make-flash9.bat: -------------------------------------------------------------------------------- 1 | @REM this builds the soundmanager 2 SWF from source 2 | @REM using mxmlc from the Adobe open-source Flex SDK 3 | 4 | c:\progra~1\flexsdk\bin\mxmlc -debug=true -use-network=false -static-link-runtime-shared-libraries=true -optimize=true -o ../swf/soundmanager2_flash9_debug.swf -file-specs SoundManager2_AS3.as 5 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/src/make-flash9.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | /Applications/flexsdk/bin/mxmlc -debug=true -static-link-runtime-shared-libraries=true -optimize=true -o ../swf/soundmanager2_flash9_debug.swf -file-specs SoundManager2_AS3.as 3 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coding-chick/BeatsMusicCSharp/148aff4d992e75f30b4e91b83e394c1bc76b5d4f/CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2.swf -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_debug.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coding-chick/BeatsMusicCSharp/148aff4d992e75f30b4e91b83e394c1bc76b5d4f/CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_debug.swf -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_flash9.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coding-chick/BeatsMusicCSharp/148aff4d992e75f30b4e91b83e394c1bc76b5d4f/CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_flash9.swf -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_flash9_debug.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coding-chick/BeatsMusicCSharp/148aff4d992e75f30b4e91b83e394c1bc76b5d4f/CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_flash9_debug.swf -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_flash_xdomain.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coding-chick/BeatsMusicCSharp/148aff4d992e75f30b4e91b83e394c1bc76b5d4f/CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/SoundManager/swf/soundmanager2_flash_xdomain.zip -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/WindowExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace CodingChick.BeatsMusic.WPFSample 4 | { 5 | public static class WindowExtensions 6 | { 7 | public static void StretchToMaximum(this Window current) 8 | { 9 | current.WindowState = WindowState.Maximized; 10 | current.Width = System.Windows.SystemParameters.PrimaryScreenWidth; 11 | current.Height = System.Windows.SystemParameters.PrimaryScreenHeight; 12 | current.WindowStyle = WindowStyle.None; 13 | current.AllowsTransparency = false; 14 | current.ResizeMode = ResizeMode.CanResize; 15 | } 16 | 17 | 18 | public static void Navigate(this Window current, Window next) 19 | { 20 | Application.Current.MainWindow = next; 21 | next.Show(); 22 | current.Close(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusic.WPFSample/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/Authorization.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Runtime.CompilerServices; 5 | using System.Threading.Tasks; 6 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 7 | using CodingChick.BeatsMusicAPI.Core.Helpers; 8 | using Newtonsoft.Json; 9 | 10 | namespace CodingChick.BeatsMusicAPI.Core.Base 11 | { 12 | internal class Authorization 13 | { 14 | private readonly ResponseType _responseType; 15 | private readonly string _redirectUri; 16 | private readonly string _clientId; 17 | 18 | public Authorization(string redirectUri, string clientId) 19 | { 20 | _redirectUri = redirectUri; 21 | _clientId = clientId; 22 | } 23 | 24 | public ResponseType ResponseType { get; set; } 25 | 26 | public string ClientId 27 | { 28 | get { return _clientId; } 29 | } 30 | 31 | public string RedirectUri 32 | { 33 | get { return _redirectUri; } 34 | } 35 | 36 | public int ExpiresAt { get; set; } 37 | 38 | public DateTime ExpiresAtWasSet { get; set; } 39 | 40 | public string ClientSecret { get; set; } 41 | 42 | public string AuthorizatioUri { get { return "oauth2/authorize?"; } } 43 | 44 | public string TokenUri { get { return "/oauth2/token"; } } 45 | 46 | 47 | public string ReadOnlyAccessToken { get; set; } 48 | 49 | public string ReadWriteAccessToken { get; set; } 50 | 51 | public string Code { get; set; } 52 | 53 | 54 | public List> CreateAuthorizatioUriParams(ResponseType responseType) 55 | { 56 | var responseTypeString = ParamValueAttributeHelper.GetParamValueOfEnumAttribute(responseType); 57 | 58 | List> authParams = new List>() 59 | { 60 | new KeyValuePair("response_type", responseTypeString), 61 | new KeyValuePair("redirect_uri", RedirectUri), 62 | new KeyValuePair("client_id", ClientId) 63 | }; 64 | 65 | return authParams; 66 | } 67 | 68 | 69 | public KeyValuePair[] GetAuthorizationTokenParams() 70 | { 71 | //TODO: make sure ClientSecret is not null 72 | 73 | return new[] 74 | { 75 | new KeyValuePair("client_secret", ClientSecret), 76 | new KeyValuePair("client_id", ClientId), 77 | new KeyValuePair("redirect_uri", RedirectUri), 78 | new KeyValuePair("code", Code) 79 | }; 80 | } 81 | 82 | public async Task ParseAccessToken(HttpContent response) 83 | { 84 | var dataResponse = await response.ReadAsStringAsync(); 85 | 86 | var parsedDataResponse = JsonConvert.DeserializeObject(dataResponse); 87 | 88 | if (parsedDataResponse.Code.ToLower() == "ok") 89 | { 90 | ReadWriteAccessToken = parsedDataResponse.Result.AccessToken; 91 | SetExpiresAt(parsedDataResponse.Result.ExpiresIn); 92 | 93 | return true; 94 | } 95 | return false; 96 | } 97 | 98 | public void SetExpiresAt(int expiresAt) 99 | { 100 | ExpiresAt = expiresAt; 101 | ExpiresAtWasSet = DateTime.Now; 102 | } 103 | 104 | public bool NeedToRenewAccessToken 105 | { 106 | get 107 | { 108 | return DateTime.Now > ExpiresAtWasSet.AddSeconds(Convert.ToDouble(ExpiresAt)).AddSeconds(-30); 109 | } 110 | } 111 | 112 | } 113 | 114 | 115 | public class AuthorizationResult 116 | { 117 | [JsonProperty("return_type")] 118 | public string ReturnType { get; set; } 119 | [JsonProperty("access_token")] 120 | public string AccessToken { get; set; } 121 | [JsonProperty("token_type")] 122 | public string TokenType { get; set; } 123 | [JsonProperty("expires_in")] 124 | public int ExpiresIn { get; set; } 125 | [JsonProperty("refresh_token")] 126 | public string RefreshToken { get; set; } 127 | [JsonProperty("scope")] 128 | public string Scope { get; set; } 129 | [JsonProperty("state")] 130 | public object State { get; set; } 131 | [JsonProperty("uri")] 132 | public object Uri { get; set; } 133 | [JsonProperty("extended")] 134 | public object Extended { get; set; } 135 | } 136 | 137 | [JsonObject("RootObject")] 138 | public class AuthorizationRootObject 139 | { 140 | [JsonProperty("jsonrpc")] 141 | public string Jsonrpc { get; set; } 142 | [JsonProperty("result")] 143 | public AuthorizationResult Result { get; set; } 144 | [JsonProperty("id")] 145 | public int Id { get; set; } 146 | [JsonProperty("code")] 147 | public string Code { get; set; } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/BeatsHttpData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net.Http; 3 | using System.Threading.Tasks; 4 | using CodingChick.BeatsMusicAPI.Core.Data; 5 | using CodingChick.BeatsMusicAPI.Core.Data.Me; 6 | using Newtonsoft.Json; 7 | 8 | namespace CodingChick.BeatsMusicAPI.Core.Base 9 | { 10 | internal class BeatsHttpData : IBeatsHttpData 11 | { 12 | private readonly IHttpBeatsMusicEngine _httpBeatsMusicEngine; 13 | 14 | public BeatsHttpData(IHttpBeatsMusicEngine httpBeatsMusicEngine) 15 | { 16 | _httpBeatsMusicEngine = httpBeatsMusicEngine; 17 | } 18 | 19 | public async Task> GetMultipleParsedResult(string methodName, 20 | List> methodParams, bool useToken = false) 21 | { 22 | string dataResponse = await GetDataResponse(methodName, methodParams, useToken); 23 | 24 | MultipleRootObject parsedDataResponse = ParsedMultipleDataResponse(dataResponse); 25 | return parsedDataResponse; 26 | } 27 | 28 | public async Task> GetSingleParsedResult(string methodName, 29 | List> methodParams, bool useToken = false) 30 | { 31 | string dataResponse = await GetDataResponse(methodName, methodParams, useToken); 32 | 33 | // This is a very annoying fix to make sure API calls are consistent and all return "data", and since "me" api is different in returning "result" I made sure all return the same. 34 | if (typeof (T) == typeof (MeData)) 35 | { 36 | dataResponse = dataResponse.Replace("result", "data"); 37 | } 38 | 39 | SingleRootObject parsedDataResponse = ParsedSingleDataResponse(dataResponse); 40 | 41 | return parsedDataResponse; 42 | } 43 | 44 | public async Task> PostData(string methodName, 45 | List> dataParams) 46 | { 47 | if (dataParams == null) 48 | dataParams = new List>(); 49 | 50 | HttpContent httpResponse = await _httpBeatsMusicEngine.PostAsync(methodName, dataParams); 51 | string dataResponse = await httpResponse.ReadAsStringAsync(); 52 | 53 | return ParsedSingleDataResponse(dataResponse); 54 | } 55 | 56 | public async Task> PutData(string methodName, 57 | List> dataParams, bool addCredentials = true) 58 | { 59 | if (dataParams == null) 60 | dataParams = new List>(); 61 | 62 | HttpContent httpResponse = await _httpBeatsMusicEngine.PutAsync(methodName, dataParams, addCredentials); 63 | string dataResponse = await httpResponse.ReadAsStringAsync(); 64 | 65 | return ParsedSingleDataResponse(dataResponse); 66 | } 67 | 68 | public async Task DeleteData(string methodName, List> dataParams) 69 | { 70 | if (dataParams == null) 71 | dataParams = new List>(); 72 | 73 | HttpContent httpResponse = await _httpBeatsMusicEngine.DeleteAsync(methodName, dataParams); 74 | string dataResponse = await httpResponse.ReadAsStringAsync(); 75 | 76 | if (dataResponse.ToLower().Contains("ok")) 77 | return true; 78 | return false; 79 | } 80 | 81 | private MultipleRootObject ParsedMultipleDataResponse(string dataResponse) 82 | { 83 | var parsedDataResponse = JsonConvert.DeserializeObject>(dataResponse); 84 | return parsedDataResponse; 85 | } 86 | 87 | public async Task> GetMultipleParsedResultWithConverter(string methodName, 88 | List> methodParams, bool useToken = false) 89 | { 90 | string dataResponse = await GetDataResponse(methodName, methodParams, useToken); 91 | 92 | var parsedDataResponse = JsonConvert.DeserializeObject>(dataResponse, 93 | new BaseDataConverter()); 94 | 95 | return parsedDataResponse; 96 | } 97 | 98 | private SingleRootObject ParsedSingleDataResponse(string dataResponse) 99 | { 100 | var parsedDataResponse = JsonConvert.DeserializeObject>(dataResponse); 101 | return parsedDataResponse; 102 | } 103 | 104 | private async Task GetDataResponse(string methodName, List> methodParams, 105 | bool useToken = false) 106 | { 107 | if (methodParams == null) 108 | methodParams = new List>(); 109 | 110 | HttpContent contentResult; 111 | if (useToken) 112 | contentResult = await _httpBeatsMusicEngine.GetAsyncWithToken(methodName, methodParams); 113 | else 114 | contentResult = await _httpBeatsMusicEngine.GetAsyncNoToken(methodName, methodParams); 115 | 116 | string dataResponse = await contentResult.ReadAsStringAsync(); 117 | return dataResponse; 118 | } 119 | 120 | 121 | public async Task PostData(string methodName, List> dataParams) 122 | { 123 | if (dataParams == null) 124 | dataParams = new List>(); 125 | 126 | HttpContent httpResponse = await _httpBeatsMusicEngine.PostAsync(methodName, dataParams); 127 | string dataResponse = await httpResponse.ReadAsStringAsync(); 128 | 129 | if (dataResponse.ToLower().Contains("ok")) 130 | return true; 131 | return false; 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/BeatsMusicManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Net.Http.Headers; 5 | using System.Threading.Tasks; 6 | using CodingChick.BeatsMusicAPI.Core.Data; 7 | 8 | namespace CodingChick.BeatsMusicAPI.Core.Base 9 | { 10 | internal class BeatsMusicManager : IBeatsMusicManager 11 | { 12 | private readonly IHttpBeatsMusicEngine _httpBeatsMusicEngine; 13 | private readonly IJsonBeatsMusicEngine _jsonBeatsMusicEngine; 14 | 15 | public BeatsMusicManager(IHttpBeatsMusicEngine httpBeatsMusicEngine, IJsonBeatsMusicEngine jsonBeatsMusicEngine) 16 | { 17 | _httpBeatsMusicEngine = httpBeatsMusicEngine; 18 | _jsonBeatsMusicEngine = jsonBeatsMusicEngine; 19 | } 20 | 21 | public async Task> GetMultipleParsedResult(string methodName, 22 | List> methodParams, bool useToken = false) 23 | { 24 | var dataResponse = await GetDataResponse(methodName, methodParams, useToken); 25 | var parsedDataResponse = _jsonBeatsMusicEngine.ParseMultipleDataResponse(dataResponse); 26 | return parsedDataResponse; 27 | } 28 | 29 | public async Task> GetSingleParsedResult(string methodName, 30 | List> methodParams, bool useToken = false) 31 | { 32 | var dataResponse = await GetDataResponse(methodName, methodParams, useToken); 33 | var parsedDataResponse = _jsonBeatsMusicEngine.ParseSingleDataResponse(dataResponse); 34 | return parsedDataResponse; 35 | } 36 | 37 | public async Task> PostData(string methodName, 38 | List> dataParams) 39 | { 40 | if (dataParams == null) 41 | dataParams = new List>(); 42 | 43 | var httpResponse = await _httpBeatsMusicEngine.PostAsync(methodName, dataParams); 44 | var dataResponse = await httpResponse.ReadAsStringAsync(); 45 | 46 | return _jsonBeatsMusicEngine.ParseSingleDataResponse(dataResponse); 47 | } 48 | 49 | public async Task> PutData(string methodName, 50 | List> dataParams, bool addCredentials = true) 51 | { 52 | if (dataParams == null) 53 | dataParams = new List>(); 54 | 55 | var httpResponse = await _httpBeatsMusicEngine.PutAsync(methodName, dataParams, addCredentials); 56 | var dataResponse = await httpResponse.ReadAsStringAsync(); 57 | 58 | return _jsonBeatsMusicEngine.ParseSingleDataResponse(dataResponse); 59 | } 60 | 61 | public async Task DeleteData(string methodName, List> dataParams) 62 | { 63 | if (dataParams == null) 64 | dataParams = new List>(); 65 | 66 | var httpResponse = await _httpBeatsMusicEngine.DeleteAsync(methodName, dataParams); 67 | var dataResponse = await httpResponse.ReadAsStringAsync(); 68 | 69 | if (dataResponse.ToLower().Contains("ok")) 70 | return true; 71 | return false; 72 | } 73 | 74 | public async Task> GetMultipleParsedResultWithConverter(string methodName, 75 | List> methodParams, bool useToken = false) 76 | { 77 | var dataResponse = await GetDataResponse(methodName, methodParams, useToken); 78 | var parsedDataResponse = 79 | _jsonBeatsMusicEngine.ParseMultipleDataResponseWithConverter(dataResponse); 80 | return parsedDataResponse; 81 | } 82 | 83 | public async Task GetDataUri(string methodName, List> methodParams, 84 | bool useToken) 85 | { 86 | var dataResponse = 87 | await _httpBeatsMusicEngine.GetHeaderAsyncWithNoToken(methodName, methodParams); 88 | return dataResponse.Location; 89 | } 90 | 91 | private async Task GetDataResponse(string methodName, List> methodParams, 92 | bool useToken = false) 93 | { 94 | if (methodParams == null) 95 | methodParams = new List>(); 96 | 97 | HttpContent contentResult; 98 | if (useToken) 99 | contentResult = await _httpBeatsMusicEngine.GetAsyncWithToken(methodName, methodParams); 100 | else 101 | contentResult = await _httpBeatsMusicEngine.GetAsyncNoToken(methodName, methodParams); 102 | 103 | var dataResponse = await contentResult.ReadAsStringAsync(); 104 | return dataResponse; 105 | } 106 | 107 | 108 | public async Task PostData(string methodName, List> dataParams) 109 | { 110 | if (dataParams == null) 111 | dataParams = new List>(); 112 | 113 | var httpResponse = await _httpBeatsMusicEngine.PostAsync(methodName, dataParams); 114 | var dataResponse = await httpResponse.ReadAsStringAsync(); 115 | 116 | if (dataResponse.ToLower().Contains("ok")) 117 | return true; 118 | return false; 119 | } 120 | 121 | public async Task PutData(string methodName, List> dataParams, 122 | bool addCredentials = true) 123 | { 124 | if (dataParams == null) 125 | dataParams = new List>(); 126 | 127 | var httpResponse = await _httpBeatsMusicEngine.PutAsync(methodName, dataParams, addCredentials); 128 | var dataResponse = await httpResponse.ReadAsStringAsync(); 129 | 130 | if (dataResponse.ToLower().Contains("ok")) 131 | return true; 132 | return false; 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/HttpBeatsMusicEngine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Net.Http.Headers; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 8 | using CodingChick.BeatsMusicAPI.Core.Helpers; 9 | 10 | namespace CodingChick.BeatsMusicAPI.Core.Base 11 | { 12 | //TODO: add assersions, lots of assersions 13 | internal class HttpBeatsMusicEngine : IHttpBeatsMusicEngine 14 | { 15 | private readonly IHttpClientAccessor _clientAccessor; 16 | private readonly Authorization _authorization; 17 | 18 | 19 | public string BaseApiAddress 20 | { 21 | get 22 | { 23 | return "https://partner.api.beatsmusic.com/"; 24 | } 25 | } 26 | 27 | public string MethodsApiAddress 28 | { 29 | get { return BaseApiAddress + "v1/api/"; } 30 | } 31 | 32 | public HttpBeatsMusicEngine(IHttpClientAccessor clientAccessor, Authorization authorization) 33 | { 34 | _clientAccessor = clientAccessor; 35 | _authorization = authorization; 36 | } 37 | 38 | public async Task GetAsyncNoToken(string method, List> queryParams) 39 | { 40 | queryParams.Add(new KeyValuePair("client_id", _authorization.ClientId)); 41 | 42 | var result = await GetAsync(method, queryParams); 43 | 44 | return result; 45 | } 46 | 47 | public async Task GetAsyncWithToken(string method, List> queryParams) 48 | { 49 | await AddAccessTokenToCall(queryParams); 50 | 51 | var result = await GetAsync(method, queryParams); 52 | 53 | return result; 54 | } 55 | 56 | public async Task GetHeaderAsyncWithNoToken(string method, 57 | List> queryParams) 58 | { 59 | queryParams.Add(new KeyValuePair("client_id", _authorization.ClientId)); 60 | 61 | var result = await GetHeaderAsync(method, queryParams); 62 | 63 | return result; 64 | 65 | } 66 | 67 | public async Task GetHeadAsyncWithToken(string method, 68 | List> queryParams) 69 | { 70 | await AddAccessTokenToCall(queryParams); 71 | 72 | var result = await GetHeaderAsync(method, queryParams); 73 | 74 | return result; 75 | 76 | } 77 | 78 | public async Task PostAsync(string method, List> dataParams) 79 | { 80 | await AddAccessTokenToCall(dataParams); 81 | var fullAddress = HttpUtilityHelper.CreateFullAddess(MethodsApiAddress, method, dataParams); 82 | var httpContent = new StringContent(string.Empty); 83 | 84 | var result = await _clientAccessor.PostAsync(fullAddress, httpContent); 85 | return result; 86 | } 87 | 88 | public async Task PutAsync(string method, List> dataParams, bool addCredentials = true) 89 | { 90 | if (addCredentials) 91 | await AddAccessTokenToCall(dataParams); 92 | var fullAddress = HttpUtilityHelper.CreateFullAddess(MethodsApiAddress, method, dataParams); 93 | var httpContent = new StringContent(string.Empty); 94 | 95 | var result = await _clientAccessor.PutAsync(fullAddress, httpContent); 96 | return result; 97 | } 98 | 99 | public async Task DeleteAsync(string method, List> dataParams) 100 | { 101 | await AddAccessTokenToCall(dataParams); 102 | var fullAddress = HttpUtilityHelper.CreateFullAddess(MethodsApiAddress, method, dataParams); 103 | 104 | var result = await _clientAccessor.DeleteAsync(fullAddress); 105 | return result; 106 | } 107 | 108 | 109 | public string UriAddressToNavigateForPermissions(ResponseType responseType) 110 | { 111 | _authorization.ResponseType = responseType; 112 | var authParams = _authorization.CreateAuthorizatioUriParams(responseType); 113 | return BaseApiAddress + _authorization.AuthorizatioUri + HttpUtilityHelper.ToQueryString(authParams); 114 | } 115 | 116 | private async Task GetAsync(string method, List> queryParams) 117 | { 118 | var finalAddress = HttpUtilityHelper.CreateFullAddess(MethodsApiAddress, method, queryParams); 119 | var result = await _clientAccessor.GetAsync(finalAddress); 120 | return result; 121 | } 122 | 123 | private async Task GetHeaderAsync(string method, 124 | List> queryParams) 125 | { 126 | var finalAddress = HttpUtilityHelper.CreateFullAddess(MethodsApiAddress, method, queryParams); 127 | var result = await _clientAccessor.GetHeaderAsync(finalAddress); 128 | return result; 129 | } 130 | 131 | private async Task AddAccessTokenToCall(List> dataParams) 132 | { 133 | if (_authorization.ReadOnlyAccessToken != null) 134 | dataParams.Add(new KeyValuePair("access_token", _authorization.ReadOnlyAccessToken)); 135 | else 136 | { 137 | if (_authorization.ReadWriteAccessToken == null || _authorization.NeedToRenewAccessToken) 138 | { 139 | var succeed = await RenewReadWriteAccessToken(); 140 | } 141 | dataParams.Add(new KeyValuePair("access_token", _authorization.ReadWriteAccessToken)); 142 | } 143 | } 144 | 145 | private async Task RenewReadWriteAccessToken() 146 | { 147 | var requestTokenUri = BaseApiAddress + _authorization.TokenUri; 148 | var requestParams = 149 | _authorization.GetAuthorizationTokenParams(); 150 | 151 | var response = 152 | await _clientAccessor.PostAsync(requestTokenUri, new FormUrlEncodedContent(requestParams)); 153 | 154 | return await _authorization.ParseAccessToken(response); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/HttpClientAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Net.Http.Headers; 5 | using System.Threading.Tasks; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Base 8 | { 9 | public class HttpClientAccessor : IHttpClientAccessor 10 | { 11 | private readonly HttpClient _httpClient; 12 | 13 | public HttpClientAccessor() 14 | { 15 | var httpClientHandler = new HttpClientHandler(); 16 | httpClientHandler.AllowAutoRedirect = false; 17 | _httpClient = new HttpClient(httpClientHandler); 18 | } 19 | 20 | public async Task GetAsync(string address) 21 | { 22 | return await GetAsync(address, new Dictionary>()); 23 | } 24 | 25 | public async Task GetAsync(string address, IDictionary> headers) 26 | { 27 | foreach (var header in headers) 28 | { 29 | _httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); 30 | } 31 | 32 | var response = await _httpClient.GetAsync(address); 33 | return response.Content; 34 | } 35 | 36 | 37 | public async Task DeleteAsync(string address) 38 | { 39 | return await DeleteAsync(address, new Dictionary>()); 40 | } 41 | 42 | public async Task DeleteAsync(string address, IDictionary> headers) 43 | { 44 | foreach (var header in headers) 45 | { 46 | _httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); 47 | } 48 | 49 | var response = await _httpClient.DeleteAsync(address); 50 | return response.Content; 51 | } 52 | 53 | public async Task GetHeaderAsync(string finalAddress) 54 | { 55 | //Would rather make this a true Head call, but the method isn't allowed so I am faking it 56 | var request = new HttpRequestMessage(HttpMethod.Get, new Uri(finalAddress, UriKind.Absolute)); 57 | var response = await _httpClient.SendAsync(request); 58 | 59 | return response.Headers; 60 | } 61 | 62 | public async Task PutAsync(string address, HttpContent content, string charSet = "", 63 | string mediaType = "") 64 | { 65 | AddHeadersToContent(content, charSet, mediaType); 66 | 67 | var response = await _httpClient.PutAsync(address, content); 68 | return response.Content; 69 | } 70 | 71 | 72 | public async Task PostAsync(string address, HttpContent content, 73 | string charSet = "", 74 | string mediaType = "") 75 | { 76 | AddHeadersToContent(content, charSet, mediaType); 77 | 78 | try 79 | { 80 | var client = new HttpClient(); 81 | var response = await client.PostAsync(address, content); 82 | return response.Content; 83 | } 84 | catch (Exception ex) 85 | { 86 | throw; 87 | } 88 | } 89 | 90 | private static void AddHeadersToContent(HttpContent content, string charSet, string mediaType) 91 | { 92 | if (charSet != string.Empty && mediaType != string.Empty) 93 | { 94 | content.Headers.ContentType.CharSet = charSet; 95 | content.Headers.ContentType.MediaType = mediaType; 96 | } 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/IBeatsHttpData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using CodingChick.BeatsMusicAPI.Core.Data; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Core.Base 6 | { 7 | internal interface IBeatsHttpData 8 | { 9 | Task> GetMultipleParsedResult(string methodName, List> methodParams, bool useToken = false); 10 | Task> GetSingleParsedResult(string methodName, List> methodParams, bool useToken = false); 11 | Task> PostData(string methodName, List> dataParams); 12 | Task> PutData(string methodName, List> dataParams, bool addCredentials = true); 13 | Task DeleteData(string methodName, List> dataParams); 14 | } 15 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/IBeatsMusicManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using CodingChick.BeatsMusicAPI.Core.Data; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Core.Base 6 | { 7 | internal interface IBeatsMusicManager 8 | { 9 | Task> GetMultipleParsedResult(string methodName, List> methodParams, bool useToken = false); 10 | Task> GetSingleParsedResult(string methodName, List> methodParams, bool useToken = false); 11 | Task> PostData(string methodName, List> dataParams); 12 | Task> PutData(string methodName, List> dataParams, bool addCredentials = true); 13 | Task DeleteData(string methodName, List> dataParams); 14 | } 15 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/IHttpBeatsMusicEngine.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net.Http; 3 | using System.Net.Http.Headers; 4 | using System.Threading.Tasks; 5 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Base 8 | { 9 | public interface IHttpBeatsMusicEngine 10 | { 11 | //Task GetAsyncWithToken(string methodAndParamethers); 12 | Task GetAsyncNoToken(string method, List> queryParams); 13 | string UriAddressToNavigateForPermissions(ResponseType responseType); 14 | Task PostAsync(string method, List> dataParams); 15 | Task GetAsyncWithToken(string method, List> queryParams); 16 | 17 | Task PutAsync(string method, List> dataParams, 18 | bool addCredentials = true); 19 | 20 | Task DeleteAsync(string method, List> dataParams); 21 | 22 | Task GetHeaderAsyncWithNoToken(string method, 23 | List> queryParams); 24 | 25 | Task GetHeadAsyncWithToken(string method, 26 | List> queryParams); 27 | } 28 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/IHttpClientAccessor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net.Http; 3 | using System.Net.Http.Headers; 4 | using System.Threading.Tasks; 5 | 6 | namespace CodingChick.BeatsMusicAPI.Core.Base 7 | { 8 | public interface IHttpClientAccessor 9 | { 10 | Task GetAsync(string address); 11 | Task GetAsync(string address, IDictionary> headers); 12 | 13 | Task PostAsync(string address, HttpContent content, 14 | string charSet = "", 15 | string mediaType = ""); 16 | Task PutAsync(string address, HttpContent content, string charSet = "", 17 | string mediaType = ""); 18 | Task DeleteAsync(string address); 19 | Task DeleteAsync(string address, IDictionary> headers); 20 | Task GetHeaderAsync(string finalAddress); 21 | } 22 | 23 | 24 | 25 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/IJsonBeatsMusicEngine.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Data; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Base 4 | { 5 | public interface IJsonBeatsMusicEngine 6 | { 7 | MultipleRootObject ParseMultipleDataResponse(string dataResponse); 8 | MultipleRootObject ParseMultipleDataResponseWithConverter(string dataResponse); 9 | SingleRootObject ParseSingleDataResponse(string dataResponse); 10 | } 11 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/JsonBeatsMusicEngine.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Base.JsonHelpers; 2 | using CodingChick.BeatsMusicAPI.Core.Data; 3 | using CodingChick.BeatsMusicAPI.Core.Data.Me; 4 | using Newtonsoft.Json; 5 | 6 | namespace CodingChick.BeatsMusicAPI.Core.Base 7 | { 8 | internal class JsonBeatsMusicEngine : IJsonBeatsMusicEngine 9 | { 10 | public MultipleRootObject ParseMultipleDataResponse(string dataResponse) 11 | { 12 | var parsedDataResponse = JsonConvert.DeserializeObject>(dataResponse, new JsonSerializerSettings() { ContractResolver = new UnderscoreResolver() }); 13 | return parsedDataResponse; 14 | } 15 | 16 | public MultipleRootObject ParseMultipleDataResponseWithConverter(string dataResponse) 17 | { 18 | var parsedDataResponse = JsonConvert.DeserializeObject>(dataResponse, new JsonSerializerSettings() { ContractResolver = new UnderscoreResolver(), Converters = new[] { new BaseDataConverter() } }); 19 | return parsedDataResponse; 20 | } 21 | 22 | public SingleRootObject ParseSingleDataResponse(string dataResponse) 23 | { 24 | // This is a very annoying fix to make sure API calls are consistent and all return "data", 25 | // and since "me" api is different in returning "result" I made sure all return the same. 26 | if (typeof(T) == typeof(MeData)) 27 | { 28 | dataResponse = dataResponse.Replace("result", "data"); 29 | } 30 | 31 | var parsedDataResponse = JsonConvert.DeserializeObject>(dataResponse, new JsonSerializerSettings() { ContractResolver = new UnderscoreResolver() }); 32 | return parsedDataResponse; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/JsonHelpers/BaseDataConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CodingChick.BeatsMusicAPI.Core.Data; 3 | using CodingChick.BeatsMusicAPI.Core.Data.Albums; 4 | using CodingChick.BeatsMusicAPI.Core.Data.Playlists; 5 | using Newtonsoft.Json.Linq; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Base.JsonHelpers 8 | { 9 | public class BaseDataConverter : JsonCreationConverter 10 | { 11 | protected override BaseConvertedData Create(Type objectType, JObject jObject) 12 | { 13 | if (FieldExists("essential", jObject)) 14 | { 15 | return new AlbumData(); 16 | } 17 | else if (FieldExists("user_display_name", jObject)) 18 | { 19 | return new PlaylistData(); 20 | } 21 | else 22 | { 23 | return new BaseConvertedData(); 24 | } 25 | } 26 | 27 | private bool FieldExists(string fieldName, JObject jObject) 28 | { 29 | return jObject[fieldName] != null; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/JsonHelpers/JsonCreationConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Linq; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Core.Base.JsonHelpers 6 | { 7 | public abstract class JsonCreationConverter : JsonConverter 8 | { 9 | /// 10 | /// Create an instance of objectType, based properties in the JSON object 11 | /// 12 | /// type of object expected 13 | /// 14 | /// contents of JSON object that will be deserialized 15 | /// 16 | /// 17 | protected abstract T Create(Type objectType, JObject jObject); 18 | 19 | public override bool CanConvert(Type objectType) 20 | { 21 | return typeof(T).IsAssignableFrom(objectType); 22 | } 23 | 24 | public override object ReadJson(JsonReader reader, 25 | Type objectType, 26 | object existingValue, 27 | JsonSerializer serializer) 28 | { 29 | // Load JObject from stream 30 | JObject jObject = JObject.Load(reader); 31 | 32 | // Create target object based on JObject 33 | T target = Create(objectType, jObject); 34 | 35 | // Populate the object properties 36 | serializer.Populate(jObject.CreateReader(), target); 37 | 38 | return target; 39 | } 40 | 41 | public override void WriteJson(JsonWriter writer, 42 | object value, 43 | JsonSerializer serializer) 44 | { 45 | throw new NotImplementedException(); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Base/JsonHelpers/UnderscoreResolver.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | using Newtonsoft.Json.Serialization; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Base.JsonHelpers 5 | { 6 | public class UnderscoreResolver : DefaultContractResolver 7 | { 8 | protected override string ResolvePropertyName(string propertyName) 9 | { 10 | string propertyNameNoUnderscore = 11 | Regex.Replace( 12 | propertyName, @"([A-Z])([A-Z][a-z])|([a-z])([A-Z])", "$3_$4"); 13 | return base.ResolvePropertyName(propertyNameNoUnderscore); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/BeatsMusicClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Threading.Tasks; 4 | using CodingChick.BeatsMusicAPI.Core.Base; 5 | using CodingChick.BeatsMusicAPI.Core.Data; 6 | using CodingChick.BeatsMusicAPI.Core.Data.Me; 7 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 8 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 9 | using CodingChick.BeatsMusicAPI.Core.Helpers; 10 | 11 | [assembly: InternalsVisibleTo("CodingChick.BeatsMusicAPI.Tests")] 12 | 13 | namespace CodingChick.BeatsMusicAPI.Core 14 | { 15 | public class BeatsMusicClient 16 | { 17 | private readonly Lazy _albums; 18 | private readonly Lazy _artists; 19 | private readonly Lazy _audio; 20 | private readonly Authorization _authorization; 21 | private readonly BeatsMusicManager _beatsMusicManager; 22 | private readonly Lazy _follow; 23 | private readonly Lazy _genre; 24 | private readonly Lazy _highlights; 25 | private readonly IHttpBeatsMusicEngine _httpBeatsMusicEngine; 26 | private readonly Lazy _images; 27 | private readonly Lazy _me; 28 | private readonly Lazy _playlists; 29 | private readonly Lazy _ratings; 30 | private readonly Lazy _search; 31 | private readonly Lazy _tracks; 32 | 33 | /// 34 | /// Initializes a new instance of for read-only operations. 35 | /// 36 | /// Beats Music API client ID. 37 | /// Beats Music Redirect Uri. 38 | public BeatsMusicClient(string clientId, string redirectUri) 39 | { 40 | _authorization = new Authorization(redirectUri, clientId); 41 | 42 | _httpBeatsMusicEngine = new HttpBeatsMusicEngine(new HttpClientAccessor(), _authorization); 43 | 44 | _beatsMusicManager = new BeatsMusicManager(_httpBeatsMusicEngine, new JsonBeatsMusicEngine()); 45 | _search = new Lazy(() => new SearchEndpoint(_beatsMusicManager)); 46 | _playlists = new Lazy(() => new PlaylistsEndpoint(_beatsMusicManager)); 47 | _albums = new Lazy(() => new AlbumsEndpoint(_beatsMusicManager)); 48 | _artists = new Lazy(() => new ArtistsEndpoint(_beatsMusicManager)); 49 | _highlights = new Lazy(() => new HighlightsEndpoint(_beatsMusicManager)); 50 | _follow = new Lazy(() => new FollowEndpoint(_beatsMusicManager)); 51 | _genre = new Lazy(() => new GenreEndpoint(_beatsMusicManager)); 52 | _audio = new Lazy(() => new AudioEndpoint(_beatsMusicManager)); 53 | _ratings = new Lazy(()=> new RatingsEndpoint(_beatsMusicManager)); 54 | _me = new Lazy(() => new MeEndpoint(_beatsMusicManager)); 55 | _images = new Lazy(() => new ImagesEndpoint(_beatsMusicManager)); 56 | _tracks = new Lazy(() => new TracksEndpoint(_beatsMusicManager)); 57 | } 58 | 59 | /// 60 | /// Initializes a new instance of for read-write and user specific operations. 61 | /// 62 | /// Beats Music API client ID. 63 | /// Beats Music API Redirect Uri. 64 | /// Beats Music API client secret 65 | public BeatsMusicClient(string clientId, string redirectUri, string clientSecret) 66 | : this(clientId, redirectUri) 67 | { 68 | _authorization.ClientSecret = clientSecret; 69 | } 70 | 71 | public MeEndpoint Me 72 | { 73 | get { return _me.Value; } 74 | } 75 | 76 | public AudioEndpoint Audio 77 | { 78 | get { return _audio.Value; } 79 | } 80 | 81 | public GenreEndpoint Genre 82 | { 83 | get { return _genre.Value; } 84 | } 85 | 86 | public FollowEndpoint Follow 87 | { 88 | get { return _follow.Value; } 89 | } 90 | 91 | public HighlightsEndpoint Highlights 92 | { 93 | get { return _highlights.Value; } 94 | } 95 | 96 | public AlbumsEndpoint Albums 97 | { 98 | get { return _albums.Value; } 99 | } 100 | 101 | public SearchEndpoint Search 102 | { 103 | get { return _search.Value; } 104 | } 105 | 106 | public PlaylistsEndpoint Playlists 107 | { 108 | get { return _playlists.Value; } 109 | } 110 | 111 | public RatingsEndpoint Ratings 112 | { 113 | get { return _ratings.Value; } 114 | } 115 | 116 | public ImagesEndpoint Images 117 | { 118 | get { return _images.Value; } 119 | } 120 | 121 | public TracksEndpoint Tracks 122 | { 123 | get { return _tracks.Value; } 124 | } 125 | 126 | public string ServerCode 127 | { 128 | get { return _authorization.Code; } 129 | set { _authorization.Code = value; } 130 | } 131 | 132 | public ArtistsEndpoint Artists 133 | { 134 | get { return _artists.Value; } 135 | } 136 | 137 | public string ClientId 138 | { 139 | get { return _authorization.ClientId; } 140 | } 141 | 142 | public string AccessToken 143 | { 144 | get 145 | { 146 | if (!string.IsNullOrEmpty(_authorization.ReadOnlyAccessToken)) 147 | return _authorization.ReadOnlyAccessToken; 148 | return _authorization.ReadWriteAccessToken; 149 | } 150 | } 151 | 152 | #region Internal 153 | 154 | internal string ReadWriteAccessToken 155 | { 156 | get { return _authorization.ReadWriteAccessToken; } 157 | set { _authorization.ReadWriteAccessToken = value; } 158 | } 159 | 160 | internal void SetExpiresAt(int seconds) 161 | { 162 | _authorization.SetExpiresAt(seconds); 163 | } 164 | 165 | #endregion 166 | 167 | public string UriAddressToNavigateForPermissions() 168 | { 169 | if (_authorization.ClientSecret == null) 170 | return _httpBeatsMusicEngine.UriAddressToNavigateForPermissions(ResponseType.Token); 171 | return _httpBeatsMusicEngine.UriAddressToNavigateForPermissions(ResponseType.Code); 172 | } 173 | 174 | public void SetClientAccessTokenFromRedirectUri(string accessToken, int expiresAt) 175 | { 176 | _authorization.ReadOnlyAccessToken = accessToken; 177 | _authorization.SetExpiresAt(expiresAt); 178 | } 179 | 180 | public async Task GetBeatsMusicPlayerCode(string playableResourceId) 181 | { 182 | var user = await Me.GetMeInfo(); 183 | var helper = new FileHelper(); 184 | var fileContents = helper.GetResourceTextFile("PlayerCode.html"); 185 | fileContents = fileContents.Replace("myClientId", _authorization.ClientId); 186 | fileContents = fileContents.Replace("myAccessToken", AccessToken); 187 | fileContents = fileContents.Replace("myUserId", user.Data.UserContext); 188 | fileContents = fileContents.Replace("myTrack", playableResourceId); 189 | return fileContents; 190 | } 191 | 192 | //Internal properties exposed for testing purposes only. 193 | } 194 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Activities/ActivityData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Activities 8 | { 9 | [JsonObject("Datum")] 10 | public class ActivityData : BaseData 11 | { 12 | public string Type { get; set; } 13 | public string Name { get; set; } 14 | public string Id { get; set; } 15 | public int CreatedAt { get; set; } 16 | public int TotalEditorialPlaylists { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Albums/AlbumData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Albums 8 | { 9 | [JsonObject("Datum")] 10 | public class AlbumData : BaseConvertedData 11 | { 12 | public string Title { get; set; } 13 | 14 | public int Duration { get; set; } 15 | 16 | public bool ParentalAdvisory { get; set; } 17 | 18 | public bool EditedVersion { get; set; } 19 | 20 | public string ReleaseDate { get; set; } 21 | 22 | public string ReleaseFormat { get; set; } 23 | 24 | public int Rating { get; set; } 25 | 26 | public int Popularity { get; set; } 27 | 28 | public bool Streamable { get; set; } 29 | public string ArtistDisplayName { get; set; } 30 | 31 | [JsonProperty("refs")] 32 | public AlbumRefs AlbumRefs { get; set; } 33 | 34 | public bool Canonical { get; set; } 35 | 36 | public int TotalCompanionAlbums { get; set; } 37 | 38 | public int TotalTracks { get; set; } 39 | 40 | public bool Essential { get; set; } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Albums/AlbumRefs.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Data.Albums 5 | { 6 | public class AlbumRefs 7 | { 8 | public List Artists { get; set; } 9 | public RefTypeInfo Label { get; set; } 10 | public List Tracks { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Artists/ArtistData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Artists 8 | { 9 | [JsonObject("Datum")] 10 | public class ArtistData : BaseData 11 | { 12 | public string Type { get; set; } 13 | public string Id { get; set; } 14 | public string Name { get; set; } 15 | public int Popularity { get; set; } 16 | public bool Streamable { get; set; } 17 | public string TotalAlbums { get; set; } 18 | public string TotalSingles { get; set; } 19 | public string TotalEps { get; set; } 20 | public string TotalLps { get; set; } 21 | public int TotalFreeplays { get; set; } 22 | public string TotalCompilations { get; set; } 23 | public string TotalTracks { get; set; } 24 | public ArtistRefs Refs { get; set; } 25 | public bool Verified { get; set; } 26 | public int TotalFollows { get; set; } 27 | public int TotalFollowedBy { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Artists/ArtistRefs.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data.Artists 4 | { 5 | public class ArtistRefs 6 | { 7 | public List Similars { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Audio/AudioData.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 2 | using Newtonsoft.Json; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Data.Audio 5 | { 6 | [JsonObject("Datum")] 7 | public class AudioData : BaseData 8 | { 9 | public string Location { get; set; } 10 | public string Resource { get; set; } 11 | public string Codec { get; set; } 12 | public int Bitrate { get; set; } 13 | public string Type { get; set; } 14 | public AudioRefs Refs { get; set; } 15 | 16 | } 17 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Audio/AudioRefs.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data.Audio 4 | { 5 | public class AudioRefs 6 | { 7 | public RefTypeInfo Track { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/BaseData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Linq; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Core.Data 6 | { 7 | public class BaseConvertedData : BaseData 8 | { 9 | public string Type { get; set; } 10 | 11 | public string Id { get; set; } 12 | } 13 | 14 | public abstract class BaseData 15 | { 16 | [JsonExtensionData] 17 | public IDictionary AdditionalData; 18 | } 19 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Content/ContentData.cs: -------------------------------------------------------------------------------- 1 |  2 | using Newtonsoft.Json; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Data.Content 5 | { 6 | [JsonObject("Datum")] 7 | public class ContentData : BaseData 8 | { 9 | public string Type { get; set; } 10 | public string Id { get; set; } 11 | public string Title { get; set; } 12 | public int Duration { get; set; } 13 | public bool ParentalAdvisory { get; set; } 14 | public bool EditedVersion { get; set; } 15 | public string ReleaseDate { get; set; } 16 | public string ReleaseFormat { get; set; } 17 | public int Rating { get; set; } 18 | public int Popularity { get; set; } 19 | public bool Streamable { get; set; } 20 | public string ArtistDisplayName { get; set; } 21 | public ContentRefs Refs { get; set; } 22 | public bool Canonical { get; set; } 23 | public int TotalCompanionAlbums { get; set; } 24 | public int TotalTracks { get; set; } 25 | public bool Essential { get; set; } 26 | public string Name { get; set; } 27 | public string Description { get; set; } 28 | public string UserDisplayName { get; set; } 29 | public string Access { get; set; } 30 | public int? TotalSubscribers { get; set; } 31 | public int? CreatedAt { get; set; } 32 | public int? UpdatedAt { get; set; } 33 | } 34 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Content/ContentRefs.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Data.Content 5 | { 6 | public class ContentRefs 7 | { 8 | public List Artists { get; set; } 9 | public RefTypeInfo Label { get; set; } 10 | public List Tracks { get; set; } 11 | public RefTypeInfo User { get; set; } 12 | public RefTypeInfo Author { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Genres/GenreData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Genres 8 | { 9 | [JsonObject("Datum")] 10 | public class GenreData : BaseData 11 | { 12 | public string Id { get; set; } 13 | public string Username { get; set; } 14 | public string Name { get; set; } 15 | public bool Verified { get; set; } 16 | public int TotalFollows { get; set; } 17 | public int TotalFollowedBy { get; set; } 18 | public int PlaylistCount { get; set; } 19 | public string Type { get; set; } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Info.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data 4 | { 5 | public class Info 6 | { 7 | public int Offset { get; set; } 8 | public int Count { get; set; } 9 | public int Total { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Me/MeData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Me 8 | { 9 | [JsonObject("Datum")] 10 | public class MeData : BaseData 11 | { 12 | public string ClientId { get; set; } 13 | 14 | public string TokenType { get; set; } 15 | 16 | public string GrantType { get; set; } 17 | 18 | public string Expires { get; set; } 19 | 20 | public string Scope { get; set; } 21 | 22 | public string UserContext { get; set; } 23 | 24 | public object Extended { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/MultipleRootObject.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Data 5 | { 6 | [JsonObject("RootObject")] 7 | public class MultipleRootObject : RootObject 8 | { 9 | public List Data { get; set; } 10 | 11 | public Info Info { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Player/PlayerCode.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | My Beats Music Player 4 | 5 | 6 | 7 | 48 | 49 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Playlists/PlaylistData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 6 | using Newtonsoft.Json; 7 | 8 | namespace CodingChick.BeatsMusicAPI.Core.Data.Playlists 9 | { 10 | [JsonObject("Datum")] 11 | public class PlaylistData : BaseConvertedData 12 | { 13 | public string Name { get; set; } 14 | public string Description { get; set; } 15 | public string UserDisplayName { get; set; } 16 | public string Access { get; set; } 17 | public int Duration { get; set; } 18 | public int TotalTracks { get; set; } 19 | public int TotalSubscribers { get; set; } 20 | public int CreatedAt { get; set; } 21 | public int UpdatedAt { get; set; } 22 | public bool ParentalAdvisory { get; set; } 23 | public PlaylistsRefs Refs { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Playlists/PlaylistsRefs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 6 | using Newtonsoft.Json; 7 | 8 | namespace CodingChick.BeatsMusicAPI.Core.Data.Playlists 9 | { 10 | public class PlaylistsRefs 11 | { 12 | public List Tracks { get; set; } 13 | public RefTypeInfo User { get; set; } 14 | public RefTypeInfo Author { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Ratings/RatingData.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 2 | using Newtonsoft.Json; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Data.Ratings 5 | { 6 | public class RatingData : BaseConvertedData 7 | { 8 | public int? UpdatedAt { get; set; } 9 | public RefTypeInfo Rated { get; set; } 10 | public Rating Rating { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/RefTypeInfo.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data 4 | { 5 | public class RefTypeInfo 6 | { 7 | public string RefType { get; set; } 8 | public string Id { get; set; } 9 | public string Display { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Reviews/ReviewData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Reviews 8 | { 9 | [JsonObject("Datum")] 10 | public class ReviewData : BaseData 11 | { 12 | public string Type { get; set; } 13 | public string Content { get; set; } 14 | public string Headline { get; set; } 15 | public string Rating { get; set; } 16 | public string Source { get; set; } 17 | public string Author { get; set; } 18 | public RefTypeInfo Subject { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/RootObject.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data 4 | { 5 | public abstract class RootObject 6 | { 7 | public string Code { get; set; } 8 | 9 | public bool HasErrors 10 | { 11 | get { return Code.ToLower() != "ok"; } 12 | } 13 | 14 | } 15 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Search/Related.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data.Search 4 | { 5 | public class Related 6 | { 7 | [JsonProperty("ref_type")] 8 | public string RefereceType { get; set; } 9 | public string Id { get; set; } 10 | public string Display { get; set; } 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Search/SearchData.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data.Search 4 | { 5 | [JsonObject("Datum")] 6 | public class SearchData : BaseData 7 | { 8 | public string Type { get; set; } 9 | public string ResultType { get; set; } 10 | public string Id { get; set; } 11 | public string Display { get; set; } 12 | public string Detail { get; set; } 13 | public Related Related { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/SingleRootObject.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Data 4 | { 5 | [JsonObject("RootObject")] 6 | public class SingleRootObject : RootObject 7 | { 8 | public T Data { get; set; } 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Tracks/TrackData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Tracks 8 | { 9 | [JsonObject("Datum")] 10 | public class TrackData : BaseData 11 | { 12 | public string Type { get; set; } 13 | public string Id { get; set; } 14 | public string Title { get; set; } 15 | public int DiscNumber { get; set; } 16 | public bool ParentalAdvisory { get; set; } 17 | public bool EditedVersion { get; set; } 18 | public int Duration { get; set; } 19 | public int TrackPosition { get; set; } 20 | public int Popularity { get; set; } 21 | public bool Streamable { get; set; } 22 | public string ReleaseDate { get; set; } 23 | public string ArtistDisplayName { get; set; } 24 | public TrackRefs Refs { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Tracks/TrackRefs.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 3 | using Newtonsoft.Json; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Core.Data.Tracks 6 | { 7 | public class TrackRefs 8 | { 9 | public List Artists { get; set; } 10 | public RefTypeInfo Album { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Data/Users/UserData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Newtonsoft.Json; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Data.Users 8 | { 9 | [JsonObject("Datum")] 10 | public class UserData : BaseData 11 | { 12 | public string Type { get; set; } 13 | public string Id { get; set; } 14 | public string Username { get; set; } 15 | public string FullName { get; set; } 16 | public int TotalFollowedBy { get; set; } 17 | public int TotalFollows { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/ActivitiesEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Threading.Tasks; 5 | using CodingChick.BeatsMusicAPI.Core.Base; 6 | using CodingChick.BeatsMusicAPI.Core.Data; 7 | using CodingChick.BeatsMusicAPI.Core.Data.Activities; 8 | 9 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 10 | { 11 | //TODO: add comments 12 | public class ActivitiesEndpoint : BaseEndpoint 13 | { 14 | 15 | internal ActivitiesEndpoint(BeatsMusicManager beatsMusicManager) : base(beatsMusicManager) 16 | { 17 | } 18 | 19 | public async Task> GetAllActivities() 20 | { 21 | return await BeatsMusicManager.GetMultipleParsedResult("activities", null); 22 | } 23 | 24 | public async Task> GetActivityById(string activityId) 25 | { 26 | Contract.Requires(!string.IsNullOrEmpty(activityId), "activityId should contain a value"); 27 | 28 | return await BeatsMusicManager.GetSingleParsedResult("activities/" + activityId, null); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/AlbumsEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using CodingChick.BeatsMusicAPI.Core.Base; 8 | using CodingChick.BeatsMusicAPI.Core.Data; 9 | using CodingChick.BeatsMusicAPI.Core.Data.Albums; 10 | using CodingChick.BeatsMusicAPI.Core.Data.Artists; 11 | using CodingChick.BeatsMusicAPI.Core.Data.Reviews; 12 | using CodingChick.BeatsMusicAPI.Core.Data.Tracks; 13 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 14 | using CodingChick.BeatsMusicAPI.Core.Helpers; 15 | 16 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 17 | { 18 | public class AlbumsEndpoint : BaseEndpoint 19 | { 20 | 21 | internal AlbumsEndpoint(BeatsMusicManager beatsMusicManager) 22 | : base(beatsMusicManager) 23 | { 24 | } 25 | 26 | /// 27 | /// You can retrieve part or all of the collection of albums in Beats, including those not available for streaming. 28 | /// 29 | /// Indicates how the results set should be sorted. 30 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 200. If a value higher than 200 is specified, no more 200 results will be returned. Default 20 31 | /// A zero-based integer offset into the results. Default 0. 32 | /// A Task containing a list of AlbumData 33 | public async Task> GetAlbumCollection(AlbumsOrderBy albumsOrderBy, int offset = 0, int limit = 20) 34 | { 35 | Contract.Requires(limit >= 0, "limit can only be a positive number"); 36 | Contract.Requires(offset >= 0, "offset can only be a positive number"); 37 | 38 | var methodParams = new List>(); 39 | methodParams = AddOffsetAndLimitParams(methodParams, offset, limit); 40 | methodParams = AddOrderByParam(albumsOrderBy, methodParams); 41 | 42 | 43 | return await BeatsMusicManager.GetMultipleParsedResult("albums", methodParams); 44 | } 45 | 46 | /// 47 | /// You can retrieve a single album from the collection of available albums. 48 | /// 49 | /// The unique ID of the album. 50 | /// 51 | //TODO: add the other two parameters (fields and refs) 52 | public async Task> GetAlbumById(string albumId) 53 | { 54 | Contract.Requires(!string.IsNullOrEmpty(albumId), "albumId is null or empty"); 55 | 56 | return 57 | await 58 | BeatsMusicManager.GetSingleParsedResult(GetSingleFirstLevelMethod(albumId), null); 59 | } 60 | 61 | public async Task> GetArtistsInAlbumId(string albumId) 62 | { 63 | Contract.Requires(!string.IsNullOrEmpty(albumId), "albumId is null or empty"); 64 | 65 | return 66 | await 67 | BeatsMusicManager.GetMultipleParsedResult(GetSingleFirstLevelMethod(albumId) + "/artists", null); 68 | } 69 | 70 | public async Task> GetTracksInAlbum(string albumId) 71 | { 72 | Contract.Requires(!string.IsNullOrEmpty(albumId), "albumId is null or empty"); 73 | 74 | return 75 | await 76 | BeatsMusicManager.GetMultipleParsedResult(GetSingleFirstLevelMethod(albumId) + "/tracks", null); 77 | } 78 | 79 | public async Task> GetReviewDataForAlbum(string albumId) 80 | { 81 | Contract.Requires(!string.IsNullOrEmpty(albumId), "albumId is null or empty"); 82 | 83 | return 84 | await 85 | BeatsMusicManager.GetSingleParsedResult(GetSingleFirstLevelMethod(albumId) + "/review", null); 86 | } 87 | 88 | public async Task> GetAllCompanionAlbums(string albumId) 89 | { 90 | Contract.Requires(!string.IsNullOrEmpty(albumId), "albumId is null or empty"); 91 | 92 | return 93 | await 94 | BeatsMusicManager.GetMultipleParsedResult(GetSingleFirstLevelMethod(albumId) + "/companion_albums", null); 95 | } 96 | 97 | private string GetSingleFirstLevelMethod(string albumId) 98 | { 99 | return "albums/" + albumId; 100 | } 101 | } 102 | 103 | 104 | 105 | 106 | } 107 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/AudioEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using CodingChick.BeatsMusicAPI.Core.Base; 7 | using CodingChick.BeatsMusicAPI.Core.Data; 8 | using CodingChick.BeatsMusicAPI.Core.Data.Audio; 9 | using CodingChick.BeatsMusicAPI.Core.Helpers; 10 | 11 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 12 | { 13 | public class AudioEndpoint : BaseEndpoint 14 | { 15 | internal AudioEndpoint(BeatsMusicManager beatsMusicManager) : base(beatsMusicManager) 16 | { 17 | } 18 | 19 | 20 | //TODO: finish the method params with the bitrate 21 | /// 22 | /// Gets the required information to play a track for a user by streaming the specified audio asset. 23 | /// 24 | /// The unique ID of the track. 25 | /// The desired bitrate of an audio asset. Values: lowest, highest 26 | /// Determines whether to automatically acquire streaming rights. Values: true, false. Default false. This parameter should only be used when: The user explicitly clicks on a play button. The audio stream request returns a StreamContention error. 27 | /// 28 | public async Task> GetAudioStreamingInfo(string trackId, Bitrate bitrate, 29 | bool aquire = false) 30 | { 31 | var methodParams = new List>() 32 | { 33 | new KeyValuePair("aquire", Convert.ToInt32(aquire).ToString()) 34 | }; 35 | 36 | return await BeatsMusicManager.GetSingleParsedResult(string.Format("tracks/{0}/audio", trackId), methodParams, 37 | true); 38 | } 39 | 40 | 41 | } 42 | 43 | public enum Bitrate 44 | { 45 | Lowest, 46 | Highest 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/BaseEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Linq; 5 | using CodingChick.BeatsMusicAPI.Core.Base; 6 | using CodingChick.BeatsMusicAPI.Core.Endpoints.DataFilters; 7 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 8 | using CodingChick.BeatsMusicAPI.Core.Helpers; 9 | 10 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 11 | { 12 | public class BaseEndpoint 13 | { 14 | private readonly BeatsMusicManager _beatsMusicManager; 15 | 16 | internal BaseEndpoint(BeatsMusicManager beatsMusicManager) 17 | { 18 | _beatsMusicManager = beatsMusicManager; 19 | } 20 | 21 | internal BeatsMusicManager BeatsMusicManager 22 | { 23 | get { return _beatsMusicManager; } 24 | } 25 | 26 | 27 | protected void AddStreamabilityFilterParams(StreamabilityFilters filters, List> methodParams) 28 | { 29 | if (filters != null) 30 | { 31 | foreach (string filterParam in filters.BuildParamsFromFilters()) 32 | { 33 | methodParams.Add(new KeyValuePair("filters", filterParam)); 34 | } 35 | } 36 | } 37 | 38 | protected List> CreateMethodParams(int offset, int limit, PlaylistRefType playlistRefType, AlbumsOrderBy orderBy) 39 | { 40 | var methodParams = new List>(); 41 | methodParams = AddOffsetAndLimitParams(methodParams, offset, limit); 42 | methodParams = AddOrderByParam(orderBy, methodParams); 43 | 44 | AddFlagedEnumValues(playlistRefType, methodParams); 45 | return methodParams; 46 | } 47 | 48 | protected List> AddOrderByParam(Enum orderBy, List> methodParams) 49 | { 50 | methodParams.Add(new KeyValuePair("order_by", 51 | ParamValueAttributeHelper.GetParamValueOfEnumAttribute( 52 | orderBy))); 53 | 54 | return methodParams; 55 | } 56 | 57 | protected List> AddFlagedEnumValues(Enum enumRefType, List> methodParams) 58 | { 59 | IEnumerable refsValues = EnumHelper.GetFlags(enumRefType); 60 | 61 | methodParams.AddRange( 62 | refsValues.Where(refsValue => !refsValue.HasFlag(PlaylistRefType.AllRefs)) 63 | .Select(refsValue => new KeyValuePair("refs", 64 | ParamValueAttributeHelper.GetParamValueOfEnumAttribute(refsValue)))); 65 | 66 | return methodParams; 67 | } 68 | 69 | protected List> AddOffsetAndLimitParams(List> methodParams, 70 | int offset, int limit) 71 | { 72 | methodParams.Add(new KeyValuePair("offset", offset.ToString())); 73 | methodParams.Add(new KeyValuePair("limit", limit.ToString())); 74 | return methodParams; 75 | } 76 | 77 | 78 | protected void ValidateIdOffsetLimit(int offset, int limit) 79 | { 80 | Contract.Requires(offset >= 0, "offset is set to less then zero"); 81 | Contract.Requires(limit > 0, "limit is set to zero or less"); 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/DataFilters/StreamabilityFilters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.DataFilters 4 | { 5 | public class StreamabilityFilters 6 | { 7 | public StreamabilityFilters(bool? streamable, bool? futureStreamable, bool? neverStreamable) 8 | { 9 | Streamable = streamable; 10 | FutureStreamable = futureStreamable; 11 | NeverStreamable = neverStreamable; 12 | } 13 | 14 | public bool? Streamable { get; set; } 15 | public bool? FutureStreamable { get; set; } 16 | public bool? NeverStreamable { get; set; } 17 | 18 | public List BuildParamsFromFilters() 19 | { 20 | var streamableParams = new List(); 21 | if (Streamable.HasValue) 22 | { 23 | streamableParams.Add("streamable:"+ Streamable.Value.ToString().ToLower()); 24 | } 25 | 26 | if (FutureStreamable.HasValue) 27 | { 28 | streamableParams.Add("future_streamable:" + FutureStreamable.Value.ToString().ToLower()); 29 | } 30 | 31 | if (NeverStreamable.HasValue) 32 | { 33 | streamableParams.Add("never_streamable:" + NeverStreamable.Value.ToString().ToLower()); 34 | } 35 | 36 | return streamableParams; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/AccessPrivilege.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Helpers; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 4 | { 5 | public enum AccessPrivilege 6 | { 7 | [ParamValue("public")] 8 | Public, 9 | [ParamValue("private")] 10 | Private 11 | } 12 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/AlbumRefType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CodingChick.BeatsMusicAPI.Core.Helpers; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 5 | { 6 | [Flags] 7 | public enum AlbumRefType 8 | { 9 | AllRefs = 1, 10 | [ParamValue("artists")] 11 | Artists = 2, 12 | [ParamValue("album")] 13 | Album = 4, 14 | [ParamValue("label")] 15 | Label = 8 16 | } 17 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/AlbumsOrderBy.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Helpers; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 4 | { 5 | public enum AlbumsOrderBy 6 | { 7 | [ParamValue("title asc")] 8 | TitleAscending, 9 | [ParamValue("title desc")] 10 | TitleDescending, 11 | [ParamValue("popularity asc")] 12 | PopularityAscending, 13 | [ParamValue("popularity desc")] 14 | PopularityDesc, 15 | [ParamValue("release_date asc")] 16 | ReleaseDateAscending, 17 | [ParamValue("release_date desc")] 18 | ReleaseDateDescending 19 | } 20 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/ArtistOrderBy.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Helpers; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 4 | { 5 | public enum ArtistOrderBy 6 | { 7 | [ParamValue("popularity desc")] 8 | PopularityDescending, 9 | [ParamValue("name asc")] 10 | NameAscending, 11 | [ParamValue("name desc")] 12 | NameDescending 13 | } 14 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/FollowType.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Helpers; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 4 | { 5 | public enum FollowType 6 | { 7 | [ParamValue("users")] 8 | User, 9 | [ParamValue("curators")] 10 | Curator, 11 | [ParamValue("genres")] 12 | Genre 13 | } 14 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/ImageSize.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using CodingChick.BeatsMusicAPI.Core.Helpers; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 8 | { 9 | public enum ImageSize 10 | { 11 | /// 12 | /// 180x80 13 | /// 14 | [ParamValue("thumb")] 15 | Thumbnail = 0, 16 | /// 17 | /// 190x230 18 | /// 19 | [ParamValue("small")] 20 | Small = 1, 21 | /// 22 | /// 375x250 23 | /// 24 | [ParamValue("medium")] 25 | Medium =2, 26 | /// 27 | /// 750x500 28 | /// 29 | [ParamValue("large")] 30 | Large = 3 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/PlaylistRefType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CodingChick.BeatsMusicAPI.Core.Helpers; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 5 | { 6 | [Flags] 7 | public enum PlaylistRefType 8 | { 9 | AllRefs = 1, 10 | [ParamValue("artists")] 11 | Artists = 2, 12 | [ParamValue("album")] 13 | Album = 4 14 | } 15 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/PlaylistsOrderBy.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Helpers; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 4 | { 5 | public enum PlaylistsOrderBy 6 | { 7 | [ParamValue("name asc")] 8 | NameAscending, 9 | [ParamValue("name desc")] 10 | NameDescending, 11 | [ParamValue("updated_at asc")] 12 | CreatedAtAscending, 13 | [ParamValue("created_at desc")] 14 | CreatedAtDescending, 15 | [ParamValue("updated_at asc")] 16 | UpdatedAtAscending, 17 | [ParamValue("updated_at desc")] 18 | UpdatedAtDescending, 19 | [ParamValue("duration asc")] 20 | DurationAscending, 21 | [ParamValue("duration desc")] 22 | DurationDescending, 23 | [ParamValue("total_tracks asc")] 24 | TotalTracksAscending, 25 | [ParamValue("total_tracks desc")] 26 | TotalTracksDescending 27 | } 28 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/Rating.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 7 | { 8 | public enum Rating 9 | { 10 | Love = 1, 11 | Hate = 0 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/ResponseType.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Helpers; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 4 | { 5 | public enum ResponseType 6 | { 7 | [ParamValue("token")] 8 | Token, 9 | [ParamValue("code")] 10 | Code 11 | } 12 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/TracksOrderByData.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Helpers; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 4 | { 5 | public enum TracksOrderByData 6 | { 7 | [ParamValue("track_position")] 8 | TrackPosition, 9 | [ParamValue("title asc")] 10 | TitleAscending, 11 | [ParamValue("title desc")] 12 | TitleDescending, 13 | [ParamValue("popularity asc")] 14 | PopularityAscending, 15 | [ParamValue("popularity desc")] 16 | PopularityDesc, 17 | [ParamValue("release_date asc")] 18 | ReleaseDateAscending, 19 | [ParamValue("release_date desc")] 20 | ReleaseDateDescending, 21 | [ParamValue("original_release_date")] 22 | OriginalReleaseDateAscending 23 | } 24 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/Enums/TracksRefType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CodingChick.BeatsMusicAPI.Core.Helpers; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints.Enums 5 | { 6 | [Flags] 7 | public enum TracksRefType 8 | { 9 | AllRefs = 1, 10 | [ParamValue("artists")] 11 | Artists = 2, 12 | [ParamValue("album")] 13 | Album = 4, 14 | [ParamValue("genres")] 15 | Genres = 8 16 | } 17 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/FollowEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CodingChick.BeatsMusicAPI.Core.Base; 3 | using CodingChick.BeatsMusicAPI.Core.Data.Content; 4 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 5 | using CodingChick.BeatsMusicAPI.Core.Helpers; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 8 | { 9 | //TODO: wonder why this enpoint doesn't seem to work 10 | public class FollowEndpoint : BaseEndpoint 11 | { 12 | internal FollowEndpoint(BeatsMusicManager beatsMusicManager) : base(beatsMusicManager) 13 | { 14 | } 15 | 16 | public async Task Follow(string userId, string followId, FollowType entityTypeToFollow) 17 | { 18 | string typeToFollow = ParamValueAttributeHelper.GetParamValueOfEnumAttribute(entityTypeToFollow); 19 | 20 | var result = 21 | await 22 | BeatsMusicManager.PutData( 23 | string.Format("{0}/{1}/follows/{2}", typeToFollow, userId, followId), null); 24 | 25 | return result.Code.ToLower() == "ok"; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/GenreEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using CodingChick.BeatsMusicAPI.Core.Base; 8 | using CodingChick.BeatsMusicAPI.Core.Data; 9 | using CodingChick.BeatsMusicAPI.Core.Data.Albums; 10 | using CodingChick.BeatsMusicAPI.Core.Data.Content; 11 | using CodingChick.BeatsMusicAPI.Core.Data.Genres; 12 | using CodingChick.BeatsMusicAPI.Core.Data.Playlists; 13 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 14 | 15 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 16 | { 17 | public class GenreEndpoint : BaseEndpoint 18 | { 19 | internal GenreEndpoint(BeatsMusicManager beatsMusicManager) : base(beatsMusicManager) 20 | { 21 | } 22 | 23 | /// 24 | /// Get an existing Beats genres. 25 | /// 26 | /// Unique ID of the genre. 27 | /// SingleRootObject with the relevant GenreData 28 | public async Task> GetGenreById(string genreId) 29 | { 30 | Contract.Requires(!string.IsNullOrEmpty(genreId), "genreId field is null or empty"); 31 | 32 | return await BeatsMusicManager.GetSingleParsedResult(string.Format("genres/{0}", genreId), null, false); 33 | } 34 | 35 | /// 36 | /// Get all genres 37 | /// 38 | /// Specifies the maximum number of records to retrieve. You are guaranteed to get at most this number of results, but you may get fewer. If set to zero or less, returns nothing. Maximum value is 200 (i.e., if greater than 200, returns only 200). Defaults to 20. 39 | /// Integer offset into results, 0 based. Defaults to 0. 40 | /// MultipleRootObject with the relevant GenreData 41 | public async Task> GetAllGenres(int limit = 20, int offset = 0) 42 | { 43 | var methodParams = ValidateAndCreateLimitOffsetParams(limit, offset); 44 | 45 | return await BeatsMusicManager.GetMultipleParsedResult("genres", methodParams); 46 | } 47 | 48 | private List> ValidateAndCreateLimitOffsetParams(int limit, int offset) 49 | { 50 | base.ValidateIdOffsetLimit(offset, limit); 51 | var methodParams = base.AddOffsetAndLimitParams(new List>(), offset, limit); 52 | return methodParams; 53 | } 54 | 55 | /// 56 | /// You can get a list of editor picks of tracks and albums within the Genres in Find It in the Beats Music app. 57 | /// 58 | /// The Id of the requested Genre 59 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 200. If a value higher than 200 is specified, no more 200 results will be returned. Default 20. 60 | /// A zero-based integer offset into the results. Default 0. 61 | /// A collection of AlbumData and PlaylistData 62 | public async Task> GetEditorPicksInGenre(string genreId, int limit = 20, int offset = 0) 63 | { 64 | return await RunMethodOnGenre("editors_picks", genreId, limit, offset); 65 | } 66 | 67 | private async Task> RunMethodOnGenre(string methodName, string genreId, int limit, int offset) 68 | { 69 | var methodParams = ValidateAndCreateLimitOffsetParams(limit, offset); 70 | return 71 | await 72 | BeatsMusicManager.GetMultipleParsedResultWithConverter( 73 | string.Format("genres/{0}/{1}", genreId, methodName), methodParams); 74 | } 75 | 76 | /// 77 | /// Gets a list of featured, tracks and albums. 78 | /// 79 | /// The Id of the requested Genre 80 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 200. If a value higher than 200 is specified, no more 200 results will be returned. Default 20. 81 | /// A zero-based integer offset into the results. Default 0. 82 | /// A collection of AlbumData and PlaylistData 83 | public async Task> GetFeaturedInGenre(string genreId, int limit = 20, 84 | int offset = 0) 85 | { 86 | return await RunMethodOnGenre("featured", genreId, limit, offset); 87 | } 88 | 89 | 90 | /// 91 | /// Gets a list of new releases, tracks and albums. 92 | /// 93 | /// The Id of the requested Genre 94 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 200. If a value higher than 200 is specified, no more 200 results will be returned. Default 20. 95 | /// A zero-based integer offset into the results. Default 0. 96 | /// A collection of AlbumData and PlaylistData 97 | public async Task> GetNewReleasesInGenre(string genreId, int limit = 20, 98 | int offset = 0) 99 | { 100 | return await RunMethodOnGenre("new_releases", genreId, limit, offset); 101 | } 102 | 103 | /// 104 | /// Get a list of playlists associated to the genre. 105 | /// 106 | /// Unique ID for Genre 107 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 200. If a value higher than 200 is specified, no more 200 results will be returned. Default 20. 108 | /// A zero-based integer offset into the results. Default 0. 109 | /// A zero-based integer offset into the results. Default 0. 110 | /// 111 | public async Task> GetAllPlaylistsInGenre(string genreId, int limit = 20, 112 | int offset = 0, PlaylistsOrderBy orderBy = PlaylistsOrderBy.NameAscending) 113 | { 114 | var methodParams = ValidateAndCreateLimitOffsetParams(limit, offset); 115 | methodParams = base.AddOrderByParam(orderBy, methodParams); 116 | 117 | return 118 | await 119 | BeatsMusicManager.GetMultipleParsedResult(string.Format("genres/{0}/playlists", genreId), 120 | methodParams); 121 | } 122 | 123 | //TODO: add bios method 124 | 125 | } 126 | 127 | 128 | 129 | 130 | 131 | } 132 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/HighlightsEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using CodingChick.BeatsMusicAPI.Core.Base; 6 | using CodingChick.BeatsMusicAPI.Core.Data; 7 | using CodingChick.BeatsMusicAPI.Core.Data.Content; 8 | 9 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 10 | { 11 | public class HighlightsEndpoint : BaseEndpoint 12 | { 13 | internal HighlightsEndpoint(BeatsMusicManager beatsMusicManager) : base(beatsMusicManager) 14 | { 15 | } 16 | 17 | /// 18 | /// You can retrieve the current Featured content, which has been selected by Beats Music editors. 19 | /// 20 | /// A collection of ContentData 21 | public async Task> GetFeaturedContent() 22 | { 23 | return await BeatsMusicManager.GetMultipleParsedResult("discoveries/featured", null); 24 | } 25 | 26 | 27 | public async Task> GetEditorPicksContent() 28 | { 29 | return await BeatsMusicManager.GetMultipleParsedResult("discoveries/editor_picks", null); 30 | 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/ImagesEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Threading.Tasks; 5 | using CodingChick.BeatsMusicAPI.Core.Base; 6 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 7 | using CodingChick.BeatsMusicAPI.Core.Helpers; 8 | 9 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 10 | { 11 | public class ImagesEndpoint : BaseEndpoint 12 | { 13 | internal ImagesEndpoint(BeatsMusicManager beatsMusicManager) 14 | : base(beatsMusicManager) 15 | { 16 | } 17 | 18 | /// 19 | /// Gets the Uri to the artist's image at the given size 20 | /// 21 | /// Id representing the artist with the desired image 22 | /// Size of the image desired 23 | /// Uri to the artist's image at the given size 24 | public async Task GetArtistImageUri(string artistId, ImageSize size = ImageSize.Medium) 25 | { 26 | ValidateResourceId(artistId); 27 | 28 | var method = string.Format("artists/{0}/images/default", 29 | artistId); 30 | 31 | var response = await GetResourceImageUri(method, size); 32 | 33 | return response; 34 | } 35 | 36 | /// 37 | /// Gets the Uri to the album's image at the given size 38 | /// 39 | /// Id representing the album with the desired image 40 | /// Size of the image desired 41 | /// Uri to the album's image at the given size 42 | public async Task GetAlbumImageUri(string albumId, ImageSize size = ImageSize.Medium) 43 | { 44 | ValidateResourceId(albumId); 45 | 46 | var method = string.Format("albums/{0}/images/default", albumId); 47 | 48 | var response = await GetResourceImageUri(method, size); 49 | 50 | return response; 51 | } 52 | 53 | /// 54 | /// Gets the Uri to the track's image at the given size 55 | /// 56 | /// Id representing the album with the desired image 57 | /// Size of the image desired 58 | /// Uri to the track's image at the given size 59 | public async Task GetTrackImageUri(string trackId, ImageSize size = ImageSize.Medium) 60 | { 61 | ValidateResourceId(trackId); 62 | 63 | var method = string.Format("tracks/{0}/images/default", trackId); 64 | 65 | var response = await GetResourceImageUri(method, size); 66 | 67 | return response; 68 | } 69 | 70 | /// 71 | /// Gets the Uri to the playlist's image at the given size 72 | /// 73 | /// Id representing the playlist with the desired image 74 | /// Size of the image desired 75 | /// Uri to the playlist's image at the given size 76 | public async Task GetPlaylistImageUri(string playlistId, ImageSize size = ImageSize.Medium) 77 | { 78 | ValidateResourceId(playlistId); 79 | 80 | var method = string.Format("playlists/{0}/images/default", playlistId); 81 | 82 | var response = await GetResourceImageUri(method, size); 83 | 84 | return response; 85 | } 86 | 87 | private static void ValidateResourceId(string resourceId) 88 | { 89 | Contract.Requires(!string.IsNullOrWhiteSpace(resourceId), 90 | "resource id is null or empty."); 91 | } 92 | 93 | private async Task GetResourceImageUri(string method, ImageSize size) 94 | { 95 | var dataParams = new List> 96 | { 97 | new KeyValuePair("size", 98 | ParamValueAttributeHelper.GetParamValueOfEnumAttribute(size)) 99 | }; 100 | 101 | var response = 102 | await 103 | BeatsMusicManager.GetDataUri(method, dataParams, false); 104 | return response; 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/MeEndoint.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Reflection; 3 | using System.Threading.Tasks; 4 | using CodingChick.BeatsMusicAPI.Core.Base; 5 | using CodingChick.BeatsMusicAPI.Core.Data; 6 | using CodingChick.BeatsMusicAPI.Core.Data.Me; 7 | 8 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 9 | { 10 | public class MeEndpoint : BaseEndpoint 11 | { 12 | internal MeEndpoint(BeatsMusicManager beatsMusicManager) : base(beatsMusicManager) 13 | { 14 | } 15 | 16 | /// 17 | /// You can retrieve information about an access token, including the user ID. 18 | /// 19 | /// 20 | public async Task> GetMeInfo() 21 | { 22 | return await BeatsMusicManager.GetSingleParsedResult("me", new List>(), true); 23 | } 24 | 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/RatingsEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Threading.Tasks; 5 | using CodingChick.BeatsMusicAPI.Core.Base; 6 | using CodingChick.BeatsMusicAPI.Core.Data; 7 | using CodingChick.BeatsMusicAPI.Core.Data.Ratings; 8 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 9 | 10 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 11 | { 12 | public class RatingsEndpoint : BaseEndpoint 13 | { 14 | internal RatingsEndpoint(BeatsMusicManager beatsMusicManager) 15 | : base(beatsMusicManager) 16 | { 17 | } 18 | 19 | /// 20 | /// Retrieve a single rating from a user 21 | /// 22 | /// The unique ID for the user. 23 | /// The unique ID for the rating. 24 | /// 25 | public async Task> GetRating(string userId, string ratingId) 26 | { 27 | ValidateUserIdRatingId(userId, ratingId); 28 | 29 | return await BeatsMusicManager.GetSingleParsedResult(GetMethodName(userId, ratingId), null, true); 30 | } 31 | 32 | /// 33 | /// Retrieve all the ratings from a user 34 | /// 35 | /// The unique ID for the user. 36 | /// A zero-based integer offset into the results. Default 0. 37 | /// 38 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less 39 | /// than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 40 | /// 200. If a value higher than 200 is specified, no more 200 results will be returned. Default 20. 41 | /// 42 | /// 43 | public async Task> GetAllRatings(string userId, int offset = 0, int limit = 20) 44 | { 45 | ValidateUserId(userId); 46 | ValidateIdOffsetLimit(offset, limit); 47 | 48 | var methodParams = new List>(); 49 | methodParams = AddOffsetAndLimitParams(methodParams, offset, limit); 50 | 51 | return 52 | await 53 | BeatsMusicManager.GetMultipleParsedResult(GetMethodName(userId), methodParams, true); 54 | } 55 | 56 | /// 57 | /// You can update an existing rating for the user 58 | /// 59 | /// The unique ID for the user. 60 | /// The unique ID for the rating. 61 | /// Rating to update the rating with. 62 | /// Updating rating as RatingData 63 | public async Task> UpdateRating(string userId, string ratingId, Rating newRating) 64 | { 65 | ValidateUserIdRatingId(userId, ratingId); 66 | 67 | var dataParams = new List> 68 | { 69 | new KeyValuePair("rating", ((int) newRating).ToString()) 70 | }; 71 | return 72 | await 73 | BeatsMusicManager.PutData(GetMethodName(userId, ratingId), dataParams); 74 | } 75 | 76 | /// 77 | /// You can delete an existing rating for the user 78 | /// 79 | /// The unique ID for the user. 80 | /// The unique ID for the rating. 81 | /// True if successful; otherwise false. 82 | public async Task DeleteRating(string userId, string ratingId) 83 | { 84 | ValidateUserIdRatingId(userId, ratingId); 85 | 86 | return await BeatsMusicManager.DeleteData(string.Format("users/{0}/ratings/{1}", userId, ratingId), null); 87 | } 88 | 89 | /// 90 | /// Get the method for the Rating endpoint 91 | /// 92 | /// The unique ID for the user. 93 | /// The unique ID for the rating. 94 | /// 95 | private static string GetMethodName(string userId, string ratingId = "") 96 | { 97 | return string.Format("users/{0}/ratings{1}", userId, string.IsNullOrWhiteSpace(ratingId) ? "" : string.Format("/{0}", ratingId)); 98 | } 99 | 100 | /// 101 | /// Validate the userId and ratingId fields 102 | /// 103 | /// The unique ID for the user. 104 | /// The unique ID for the rating. 105 | private static void ValidateUserIdRatingId(string userId, string ratingId) 106 | { 107 | Contract.Requires(!string.IsNullOrWhiteSpace(ratingId), 108 | "ratingId field is null or empty"); 109 | ValidateUserId(userId); 110 | } 111 | 112 | /// 113 | /// Validate the userId field 114 | /// 115 | /// The unique ID for the user. 116 | private static void ValidateUserId(string userId) 117 | { 118 | Contract.Requires(!string.IsNullOrWhiteSpace(userId), "userId field is null or empty"); 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/SearchEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using CodingChick.BeatsMusicAPI.Core.Base; 7 | using CodingChick.BeatsMusicAPI.Core.Data; 8 | using CodingChick.BeatsMusicAPI.Core.Data.Search; 9 | 10 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 11 | { 12 | public class SearchEndpoint : BaseEndpoint 13 | { 14 | internal SearchEndpoint(BeatsMusicManager beatsMusicManager) : base(beatsMusicManager) 15 | { 16 | } 17 | 18 | public async Task> SearchByArtist(string artistName) 19 | { 20 | Contract.Requires(!string.IsNullOrEmpty(artistName), "user field is empty"); 21 | return await GetSearchResult(artistName, "artist"); 22 | } 23 | 24 | public async Task> SearchByGenre(string genre) 25 | { 26 | Contract.Requires(!string.IsNullOrEmpty(genre), "user field is empty"); 27 | return await GetSearchResult(genre, "genre"); 28 | } 29 | 30 | public async Task> SearchByAlbum(string album) 31 | { 32 | Contract.Requires(!string.IsNullOrEmpty(album), "user field is empty"); 33 | 34 | return await GetSearchResult(album, "album"); 35 | } 36 | 37 | public async Task> SearchByTrack(string track) 38 | { 39 | Contract.Requires(!string.IsNullOrEmpty(track), "user field is empty"); 40 | 41 | return await GetSearchResult(track, "track"); 42 | } 43 | 44 | public async Task> SearchByPlaylist(string playlist) 45 | { 46 | Contract.Requires(!string.IsNullOrEmpty(playlist), "user field is empty"); 47 | 48 | return await GetSearchResult(playlist, "playlist"); 49 | } 50 | 51 | public async Task> SearchByUser(string user) 52 | { 53 | Contract.Requires(!string.IsNullOrEmpty(user), "user field is empty"); 54 | 55 | return await GetSearchResult(user, "user"); 56 | } 57 | 58 | private async Task> GetSearchResult(string queryParam, string queryType) 59 | { 60 | 61 | Dictionary searchParams = new Dictionary() 62 | { 63 | {"q", queryParam}, 64 | {"type", queryType} 65 | }; 66 | 67 | return await BeatsMusicManager.GetMultipleParsedResult("search", searchParams.ToList()); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Endpoints/TracksEndpoint.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics.Contracts; 4 | using System.Threading.Tasks; 5 | using CodingChick.BeatsMusicAPI.Core.Base; 6 | using CodingChick.BeatsMusicAPI.Core.Data; 7 | using CodingChick.BeatsMusicAPI.Core.Data.Tracks; 8 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 9 | 10 | namespace CodingChick.BeatsMusicAPI.Core.Endpoints 11 | { 12 | public class TracksEndpoint : BaseEndpoint 13 | { 14 | internal TracksEndpoint(BeatsMusicManager beatsMusicManager) 15 | : base(beatsMusicManager) 16 | { 17 | } 18 | 19 | /// 20 | /// You can retrieve a track. 21 | /// 22 | /// The unique ID for the track. 23 | /// Returns the track as TrackData 24 | public async Task> GetTrack(string trackId) 25 | { 26 | Contract.Requires(!string.IsNullOrWhiteSpace(trackId), "trackId is null or empty"); 27 | return 28 | await 29 | BeatsMusicManager.GetSingleParsedResult(string.Format("tracks/{0}", trackId), null, 30 | false); 31 | } 32 | 33 | /// 34 | /// You can retrieve the entire collection of tracks available in Beats Music. 35 | /// 36 | /// A zero-based integer offset into the results. Default 0 37 | /// 38 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less 39 | /// than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 40 | /// 200. If a value higher than 200 is specified, no more 200 results will be returned. Default 20. 41 | /// 42 | /// Indicates how the results set should be sorted. Values (default is TrackPosition) 43 | /// 44 | public async Task> GetTracks(int offset = 0, int limit = 20, 45 | TracksOrderByData tracksOrderByData = TracksOrderByData.PopularityDesc) 46 | { 47 | ValidateIdOffsetLimit(offset, limit); 48 | var methodParams = new List>(); 49 | methodParams = AddOffsetAndLimitParams(methodParams, offset, limit); 50 | methodParams = AddOrderByParam(tracksOrderByData, methodParams); 51 | 52 | return await BeatsMusicManager.GetMultipleParsedResult("tracks", methodParams); 53 | } 54 | 55 | /// 56 | /// You can get the tracks list in My Library. 57 | /// 58 | /// The unique ID for the user. 59 | /// A zero-based integer offset into the results. Default 0. 60 | /// 61 | /// Specifies the maximum number of records to retrieve. The number of results returned will be less 62 | /// than or equal to this value. No results are returned if it is set to zero or less. The maximum permitted value is 63 | /// 150. If a value higher than 150 is specified, no more 150 results will be returned. Default 40. 64 | /// 65 | /// 66 | public async Task> GetMyLibraryTracks(string userId, int offset = 0, 67 | int limit = 40) 68 | { 69 | Contract.Requires(!string.IsNullOrEmpty(userId), "userId field is null"); 70 | ValidateIdOffsetLimit(offset, limit); 71 | var methodParams = new List>(); 72 | methodParams = AddOffsetAndLimitParams(methodParams, offset, limit); 73 | 74 | return 75 | await 76 | BeatsMusicManager.GetMultipleParsedResult( 77 | string.Format("users/{0}/mymusic/tracks", userId), methodParams, true); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Helpers/EnumHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Core.Helpers 6 | { 7 | public class EnumHelper 8 | { 9 | public static IEnumerable GetFlags(Enum input) 10 | { 11 | foreach (var value in GetValues(input, typeof(T))) 12 | { 13 | if (input.HasFlag(value)) 14 | yield return value; 15 | } 16 | } 17 | 18 | 19 | public static IEnumerable GetValues(Enum input, Type enumType) 20 | { 21 | 22 | return from field in enumType.GetFields() 23 | where field.IsLiteral && !String.IsNullOrEmpty(field.Name) 24 | select (Enum)field.GetValue(null); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Helpers/FileHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace CodingChick.BeatsMusicAPI.Core.Helpers 8 | { 9 | public class FileHelper 10 | { 11 | public string GetResourceTextFile(string filename) 12 | { 13 | string result = string.Empty; 14 | //PlayerCode.html 15 | using (Stream stream = this.GetType().Assembly. 16 | GetManifestResourceStream("CodingChick.BeatsMusicAPI.Core.Data.Player." + filename)) 17 | { 18 | using (StreamReader sr = new StreamReader(stream)) 19 | { 20 | result = sr.ReadToEnd(); 21 | } 22 | } 23 | return result; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Helpers/HttpUtilityHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Core.Helpers 6 | { 7 | public class HttpUtilityHelper 8 | { 9 | public static string ToQueryString(List> queryParams) 10 | { 11 | StringBuilder queryParamsBuilder = new StringBuilder(); 12 | 13 | foreach (KeyValuePair keyValuePair in queryParams) 14 | { 15 | queryParamsBuilder.Append(string.Format("&{0}={1}", Uri.EscapeDataString(keyValuePair.Key), 16 | Uri.EscapeDataString(keyValuePair.Value))); 17 | } 18 | 19 | return queryParamsBuilder.ToString(); 20 | } 21 | 22 | public static string CreateFullAddess(string baseAddress, string method, List> queryParams) 23 | { 24 | StringBuilder addressCallBuilder = new StringBuilder(); 25 | addressCallBuilder.Append(baseAddress); 26 | addressCallBuilder.Append(method); 27 | addressCallBuilder.Append("?"); 28 | addressCallBuilder.Append(ToQueryString(queryParams)); 29 | 30 | return addressCallBuilder.ToString(); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Helpers/ParamValueAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodingChick.BeatsMusicAPI.Core.Helpers 4 | { 5 | public class ParamValueAttribute : Attribute 6 | { 7 | public ParamValueAttribute(string name) 8 | { 9 | Name = name; 10 | } 11 | 12 | public string Name { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Helpers/ParamValueAttributeHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 5 | 6 | namespace CodingChick.BeatsMusicAPI.Core.Helpers 7 | { 8 | public class ParamValueAttributeHelper 9 | { 10 | public static string GetParamValueOfEnumAttribute(Enum enumMember) 11 | { 12 | MemberInfo memberInfo = typeof(T).GetMember(enumMember.ToString()) 13 | .FirstOrDefault(); 14 | 15 | if (memberInfo != null) 16 | { 17 | ParamValueAttribute attribute = (ParamValueAttribute) 18 | memberInfo.GetCustomAttributes(typeof(ParamValueAttribute), false) 19 | .FirstOrDefault(); 20 | 21 | return attribute.Name; 22 | } 23 | 24 | return null; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("CodingChick.BeatsMusicAPI.Core")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("CodingChick.BeatsMusicAPI.Core")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Core/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/ArtistsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using CodingChick.BeatsMusicAPI.Core.Data; 7 | using CodingChick.BeatsMusicAPI.Core.Data.Artists; 8 | using CodingChick.BeatsMusicAPI.Core.Data.Audio; 9 | using CodingChick.BeatsMusicAPI.Core.Data.Playlists; 10 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 11 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 12 | using NUnit.Framework; 13 | 14 | namespace CodingChick.BeatsMusicAPI.Tests 15 | { 16 | public class ArtistsTests : BaseTest 17 | { 18 | [Test] 19 | public async void GetAllArtistsTest() 20 | { 21 | MultipleRootObject result = await Client.Artists.GetAllArtists(5, 10, ArtistOrderBy.NameAscending); 22 | 23 | } 24 | } 25 | 26 | 27 | public class AudioTests : BaseTest 28 | { 29 | [Test] 30 | public async void GetAudioStreamingInfoTest() 31 | { 32 | SingleRootObject result = await Client.Audio.GetAudioStreamingInfo("tr61032803", Bitrate.Highest, false); 33 | base.AssertResponseIsOK(result); 34 | Assert.IsTrue(result.Data.Refs.Track.Id == "tr61032803"); 35 | 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/AudioTests.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Data; 2 | using CodingChick.BeatsMusicAPI.Core.Data.Audio; 3 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 4 | using NUnit.Framework; 5 | 6 | namespace CodingChick.BeatsMusicAPI.Tests 7 | { 8 | public class AudioTests : BaseTest 9 | { 10 | [Test] 11 | public async void GetAudioStreamingInfoTest() 12 | { 13 | SingleRootObject result = await Client.Audio.GetAudioStreamingInfo("tr61032803", Bitrate.Highest, true); 14 | 15 | base.AssertResponseIsOK(result); 16 | Assert.IsTrue(result.Data.Refs.Track.Id == "tr61032803"); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/BaseTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CodingChick.BeatsMusicAPI.Core; 4 | using CodingChick.BeatsMusicAPI.Core.Data; 5 | using CodingChick.BeatsMusicAPI.Core.Data.Search; 6 | using NUnit.Framework; 7 | 8 | namespace CodingChick.BeatsMusicAPI.Tests 9 | { 10 | [TestFixture] 11 | public class BaseTest 12 | { 13 | 14 | private const string ClientId = ""; 15 | private const string ClientSecret = " "; 16 | private const string RedirectUrl = @" "; 17 | private const string Token = @""; 18 | private const string Code = @""; 19 | 20 | private BeatsMusicClient _client; 21 | public BeatsMusicClient Client { get { return _client; }} 22 | 23 | protected string[] TestStrings 24 | { 25 | get { return new[] { "foo", "hello", "world"}; } 26 | } 27 | 28 | [SetUp] 29 | public void Setup() 30 | { 31 | _client = new BeatsMusicClient(ClientId, RedirectUrl, ClientSecret); 32 | _client.ReadWriteAccessToken = Token; 33 | _client.ServerCode = Code; 34 | _client.SetExpiresAt(3600); 35 | } 36 | 37 | protected void AssertCollectionHasItems(List list) 38 | { 39 | Assert.IsTrue(list.Any()); 40 | } 41 | 42 | protected void AssertResponseIsOK(MultipleRootObject result) 43 | { 44 | Assert.IsFalse(result.HasErrors); 45 | } 46 | 47 | protected void AssertResponseIsOK(SingleRootObject result) 48 | { 49 | Assert.IsFalse(result.HasErrors); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/CodingChick.BeatsMusicAPI.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8} 8 | Library 9 | Properties 10 | CodingChick.BeatsMusicAPI.Tests 11 | CodingChick.BeatsMusicAPI.Tests 12 | v4.5 13 | 512 14 | ..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | False 37 | ..\packages\FakeItEasy.1.21.0\lib\net40\FakeItEasy.dll 38 | 39 | 40 | False 41 | ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll 42 | 43 | 44 | False 45 | ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll 46 | 47 | 48 | ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll 49 | 50 | 51 | False 52 | ..\packages\Newtonsoft.Json.6.0.3\lib\net45\Newtonsoft.Json.dll 53 | 54 | 55 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll 56 | 57 | 58 | 59 | 60 | 61 | 62 | False 63 | ..\packages\Microsoft.Net.Http.2.2.23-beta\lib\net45\System.Net.Http.Extensions.dll 64 | 65 | 66 | False 67 | ..\packages\Microsoft.Net.Http.2.2.23-beta\lib\net45\System.Net.Http.Primitives.dll 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | {2FFAEE12-A318-414D-AE3B-C666A4BBB589} 97 | CodingChick.BeatsMusicAPI.Core 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 123 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/FollowTests.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Data; 2 | using CodingChick.BeatsMusicAPI.Core.Data.Artists; 3 | using CodingChick.BeatsMusicAPI.Core.Data.Me; 4 | using CodingChick.BeatsMusicAPI.Core.Endpoints; 5 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 6 | using NUnit.Framework; 7 | 8 | namespace CodingChick.BeatsMusicAPI.Tests 9 | { 10 | public class FollowTests : BaseTest 11 | { 12 | [Test] 13 | public async void FollowTest() 14 | { 15 | //Arrange 16 | //users/154708885926576640/follows/eg109673939000754944 17 | //users/154708885926576640/follows/eg109673939000754944 18 | //Act 19 | bool result = await Client.Follow.Follow("154708885926576640", "eg109673939000754944", FollowType.User); 20 | 21 | //Assert 22 | Assert.IsTrue(result); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/GenreTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NUnit.Framework; 3 | 4 | namespace CodingChick.BeatsMusicAPI.Tests 5 | { 6 | public class GenreTests : BaseTest 7 | { 8 | [Test] 9 | public async void GetGenreByIdTest() 10 | { 11 | //Arrange 12 | 13 | //Act 14 | var result = await Client.Genre.GetGenreById("eg77531656377860096"); 15 | 16 | //Assert 17 | AssertResponseIsOK(result); 18 | Assert.IsTrue(result.Data.Id == "eg77531656377860096"); 19 | } 20 | 21 | [Test] 22 | public async void GetAllGenresTest() 23 | { 24 | //Arrange 25 | 26 | //Act 27 | var result = await Client.Genre.GetAllGenres(200); 28 | 29 | //Assert 30 | AssertResponseIsOK(result); 31 | AssertCollectionHasItems(result.Data); 32 | Assert.IsTrue(result.Data.Any(a => a.Id == "eg77531656377860096")); 33 | } 34 | 35 | [Test] 36 | public async void GetEditorPicksInGenreTest() 37 | { 38 | //Arrange 39 | 40 | //Act 41 | var result = await Client.Genre.GetEditorPicksInGenre("eg77531656377860096"); 42 | 43 | //Assert 44 | AssertResponseIsOK(result); 45 | AssertCollectionHasItems(result.Data); 46 | } 47 | 48 | [Test] 49 | public async void GetFeaturedInGenreTest() 50 | { 51 | //Arrange 52 | 53 | //Act 54 | var result = await Client.Genre.GetFeaturedInGenre("eg77531656377860096"); 55 | 56 | //Assert 57 | AssertResponseIsOK(result); 58 | AssertCollectionHasItems(result.Data); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/HightlightsTests.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Data; 2 | using CodingChick.BeatsMusicAPI.Core.Data.Content; 3 | using NUnit.Framework; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Tests 6 | { 7 | public class HightlightsTests : BaseTest 8 | { 9 | [Test] 10 | public async void GetFeaturedContentTest() 11 | { 12 | MultipleRootObject result = await Client.Highlights.GetFeaturedContent(); 13 | 14 | AssertResponseIsOK(result); 15 | AssertCollectionHasItems(result.Data); 16 | } 17 | 18 | [Test] 19 | public async void GetEditorPicksContentTest() 20 | { 21 | MultipleRootObject result = await Client.Highlights.GetEditorPicksContent(); 22 | 23 | AssertResponseIsOK(result); 24 | AssertCollectionHasItems(result.Data); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/ImagesTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CodingChick.BeatsMusicAPI.Core.Endpoints.Enums; 3 | using NUnit.Framework; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Tests 6 | { 7 | public class ImagesTests : BaseTest 8 | { 9 | [Test] 10 | public async void GetArtistImage() 11 | { 12 | var imageUri = await Client.Images.GetArtistImageUri("ar1033754", ImageSize.Large); 13 | Assert.IsNotNull(imageUri); 14 | } 15 | 16 | [Test] 17 | public async void GetAlbumImage() 18 | { 19 | var imageUri = await Client.Images.GetAlbumImageUri("al74961607", ImageSize.Large); 20 | Assert.IsNotNull(imageUri); 21 | } 22 | 23 | [Test] 24 | public async void GetTrackImage() 25 | { 26 | var imageUri = await Client.Images.GetTrackImageUri("tr82071543", ImageSize.Large); 27 | Assert.IsNotNull(imageUri); 28 | } 29 | 30 | [Test] 31 | public async void GetPlaylistImage() 32 | { 33 | var imageUri = await Client.Images.GetPlaylistImageUri("pl266636933575344128", ImageSize.Large); 34 | Assert.IsNotNull(imageUri); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/PlaylistTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CodingChick.BeatsMusicAPI.Core.Data; 3 | using CodingChick.BeatsMusicAPI.Core.Data.Playlists; 4 | using NUnit.Framework; 5 | 6 | namespace CodingChick.BeatsMusicAPI.Tests 7 | { 8 | public class PlaylistTests : BaseTest 9 | { 10 | private void DeletePlaylist(string id) 11 | { 12 | Client.Playlists.DeletePlaylist(id); 13 | } 14 | 15 | [Test] 16 | public async void AddTracksToPlaylist() 17 | { 18 | const string PlaylistName = "foo"; 19 | const string PlaylistDescription = "bar"; 20 | 21 | var originalPlaylist = 22 | await Client.Playlists.CreatePlaylist(PlaylistName, PlaylistDescription); 23 | 24 | AssertResponseIsOK(originalPlaylist); 25 | 26 | var trackIds = new List {"tr58141709", "tr63366021", "tr50508231"}; 27 | var tracksAdded = await Client.Playlists.AddTracksToPlaylist(originalPlaylist.Data.Id, trackIds); 28 | 29 | Assert.IsTrue(tracksAdded); 30 | var updatedPlaylistData = 31 | await Client.Playlists.GetPlaylist(originalPlaylist.Data.Id); 32 | AssertResponseIsOK(updatedPlaylistData); 33 | var updatedPlaylist = updatedPlaylistData.Data; 34 | Assert.AreEqual(trackIds.Count, updatedPlaylist.TotalTracks); 35 | DeletePlaylist(originalPlaylist.Data.Id); 36 | } 37 | 38 | [Test] 39 | public async void UpdateTracksInPlaylist() 40 | { 41 | const string PlaylistName = "foo"; 42 | const string PlaylistDescription = "bar"; 43 | 44 | var originalPlaylist = 45 | await Client.Playlists.CreatePlaylist(PlaylistName, PlaylistDescription); 46 | 47 | AssertResponseIsOK(originalPlaylist); 48 | 49 | var trackIds = new List { "tr58141709", "tr63366021", "tr50508231" }; 50 | var tracksUpdated = await Client.Playlists.UpdateTracksInPlaylist(originalPlaylist.Data.Id, trackIds); 51 | 52 | Assert.IsTrue(tracksUpdated); 53 | var updatedPlaylistData = 54 | await Client.Playlists.GetPlaylist(originalPlaylist.Data.Id); 55 | AssertResponseIsOK(updatedPlaylistData); 56 | var updatedPlaylist = updatedPlaylistData.Data; 57 | Assert.AreEqual(trackIds.Count, updatedPlaylist.TotalTracks); 58 | DeletePlaylist(originalPlaylist.Data.Id); 59 | } 60 | 61 | [Test] 62 | public async void CreatePlaylist() 63 | { 64 | const string PlaylistName = "foo"; 65 | const string PlaylistDescription = "bar"; 66 | 67 | var result = 68 | await Client.Playlists.CreatePlaylist(PlaylistName, PlaylistDescription); 69 | 70 | AssertResponseIsOK(result); 71 | Assert.IsTrue(result.Data.Name == PlaylistName); 72 | Assert.IsTrue(result.Data.Description == PlaylistDescription); 73 | 74 | DeletePlaylist(result.Data.Id); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/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("CodingChick.BeatsMusicAPI.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CodingChick.BeatsMusicAPI.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bd155edc-f010-4ff1-b200-5bb87090fc5a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/RatingTests.cs: -------------------------------------------------------------------------------- 1 | using CodingChick.BeatsMusicAPI.Core.Data; 2 | using CodingChick.BeatsMusicAPI.Core.Data.Ratings; 3 | using NUnit.Framework; 4 | 5 | namespace CodingChick.BeatsMusicAPI.Tests 6 | { 7 | public class RatingTests : BaseTest 8 | { 9 | 10 | [Test] 11 | public async void RetrieveRatings() 12 | { 13 | var result = await Client.Ratings.GetAllRatings("154708885926576640"); 14 | 15 | Assert.IsNotNull(result); 16 | Assert.IsNotNull(result.Data); 17 | Assert.AreNotEqual(0, result.Data.Count); 18 | 19 | } 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/SearchTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using CodingChick.BeatsMusicAPI.Core.Data; 9 | using CodingChick.BeatsMusicAPI.Core.Data.Search; 10 | using NUnit.Framework; 11 | 12 | namespace CodingChick.BeatsMusicAPI.Tests 13 | { 14 | public class SearchTests : BaseTest 15 | { 16 | private const string AlbumName = "Beat The Drum"; 17 | private const string ArtistName = "Runrig"; 18 | private const string AlbumId = "al4986113"; 19 | 20 | [Test] 21 | public async void SearchByAlbum() 22 | { 23 | MultipleRootObject result = await Client.Search.SearchByAlbum(AlbumName); 24 | 25 | AssertResponseIsOK(result); 26 | AssertCollectionHasItems(result.Data); 27 | Assert.True(result.Data.Any(r => r.Display.Contains(AlbumName))); 28 | Assert.True(result.Data.Any(r => r.Detail.Contains(ArtistName))); 29 | Assert.True(result.Data.Any(r => r.Id.Contains(AlbumId))); 30 | } 31 | 32 | private const string ArtistId = "ar208846"; 33 | 34 | [Test] 35 | public async void SearchByArtist() 36 | { 37 | var result = await Client.Search.SearchByArtist(ArtistName); 38 | 39 | AssertResponseIsOK(result); 40 | AssertCollectionHasItems(result.Data); 41 | Assert.True(result.Data.Any(r => r.Display.Contains(ArtistName))); 42 | Assert.True(result.Data.Any(r => r.Id.Contains(ArtistId))); 43 | } 44 | 45 | 46 | private const string GenreName = "Beats Hip-Hop"; 47 | private const string GenreDetail = "beatshiphop"; 48 | private const string GenreId = "eg97074088215970048"; 49 | 50 | [Test] 51 | public async void SearchByGenre() 52 | { 53 | var result = await Client.Search.SearchByGenre("hip"); 54 | 55 | AssertResponseIsOK(result); 56 | AssertCollectionHasItems(result.Data); 57 | Assert.True(result.Data.Any(r => r.Display.Contains(GenreName))); 58 | Assert.True(result.Data.Any(r => r.Detail.Contains(GenreDetail))); 59 | Assert.True(result.Data.Any(r => r.Id.Contains(GenreId))); 60 | } 61 | 62 | private const string PlaylistName = "Music for Power Tools"; 63 | private const string PlaylistDetail = "Pitchfork"; 64 | private const string PlaylistId = "pl142123717680431104"; 65 | 66 | [Test] 67 | public async void SearchByPlaylist() 68 | { 69 | var result = await Client.Search.SearchByPlaylist(PlaylistName); 70 | 71 | AssertResponseIsOK(result); 72 | AssertCollectionHasItems(result.Data); 73 | Assert.True(result.Data.Any(r => r.Display.Contains(PlaylistName))); 74 | Assert.True(result.Data.Any(r => r.Detail.Contains(PlaylistDetail))); 75 | Assert.True(result.Data.Any(r => r.Id.Contains(PlaylistId))); 76 | } 77 | 78 | private const string TrackName = "What's My Name?"; 79 | private const string TrackDetail = "Rihanna"; 80 | private const string TrackId = "tr57535983"; 81 | 82 | [Test] 83 | public async void SearchByTrack() 84 | { 85 | var result = await Client.Search.SearchByTrack(TrackName); 86 | 87 | AssertResponseIsOK(result); 88 | AssertCollectionHasItems(result.Data); 89 | Assert.True(result.Data.Any(r => r.Display.Contains(TrackName))); 90 | Assert.True(result.Data.Any(r => r.Detail.Contains(TrackDetail))); 91 | Assert.True(result.Data.Any(r => r.Id.Contains(TrackId))); 92 | 93 | } 94 | 95 | private const string UserDetail = "codingchick"; 96 | private const string UserName = "Efrat Barak"; 97 | private const string UserId = "154708885926576640"; 98 | 99 | [Test] 100 | public async void SearchByUser() 101 | { 102 | var result = await Client.Search.SearchByUser(UserDetail); 103 | 104 | AssertResponseIsOK(result); 105 | AssertCollectionHasItems(result.Data); 106 | Assert.True(result.Data.Any(r => r.Display.Contains(UserName))); 107 | Assert.True(result.Data.Any(r => r.Detail.Contains(UserDetail))); 108 | Assert.True(result.Data.Any(r => r.Id.Contains(UserId))); 109 | } 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/TracksTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using CodingChick.BeatsMusicAPI.Core.Data; 7 | using CodingChick.BeatsMusicAPI.Core.Data.Tracks; 8 | using NUnit.Framework; 9 | 10 | namespace CodingChick.BeatsMusicAPI.Tests 11 | { 12 | public class TracksTest : BaseTest 13 | { 14 | [Test] 15 | public async void GetTrack() 16 | { 17 | var data = await Client.Tracks.GetTrack("tr82071543"); 18 | 19 | AssertResponseIsOK(data); 20 | Assert.IsNotNull(data.Data); 21 | 22 | } 23 | 24 | [Test] 25 | public async void GetTracks() 26 | { 27 | var expected = 23; 28 | var data = await Client.Tracks.GetTracks(0, expected); 29 | 30 | AssertResponseIsOK(data); 31 | Assert.AreEqual(expected, data.Data.Count); 32 | } 33 | 34 | [Test] 35 | public async void GetMyLibraryTracks() 36 | { 37 | var data = await Client.Tracks.GetMyLibraryTracks("195706866226036992"); 38 | 39 | AssertResponseIsOK(data); 40 | Assert.IsNotNull(data.Data); 41 | Assert.AreNotEqual(0,data.Data.Count); 42 | 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/CodingChick.BeatsMusicAPI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30324.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{CAE07E72-EB1A-47F0-8849-248ECC5BF198}" 7 | ProjectSection(SolutionItems) = preProject 8 | .nuget\NuGet.Config = .nuget\NuGet.Config 9 | .nuget\NuGet.exe = .nuget\NuGet.exe 10 | .nuget\NuGet.targets = .nuget\NuGet.targets 11 | EndProjectSection 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodingChick.BeatsMusicAPI.Core", "CodingChick.BeatsMusicAPI.Core\CodingChick.BeatsMusicAPI.Core.csproj", "{2FFAEE12-A318-414D-AE3B-C666A4BBB589}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodingChick.BeatsMusicAPI.Tests", "CodingChick.BeatsMusicAPI.Tests\CodingChick.BeatsMusicAPI.Tests.csproj", "{9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8}" 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodingChick.BeatsMusic.WPFSample", "CodingChick.BeatsMusic.WPFSample\CodingChick.BeatsMusic.WPFSample.csproj", "{DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}" 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Debug|x86 = Debug|x86 23 | Release|Any CPU = Release|Any CPU 24 | Release|x86 = Release|x86 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {2FFAEE12-A318-414D-AE3B-C666A4BBB589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {2FFAEE12-A318-414D-AE3B-C666A4BBB589}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {2FFAEE12-A318-414D-AE3B-C666A4BBB589}.Debug|x86.ActiveCfg = Debug|Any CPU 30 | {2FFAEE12-A318-414D-AE3B-C666A4BBB589}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {2FFAEE12-A318-414D-AE3B-C666A4BBB589}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {2FFAEE12-A318-414D-AE3B-C666A4BBB589}.Release|x86.ActiveCfg = Release|Any CPU 33 | {9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8}.Debug|x86.ActiveCfg = Debug|Any CPU 36 | {9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {9B2CCCCD-AA35-4099-BD15-1CBD85F3E1C8}.Release|x86.ActiveCfg = Release|Any CPU 39 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Debug|x86.ActiveCfg = Debug|x86 42 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Debug|x86.Build.0 = Debug|x86 43 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Release|x86.ActiveCfg = Release|x86 46 | {DB560A02-E58B-4BAC-83E7-5FC79C64B7BF}.Release|x86.Build.0 = Release|x86 47 | EndGlobalSection 48 | GlobalSection(SolutionProperties) = preSolution 49 | HideSolutionNode = FALSE 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /CodingChick.BeatsMusicAPI/UpgradeLog.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coding-chick/BeatsMusicCSharp/148aff4d992e75f30b4e91b83e394c1bc76b5d4f/CodingChick.BeatsMusicAPI/UpgradeLog.htm -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Public License (MS-PL) 3 | . 4 | 5 | 6 | 7 | 8 | 9 | [OSI Approved License] 10 | 11 | 12 | 13 | This license governs use of the accompanying software. If you use the software, you 14 | accept this license. If you do not accept the license, do not use the software. 15 | 16 | 1. Definitions 17 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the 18 | same meaning here as under U.S. copyright law. 19 | A "contribution" is the original software, or any additions or changes to the software. 20 | A "contributor" is any person that distributes its contribution under this license. 21 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 22 | 23 | 2. Grant of Rights 24 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 25 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 26 | 27 | 3. Conditions and Limitations 28 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 29 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 30 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 31 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 32 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Beats Music C# API 2 | ================ 3 | 4 | BeatsMusic C# API is a .net framwork that accesses the Beats Music Developer API (@[https://developer.beatsmusic.com/](https://developer.beatsmusic.com/) 5 | ). It provides a consistent C# API and data types for the Beats Music REST API. This API is a portable C# class library which is designed to work in multiple .Net environments, including: 6 | * .Net framework 4.5 (desktop & web) 7 | * Silverlight 5 (web plguin) 8 | * Windows 8 (tablet) 9 | * Windows Phone Silverlight 8 (mobile) 10 | * Xamarin.Android 11 | * Xamarin.iOS 12 | 13 | # Getting started 14 | ### Getting Started #1: Get the framework 15 | To install BeatsMusicCSharpAPI, run the following command in Visual Studio's Package Manager Console. 16 | ![PM> Install-Package BeatsMusicCSharpAPI](http://i.imgur.com/L8LDmFk.png) 17 | PM> Install-Package BeatsMusicCSharpAPI 18 |
19 |
20 | 21 | ### Getting Started #2: Get Beats Music developer credentials 22 | In order to use this API you'll need to register and get credentials from the Beats Music Developer website (@[https://developer.beatsmusic.com/member/register](https://developer.beatsmusic.com/member/register)). What you need to obtain is your application's ClientId and optionally a ClientSecret. 23 |

24 | ![Beats Music Developer Credentials](http://i.imgur.com/HvRscvX.png) 25 |
26 |
27 | 28 | 29 | ### Getting Started #3: Initialize a BeatsMusicClient 30 | You will then use the ClientId and optionally the ClientSecret to initialize the BeatsMusicClient object which will serve as gateway to all the API calls. Depending on the security level you wish to give your application you can choose to embed your apps' ClientSecret and gain further access to the Beats Music developer APIs. 31 | 32 | ![Initialize a BeatsMusicClient](http://i.imgur.com/LL6pqfB.png) 33 | 34 | ### Getting Started #4: Do stuff 35 | That's it! You're ready to use API calls which do not require user- specific permissions. 36 | 37 | **Sample: Searching by artist** 38 | ![Searching by artist](http://i.imgur.com/t4MwrMb.png) 39 | 40 | **Sample: Fetching an album by ID** 41 | ![Fetching an album by ID](http://i.imgur.com/9cxICVJ.png) 42 | 43 | 44 | # Advanced actions and authentication 45 | ### Getting the authentication URI 46 | If you need to perform actions which would require user specific permissions you'll need to oauth your user to Beats Music. first, have your app navigate to Beats Music's OAuth webpage, with the OAuth login URL you obtain from the BeatsMusicClient. 47 | The URI address you recieve from the Beats Music client depends on which c'tor was used to intialize your client (with or without ClientSecret). 48 | ![Getting the authentication URI](http://i.imgur.com/oOJrh7M.png) 49 | 50 | ### Getting the authentication details from the redirected URI 51 | After the user inputs their credentials, the WebBrowser will be the redirected to your application's RedirectUri (again, the one inserted when creating BeatsMusicClient). The URI's query string parameters contain the relevant authorization information. Your application will need to provide that authorization information when making API calls. You will get the query string values and pass those to the BeatsMusicClient instance. Those values are again different if ClientSecret was provided. 52 | ![Getting the authentication details from the redirected URI](http://i.imgur.com/63xWRO9.png) 53 | 54 | ### Calling methods requiring OAuth 55 | After OAuthing your user you can invoke additional APIs (depends on the c'tor you've used for the BeatsMusicClient). 56 | ![Calling methods requiring OAuth](http://i.imgur.com/0r2NKl8.png) 57 | 58 | Obligatory Long Code Sample 59 | ------- 60 | 61 | ```csharp 62 | // Initialize a BeatsMusicClient object which will serve as the endpoint for accessing Beats Music API. 63 | BeatsMusicClient client = new BeatsMusicClient(ClientId, RedirectUrl, ClientSecret); 64 | 65 | //You can immediately call methods which do not require user permissions. 66 | MultipleRootObject result2 = await client.Search.SearchByArtist("Connie"); 67 | 68 | // If you need to use methods that require user permissions- 69 | // Get the address the web browser needs to navigate to for OAuth 2.0 protocol authentication. 70 | var addressString = client.UriAddressToNavigateForPermissions(); 71 | 72 | // Navigate to the BeatsMusic OAuth page. This code is browser/ platform- specific. 73 | BeatsMusicWebBrowser.Source = new Uri(addressString); 74 | 75 | // After the user logs in Beats Music using AOuth the redirected URL contains the authorization code you need to 76 | // provide the Beats Music API in order to make calls against the API. 77 | client.Code = queryStringParams.GetValues("code").FirstOrDefault(); 78 | 79 | // That's it, now you can use the API endpoints to make calls against the server. 80 | SingleRootObject result = await client.Audio.GetAudioStreamingInfo("tr61032803", Bitrate.Highest, true); 81 | ``` 82 | 83 | 84 | # Authentication levels 85 | There are two authentication levels you can use in your application: 86 | * Client Side Application (@[https://developer.beatsmusic.com/docs/read/getting_started/Client_Side_Applications](https://developer.beatsmusic.com/docs/read/getting_started/Client_Side_Applications)). This authentication requires your application to provide only the ClientId when initializing the client. It provides a short- term more limited access that is not renewable. 87 | * Web Server Application (@[https://developer.beatsmusic.com/docs/read/getting_started/Web_Server_Applications](https://developer.beatsmusic.com/docs/read/getting_started/Web_Server_Applications)). This authentication requires your application to provide ClientId and SecretId when initializing the client. It provides a long- term full access and renews automatically after timing out as long as the application is running. 88 | 89 | # Playing music 90 | 91 | There are two main ways to play music using the C# API, you can use any player that supports RMTP, or alternatively, you can use Beats JavaScript web player to play with (@ 92 | [https://developer.beatsmusic.com/docs/read/web_playback_api/Getting_Started](https://developer.beatsmusic.com/docs/read/web_plIfayback_api/Getting_Started)). 93 | 94 | ### Working with Beats' javascript web player 95 | You can get the basic javascript code you need to use in order to play a resource (like a track or a playlist), with all the parameters you need already set by calling the Client's 96 | GetBeatsMusicPlayerCode("playable resource") method, which returns a string containing the basic javascript code needed. 97 | 98 | ```csharp 99 | string beatsPlayer = await client.GetBeatsMusicPlayerCode("tr61032803"); 100 | ``` 101 | 102 | Which returns a string with the basic javascript player with all the parameters filled in and ready to play. 103 | 104 | ```html 105 | 106 | 107 | My Beats Music Player 108 | 109 | 110 | 111 | 152 | 153 | 154 | ``` 155 | 156 | Another option is to obtain all the needed parameters yourself and use them however you'd prefer, you will need: 157 | 158 | ![All details needed for web player to work](http://i.imgur.com/npWm3i5.jpg) 159 | 160 | 161 | ### Working with other players 162 | 163 | You can get the basic information needed to give to other players by using the API call GetAudioStreamingInfo in Audio. 164 | 165 | ```csharp 166 | SingleRootObject trackResult = 167 | await client.Audio.GetAudioStreamingInfo("tr61032803", Bitrate.Highest, true); 168 | ``` 169 | 170 | The result has parameters such as Data.Resource and Data.Location that you can provide alongside with the playable resource id to other players in order to play audio. 171 | 172 | For example if you want to use the SoundManager 2 (@[http://www.schillmania.com/projects/soundmanager2/](http://www.schillmania.com/projects/soundmanager2)), you will need to supply it those 3 parameters, so your javascript can look similar to this: 173 | 174 | ```js 175 | 176 | 192 | 193 | ``` --------------------------------------------------------------------------------