From b0429564a97331c106ef82b6c191bb1dd33de877 Mon Sep 17 00:00:00 2001 From: Kamran Ayub Date: Fri, 26 May 2017 12:17:12 -0500 Subject: [PATCH 1/4] Switch to .NET Standard 1.2 --- GiantBomb.Api.NetStandard/Core.cs | 277 +++++++++++++++++ .../GiantBomb.Api.csproj | 31 ++ .../GiantBomb.Api.nuspec | 33 ++ .../GiantBombApiException.cs | 15 + .../GiantBombDeserializer.cs | 21 ++ .../GiantBombHttpException.cs | 19 ++ .../IGiantBombRestClient.cs | 291 ++++++++++++++++++ GiantBomb.Api.NetStandard/Model/Developer.cs | 8 + GiantBomb.Api.NetStandard/Model/Franchise.cs | 21 ++ GiantBomb.Api.NetStandard/Model/Game.cs | 59 ++++ GiantBomb.Api.NetStandard/Model/Genre.cs | 10 + .../Model/GiantBombBase.cs | 33 ++ GiantBomb.Api.NetStandard/Model/Image.cs | 16 + GiantBomb.Api.NetStandard/Model/Platform.cs | 24 ++ GiantBomb.Api.NetStandard/Model/Publisher.cs | 8 + GiantBomb.Api.NetStandard/Model/Rating.cs | 7 + GiantBomb.Api.NetStandard/Model/Region.cs | 11 + GiantBomb.Api.NetStandard/Model/Release.cs | 33 ++ GiantBomb.Api.NetStandard/ResourceTypes.cs | 9 + GiantBomb.Api.NetStandard/Resources/Games.cs | 30 ++ .../Resources/Platforms.cs | 30 ++ .../Resources/Regions.cs | 32 ++ .../Resources/Releases.cs | 45 +++ GiantBomb.Api.NetStandard/Resources/Search.cs | 75 +++++ GiantBomb.Api.Tests/Core.cs | 3 +- .../GiantBomb.Api.Tests.csproj | 25 +- GiantBomb.Api.Tests/TestBase.cs | 2 +- GiantBomb.Api.Tests/packages.config | 4 +- GiantBomb.sln | 93 ++---- 29 files changed, 1182 insertions(+), 83 deletions(-) create mode 100644 GiantBomb.Api.NetStandard/Core.cs create mode 100644 GiantBomb.Api.NetStandard/GiantBomb.Api.csproj create mode 100644 GiantBomb.Api.NetStandard/GiantBomb.Api.nuspec create mode 100644 GiantBomb.Api.NetStandard/GiantBombApiException.cs create mode 100644 GiantBomb.Api.NetStandard/GiantBombDeserializer.cs create mode 100644 GiantBomb.Api.NetStandard/GiantBombHttpException.cs create mode 100644 GiantBomb.Api.NetStandard/IGiantBombRestClient.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Developer.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Franchise.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Game.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Genre.cs create mode 100644 GiantBomb.Api.NetStandard/Model/GiantBombBase.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Image.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Platform.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Publisher.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Rating.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Region.cs create mode 100644 GiantBomb.Api.NetStandard/Model/Release.cs create mode 100644 GiantBomb.Api.NetStandard/ResourceTypes.cs create mode 100644 GiantBomb.Api.NetStandard/Resources/Games.cs create mode 100644 GiantBomb.Api.NetStandard/Resources/Platforms.cs create mode 100644 GiantBomb.Api.NetStandard/Resources/Regions.cs create mode 100644 GiantBomb.Api.NetStandard/Resources/Releases.cs create mode 100644 GiantBomb.Api.NetStandard/Resources/Search.cs diff --git a/GiantBomb.Api.NetStandard/Core.cs b/GiantBomb.Api.NetStandard/Core.cs new file mode 100644 index 0000000..c4ab47c --- /dev/null +++ b/GiantBomb.Api.NetStandard/Core.cs @@ -0,0 +1,277 @@ +using System; +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 Newtonsoft.Json; +using RestSharp.Portable; +using RestSharp.Portable.Deserializers; +using RestSharp.Portable.HttpClient; + +namespace GiantBomb.Api +{ + public partial class GiantBombRestClient : IGiantBombRestClient + { + private readonly RestClient _client; + + /// + /// Base URL of API (defaults to http://www.giantbomb.com/api/) + /// + public string BaseUrl { get; set; } + + /// + /// Your GiantBomb API token + /// + private string ApiKey { get; set; } + + /// + /// Create a new Rest client with your API token and custom base URL + /// + /// Your secret API token + /// The base API URL, for example, pre-release API versions + public GiantBombRestClient(string apiToken, Uri baseUrl) + { + BaseUrl = baseUrl.ToString(); + ApiKey = apiToken; + + var version = typeof(GiantBombRestClient).GetTypeInfo().Assembly.GetName().Version; + + _client = new RestClient + { + UserAgent = "giantbomb-csharp/" + version, + BaseUrl = baseUrl + }; + + // API token is used on every request + _client.AddDefaultParameter("api_key", ApiKey); + _client.AddDefaultParameter("format", "json"); + + // Replace JSON deserializer + _client.ContentHandlers["application/json"] = new GiantBombDeserializer(); + } + + public GiantBombRestClient(string apiToken) + : this(apiToken, new Uri("https://www.giantbomb.com/api/")) + { + + } + + /// + /// 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) + 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() + { + IRestResponse response = null; + + try + { + response = await _client.Execute(request).ConfigureAwait(false); + } + catch (Exception ex) + { + throw new GiantBombHttpException( + "Unable to retrieve response from GiantBomb.", ex, response?.Content); + } + + // Deserialize original requested type + T data = default(T); + Exception deserializeEx = null; + try + { + data = _client.ContentHandlers["application/json"].Deserialize(response); + } + catch (Exception dex) + { + deserializeEx = dex; + } + + if (data == null) + { + // handle GiantBomb raw errors without result wrapper + try + { + var responseData = _client.ContentHandlers["application/json"].Deserialize(response); + + if (responseData != null && !String.IsNullOrWhiteSpace(responseData.Error) && responseData.Error != GiantBombBase.ErrorOK) + { + throw new GiantBombApiException(responseData.StatusCode, responseData.Error + Environment.NewLine + response.Content); + } + } + catch (Exception ex) + { + if (ex is GiantBombApiException) + { + throw; + } + else + { + throw new GiantBombHttpException("Could not deserialize response", ex); + } + } + + throw new GiantBombHttpException("Bad content", deserializeEx, response.Content); + } + + if (response.StatusCode != HttpStatusCode.OK) + { + throw new GiantBombHttpException($"GiantBomb returned status code {response.StatusCode}: {response.StatusDescription}", response.Content); + } + + return data; + } + + /// + /// Execute a manual REST request + /// + /// The RestRequest to execute (will use client credentials) + 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.Execute(request).ConfigureAwait(false); + } + + public virtual RestRequest GetListResource(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null) + { + if (pageSize > GiantBombBase.DefaultLimit) + throw new ArgumentOutOfRangeException("pageSize", "Page size cannot be greater than " + GiantBombBase.DefaultLimit + "."); + + var request = new RestRequest + { + Resource = resource + "/" + }; + + if (page > 1) + { + + // HACK: Giant Bomb uses `page` for search instead of `offset` + if (resource == "search") + { + request.AddParameter("page", page); + } + else + { + request.AddParameter("offset", pageSize * (page - 1)); + } + } + + request.AddParameter("limit", pageSize); + + if (fieldList != null) + request.AddParameter("field_list", String.Join(",", fieldList)); + + if (sortOptions != null) + request.AddParameter("sort", BuildKeyValueListForUrl(sortOptions)); + + if (filterOptions != null) + request.AddParameter("filter", BuildKeyValueListForUrl(filterOptions)); + + return request; + } + + private string BuildKeyValueListForUrl(IEnumerable> dictionary) + { + // format is like :,: + return String.Join(",", (from pair in dictionary + select pair.Key + ":" + pair.Value).ToArray()); + } + + private string BuildKeyValueListForUrl(IEnumerable> sortOptions) + { + + var sortDictionary = new Dictionary(); + + foreach (var kv in sortOptions) + sortDictionary.Add(kv.Key, kv.Value == SortDirection.Ascending ? "asc" : "desc"); + + return BuildKeyValueListForUrl(sortDictionary); + } + + public virtual RestRequest GetSingleResource(string resource, int resourceId, int id, string[] fieldList = null) + { + var request = new RestRequest + { + Resource = resource + "/{ResourceId}-{Id}/" + }; + + request.AddUrlSegment("ResourceId", resourceId.ToString(CultureInfo.InvariantCulture)); + request.AddUrlSegment("Id", id.ToString(CultureInfo.InvariantCulture)); + + if (fieldList != null) + request.AddParameter("field_list", String.Join(",", fieldList)); + + return request; + } + + 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).ConfigureAwait(false); + + 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 = await ExecuteAsync>(request).ConfigureAwait(false); + + if (result != null && result.StatusCode == GiantBombBase.StatusOk) + return result.Results; + + if (result != null && result.StatusCode != GiantBombBase.StatusOk) + throw new GiantBombApiException(result.StatusCode, result.Error); + + return null; + } + } + + public enum SortDirection + { + Ascending, + Descending + } +} diff --git a/GiantBomb.Api.NetStandard/GiantBomb.Api.csproj b/GiantBomb.Api.NetStandard/GiantBomb.Api.csproj new file mode 100644 index 0000000..9cac5d5 --- /dev/null +++ b/GiantBomb.Api.NetStandard/GiantBomb.Api.csproj @@ -0,0 +1,31 @@ + + + + netstandard1.2 + GiantBomb.Api.NetStandard + GiantBomb.Api + True + 2.4.0 + kayub + kayub + GiantBomb API (C#) + Restful API wrapper for the GiantBomb games database public API + Copyright © kayub 2015 + https://github.com/kamranayub/GiantBomb-CSharp/blob/master/LICENSE.txt + https://github.com/kamranayub/GiantBomb-CSharp + GiantBomb.Api + https://github.com/kamranayub/GiantBomb-CSharp + Git + giantbomb games database sdk gaming + For changes, see README. + + + + AnyCPU + + + + + + + \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/GiantBomb.Api.nuspec b/GiantBomb.Api.NetStandard/GiantBomb.Api.nuspec new file mode 100644 index 0000000..e472507 --- /dev/null +++ b/GiantBomb.Api.NetStandard/GiantBomb.Api.nuspec @@ -0,0 +1,33 @@ + + + + $version$ + kayub + kayub + GiantBomb.Api + GiantBomb API (C#) + 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 + + For changes, see README. + + giantbomb + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/GiantBombApiException.cs b/GiantBomb.Api.NetStandard/GiantBombApiException.cs new file mode 100644 index 0000000..026ffd5 --- /dev/null +++ b/GiantBomb.Api.NetStandard/GiantBombApiException.cs @@ -0,0 +1,15 @@ +using System; + +namespace GiantBomb.Api +{ + public class GiantBombApiException : Exception + { + public int StatusCode { get; private set; } + + public GiantBombApiException(int statusCode, string error) + : base("GiantBomb API Error: " + statusCode + ": " + error) + { + StatusCode = statusCode; + } + } +} \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/GiantBombDeserializer.cs b/GiantBomb.Api.NetStandard/GiantBombDeserializer.cs new file mode 100644 index 0000000..291643c --- /dev/null +++ b/GiantBomb.Api.NetStandard/GiantBombDeserializer.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using RestSharp.Portable.Deserializers; + +namespace GiantBomb.Api +{ + class GiantBombDeserializer : JsonDeserializer + { + protected override void ConfigureSerializer(JsonSerializer serializer) + { + serializer.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + serializer.ContractResolver = new DefaultContractResolver() + { + NamingStrategy = new SnakeCaseNamingStrategy() + }; + } + } +} diff --git a/GiantBomb.Api.NetStandard/GiantBombHttpException.cs b/GiantBomb.Api.NetStandard/GiantBombHttpException.cs new file mode 100644 index 0000000..eb7503f --- /dev/null +++ b/GiantBomb.Api.NetStandard/GiantBombHttpException.cs @@ -0,0 +1,19 @@ +using System; + +namespace GiantBomb.Api +{ + public class GiantBombHttpException : Exception + { + public GiantBombHttpException(string message, string response = null) + : base("GiantBomb HTTP Exception, bad request from API: " + message + ", Response: " + response) + { + + } + + public GiantBombHttpException(string message, Exception innerEx, string response = null) + : base("GiantBomb HTTP Exception, bad request from API: " + message + ", Response: " + response, innerEx) + { + + } + } +} \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/IGiantBombRestClient.cs b/GiantBomb.Api.NetStandard/IGiantBombRestClient.cs new file mode 100644 index 0000000..98e1aea --- /dev/null +++ b/GiantBomb.Api.NetStandard/IGiantBombRestClient.cs @@ -0,0 +1,291 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using GiantBomb.Api.Model; +using RestSharp.Portable; + +namespace GiantBomb.Api +{ + public interface IGiantBombRestClient + { + /// + /// Base URL of API (defaults to http://api.giantbomb.com) + /// + string BaseUrl { get; set; } + + /// + /// 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. + /// + Platform GetPlatform(int id, string[] limitFields = null); + + /// + /// 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 + /// + /// + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + 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 + /// + /// 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. + /// + 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 + /// + /// 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. + /// + 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. + /// + 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 + /// + /// 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. + /// + 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) + /// + /// 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. + /// + 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. + /// + Task> GetReleasesForGameAsync(Game game, 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. + /// + 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. + /// + /// + /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. + /// + 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 + /// + /// 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 + /// + RestRequest GetListResource(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null); + + /// + /// 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 + 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 + /// + /// 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 + RestRequest GetSingleResource(string resource, int resourceId, int id, string[] fieldList = null); + + /// + /// 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 + 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 + /// + /// The type of object to create and populate with the returned data. + /// 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.NetStandard/Model/Developer.cs b/GiantBomb.Api.NetStandard/Model/Developer.cs new file mode 100644 index 0000000..545f4c2 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Developer.cs @@ -0,0 +1,8 @@ +namespace GiantBomb.Api.Model { + public class Developer { + public int Id { get; set; } + public string ApiDetailUrl { get; set; } + public string SiteDetailUrl { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/Model/Franchise.cs b/GiantBomb.Api.NetStandard/Model/Franchise.cs new file mode 100644 index 0000000..9d2252d --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Franchise.cs @@ -0,0 +1,21 @@ +using System; + +namespace GiantBomb.Api.Model +{ + public class Franchise + { + /// + /// Newline-delimited list of aliases + /// + public string Aliases { get; set; } + public int Id { get; set; } + public string Name { get; set; } + public string SiteDetailUrl { get; set; } + public string ApiDetailUrl { get; set; } + public DateTime DateAdded { get; set; } + public DateTime DateLastUpdated { get; set; } + public string Deck { get; set; } + public string Description { get; set; } + public Image Image { get; set; } + } +} \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/Model/Game.cs b/GiantBomb.Api.NetStandard/Model/Game.cs new file mode 100644 index 0000000..183ad8c --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Game.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace GiantBomb.Api.Model { + public class Game { + public int Id { get; set; } + + /// + /// Newline-delimited list of aliases + /// + public string Aliases { get; set; } + public string Name { get; set; } + public string ApiDetailUrl { get; set; } + public DateTime DateAdded { get; set; } + public DateTime DateLastUpdated { get; set; } + public string Deck { get; set; } + public string Description { get; set; } + public List Developers { get; set; } + public int? ExpectedReleaseDay { get; set; } + public int? ExpectedReleaseMonth { get; set; } + public int? ExpectedReleaseQuarter { get; set; } + public int? ExpectedReleaseYear { get; set; } + public List Franchises { get; set; } + public List Genres { get; set; } + public Image Image { get; set; } + public List Images { get; set; } + public int NumberOfUserReviews { get; set; } + public List OriginalGameRating { get; set; } + public DateTime? OriginalReleaseDate { get; set; } + public List Platforms { get; set; } + public List Publishers { get; set; } + public List Releases { get; set; } + public string SiteDetailUrl { get; set; } + public List SimilarGames { get; set; } + } + + public class GameRating + { + public string ApiDetailUrl { get; set; } + + public int Id { get; set; } + + public string Name { 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.NetStandard/Model/Genre.cs b/GiantBomb.Api.NetStandard/Model/Genre.cs new file mode 100644 index 0000000..bd7d326 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Genre.cs @@ -0,0 +1,10 @@ +namespace GiantBomb.Api.Model +{ + public class Genre + { + public int Id { get; set; } + public string ApiDetailUrl { get; set; } + public string SiteDetailUrl { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/Model/GiantBombBase.cs b/GiantBomb.Api.NetStandard/Model/GiantBombBase.cs new file mode 100644 index 0000000..6980c41 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/GiantBombBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace GiantBomb.Api.Model { + public class GiantBombBase { + public string Error { get; set; } + public int Limit { get; set; } + public int NumberOfPageResults { get; set; } + public int NumberOfTotalResults { get; set; } + public int StatusCode { get; set; } + public string Version { get; set; } + + public const string ErrorOK = "OK"; + public const int StatusOk = 1; + public const int StatusApiKeyInvalid = 100; + public const int StatusObjectNotFound = 101; + public const int StatusErrorUrlFormat = 102; + public const int StatusFilterError = 104; + public const int StatusRateLimitExceeded = 107; + public const int DefaultLimit = 100; + } + + public class GiantBombResult : GiantBombBase + { + public TResult Results { get; set; } + } + + public class GiantBombResults : GiantBombBase { + public List Results { get; set; } + } +} diff --git a/GiantBomb.Api.NetStandard/Model/Image.cs b/GiantBomb.Api.NetStandard/Model/Image.cs new file mode 100644 index 0000000..ee50a37 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Image.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace GiantBomb.Api.Model { + public class Image { + public string IconUrl { get; set; } + public string MediumUrl { get; set; } + public string ScreenUrl { get; set; } + public string SmallUrl { get; set; } + public string SuperUrl { get; set; } + public string ThumbUrl { get; set; } + public string TinyUrl { get; set; } + } +} diff --git a/GiantBomb.Api.NetStandard/Model/Platform.cs b/GiantBomb.Api.NetStandard/Model/Platform.cs new file mode 100644 index 0000000..5abf0f3 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Platform.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace GiantBomb.Api.Model { + public class Platform { + public int Id { get; set; } + public string Aliases { get; set; } + public string Name { get; set; } + public string ApiDetailUrl { get; set; } + public string SiteDetailUrl { get; set; } + public string Abbreviation { get; set; } + public DateTime DateAdded { get; set; } + public DateTime DateLastUpdated { get; set; } + public string Deck { get; set; } + public string Description { get; set; } + public Image Image { get; set; } + public int? InstallBase { get; set; } + public bool OnlineSupport { get; set; } + public decimal? OriginalPrice { get; set; } + public DateTime? ReleaseDate { get; set; } + } +} diff --git a/GiantBomb.Api.NetStandard/Model/Publisher.cs b/GiantBomb.Api.NetStandard/Model/Publisher.cs new file mode 100644 index 0000000..7dba313 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Publisher.cs @@ -0,0 +1,8 @@ +namespace GiantBomb.Api.Model { + public class Publisher { + public int Id { get; set; } + public string ApiDetailUrl { get; set; } + public string SiteDetailUrl { get; set; } + public string Name { get; set; } + } +} diff --git a/GiantBomb.Api.NetStandard/Model/Rating.cs b/GiantBomb.Api.NetStandard/Model/Rating.cs new file mode 100644 index 0000000..ff4d660 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Rating.cs @@ -0,0 +1,7 @@ +namespace GiantBomb.Api.Model { + public class Rating { + public int Id { get; set; } + public string ApiDetailUrl { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/Model/Region.cs b/GiantBomb.Api.NetStandard/Model/Region.cs new file mode 100644 index 0000000..56c0594 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Region.cs @@ -0,0 +1,11 @@ +using System; + +namespace GiantBomb.Api.Model { + public class Region { + public int Id { get; set; } + public string ApiDetailUrl { get; set; } + public string Name { get; set; } + public DateTime DateAdded { get; set; } + public DateTime DateLastUpdated { get; set; } + } +} \ No newline at end of file diff --git a/GiantBomb.Api.NetStandard/Model/Release.cs b/GiantBomb.Api.NetStandard/Model/Release.cs new file mode 100644 index 0000000..7459474 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Model/Release.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace GiantBomb.Api.Model { + public class Release { + public int Id { get; set; } + public string ApiDetailUrl { get; set; } + public string Name { get; set; } + public DateTime DateAdded { get; set; } + public DateTime DateLastUpdated { get; set; } + public string Deck { get; set; } + public string Description { get; set; } + public List Developers { get; set; } + public List Publishers { get; set; } + public int? ExpectedReleaseDay { get; set; } + public int? ExpectedReleaseMonth { get; set; } + public int? ExpectedReleaseQuarter { get; set; } + public int? ExpectedReleaseYear { get; set; } + public Game Game { get; set; } + public DateTime? ReleaseDate { get; set; } + public Rating Rating { get; set; } + public Image Image { get; set; } + public Platform Platform { get; set; } + public string ProductCodeValue { get; set; } + // TODO: Enable once value is fixed in API + //public string ProductCodeType { get; set; } + public string SiteDetailUrl { get; set; } + public Region Region { get; set; } + + } +} diff --git a/GiantBomb.Api.NetStandard/ResourceTypes.cs b/GiantBomb.Api.NetStandard/ResourceTypes.cs new file mode 100644 index 0000000..73fbc8f --- /dev/null +++ b/GiantBomb.Api.NetStandard/ResourceTypes.cs @@ -0,0 +1,9 @@ +namespace GiantBomb.Api { + public class ResourceTypes + { + public const int Games = 3030; + public const int Platforms = 3045; + public const int Releases = 3050; + public const int Regions = 3075; + } +} diff --git a/GiantBomb.Api.NetStandard/Resources/Games.cs b/GiantBomb.Api.NetStandard/Resources/Games.cs new file mode 100644 index 0000000..5cfcdd0 --- /dev/null +++ b/GiantBomb.Api.NetStandard/Resources/Games.cs @@ -0,0 +1,30 @@ +using System; +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 GetGameAsync(id, limitFields).Result; + } + + public async Task GetGameAsync(int id, string[] limitFields = null) { + return await GetSingleResourceAsync("game", ResourceTypes.Games, id, limitFields).ConfigureAwait(false); + } + + public IEnumerable GetGames(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) + { + return GetGamesAsync(page, pageSize, limitFields).Result; + } + + public async Task> GetGamesAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { + return await GetListResourceAsync("games", page, pageSize, limitFields).ConfigureAwait(false); + } + } +} diff --git a/GiantBomb.Api.NetStandard/Resources/Platforms.cs b/GiantBomb.Api.NetStandard/Resources/Platforms.cs new file mode 100644 index 0000000..907526a --- /dev/null +++ b/GiantBomb.Api.NetStandard/Resources/Platforms.cs @@ -0,0 +1,30 @@ +using System; +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 GetPlatformAsync(id, limitFields).Result; + } + + public async Task GetPlatformAsync(int id, string[] limitFields = null) { + return await GetSingleResourceAsync("platform", ResourceTypes.Platforms, id, limitFields).ConfigureAwait(false); + } + + 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).ConfigureAwait(false); + } + } +} diff --git a/GiantBomb.Api.NetStandard/Resources/Regions.cs b/GiantBomb.Api.NetStandard/Resources/Regions.cs new file mode 100644 index 0000000..ac0969d --- /dev/null +++ b/GiantBomb.Api.NetStandard/Resources/Regions.cs @@ -0,0 +1,32 @@ +using System; +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 Region GetRegion(int id, string[] limitFields = null) + { + return GetRegionAsync(id, limitFields).Result; + } + + public async Task GetRegionAsync(int id, string[] limitFields = null) + { + return await GetSingleResourceAsync("region", ResourceTypes.Regions, id, limitFields).ConfigureAwait(false); + } + + public IEnumerable GetRegions(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) + { + 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).ConfigureAwait(false); + } + } +} diff --git a/GiantBomb.Api.NetStandard/Resources/Releases.cs b/GiantBomb.Api.NetStandard/Resources/Releases.cs new file mode 100644 index 0000000..0b5db6d --- /dev/null +++ b/GiantBomb.Api.NetStandard/Resources/Releases.cs @@ -0,0 +1,45 @@ +using System; +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 GetReleaseAsync(id, limitFields).Result; + } + + public async Task GetReleaseAsync(int id, string[] limitFields = null) { + return await GetSingleResourceAsync("release", ResourceTypes.Releases, id, limitFields).ConfigureAwait(false); + } + + 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 await GetListResourceAsync("releases", fieldList: limitFields, filterOptions: filter).ConfigureAwait(false); + } + + 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.NetStandard/Resources/Search.cs b/GiantBomb.Api.NetStandard/Resources/Search.cs new file mode 100644 index 0000000..91ec24a --- /dev/null +++ b/GiantBomb.Api.NetStandard/Resources/Search.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GiantBomb.Api.Model; +using RestSharp; +using RestSharp.Portable; + +namespace GiantBomb.Api { + public partial class GiantBombRestClient { + + 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).ConfigureAwait(false); + + if (result.StatusCode == GiantBombBase.StatusOk) + return result.Results; + + return null; + } + + public IEnumerable SearchForAllGames(string query, string[] limitFields = null) + { + return SearchForAllGamesAsync(query, limitFields).Result; + } + + public async Task> SearchForAllGamesAsync(string query, string[] limitFields = null) { + var results = new List(); + var result = await InternalSearchForGames(query, limitFields: limitFields).ConfigureAwait(false); + + if (result == null || result.StatusCode != GiantBombBase.StatusOk) + return null; + + results.AddRange(result.Results); + + if (result.NumberOfTotalResults > result.Limit) { + double remaining = Math.Ceiling(Convert.ToDouble(result.NumberOfTotalResults) / Convert.ToDouble(result.Limit)); + + // Start on page 2 + for (var i = 2; i <= remaining; i++) { + result = await InternalSearchForGames(query, i, result.Limit, limitFields).ConfigureAwait(false); + + if (result.StatusCode != GiantBombBase.StatusOk) + break; + + results.AddRange(result.Results); + } + } + + // 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).ConfigureAwait(false); + } + } +} diff --git a/GiantBomb.Api.Tests/Core.cs b/GiantBomb.Api.Tests/Core.cs index efcb438..3ec0cb9 100644 --- a/GiantBomb.Api.Tests/Core.cs +++ b/GiantBomb.Api.Tests/Core.cs @@ -3,9 +3,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using GiantBomb.Api.Tests.Support; using NUnit.Framework; -using RestSharp; +using RestSharp.Portable; namespace GiantBomb.Api.Tests { diff --git a/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj b/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj index 76b9497..786e0f6 100644 --- a/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj +++ b/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj @@ -36,16 +36,23 @@ false + + ..\packages\FubarCoder.RestSharp.Portable.Core.4.0.8\lib\net45\FubarCoder.RestSharp.Portable.Core.dll + + + ..\packages\FubarCoder.RestSharp.Portable.HttpClient.4.0.8\lib\net45\FubarCoder.RestSharp.Portable.HttpClient.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + ..\packages\NUnit.2.6.4\lib\nunit.framework.dll True - - ..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll - True - + + @@ -68,13 +75,13 @@ - - {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB} - GiantBomb.Api - + - + + {9980b512-d08b-4505-971c-6dfb5cb44e36} + GiantBomb.Api + diff --git a/GiantBomb.Api.Tests/TestBase.cs b/GiantBomb.Api.Tests/TestBase.cs index f3bc082..bfc2e54 100644 --- a/GiantBomb.Api.Tests/TestBase.cs +++ b/GiantBomb.Api.Tests/TestBase.cs @@ -16,7 +16,7 @@ public class TestBase public void Setup() { var token = Token.GetToken(); - _client = new GiantBombRestClient(token, new Uri("http://www.giantbomb.com/api/")); + _client = new GiantBombRestClient(token); } } } diff --git a/GiantBomb.Api.Tests/packages.config b/GiantBomb.Api.Tests/packages.config index e3743f7..9a86d5a 100644 --- a/GiantBomb.Api.Tests/packages.config +++ b/GiantBomb.Api.Tests/packages.config @@ -1,5 +1,7 @@  + + + - \ No newline at end of file diff --git a/GiantBomb.sln b/GiantBomb.sln index 0afcdae..5e0bc42 100644 --- a/GiantBomb.sln +++ b/GiantBomb.sln @@ -1,17 +1,14 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.6 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}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4851769F-6AF7-484A-88BE-52F7478878B9}" ProjectSection(SolutionItems) = preProject LICENSE.txt = LICENSE.txt Readme.md = Readme.md - SharedAssemblyInfo.cs = SharedAssemblyInfo.cs EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9DBE19DE-C523-4B80-88A9-390F46769835}" @@ -20,11 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9DBE19 .nuget\NuGet.targets = .nuget\NuGet.targets EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependencies", "Dependencies", "{90F6B7F2-5AAE-4D20-A383-F7DEDDC1CD10}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api.Net46", "GiantBomb.Api.Net46\GiantBomb.Api.Net46.csproj", "{0F3123EB-BEE8-4D22-8B82-FEE48332479B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api.Net461", "GiantBomb.Api.Net461\GiantBomb.Api.Net461.csproj", "{64569B67-6E98-490C-A773-E23831189AD7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api", "GiantBomb.Api.NetStandard\GiantBomb.Api.csproj", "{9980B512-D08B-4505-971C-6DFB5CB44E36}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -40,26 +33,6 @@ Global 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 @@ -80,46 +53,26 @@ Global {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 - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|ARM.ActiveCfg = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|ARM.Build.0 = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|x64.ActiveCfg = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|x64.Build.0 = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|x86.ActiveCfg = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Debug|x86.Build.0 = Debug|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|Any CPU.Build.0 = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|ARM.ActiveCfg = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|ARM.Build.0 = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|x64.ActiveCfg = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|x64.Build.0 = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|x86.ActiveCfg = Release|Any CPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B}.Release|x86.Build.0 = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|ARM.ActiveCfg = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|ARM.Build.0 = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|x64.ActiveCfg = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|x64.Build.0 = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|x86.ActiveCfg = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Debug|x86.Build.0 = Debug|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|Any CPU.Build.0 = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|ARM.ActiveCfg = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|ARM.Build.0 = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|x64.ActiveCfg = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|x64.Build.0 = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|x86.ActiveCfg = Release|Any CPU - {64569B67-6E98-490C-A773-E23831189AD7}.Release|x86.Build.0 = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|ARM.Build.0 = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|x64.ActiveCfg = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|x64.Build.0 = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|x86.ActiveCfg = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Debug|x86.Build.0 = Debug|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|Any CPU.Build.0 = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|ARM.ActiveCfg = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|ARM.Build.0 = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|x64.ActiveCfg = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|x64.Build.0 = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|x86.ActiveCfg = Release|Any CPU + {9980B512-D08B-4505-971C-6DFB5CB44E36}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From fa21be49fc99c428b5c3c766a7230f2aabc715e6 Mon Sep 17 00:00:00 2001 From: Kamran Ayub Date: Fri, 26 May 2017 12:18:29 -0500 Subject: [PATCH 2/4] Delete unused folders --- Dependencies/fastJSON.dll | Bin 34304 -> 0 bytes .../GiantBomb.Api.Net46.csproj | 127 -------- .../Properties/AssemblyInfo.cs | 3 - GiantBomb.Api.Net46/packages.config | 4 - .../GiantBomb.Api.Net461.csproj | 127 -------- .../Properties/AssemblyInfo.cs | 3 - GiantBomb.Api.Net461/packages.config | 4 - GiantBomb.Api/Core.cs | 243 --------------- GiantBomb.Api/GiantBomb.Api.csproj | 100 ------ GiantBomb.Api/GiantBomb.Api.nuspec | 33 -- GiantBomb.Api/GiantBombApiException.cs | 15 - GiantBomb.Api/GiantBombHttpException.cs | 19 -- GiantBomb.Api/IGiantBombRestClient.cs | 291 ------------------ GiantBomb.Api/Model/Developer.cs | 8 - GiantBomb.Api/Model/Franchise.cs | 21 -- GiantBomb.Api/Model/Game.cs | 50 --- GiantBomb.Api/Model/Genre.cs | 10 - GiantBomb.Api/Model/GiantBombBase.cs | 32 -- GiantBomb.Api/Model/Image.cs | 16 - GiantBomb.Api/Model/Platform.cs | 24 -- GiantBomb.Api/Model/Publisher.cs | 8 - GiantBomb.Api/Model/Rating.cs | 7 - GiantBomb.Api/Model/Region.cs | 11 - GiantBomb.Api/Model/Release.cs | 32 -- GiantBomb.Api/Properties/AssemblyInfo.cs | 4 - GiantBomb.Api/ResourceTypes.cs | 9 - GiantBomb.Api/Resources/Games.cs | 30 -- GiantBomb.Api/Resources/Platforms.cs | 30 -- GiantBomb.Api/Resources/Regions.cs | 32 -- GiantBomb.Api/Resources/Releases.cs | 45 --- GiantBomb.Api/Resources/Search.cs | 74 ----- GiantBomb.Api/packages.config | 4 - GiantBomb.Api/readme.txt | 92 ------ SharedAssemblyInfo.cs | 16 - 34 files changed, 1524 deletions(-) delete mode 100644 Dependencies/fastJSON.dll delete mode 100644 GiantBomb.Api.Net46/GiantBomb.Api.Net46.csproj delete mode 100644 GiantBomb.Api.Net46/Properties/AssemblyInfo.cs delete mode 100644 GiantBomb.Api.Net46/packages.config delete mode 100644 GiantBomb.Api.Net461/GiantBomb.Api.Net461.csproj delete mode 100644 GiantBomb.Api.Net461/Properties/AssemblyInfo.cs delete mode 100644 GiantBomb.Api.Net461/packages.config delete mode 100644 GiantBomb.Api/Core.cs delete mode 100644 GiantBomb.Api/GiantBomb.Api.csproj delete mode 100644 GiantBomb.Api/GiantBomb.Api.nuspec delete mode 100644 GiantBomb.Api/GiantBombApiException.cs delete mode 100644 GiantBomb.Api/GiantBombHttpException.cs delete mode 100644 GiantBomb.Api/IGiantBombRestClient.cs delete mode 100644 GiantBomb.Api/Model/Developer.cs delete mode 100644 GiantBomb.Api/Model/Franchise.cs delete mode 100644 GiantBomb.Api/Model/Game.cs delete mode 100644 GiantBomb.Api/Model/Genre.cs delete mode 100644 GiantBomb.Api/Model/GiantBombBase.cs delete mode 100644 GiantBomb.Api/Model/Image.cs delete mode 100644 GiantBomb.Api/Model/Platform.cs delete mode 100644 GiantBomb.Api/Model/Publisher.cs delete mode 100644 GiantBomb.Api/Model/Rating.cs delete mode 100644 GiantBomb.Api/Model/Region.cs delete mode 100644 GiantBomb.Api/Model/Release.cs delete mode 100644 GiantBomb.Api/Properties/AssemblyInfo.cs delete mode 100644 GiantBomb.Api/ResourceTypes.cs delete mode 100644 GiantBomb.Api/Resources/Games.cs delete mode 100644 GiantBomb.Api/Resources/Platforms.cs delete mode 100644 GiantBomb.Api/Resources/Regions.cs delete mode 100644 GiantBomb.Api/Resources/Releases.cs delete mode 100644 GiantBomb.Api/Resources/Search.cs delete mode 100644 GiantBomb.Api/packages.config delete mode 100644 GiantBomb.Api/readme.txt delete mode 100644 SharedAssemblyInfo.cs diff --git a/Dependencies/fastJSON.dll b/Dependencies/fastJSON.dll deleted file mode 100644 index b56e4a0f7e79c99097260a8cd1840477df224d24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34304 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 aKUNN^|M&jfF8{X0hgSagHp73{*8d;uLkOJ! diff --git a/GiantBomb.Api.Net46/GiantBomb.Api.Net46.csproj b/GiantBomb.Api.Net46/GiantBomb.Api.Net46.csproj deleted file mode 100644 index 5acdbeb..0000000 --- a/GiantBomb.Api.Net46/GiantBomb.Api.Net46.csproj +++ /dev/null @@ -1,127 +0,0 @@ - - - - - Debug - AnyCPU - {0F3123EB-BEE8-4D22-8B82-FEE48332479B} - Library - Properties - GiantBomb.Api - GiantBomb.Api - v4.6 - 512 - - - - true - full - false - ..\bin\Debug\net46\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\bin\Release\net46\ - TRACE - prompt - 4 - - - - ..\packages\RestSharp.105.2.3\lib\net46\RestSharp.dll - True - - - - - - - - - - - - - Core.cs - - - GiantBombApiException.cs - - - GiantBombHttpException.cs - - - IGiantBombRestClient.cs - - - Model\Developer.cs - - - Model\Franchise.cs - - - Model\Game.cs - - - Model\Genre.cs - - - Model\GiantBombBase.cs - - - Model\Image.cs - - - Model\Platform.cs - - - Model\Publisher.cs - - - Model\Rating.cs - - - Model\Region.cs - - - Model\Release.cs - - - Resources\Games.cs - - - Resources\Platforms.cs - - - Resources\Regions.cs - - - Resources\Releases.cs - - - Resources\Search.cs - - - ResourceTypes.cs - - - SharedAssemblyInfo.cs - - - - - - - - - \ No newline at end of file diff --git a/GiantBomb.Api.Net46/Properties/AssemblyInfo.cs b/GiantBomb.Api.Net46/Properties/AssemblyInfo.cs deleted file mode 100644 index 190befe..0000000 --- a/GiantBomb.Api.Net46/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Runtime.InteropServices; - -[assembly: Guid("0f3123eb-bee8-4d22-8b82-fee48332479b")] \ No newline at end of file diff --git a/GiantBomb.Api.Net46/packages.config b/GiantBomb.Api.Net46/packages.config deleted file mode 100644 index ba5e32a..0000000 --- a/GiantBomb.Api.Net46/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/GiantBomb.Api.Net461/GiantBomb.Api.Net461.csproj b/GiantBomb.Api.Net461/GiantBomb.Api.Net461.csproj deleted file mode 100644 index 3802b5b..0000000 --- a/GiantBomb.Api.Net461/GiantBomb.Api.Net461.csproj +++ /dev/null @@ -1,127 +0,0 @@ - - - - - Debug - AnyCPU - {64569B67-6E98-490C-A773-E23831189AD7} - Library - Properties - GiantBomb.Api - GiantBomb.Api - v4.6.1 - 512 - - - - true - full - false - ..\bin\Debug\net461\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\bin\Release\net461\ - TRACE - prompt - 4 - - - - ..\packages\RestSharp.105.2.3\lib\net46\RestSharp.dll - True - - - - - - - - - - - - - Core.cs - - - GiantBombApiException.cs - - - GiantBombHttpException.cs - - - IGiantBombRestClient.cs - - - Model\Developer.cs - - - Model\Franchise.cs - - - Model\Game.cs - - - Model\Genre.cs - - - Model\GiantBombBase.cs - - - Model\Image.cs - - - Model\Platform.cs - - - Model\Publisher.cs - - - Model\Rating.cs - - - Model\Region.cs - - - Model\Release.cs - - - Resources\Games.cs - - - Resources\Platforms.cs - - - Resources\Regions.cs - - - Resources\Releases.cs - - - Resources\Search.cs - - - ResourceTypes.cs - - - SharedAssemblyInfo.cs - - - - - - - - - \ No newline at end of file diff --git a/GiantBomb.Api.Net461/Properties/AssemblyInfo.cs b/GiantBomb.Api.Net461/Properties/AssemblyInfo.cs deleted file mode 100644 index 54d31a7..0000000 --- a/GiantBomb.Api.Net461/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Runtime.InteropServices; - -[assembly: Guid("64569b67-6e98-490c-a773-e23831189ad7")] \ No newline at end of file diff --git a/GiantBomb.Api.Net461/packages.config b/GiantBomb.Api.Net461/packages.config deleted file mode 100644 index 29f5629..0000000 --- a/GiantBomb.Api.Net461/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/GiantBomb.Api/Core.cs b/GiantBomb.Api/Core.cs deleted file mode 100644 index 2d8a293..0000000 --- a/GiantBomb.Api/Core.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System; -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; -using RestSharp.Deserializers; - -namespace GiantBomb.Api { - public partial class GiantBombRestClient : IGiantBombRestClient { - private readonly RestClient _client; - - /// - /// Base URL of API (defaults to http://www.giantbomb.com/api/) - /// - public string BaseUrl { get; set; } - - /// - /// Your GiantBomb API token - /// - private string ApiKey { get; set; } - - /// - /// Create a new Rest client with your API token and custom base URL - /// - /// Your secret API token - /// The base API URL, for example, pre-release API versions - public GiantBombRestClient(string apiToken, Uri baseUrl) { - BaseUrl = baseUrl.ToString(); - ApiKey = apiToken; - - var assembly = Assembly.GetExecutingAssembly(); - var version = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion; - - _client = new RestClient - { - UserAgent = "giantbomb-csharp/" + version, - BaseUrl = baseUrl - }; - - // API token is used on every request - _client.AddDefaultParameter("api_key", ApiKey); - _client.AddDefaultParameter("format", "json"); - } - - public GiantBombRestClient(string apiToken) - : this(apiToken, new Uri("http://www.giantbomb.com/api/")) { - - } - - /// - /// 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) - 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).ConfigureAwait(false); - - if (response.Data == null) - { - // handle GiantBomb raw errors without result wrapper - try - { - var responseData = new JsonDeserializer().Deserialize(response); - - if (responseData != null && !String.IsNullOrWhiteSpace(responseData.Error)) - { - throw new GiantBombApiException(responseData.StatusCode, responseData.Error); - } - } - catch (Exception ex) - { - if (ex is GiantBombApiException) - { - throw; - } - } - - if (response.ErrorException != null) - { - throw new GiantBombHttpException(response.ErrorMessage, response.ErrorException, response.Content); - } - else - { - throw new GiantBombHttpException("Bad content", response.Content); - } - } - else if (response.StatusCode != HttpStatusCode.OK) - { - throw new GiantBombHttpException(response.ErrorMessage, response.Content); - } - - return response.Data; - } - - /// - /// Execute a manual REST request - /// - /// The RestRequest to execute (will use client credentials) - 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).ConfigureAwait(false); - } - - public virtual RestRequest GetListResource(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null) { - if (pageSize > GiantBombBase.DefaultLimit) - throw new ArgumentOutOfRangeException("pageSize", "Page size cannot be greater than " + GiantBombBase.DefaultLimit + "."); - - var request = new RestRequest { - Resource = resource + "/", - DateFormat = "yyyy-MM-dd HH:mm:ss" - }; - - if (page > 1) { - - // HACK: Giant Bomb uses `page` for search instead of `offset` - if (resource == "search") { - request.AddParameter("page", page); - } - else { - request.AddParameter("offset", pageSize*(page - 1)); - } - } - - request.AddParameter("limit", pageSize); - - if (fieldList != null) - request.AddParameter("field_list", String.Join(",", fieldList)); - - if (sortOptions != null) - request.AddParameter("sort", BuildKeyValueListForUrl(sortOptions)); - - if (filterOptions != null) - request.AddParameter("filter", BuildKeyValueListForUrl(filterOptions)); - - return request; - } - - private string BuildKeyValueListForUrl(IEnumerable> dictionary) - { - // format is like :,: - return String.Join(",", (from pair in dictionary - select pair.Key + ":" + pair.Value).ToArray()); - } - - private string BuildKeyValueListForUrl(IEnumerable> sortOptions) - { - - var sortDictionary = new Dictionary(); - - foreach(var kv in sortOptions) - sortDictionary.Add(kv.Key, kv.Value == SortDirection.Ascending ? "asc" : "desc"); - - return BuildKeyValueListForUrl(sortDictionary); - } - - public virtual RestRequest GetSingleResource(string resource, int resourceId, int id, string[] fieldList = null) { - 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)); - - if (fieldList != null) - request.AddParameter("field_list", String.Join(",", fieldList)); - - return request; - } - - 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).ConfigureAwait(false); - - 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 = await ExecuteAsync>(request).ConfigureAwait(false); - - if (result != null && result.StatusCode == GiantBombBase.StatusOk) - return result.Results; - - if (result != null && result.StatusCode != GiantBombBase.StatusOk) - throw new GiantBombApiException(result.StatusCode, result.Error); - - return null; - } - } - - public enum SortDirection - { - Ascending, - Descending - } -} diff --git a/GiantBomb.Api/GiantBomb.Api.csproj b/GiantBomb.Api/GiantBomb.Api.csproj deleted file mode 100644 index ec4708b..0000000 --- a/GiantBomb.Api/GiantBomb.Api.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {9CB78FD8-C888-4A8C-B16F-AB762A5D5BAB} - Library - Properties - GiantBomb.Api - GiantBomb.Api - v4.5.2 - 512 - ..\..\GiantBomb-CSharp\ - true - - - - true - full - false - ..\bin\Debug\net452\ - TRACE;DEBUG;FRAMEWORK - prompt - 4 - false - - - pdbonly - true - ..\bin\Release\net452\ - TRACE;FRAMEWORK - prompt - 4 - false - - - - ..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll - True - - - - - - - - - - - - SharedAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - - - - - - - - copy "$(SolutionDir)Readme.md" "$(ProjectDir)readme.txt" /y - - - \ No newline at end of file diff --git a/GiantBomb.Api/GiantBomb.Api.nuspec b/GiantBomb.Api/GiantBomb.Api.nuspec deleted file mode 100644 index e472507..0000000 --- a/GiantBomb.Api/GiantBomb.Api.nuspec +++ /dev/null @@ -1,33 +0,0 @@ - - - - $version$ - kayub - kayub - GiantBomb.Api - GiantBomb API (C#) - 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 - - For changes, see README. - - giantbomb - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/GiantBomb.Api/GiantBombApiException.cs b/GiantBomb.Api/GiantBombApiException.cs deleted file mode 100644 index 026ffd5..0000000 --- a/GiantBomb.Api/GiantBombApiException.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace GiantBomb.Api -{ - public class GiantBombApiException : Exception - { - public int StatusCode { get; private set; } - - public GiantBombApiException(int statusCode, string error) - : base("GiantBomb API Error: " + statusCode + ": " + error) - { - StatusCode = statusCode; - } - } -} \ No newline at end of file diff --git a/GiantBomb.Api/GiantBombHttpException.cs b/GiantBomb.Api/GiantBombHttpException.cs deleted file mode 100644 index eb7503f..0000000 --- a/GiantBomb.Api/GiantBombHttpException.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace GiantBomb.Api -{ - public class GiantBombHttpException : Exception - { - public GiantBombHttpException(string message, string response = null) - : base("GiantBomb HTTP Exception, bad request from API: " + message + ", Response: " + response) - { - - } - - public GiantBombHttpException(string message, Exception innerEx, string response = null) - : base("GiantBomb HTTP Exception, bad request from API: " + message + ", Response: " + response, innerEx) - { - - } - } -} \ No newline at end of file diff --git a/GiantBomb.Api/IGiantBombRestClient.cs b/GiantBomb.Api/IGiantBombRestClient.cs deleted file mode 100644 index ac796d2..0000000 --- a/GiantBomb.Api/IGiantBombRestClient.cs +++ /dev/null @@ -1,291 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using GiantBomb.Api.Model; -using RestSharp; - -namespace GiantBomb.Api -{ - public interface IGiantBombRestClient - { - /// - /// Base URL of API (defaults to http://api.giantbomb.com) - /// - string BaseUrl { get; set; } - - /// - /// 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. - /// - Platform GetPlatform(int id, string[] limitFields = null); - - /// - /// 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 - /// - /// - /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. - /// - 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 - /// - /// 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. - /// - 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 - /// - /// 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. - /// - 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. - /// - 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 - /// - /// 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. - /// - 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) - /// - /// 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. - /// - 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. - /// - Task> GetReleasesForGameAsync(Game game, 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. - /// - 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. - /// - /// - /// List of field names to include in the response. Use this if you want to reduce the size of the response payload. - /// - 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 - /// - /// 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 - /// - RestRequest GetListResource(string resource, int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] fieldList = null, IDictionary sortOptions = null, IDictionary filterOptions = null); - - /// - /// 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 - 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 - /// - /// 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 - RestRequest GetSingleResource(string resource, int resourceId, int id, string[] fieldList = null); - - /// - /// 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 - 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 - /// - /// The type of object to create and populate with the returned data. - /// 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/Developer.cs b/GiantBomb.Api/Model/Developer.cs deleted file mode 100644 index 7a2fc34..0000000 --- a/GiantBomb.Api/Model/Developer.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace GiantBomb.Api.Model { - public class Developer { - public int Id { get; set; } - public string ApiDetailUrl { get; set; } - public string SiteDetailUrl { get; set; } - public string Name { get; set; } - } -} \ No newline at end of file diff --git a/GiantBomb.Api/Model/Franchise.cs b/GiantBomb.Api/Model/Franchise.cs deleted file mode 100644 index 9d2252d..0000000 --- a/GiantBomb.Api/Model/Franchise.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace GiantBomb.Api.Model -{ - public class Franchise - { - /// - /// Newline-delimited list of aliases - /// - public string Aliases { get; set; } - public int Id { get; set; } - public string Name { get; set; } - public string SiteDetailUrl { get; set; } - public string ApiDetailUrl { get; set; } - public DateTime DateAdded { get; set; } - public DateTime DateLastUpdated { get; set; } - public string Deck { get; set; } - public string Description { get; set; } - public Image Image { get; set; } - } -} \ No newline at end of file diff --git a/GiantBomb.Api/Model/Game.cs b/GiantBomb.Api/Model/Game.cs deleted file mode 100644 index 16e10c0..0000000 --- a/GiantBomb.Api/Model/Game.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace GiantBomb.Api.Model { - public class Game { - public int Id { get; set; } - - /// - /// Newline-delimited list of aliases - /// - public string Aliases { get; set; } - public string Name { get; set; } - public string ApiDetailUrl { get; set; } - public DateTime DateAdded { get; set; } - public DateTime DateLastUpdated { get; set; } - public string Deck { get; set; } - public string Description { get; set; } - public List Developers { get; set; } - public int? ExpectedReleaseDay { get; set; } - public int? ExpectedReleaseMonth { get; set; } - public int? ExpectedReleaseQuarter { get; set; } - public int? ExpectedReleaseYear { get; set; } - public List Franchises { get; set; } - public List Genres { get; set; } - public Image Image { get; set; } - public List Images { get; set; } - public int NumberOfUserReviews { get; set; } - public string OriginalGameRating { get; set; } - public DateTime? OriginalReleaseDate { get; set; } - public List Platforms { get; set; } - public List Publishers { get; set; } - public List Releases { get; set; } - 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/Model/Genre.cs b/GiantBomb.Api/Model/Genre.cs deleted file mode 100644 index 275c989..0000000 --- a/GiantBomb.Api/Model/Genre.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace GiantBomb.Api.Model -{ - public class Genre - { - public int Id { get; set; } - public string ApiDetailUrl { get; set; } - public string SiteDetailUrl { get; set; } - public string Name { get; set; } - } -} \ No newline at end of file diff --git a/GiantBomb.Api/Model/GiantBombBase.cs b/GiantBomb.Api/Model/GiantBombBase.cs deleted file mode 100644 index c56c52b..0000000 --- a/GiantBomb.Api/Model/GiantBombBase.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace GiantBomb.Api.Model { - public class GiantBombBase { - public string Error { get; set; } - public int Limit { get; set; } - public int NumberOfPageResults { get; set; } - public int NumberOfTotalResults { get; set; } - public int StatusCode { get; set; } - public string Version { get; set; } - - public const int StatusOk = 1; - public const int StatusApiKeyInvalid = 100; - public const int StatusObjectNotFound = 101; - public const int StatusErrorUrlFormat = 102; - public const int StatusFilterError = 104; - public const int StatusRateLimitExceeded = 107; - public const int DefaultLimit = 100; - } - - public class GiantBombResult : GiantBombBase - { - public TResult Results { get; set; } - } - - public class GiantBombResults : GiantBombBase { - public List Results { get; set; } - } -} diff --git a/GiantBomb.Api/Model/Image.cs b/GiantBomb.Api/Model/Image.cs deleted file mode 100644 index ee50a37..0000000 --- a/GiantBomb.Api/Model/Image.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace GiantBomb.Api.Model { - public class Image { - public string IconUrl { get; set; } - public string MediumUrl { get; set; } - public string ScreenUrl { get; set; } - public string SmallUrl { get; set; } - public string SuperUrl { get; set; } - public string ThumbUrl { get; set; } - public string TinyUrl { get; set; } - } -} diff --git a/GiantBomb.Api/Model/Platform.cs b/GiantBomb.Api/Model/Platform.cs deleted file mode 100644 index 5abf0f3..0000000 --- a/GiantBomb.Api/Model/Platform.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace GiantBomb.Api.Model { - public class Platform { - public int Id { get; set; } - public string Aliases { get; set; } - public string Name { get; set; } - public string ApiDetailUrl { get; set; } - public string SiteDetailUrl { get; set; } - public string Abbreviation { get; set; } - public DateTime DateAdded { get; set; } - public DateTime DateLastUpdated { get; set; } - public string Deck { get; set; } - public string Description { get; set; } - public Image Image { get; set; } - public int? InstallBase { get; set; } - public bool OnlineSupport { get; set; } - public decimal? OriginalPrice { get; set; } - public DateTime? ReleaseDate { get; set; } - } -} diff --git a/GiantBomb.Api/Model/Publisher.cs b/GiantBomb.Api/Model/Publisher.cs deleted file mode 100644 index 96c635a..0000000 --- a/GiantBomb.Api/Model/Publisher.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace GiantBomb.Api.Model { - public class Publisher { - public int Id { get; set; } - public string ApiDetailUrl { get; set; } - public string SiteDetailUrl { get; set; } - public string Name { get; set; } - } -} diff --git a/GiantBomb.Api/Model/Rating.cs b/GiantBomb.Api/Model/Rating.cs deleted file mode 100644 index 498f487..0000000 --- a/GiantBomb.Api/Model/Rating.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace GiantBomb.Api.Model { - public class Rating { - public int Id { get; set; } - public string ApiDetailUrl { get; set; } - public string Name { get; set; } - } -} \ No newline at end of file diff --git a/GiantBomb.Api/Model/Region.cs b/GiantBomb.Api/Model/Region.cs deleted file mode 100644 index 2780d83..0000000 --- a/GiantBomb.Api/Model/Region.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace GiantBomb.Api.Model { - public class Region { - public int Id { get; set; } - public string ApiDetailUrl { get; set; } - public string Name { get; set; } - public DateTime DateAdded { get; set; } - public DateTime DateLastUpdated { get; set; } - } -} \ No newline at end of file diff --git a/GiantBomb.Api/Model/Release.cs b/GiantBomb.Api/Model/Release.cs deleted file mode 100644 index c3277aa..0000000 --- a/GiantBomb.Api/Model/Release.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace GiantBomb.Api.Model { - public class Release { - public int Id { get; set; } - public string ApiDetailUrl { get; set; } - public string Name { get; set; } - public DateTime DateAdded { get; set; } - public DateTime DateLastUpdated { get; set; } - public string Deck { get; set; } - public string Description { get; set; } - public List Developers { get; set; } - public List Publishers { get; set; } - public int? ExpectedReleaseDay { get; set; } - public int? ExpectedReleaseMonth { get; set; } - public int? ExpectedReleaseQuarter { get; set; } - public int? ExpectedReleaseYear { get; set; } - public Game Game { get; set; } - public DateTime? ReleaseDate { get; set; } - public Rating Rating { get; set; } - public Image Image { get; set; } - public Platform Platform { get; set; } - public string ProductCodeValue { get; set; } - public string ProductCodeType { get; set; } - public string SiteDetailUrl { get; set; } - public Region Region { get; set; } - - } -} diff --git a/GiantBomb.Api/Properties/AssemblyInfo.cs b/GiantBomb.Api/Properties/AssemblyInfo.cs deleted file mode 100644 index 310170f..0000000 --- a/GiantBomb.Api/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: Guid("5d910805-e5ae-48f0-8e39-d37104d7a91e")] \ No newline at end of file diff --git a/GiantBomb.Api/ResourceTypes.cs b/GiantBomb.Api/ResourceTypes.cs deleted file mode 100644 index fcbd7e4..0000000 --- a/GiantBomb.Api/ResourceTypes.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace GiantBomb.Api { - public class ResourceTypes - { - public const int Games = 3030; - public const int Platforms = 3045; - public const int Releases = 3050; - public const int Regions = 3075; - } -} diff --git a/GiantBomb.Api/Resources/Games.cs b/GiantBomb.Api/Resources/Games.cs deleted file mode 100644 index 5cfcdd0..0000000 --- a/GiantBomb.Api/Resources/Games.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -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 GetGameAsync(id, limitFields).Result; - } - - public async Task GetGameAsync(int id, string[] limitFields = null) { - return await GetSingleResourceAsync("game", ResourceTypes.Games, id, limitFields).ConfigureAwait(false); - } - - public IEnumerable GetGames(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) - { - return GetGamesAsync(page, pageSize, limitFields).Result; - } - - public async Task> GetGamesAsync(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) { - return await GetListResourceAsync("games", page, pageSize, limitFields).ConfigureAwait(false); - } - } -} diff --git a/GiantBomb.Api/Resources/Platforms.cs b/GiantBomb.Api/Resources/Platforms.cs deleted file mode 100644 index 7c47ebb..0000000 --- a/GiantBomb.Api/Resources/Platforms.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -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 GetPlatformAsync(id, limitFields).Result; - } - - public async Task GetPlatformAsync(int id, string[] limitFields = null) { - return await GetSingleResourceAsync("platform", ResourceTypes.Platforms, id, limitFields).ConfigureAwait(false); - } - - 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).ConfigureAwait(false); - } - } -} diff --git a/GiantBomb.Api/Resources/Regions.cs b/GiantBomb.Api/Resources/Regions.cs deleted file mode 100644 index 5f062db..0000000 --- a/GiantBomb.Api/Resources/Regions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -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 Region GetRegion(int id, string[] limitFields = null) - { - return GetRegionAsync(id, limitFields).Result; - } - - public async Task GetRegionAsync(int id, string[] limitFields = null) - { - return await GetSingleResourceAsync("region", ResourceTypes.Regions, id, limitFields).ConfigureAwait(false); - } - - public IEnumerable GetRegions(int page = 1, int pageSize = GiantBombBase.DefaultLimit, string[] limitFields = null) - { - 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).ConfigureAwait(false); - } - } -} diff --git a/GiantBomb.Api/Resources/Releases.cs b/GiantBomb.Api/Resources/Releases.cs deleted file mode 100644 index 0b5db6d..0000000 --- a/GiantBomb.Api/Resources/Releases.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -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 GetReleaseAsync(id, limitFields).Result; - } - - public async Task GetReleaseAsync(int id, string[] limitFields = null) { - return await GetSingleResourceAsync("release", ResourceTypes.Releases, id, limitFields).ConfigureAwait(false); - } - - 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 await GetListResourceAsync("releases", fieldList: limitFields, filterOptions: filter).ConfigureAwait(false); - } - - 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 deleted file mode 100644 index 59348fa..0000000 --- a/GiantBomb.Api/Resources/Search.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -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) - { - 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).ConfigureAwait(false); - - if (result.StatusCode == GiantBombBase.StatusOk) - return result.Results; - - return null; - } - - public IEnumerable SearchForAllGames(string query, string[] limitFields = null) - { - return SearchForAllGamesAsync(query, limitFields).Result; - } - - public async Task> SearchForAllGamesAsync(string query, string[] limitFields = null) { - var results = new List(); - var result = await InternalSearchForGames(query, limitFields: limitFields).ConfigureAwait(false); - - if (result == null || result.StatusCode != GiantBombBase.StatusOk) - return null; - - results.AddRange(result.Results); - - if (result.NumberOfTotalResults > result.Limit) { - double remaining = Math.Ceiling(Convert.ToDouble(result.NumberOfTotalResults) / Convert.ToDouble(result.Limit)); - - // Start on page 2 - for (var i = 2; i <= remaining; i++) { - result = await InternalSearchForGames(query, i, result.Limit, limitFields).ConfigureAwait(false); - - if (result.StatusCode != GiantBombBase.StatusOk) - break; - - results.AddRange(result.Results); - } - } - - // 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).ConfigureAwait(false); - } - } -} diff --git a/GiantBomb.Api/packages.config b/GiantBomb.Api/packages.config deleted file mode 100644 index 43a581e..0000000 --- a/GiantBomb.Api/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/GiantBomb.Api/readme.txt b/GiantBomb.Api/readme.txt deleted file mode 100644 index 6f9ada7..0000000 --- a/GiantBomb.Api/readme.txt +++ /dev/null @@ -1,92 +0,0 @@ -GiantBomb C# ------------- - -[![Build status](https://ci.appveyor.com/api/projects/status/hh268dmpd08qfjqt?svg=true)](https://ci.appveyor.com/project/kamranayub/giantbomb-csharp) - -## 2.3.0 - -- **BUG:** Fixed deserialization exception for single resource errors (e.g. Object Not Found) -- **BUG:** Fixed synchronous API to not deadlock -- Removed fastJSON DLL since it wasn't *actually* being used -- Upgrade to RestSharp 105.2.3 -- Added .NET 4.6 and 4.6.1 support - -## 2.2.1 - -- Better error handling for API exceptions - -## 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: - - `Platform.Aliases` - - `Platform.InstallBase` - - `Platform.OnlineOnly` - - `Platform.OriginalPrice` - - `Game.Franchises` - - `Release.Game` -- Add exception handling and wrapping for GiantBomb API errors (`GiantBombApiException` class) - - For example, exceeding the 400 requests in 15 minutes rate limit -- Allow overriding `Execute` methods -- Update RestSharp to 105 (fixes #13) - -## 2.0.3 - -- Fixes issue with search paging (`offset` vs. `page` parameter) - -## API v2 Support - -GiantBomb-C# 2.0+ is only compatible with GiantBomb APIv2. Keep using the old packages if you need v1 support, as there are breaking changes in v2! - -### Notable Changes - -* Search is now MUCH better in GiantBomb's v2 API, there's little to no need for `SearchAllGames` now unless you expect/want more than 100 results -* List resources support new `sort` and `filter` options -* All single resource requests must use a resource ID, e.g. "game/3030-33394", which GBCS implements transparently for you -* `Game` and `Release` now have `ExpectedReleaseDay` -* Search results now include platforms -* `Game` has two new fields: - - `Aliases` - newline delimited aliases - - `OriginalGameRating` -* You can now use `GetReleasesForGame()` to directly retrieve releases for a game in one request -* Using [FastJSON](http://www.codeproject.com/Articles/159450/fastJSON) to deserialize, which is... fast, obviously - -## Readme - -This library aims to wrap the GiantBomb REST API in C# with strongly-typed models and is built on top of [RestSharp](https://github.com/johnsheehan/RestSharp). - -It also helps make your life easier when dealing with searching because it recursively fetches your search results all at once to enable better sorting. - -**Note: This is not really needed anymore due to search improvements in APIv2** - - var giantBomb = new GiantBombRestClient(); - - // Get all search results - var results = giantBomb.SearchForAllGames("assassin's creed"); - - // Display - return results.OrderByDescending(g => g.DateAdded) - - -## Nuget -Download and install the GiantBomb.Api Nuget package: - - PM> Install-Package GiantBomb.Api - -## Contributing -Read about [contributing on the wiki](https://github.com/kamranayub/GiantBomb-CSharp/wiki). If you plan to contribute, you **must** read this. - -## Examples -Read about [examples on the wiki](https://github.com/kamranayub/GiantBomb-CSharp/wiki). - -## License -Dual-licensed on MIT & GPL diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs deleted file mode 100644 index ac426d9..0000000 --- a/SharedAssemblyInfo.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("GiantBomb.Api")] -[assembly: AssemblyDescription("RestSharp-based API wrapper for the GiantBomb games database public API")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("kayub")] -[assembly: AssemblyProduct("GiantBomb.Api")] -[assembly: AssemblyCopyright("Copyright © kayub 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: ComVisible(false)] - -[assembly: AssemblyVersion("2.3.0")] -[assembly: AssemblyFileVersion("2.3.0")] -[assembly: AssemblyInformationalVersion("2.3.0")] \ No newline at end of file From 29da459f3fc54df1b15f4bde8d62be9002983086 Mon Sep 17 00:00:00 2001 From: Kamran Ayub Date: Fri, 26 May 2017 12:22:14 -0500 Subject: [PATCH 3/4] Move NetStandard folder to normal Api folder --- .gitignore | 1 + GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj | 2 +- {GiantBomb.Api.NetStandard => GiantBomb.Api}/Core.cs | 0 .../GiantBomb.Api.csproj | 2 +- .../GiantBomb.Api.nuspec | 0 .../GiantBombApiException.cs | 0 .../GiantBombDeserializer.cs | 0 .../GiantBombHttpException.cs | 0 .../IGiantBombRestClient.cs | 0 .../Model/Developer.cs | 0 .../Model/Franchise.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Game.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Genre.cs | 0 .../Model/GiantBombBase.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Image.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Platform.cs | 0 .../Model/Publisher.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Rating.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Region.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Release.cs | 0 {GiantBomb.Api.NetStandard => GiantBomb.Api}/ResourceTypes.cs | 0 .../Resources/Games.cs | 0 .../Resources/Platforms.cs | 0 .../Resources/Regions.cs | 0 .../Resources/Releases.cs | 0 .../Resources/Search.cs | 0 GiantBomb.sln | 3 ++- 27 files changed, 5 insertions(+), 3 deletions(-) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Core.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/GiantBomb.Api.csproj (95%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/GiantBomb.Api.nuspec (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/GiantBombApiException.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/GiantBombDeserializer.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/GiantBombHttpException.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/IGiantBombRestClient.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Developer.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Franchise.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Game.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Genre.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/GiantBombBase.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Image.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Platform.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Publisher.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Rating.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Region.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Model/Release.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/ResourceTypes.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Resources/Games.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Resources/Platforms.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Resources/Regions.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Resources/Releases.cs (100%) rename {GiantBomb.Api.NetStandard => GiantBomb.Api}/Resources/Search.cs (100%) diff --git a/.gitignore b/.gitignore index 4c22f47..611d2e4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.DS_Store #Visual Studio files +.vs/ *.[Oo]bj bin*/*.exe *.pdb diff --git a/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj b/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj index 786e0f6..2a50901 100644 --- a/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj +++ b/GiantBomb.Api.Tests/GiantBomb.Api.Tests.csproj @@ -78,7 +78,7 @@ - + {9980b512-d08b-4505-971c-6dfb5cb44e36} GiantBomb.Api diff --git a/GiantBomb.Api.NetStandard/Core.cs b/GiantBomb.Api/Core.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Core.cs rename to GiantBomb.Api/Core.cs diff --git a/GiantBomb.Api.NetStandard/GiantBomb.Api.csproj b/GiantBomb.Api/GiantBomb.Api.csproj similarity index 95% rename from GiantBomb.Api.NetStandard/GiantBomb.Api.csproj rename to GiantBomb.Api/GiantBomb.Api.csproj index 9cac5d5..3546aee 100644 --- a/GiantBomb.Api.NetStandard/GiantBomb.Api.csproj +++ b/GiantBomb.Api/GiantBomb.Api.csproj @@ -2,7 +2,7 @@ netstandard1.2 - GiantBomb.Api.NetStandard + GiantBomb.Api GiantBomb.Api True 2.4.0 diff --git a/GiantBomb.Api.NetStandard/GiantBomb.Api.nuspec b/GiantBomb.Api/GiantBomb.Api.nuspec similarity index 100% rename from GiantBomb.Api.NetStandard/GiantBomb.Api.nuspec rename to GiantBomb.Api/GiantBomb.Api.nuspec diff --git a/GiantBomb.Api.NetStandard/GiantBombApiException.cs b/GiantBomb.Api/GiantBombApiException.cs similarity index 100% rename from GiantBomb.Api.NetStandard/GiantBombApiException.cs rename to GiantBomb.Api/GiantBombApiException.cs diff --git a/GiantBomb.Api.NetStandard/GiantBombDeserializer.cs b/GiantBomb.Api/GiantBombDeserializer.cs similarity index 100% rename from GiantBomb.Api.NetStandard/GiantBombDeserializer.cs rename to GiantBomb.Api/GiantBombDeserializer.cs diff --git a/GiantBomb.Api.NetStandard/GiantBombHttpException.cs b/GiantBomb.Api/GiantBombHttpException.cs similarity index 100% rename from GiantBomb.Api.NetStandard/GiantBombHttpException.cs rename to GiantBomb.Api/GiantBombHttpException.cs diff --git a/GiantBomb.Api.NetStandard/IGiantBombRestClient.cs b/GiantBomb.Api/IGiantBombRestClient.cs similarity index 100% rename from GiantBomb.Api.NetStandard/IGiantBombRestClient.cs rename to GiantBomb.Api/IGiantBombRestClient.cs diff --git a/GiantBomb.Api.NetStandard/Model/Developer.cs b/GiantBomb.Api/Model/Developer.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Developer.cs rename to GiantBomb.Api/Model/Developer.cs diff --git a/GiantBomb.Api.NetStandard/Model/Franchise.cs b/GiantBomb.Api/Model/Franchise.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Franchise.cs rename to GiantBomb.Api/Model/Franchise.cs diff --git a/GiantBomb.Api.NetStandard/Model/Game.cs b/GiantBomb.Api/Model/Game.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Game.cs rename to GiantBomb.Api/Model/Game.cs diff --git a/GiantBomb.Api.NetStandard/Model/Genre.cs b/GiantBomb.Api/Model/Genre.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Genre.cs rename to GiantBomb.Api/Model/Genre.cs diff --git a/GiantBomb.Api.NetStandard/Model/GiantBombBase.cs b/GiantBomb.Api/Model/GiantBombBase.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/GiantBombBase.cs rename to GiantBomb.Api/Model/GiantBombBase.cs diff --git a/GiantBomb.Api.NetStandard/Model/Image.cs b/GiantBomb.Api/Model/Image.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Image.cs rename to GiantBomb.Api/Model/Image.cs diff --git a/GiantBomb.Api.NetStandard/Model/Platform.cs b/GiantBomb.Api/Model/Platform.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Platform.cs rename to GiantBomb.Api/Model/Platform.cs diff --git a/GiantBomb.Api.NetStandard/Model/Publisher.cs b/GiantBomb.Api/Model/Publisher.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Publisher.cs rename to GiantBomb.Api/Model/Publisher.cs diff --git a/GiantBomb.Api.NetStandard/Model/Rating.cs b/GiantBomb.Api/Model/Rating.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Rating.cs rename to GiantBomb.Api/Model/Rating.cs diff --git a/GiantBomb.Api.NetStandard/Model/Region.cs b/GiantBomb.Api/Model/Region.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Region.cs rename to GiantBomb.Api/Model/Region.cs diff --git a/GiantBomb.Api.NetStandard/Model/Release.cs b/GiantBomb.Api/Model/Release.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Model/Release.cs rename to GiantBomb.Api/Model/Release.cs diff --git a/GiantBomb.Api.NetStandard/ResourceTypes.cs b/GiantBomb.Api/ResourceTypes.cs similarity index 100% rename from GiantBomb.Api.NetStandard/ResourceTypes.cs rename to GiantBomb.Api/ResourceTypes.cs diff --git a/GiantBomb.Api.NetStandard/Resources/Games.cs b/GiantBomb.Api/Resources/Games.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Resources/Games.cs rename to GiantBomb.Api/Resources/Games.cs diff --git a/GiantBomb.Api.NetStandard/Resources/Platforms.cs b/GiantBomb.Api/Resources/Platforms.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Resources/Platforms.cs rename to GiantBomb.Api/Resources/Platforms.cs diff --git a/GiantBomb.Api.NetStandard/Resources/Regions.cs b/GiantBomb.Api/Resources/Regions.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Resources/Regions.cs rename to GiantBomb.Api/Resources/Regions.cs diff --git a/GiantBomb.Api.NetStandard/Resources/Releases.cs b/GiantBomb.Api/Resources/Releases.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Resources/Releases.cs rename to GiantBomb.Api/Resources/Releases.cs diff --git a/GiantBomb.Api.NetStandard/Resources/Search.cs b/GiantBomb.Api/Resources/Search.cs similarity index 100% rename from GiantBomb.Api.NetStandard/Resources/Search.cs rename to GiantBomb.Api/Resources/Search.cs diff --git a/GiantBomb.sln b/GiantBomb.sln index 5e0bc42..93afbd6 100644 --- a/GiantBomb.sln +++ b/GiantBomb.sln @@ -7,6 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api.Tests", "Gian EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4851769F-6AF7-484A-88BE-52F7478878B9}" ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore LICENSE.txt = LICENSE.txt Readme.md = Readme.md EndProjectSection @@ -17,7 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9DBE19 .nuget\NuGet.targets = .nuget\NuGet.targets EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api", "GiantBomb.Api.NetStandard\GiantBomb.Api.csproj", "{9980B512-D08B-4505-971C-6DFB5CB44E36}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiantBomb.Api", "GiantBomb.Api\GiantBomb.Api.csproj", "{9980B512-D08B-4505-971C-6DFB5CB44E36}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 5fa007e54e339c22a24f54a0e35693c54263e12b Mon Sep 17 00:00:00 2001 From: Kamran Ayub Date: Fri, 26 May 2017 12:34:27 -0500 Subject: [PATCH 4/4] Update changelog, readme --- CHANGELOG.md | 73 ++++++++++++++++++++++++++++++++++++++ GiantBomb.sln | 1 + Readme.md | 97 ++++++++++++++++++--------------------------------- 3 files changed, 107 insertions(+), 64 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..370dec1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,73 @@ +# Changelog + +## 2.4.0 + +- Switch to [.NET Standard 1.2](https://docs.microsoft.com/en-us/dotnet/standard/library). Adds support for: + - .NET Core 1.0+ + - .NET 4.5.1+ + - Mono 4.6+ + - Xamarin.iOS 10.0+ + - Xamarin.Android 7.0+ + - UWP 10.0+ + - Windows 8.1 + - Windows Phone 8.1 +- Switch to [Fubar.RestSharp.Portable](https://github.com/FubarDevelopment/restsharp.portable) +- More descriptive error handling +- **Temporary:** Remove `Game.ProductCodeType` because API returns incorrect response + +## 2.3.0 + +- **BUG:** Fixed deserialization exception for single resource errors (e.g. Object Not Found) +- **BUG:** Fixed synchronous API to not deadlock +- Removed fastJSON DLL since it wasn't *actually* being used +- Upgrade to RestSharp 105.2.3 +- Added .NET 4.6 and 4.6.1 support + +## 2.2.1 + +- Better error handling for API exceptions + +## 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: + - `Platform.Aliases` + - `Platform.InstallBase` + - `Platform.OnlineOnly` + - `Platform.OriginalPrice` + - `Game.Franchises` + - `Release.Game` +- Add exception handling and wrapping for GiantBomb API errors (`GiantBombApiException` class) + - For example, exceeding the 400 requests in 15 minutes rate limit +- Allow overriding `Execute` methods +- Update RestSharp to 105 (fixes #13) + +## 2.0.3 + +- Fixes issue with search paging (`offset` vs. `page` parameter) + +## API v2 Support + +GiantBomb-C# 2.0+ is only compatible with GiantBomb APIv2. Keep using the old packages if you need v1 support, as there are breaking changes in v2! + +### Notable Changes + +* Search is now MUCH better in GiantBomb's v2 API, there's little to no need for `SearchAllGames` now unless you expect/want more than 100 results +* List resources support new `sort` and `filter` options +* All single resource requests must use a resource ID, e.g. "game/3030-33394", which GBCS implements transparently for you +* `Game` and `Release` now have `ExpectedReleaseDay` +* Search results now include platforms +* `Game` has two new fields: + - `Aliases` - newline delimited aliases + - `OriginalGameRating` +* You can now use `GetReleasesForGame()` to directly retrieve releases for a game in one request +* Using [FastJSON](http://www.codeproject.com/Articles/159450/fastJSON) to deserialize, which is... fast, obviously diff --git a/GiantBomb.sln b/GiantBomb.sln index 93afbd6..69502a4 100644 --- a/GiantBomb.sln +++ b/GiantBomb.sln @@ -8,6 +8,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4851769F-6AF7-484A-88BE-52F7478878B9}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore + CHANGELOG.md = CHANGELOG.md LICENSE.txt = LICENSE.txt Readme.md = Readme.md EndProjectSection diff --git a/Readme.md b/Readme.md index 6f9ada7..f4755ed 100644 --- a/Readme.md +++ b/Readme.md @@ -3,85 +3,50 @@ GiantBomb C# [![Build status](https://ci.appveyor.com/api/projects/status/hh268dmpd08qfjqt?svg=true)](https://ci.appveyor.com/project/kamranayub/giantbomb-csharp) -## 2.3.0 - -- **BUG:** Fixed deserialization exception for single resource errors (e.g. Object Not Found) -- **BUG:** Fixed synchronous API to not deadlock -- Removed fastJSON DLL since it wasn't *actually* being used -- Upgrade to RestSharp 105.2.3 -- Added .NET 4.6 and 4.6.1 support - -## 2.2.1 - -- Better error handling for API exceptions - -## 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: - - `Platform.Aliases` - - `Platform.InstallBase` - - `Platform.OnlineOnly` - - `Platform.OriginalPrice` - - `Game.Franchises` - - `Release.Game` -- Add exception handling and wrapping for GiantBomb API errors (`GiantBombApiException` class) - - For example, exceeding the 400 requests in 15 minutes rate limit -- Allow overriding `Execute` methods -- Update RestSharp to 105 (fixes #13) - -## 2.0.3 - -- Fixes issue with search paging (`offset` vs. `page` parameter) - -## API v2 Support - -GiantBomb-C# 2.0+ is only compatible with GiantBomb APIv2. Keep using the old packages if you need v1 support, as there are breaking changes in v2! - -### Notable Changes - -* Search is now MUCH better in GiantBomb's v2 API, there's little to no need for `SearchAllGames` now unless you expect/want more than 100 results -* List resources support new `sort` and `filter` options -* All single resource requests must use a resource ID, e.g. "game/3030-33394", which GBCS implements transparently for you -* `Game` and `Release` now have `ExpectedReleaseDay` -* Search results now include platforms -* `Game` has two new fields: - - `Aliases` - newline delimited aliases - - `OriginalGameRating` -* You can now use `GetReleasesForGame()` to directly retrieve releases for a game in one request -* Using [FastJSON](http://www.codeproject.com/Articles/159450/fastJSON) to deserialize, which is... fast, obviously - -## Readme - This library aims to wrap the GiantBomb REST API in C# with strongly-typed models and is built on top of [RestSharp](https://github.com/johnsheehan/RestSharp). It also helps make your life easier when dealing with searching because it recursively fetches your search results all at once to enable better sorting. **Note: This is not really needed anymore due to search improvements in APIv2** - var giantBomb = new GiantBombRestClient(); +```c# +var giantBomb = new GiantBombRestClient(); + +// Get all search results +var results = giantBomb.SearchForAllGames("assassin's creed"); + +// Display +return results.OrderByDescending(g => g.DateAdded) +``` - // Get all search results - var results = giantBomb.SearchForAllGames("assassin's creed"); +It's also easy to extend to support other GiantBomb resource types that aren't included by default. +Just create a C# class representing the model and use `GetSingleResource` or `GetListResource`: - // Display - return results.OrderByDescending(g => g.DateAdded) +```c# +var giantBomb = new GiantBombRestClient(); +// Get video +var video = await giantBomb.GetSingleResourceAsync("video", 2300, 123456); +``` ## Nuget Download and install the GiantBomb.Api Nuget package: PM> Install-Package GiantBomb.Api +## Supported Platforms + +This project targets [.NET Standard 1.2](https://docs.microsoft.com/en-us/dotnet/standard/library) + +- .NET Core 1.0+ +- .NET 4.5.1+ +- Mono 4.6+ +- Xamarin.iOS 10.0+ +- Xamarin.Android 7.0+ +- UWP 10.0+ +- Windows 8.1 +- Windows Phone 8.1 + ## Contributing Read about [contributing on the wiki](https://github.com/kamranayub/GiantBomb-CSharp/wiki). If you plan to contribute, you **must** read this. @@ -90,3 +55,7 @@ Read about [examples on the wiki](https://github.com/kamranayub/GiantBomb-CSharp ## License Dual-licensed on MIT & GPL + +## Changelog + +See [CHANGELOG](CHANGELOG.md) \ No newline at end of file