diff --git a/.nuget/NuGet.exe b/.nuget/NuGet.exe index 8d13fd8..324daa8 100644 Binary files a/.nuget/NuGet.exe and b/.nuget/NuGet.exe differ diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config new file mode 100644 index 0000000..c2abfb4 --- /dev/null +++ b/.vs/config/applicationhost.config @@ -0,0 +1,1030 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GiantBomb.Api.Tests/Core.cs b/GiantBomb.Api.Tests/Core.cs index 20186ad..efcb438 100644 --- a/GiantBomb.Api.Tests/Core.cs +++ b/GiantBomb.Api.Tests/Core.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using GiantBomb.Api.Tests.Support; using NUnit.Framework; using RestSharp; @@ -14,7 +15,7 @@ public class Core : TestBase [Test] public void giantbomb_should_respond_to_request() { - var request = new RestRequest(); + var request = new RestRequest(); request.Resource = "games"; var result = _client.Execute(request); @@ -22,5 +23,16 @@ public void giantbomb_should_respond_to_request() Assert.IsNotNull(result.Content); } + [Test] + public async Task giantbomb_should_respond_to_request_async() + { + var request = new RestRequest(); + request.Resource = "games"; + + var result = await _client.ExecuteAsync(request); + + Assert.IsNotNull(result.Content); + } + } } diff --git a/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj b/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj index 5081626..41816c5 100644 --- a/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj +++ b/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,10 +10,11 @@ Properties GiantBomb.Api.Tests GiantBomb.Api.Tests - v4.0 + v4.5.2 512 ..\..\GiantBomb-CSharp\ true + true @@ -23,6 +24,7 @@ DEBUG;TRACE prompt 4 + false pdbonly @@ -31,15 +33,16 @@ TRACE prompt 4 + false - False ..\packages\NUnit.2.6.4\lib\nunit.framework.dll + True - - False - ..\packages\RestSharp.105.0.1\lib\net4\RestSharp.dll + + ..\packages\RestSharp.105.1.0\lib\net452\RestSharp.dll + True @@ -62,12 +65,10 @@ - - Designer - Always + diff --git a/GiantBomb.Api.Tests/app.config b/GiantBomb.Api.Tests/app.config index 71eaee6..daaa64d 100644 --- a/GiantBomb.Api.Tests/app.config +++ b/GiantBomb.Api.Tests/app.config @@ -8,4 +8,4 @@ - + diff --git a/GiantBomb.Api.Tests/packages.config b/GiantBomb.Api.Tests/packages.config index 7733ef3..7fd2f62 100644 --- a/GiantBomb.Api.Tests/packages.config +++ b/GiantBomb.Api.Tests/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/GiantBomb.Api/Core.cs b/GiantBomb.Api/Core.cs index 50913bd..ea86710 100644 --- a/GiantBomb.Api/Core.cs +++ b/GiantBomb.Api/Core.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Net; using System.Reflection; using System.Text; +using System.Threading.Tasks; using GiantBomb.Api.Model; using RestSharp; @@ -19,7 +21,7 @@ public partial class GiantBombRestClient : IGiantBombRestClient { /// /// Your GiantBomb API token /// - private string ApiKey { get; set; } + private string ApiKey { get; set; } /// /// Create a new Rest client with your API token and custom base URL @@ -32,7 +34,7 @@ public GiantBombRestClient(string apiToken, Uri baseUrl) { var assembly = Assembly.GetExecutingAssembly(); var version = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion; - + _client = new RestClient { UserAgent = "giantbomb-csharp/" + version, @@ -58,8 +60,29 @@ public GiantBombRestClient(string apiToken) /// /// The type of object to create and populate with the returned data. /// The RestRequest to execute (will use client credentials) - public virtual T Execute(RestRequest request) where T : new() { - var response = _client.Execute(request); + public virtual T Execute(RestRequest request) where T : new() + { + return ExecuteAsync(request).Result; + } + + /// + /// Execute a manual REST request (async) + /// + /// The type of object to create and populate with the returned data. + /// The RestRequest to execute (will use client credentials) + public virtual async Task ExecuteAsync(RestRequest request) where T : new() + { + var response = await _client.ExecuteTaskAsync(request); + + if (response.Data == null) + { + throw new GiantBombHttpException(response.Content); + } + else if (response.StatusCode != HttpStatusCode.OK) + { + throw new GiantBombHttpException(response.ErrorMessage + ": " + response.Content); + } + return response.Data; } @@ -67,8 +90,18 @@ public GiantBombRestClient(string apiToken) /// Execute a manual REST request /// /// The RestRequest to execute (will use client credentials) - public virtual IRestResponse Execute(RestRequest request) { - return _client.Execute(request); + public virtual IRestResponse Execute(RestRequest request) + { + return ExecuteAsync(request).Result; + } + + /// + /// Execute a manual REST request (async) + /// + /// The RestRequest to execute (will use client credentials) + public virtual async Task ExecuteAsync(RestRequest request) + { + return await _client.ExecuteTaskAsync(request); } #endif @@ -124,25 +157,12 @@ private string BuildKeyValueListForUrl(IEnumerable GetListResource(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null) where TResult : new() { - var request = GetListResource(resource, page, pageSize, fieldList, sortOptions, filterOptions); - var results = Execute>(request); - - if (results != null && results.StatusCode == GiantBombBase.StatusOk) - return results.Results; - - if (results != null && results.StatusCode != GiantBombBase.StatusOk) - throw new GiantBombApiException(results.StatusCode, results.Error); - - return null; - } - public virtual RestRequest GetSingleResource(string resource, int resourceId, int id, string[] fieldList = null) { - var request = new RestRequest { + var request = new RestRequest { Resource = resource + "/{ResourceId}-{Id}/", DateFormat = "yyyy-MM-dd HH:mm:ss" }; - + request.AddUrlSegment("ResourceId", resourceId.ToString(CultureInfo.InvariantCulture)); request.AddUrlSegment("Id", id.ToString(CultureInfo.InvariantCulture)); @@ -152,9 +172,37 @@ public virtual RestRequest GetSingleResource(string resource, int resourceId, in return request; } - public virtual TResult GetSingleResource(string resource, int resourceId, int id, string[] fieldList = null) where TResult : class, new() { + public virtual IEnumerable GetListResource(string resource, int page = 1, + int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, + IDictionary sortOptions = null, IDictionary filterOptions = null) + where TResult : new() + { + return GetListResourceAsync(resource, page, pageSize, fieldList, sortOptions, filterOptions).Result; + } + + public virtual async Task> GetListResourceAsync(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null) where TResult : new() + { + var request = GetListResource(resource, page, pageSize, fieldList, sortOptions, filterOptions); + var results = await ExecuteAsync>(request); + + if (results != null && results.StatusCode == GiantBombBase.StatusOk) + return results.Results; + + if (results != null && results.StatusCode != GiantBombBase.StatusOk) + throw new GiantBombApiException(results.StatusCode, results.Error); + + return null; + } + + public virtual TResult GetSingleResource(string resource, int resourceId, int id, + string[] fieldList = null) where TResult : class, new() + { + return GetSingleResourceAsync(resource, resourceId, id, fieldList).Result; + } + + public virtual async Task GetSingleResourceAsync(string resource, int resourceId, int id, string[] fieldList = null) where TResult : class, new() { var request = GetSingleResource(resource, resourceId, id, fieldList); - var result = Execute>(request); + var result = await ExecuteAsync>(request); if (result != null && result.StatusCode == GiantBombBase.StatusOk) return result.Results; diff --git a/GiantBomb.Api/GiantBomb.Api.csproj b/GiantBomb.Api/GiantBomb.Api.csproj index 5b4325d..b06c7d7 100644 --- a/GiantBomb.Api/GiantBomb.Api.csproj +++ b/GiantBomb.Api/GiantBomb.Api.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,10 +10,11 @@ Properties GiantBomb.Api GiantBomb.Api - v4.0 + v4.5.2 512 ..\..\GiantBomb-CSharp\ true + true @@ -23,6 +24,7 @@ TRACE;DEBUG;FRAMEWORK prompt 4 + false pdbonly @@ -31,14 +33,15 @@ TRACE;FRAMEWORK prompt 4 + false ..\Dependencies\fastJSON.dll - - False - ..\packages\RestSharp.105.0.1\lib\net4\RestSharp.dll + + ..\packages\RestSharp.105.1.0\lib\net452\RestSharp.dll + True @@ -51,6 +54,7 @@ + diff --git a/GiantBomb.Api/GiantBomb.Api.nuspec b/GiantBomb.Api/GiantBomb.Api.nuspec index 444ae43..9e8c2ed 100644 --- a/GiantBomb.Api/GiantBomb.Api.nuspec +++ b/GiantBomb.Api/GiantBomb.Api.nuspec @@ -6,13 +6,15 @@ kayub GiantBomb.Api GiantBomb API (C#) - http://github.com/kamranayub/GiantBomb-CSharp + https://github.com/kamranayub/GiantBomb-CSharp + https://github.com/kamranayub/GiantBomb-CSharp/blob/master/LICENSE.txt false RestSharp-based API wrapper for the GiantBomb games database public API Copyright © kayub 2015 - Updated with fixes, see README. + For changes, see README. + giantbomb diff --git a/GiantBomb.Api/GiantBombHttpException.cs b/GiantBomb.Api/GiantBombHttpException.cs new file mode 100644 index 0000000..3bee728 --- /dev/null +++ b/GiantBomb.Api/GiantBombHttpException.cs @@ -0,0 +1,19 @@ +using System; + +namespace GiantBomb.Api +{ + public class GiantBombHttpException : Exception + { + public GiantBombHttpException(string content) + : base("GiantBomb HTTP Exception, bad request from API: " + content) + { + + } + + public GiantBombHttpException(string content, Exception innerEx) + : base("GiantBomb HTTP Exception, bad request from API: " + content, innerEx) + { + + } + } +} \ No newline at end of file diff --git a/GiantBomb.Api/IGiantBombRestClient.cs b/GiantBomb.Api/IGiantBombRestClient.cs index ffca8b9..ac796d2 100644 --- a/GiantBomb.Api/IGiantBombRestClient.cs +++ b/GiantBomb.Api/IGiantBombRestClient.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using GiantBomb.Api.Model; using RestSharp; @@ -20,11 +21,25 @@ public interface IGiantBombRestClient Platform GetPlatform(int id, string[] limitFields = null); /// - /// Gets list of games - /// + /// Gets a single platform + /// + /// The platform's ID + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task GetPlatformAsync(int id, string[] limitFields = null); + + /// + /// Gets list of platforms + /// /// IEnumerable GetPlatforms(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// + /// Gets list of platforms + /// + /// + Task> GetPlatformsAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// /// Get a region /// @@ -33,6 +48,14 @@ public interface IGiantBombRestClient /// Region GetRegion(int id, string[] limitFields = null); + /// + /// Get a region + /// + /// + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task GetRegionAsync(int id, string[] limitFields = null); + /// /// Gets list of regions /// @@ -42,6 +65,15 @@ public interface IGiantBombRestClient /// IEnumerable GetRegions(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// + /// Gets list of regions + /// + /// The page to retrieve + /// The number of results per page (default: 100) + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task> GetRegionsAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// /// Gets a game with the given ID /// @@ -50,15 +82,32 @@ public interface IGiantBombRestClient /// Game GetGame(int id, string[] limitFields = null); + /// + /// Gets a game with the given ID + /// + /// The ID of the game + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task GetGameAsync(int id, string[] limitFields = null); + /// /// Gets list of games - /// + /// /// The page to retrieve /// The number of results per page (default: 100) - /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. /// IEnumerable GetGames(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// + /// Gets list of games + /// + /// The page to retrieve + /// The number of results per page (default: 100) + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task> GetGamesAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// /// Gets a release with the given ID /// @@ -67,6 +116,14 @@ public interface IGiantBombRestClient /// Release GetRelease(int id, string[] limitFields = null); + /// + /// Gets a release with the given ID + /// + /// The ID of the release + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task GetReleaseAsync(int id, string[] limitFields = null); + /// /// Gets all releases for a game with the given ID (multiple requests) /// @@ -75,13 +132,29 @@ public interface IGiantBombRestClient /// IEnumerable GetReleasesForGame(int gameId, string[] limitFields = null); + /// + /// Gets all releases for a game with the given ID (multiple requests) + /// + /// The ID of the game to get releases for + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task> GetReleasesForGameAsync(int gameId, string[] limitFields = null); + + /// + /// Gets all releases for the given game (multiple requests) + /// + /// The game to get releases for + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + IEnumerable GetReleasesForGame(Game game, string[] limitFields = null); + /// /// Gets all releases for the given game (multiple requests) /// /// The game to get releases for /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. /// - IEnumerable GetReleasesForGame(Game game, string[] limitFields = null); + Task> GetReleasesForGameAsync(Game game, string[] limitFields = null); /// /// Searches for a game by keyword and gets paged results @@ -93,6 +166,16 @@ public interface IGiantBombRestClient /// IEnumerable SearchForGames(string query, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// + /// Searches for a game by keyword and gets paged results + /// + /// The search string + /// The page to retrieve + /// The number of results per page (default: 100) + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task> SearchForGamesAsync(string query, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null); + /// /// Searches for a game by keyword and recursively gets all results to enable sorting, filtering, etc. /// @@ -101,6 +184,14 @@ public interface IGiantBombRestClient /// IEnumerable SearchForAllGames(string query, string[] limitFields = null); + /// + /// Searches for a game by keyword and recursively gets all results to enable sorting, filtering, etc. + /// + /// + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + Task> SearchForAllGamesAsync(string query, string[] limitFields = null); + /// /// Gets a list resource request /// @@ -125,7 +216,20 @@ public interface IGiantBombRestClient /// Results will be filtered by the field name and value you specify /// A typed list of TResult IEnumerable GetListResource(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null) where TResult : new(); - + + /// + /// Gets a typed list from a GiantBomb list resource request + /// + /// The type of result you expect the request to result in + /// The resource name (e.g. "games") + /// The page to fetch (default: 1) + /// The number of results per page (default: 100) + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// Results will be sorted by field names in the order you specify + /// Results will be filtered by the field name and value you specify + /// A typed list of TResult + Task> GetListResourceAsync(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null) where TResult : new(); + /// /// Gets a single resource request /// @@ -147,6 +251,17 @@ public interface IGiantBombRestClient /// A REST request object TResult GetSingleResource(string resource, int resourceId, int id, string[] fieldList = null) where TResult : class, new(); + /// + /// Returns a single object from a resource + /// + /// The model of what you expect + /// The resource name (e.g. "game") + /// The resource type ID (e.g. 3030) + /// The ID of the resource + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// A REST request object + Task GetSingleResourceAsync(string resource, int resourceId, int id, string[] fieldList = null) where TResult : class, new(); + /// /// Execute a manual REST request /// @@ -154,10 +269,23 @@ public interface IGiantBombRestClient /// The RestRequest to execute (will use client credentials) T Execute(RestRequest request) where T : new(); + /// + /// Execute a manual REST request + /// + /// The type of object to create and populate with the returned data. + /// The RestRequest to execute (will use client credentials) + Task ExecuteAsync(RestRequest request) where T : new(); + /// /// Execute a manual REST request /// /// The RestRequest to execute (will use client credentials) IRestResponse Execute(RestRequest request); + + /// + /// Execute a manual REST request + /// + /// The RestRequest to execute (will use client credentials) + Task ExecuteAsync(RestRequest request); } } \ No newline at end of file diff --git a/GiantBomb.Api/Model/Game.cs b/GiantBomb.Api/Model/Game.cs index 252b3c6..16e10c0 100644 --- a/GiantBomb.Api/Model/Game.cs +++ b/GiantBomb.Api/Model/Game.cs @@ -34,4 +34,17 @@ public class Game { public string SiteDetailUrl { get; set; } public List SimilarGames { get; set; } } + + public class GameDistinctComparer : IEqualityComparer + { + public bool Equals(Game x, Game y) + { + return x.Id == y.Id; + } + + public int GetHashCode(Game obj) + { + return obj.Id.GetHashCode(); + } + } } diff --git a/GiantBomb.Api/Properties/AssemblyInfo.cs b/GiantBomb.Api/Properties/AssemblyInfo.cs index c3ef4bf..0125faf 100644 --- a/GiantBomb.Api/Properties/AssemblyInfo.cs +++ b/GiantBomb.Api/Properties/AssemblyInfo.cs @@ -12,6 +12,6 @@ [assembly: ComVisible(false)] [assembly: Guid("5d910805-e5ae-48f0-8e39-d37104d7a91e")] -[assembly: AssemblyVersion("2.1.0")] -[assembly: AssemblyFileVersion("2.1.0")] -[assembly: AssemblyInformationalVersion("2.1.0")] \ No newline at end of file +[assembly: AssemblyVersion("2.2.0")] +[assembly: AssemblyFileVersion("2.2.0")] +[assembly: AssemblyInformationalVersion("2.2.0")] \ No newline at end of file diff --git a/GiantBomb.Api/Resources/Games.cs b/GiantBomb.Api/Resources/Games.cs index 6937f7b..9958b41 100644 --- a/GiantBomb.Api/Resources/Games.cs +++ b/GiantBomb.Api/Resources/Games.cs @@ -2,21 +2,29 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using GiantBomb.Api.Model; using RestSharp; namespace GiantBomb.Api { public partial class GiantBombRestClient { - public Game GetGame(int id, string[] limitFields = null) { - return GetSingleResource("game", ResourceTypes.Games, id, limitFields); + + public Game GetGame(int id, string[] limitFields = null) + { + return GetGameAsync(id, limitFields).Result; } - public IEnumerable GetGames(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { - var liteGames = GetListResource("games", page, pageSize, limitFields); + public async Task GetGameAsync(int id, string[] limitFields = null) { + return await GetSingleResourceAsync("game", ResourceTypes.Games, id, limitFields); + } - if (liteGames == null) return null; + public IEnumerable GetGames(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) + { + return GetGamesAsync(page, pageSize, limitFields).Result; + } - return liteGames; + public async Task> GetGamesAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { + return await GetListResourceAsync("games", page, pageSize, limitFields); } } } diff --git a/GiantBomb.Api/Resources/Platforms.cs b/GiantBomb.Api/Resources/Platforms.cs index 993f6f9..53e6b8f 100644 --- a/GiantBomb.Api/Resources/Platforms.cs +++ b/GiantBomb.Api/Resources/Platforms.cs @@ -2,17 +2,29 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using GiantBomb.Api.Model; using RestSharp; namespace GiantBomb.Api { public partial class GiantBombRestClient { - public Platform GetPlatform(int id, string[] limitFields = null) { - return GetSingleResource("platform", ResourceTypes.Platforms, id, limitFields); + public Platform GetPlatform(int id, string[] limitFields = null) + { + return GetPlatformAsync(id, limitFields).Result; } - public IEnumerable GetPlatforms(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { - return GetListResource("platforms", page, pageSize, limitFields); + public async Task GetPlatformAsync(int id, string[] limitFields = null) { + return await GetSingleResourceAsync("platform", ResourceTypes.Platforms, id, limitFields); + } + + public IEnumerable GetPlatforms(int page = 1, int pageSize = GiantBombBase.DefaultLimit, + string[] limitFields = null) + { + return GetPlatformsAsync(page, pageSize, limitFields).Result; + } + + public async Task> GetPlatformsAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { + return await GetListResourceAsync("platforms", page, pageSize, limitFields); } } } diff --git a/GiantBomb.Api/Resources/Regions.cs b/GiantBomb.Api/Resources/Regions.cs index e843e92..92bee71 100644 --- a/GiantBomb.Api/Resources/Regions.cs +++ b/GiantBomb.Api/Resources/Regions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using GiantBomb.Api.Model; namespace GiantBomb.Api @@ -10,12 +11,22 @@ public partial class GiantBombRestClient { public Region GetRegion(int id, string[] limitFields = null) { - return GetSingleResource("region", ResourceTypes.Regions, id, limitFields); + return GetRegionAsync(id, limitFields).Result; + } + + public async Task GetRegionAsync(int id, string[] limitFields = null) + { + return await GetSingleResourceAsync("region", ResourceTypes.Regions, id, limitFields); } public IEnumerable GetRegions(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { - return GetListResource("regions", page, pageSize, limitFields); + return GetRegionsAsync(page, pageSize, limitFields).Result; + } + + public async Task> GetRegionsAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) + { + return await GetListResourceAsync("regions", page, pageSize, limitFields); } } } diff --git a/GiantBomb.Api/Resources/Releases.cs b/GiantBomb.Api/Resources/Releases.cs index 48d6417..659345d 100644 --- a/GiantBomb.Api/Resources/Releases.cs +++ b/GiantBomb.Api/Resources/Releases.cs @@ -2,28 +2,44 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using GiantBomb.Api.Model; namespace GiantBomb.Api { public partial class GiantBombRestClient { - public Release GetRelease(int id, string[] limitFields = null) { - return GetSingleResource("release", ResourceTypes.Releases, id, limitFields); + public Release GetRelease(int id, string[] limitFields = null) + { + return GetReleaseAsync(id, limitFields).Result; + } + + public async Task GetReleaseAsync(int id, string[] limitFields = null) { + return await GetSingleResourceAsync("release", ResourceTypes.Releases, id, limitFields); } public IEnumerable GetReleasesForGame(int gameId, string[] limitFields = null) + { + return GetReleasesForGameAsync(gameId, limitFields).Result; + } + + public async Task> GetReleasesForGameAsync(int gameId, string[] limitFields = null) { var filter = new Dictionary() { {"game", gameId} }; - return GetListResource("releases", fieldList: limitFields, filterOptions: filter); + return await GetListResourceAsync("releases", fieldList: limitFields, filterOptions: filter); } public IEnumerable GetReleasesForGame(Game game, string[] limitFields = null) { return GetReleasesForGame(game.Id, limitFields); } + + public Task> GetReleasesForGameAsync(Game game, string[] limitFields = null) + { + return GetReleasesForGameAsync(game.Id, limitFields); + } } } diff --git a/GiantBomb.Api/Resources/Search.cs b/GiantBomb.Api/Resources/Search.cs index 003bbf4..483537a 100644 --- a/GiantBomb.Api/Resources/Search.cs +++ b/GiantBomb.Api/Resources/Search.cs @@ -2,13 +2,20 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using GiantBomb.Api.Model; using RestSharp; namespace GiantBomb.Api { public partial class GiantBombRestClient { - public IEnumerable SearchForGames(string query, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { - var result = InternalSearchForGames(query, page, pageSize, limitFields); + + public IEnumerable SearchForGames(string query, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) + { + return SearchForGamesAsync(query, page, pageSize, limitFields).Result; + } + + public async Task> SearchForGamesAsync(string query, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { + var result = await InternalSearchForGames(query, page, pageSize, limitFields); if (result.StatusCode == GiantBombBase.StatusOk) return result.Results; @@ -16,18 +23,14 @@ public IEnumerable SearchForGames(string query, int page = 1, int pageSize return null; } - internal GiantBombResults InternalSearchForGames(string query, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { - var request = GetListResource("search", page, pageSize, limitFields); - - request.AddParameter("query", query); - request.AddParameter("resources", "game"); - - return Execute>(request); + public IEnumerable SearchForAllGames(string query, string[] limitFields = null) + { + return SearchForAllGamesAsync(query, limitFields).Result; } - public IEnumerable SearchForAllGames(string query, string[] limitFields = null) { + public async Task> SearchForAllGamesAsync(string query, string[] limitFields = null) { var results = new List(); - var result = InternalSearchForGames(query, limitFields: limitFields); + var result = await InternalSearchForGames(query, limitFields: limitFields); if (result == null || result.StatusCode != GiantBombBase.StatusOk) return null; @@ -39,7 +42,7 @@ public IEnumerable SearchForAllGames(string query, string[] limitFields = // Start on page 2 for (var i = 2; i <= remaining; i++) { - result = InternalSearchForGames(query, i, result.Limit, limitFields); + result = await InternalSearchForGames(query, i, result.Limit, limitFields); if (result.StatusCode != GiantBombBase.StatusOk) break; @@ -48,7 +51,24 @@ public IEnumerable SearchForAllGames(string query, string[] limitFields = } } + // FIX: Clean duplicates that GiantBomb returns + // Can only do it if we have IDs in the resultset + if (limitFields == null || limitFields.Contains("id")) + { + results = results.Distinct(new GameDistinctComparer()).ToList(); + } + return results; } + + internal async Task> InternalSearchForGames(string query, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) + { + var request = GetListResource("search", page, pageSize, limitFields); + + request.AddParameter("query", query); + request.AddParameter("resources", "game"); + + return await ExecuteAsync>(request); + } } } diff --git a/GiantBomb.Api/packages.config b/GiantBomb.Api/packages.config index 46fa071..70eb09e 100644 --- a/GiantBomb.Api/packages.config +++ b/GiantBomb.Api/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/GiantBomb.Api/readme.txt b/GiantBomb.Api/readme.txt index 4ed10b0..ca2d59d 100644 --- a/GiantBomb.Api/readme.txt +++ b/GiantBomb.Api/readme.txt @@ -1,6 +1,16 @@ GiantBomb C# ------------ +## 2.2.0 + +- Upgrade to .NET 4.5.2 (you should too!) +- Upgrade RestSharp to 105.1 +- `async/await` support for all methods +- Better fatal error handling + - If GiantBomb returns a non-JSON response, the library will throw a `GiantBombHttpException` + containing the raw response body +- **FIX:** Issue with searches returning duplicate games from GiantBomb + ## 2.1.0 - Add new fields: diff --git a/GiantBomb.sln b/GiantBomb.sln index bf0786e..af3280f 100644 --- a/GiantBomb.sln +++ b/GiantBomb.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api", "GiantBomb.Api\GiantBomb.Api.csproj", "{9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api.Tests", "GiantBomb.Api.Tests\GiantBomb.Api.Tests.csproj", "{1B4925AE-F785-4F8D-AFBE-8FAEF0980946}" @@ -25,17 +27,57 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|Mixed Platforms = Release|Mixed Platforms + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|ARM.Build.0 = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|x64.ActiveCfg = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|x64.Build.0 = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|x86.ActiveCfg = Debug|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Debug|x86.Build.0 = Debug|Any CPU {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|Any CPU.ActiveCfg = Release|Any CPU {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|Any CPU.Build.0 = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|ARM.ActiveCfg = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|ARM.Build.0 = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|x64.ActiveCfg = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|x64.Build.0 = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|x86.ActiveCfg = Release|Any CPU + {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB}.Release|x86.Build.0 = Release|Any CPU {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|ARM.Build.0 = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|x64.ActiveCfg = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|x64.Build.0 = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|x86.ActiveCfg = Debug|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Debug|x86.Build.0 = Debug|Any CPU {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|Any CPU.Build.0 = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|ARM.ActiveCfg = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|ARM.Build.0 = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|x64.ActiveCfg = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|x64.Build.0 = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|x86.ActiveCfg = Release|Any CPU + {1B4925AE-F785-4F8D-AFBE-8FAEF0980946}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Readme.md b/Readme.md index 4ed10b0..ca2d59d 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,16 @@ GiantBomb C# ------------ +## 2.2.0 + +- Upgrade to .NET 4.5.2 (you should too!) +- Upgrade RestSharp to 105.1 +- `async/await` support for all methods +- Better fatal error handling + - If GiantBomb returns a non-JSON response, the library will throw a `GiantBombHttpException` + containing the raw response body +- **FIX:** Issue with searches returning duplicate games from GiantBomb + ## 2.1.0 - Add new fields: