From 6a9b69b254a935c88c5ec0d2f9c4f3b2858be613 Mon Sep 17 00:00:00 2001 From: Mikhail Shabanov Date: Sat, 6 Jun 2020 15:54:23 +0200 Subject: [PATCH] AchievementDictionaries saving done --- .../Dictionaries/AchievementDictionary.cs | 76 +++++ .../Dictionaries/AchievementOption.cs | 31 +++ .../DictionariesDataAccessor.cs | 10 + .../IDictionariesDataAccessor.cs | 2 + .../AchievementsDictionaryUpdater.cs | 70 ++++- .../Mappers/AchievementDictionaryProfile.cs | 22 ++ .../Mappers/AchievementOptionProfile.cs | 17 ++ .../AchievementsDictionaryUpdaterTests.cs | 263 ++++++++++++++++++ .../IWargamingDictionariesApiClient.cs | 7 +- .../WotEncyclopediaAchievementsResponse.cs | 108 +++++++ .../WargamingApiClient.cs | 10 + 11 files changed, 613 insertions(+), 3 deletions(-) create mode 100644 WotBlitzStatisticsPro.Common/Dictionaries/AchievementDictionary.cs create mode 100644 WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs create mode 100644 WotBlitzStatisticsPro.Logic/Mappers/AchievementDictionaryProfile.cs create mode 100644 WotBlitzStatisticsPro.Logic/Mappers/AchievementOptionProfile.cs create mode 100644 WotBlitzStatisticsPro.Tests/DictionariesTests/AchievementsDictionaryUpdaterTests.cs create mode 100644 WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs diff --git a/WotBlitzStatisticsPro.Common/Dictionaries/AchievementDictionary.cs b/WotBlitzStatisticsPro.Common/Dictionaries/AchievementDictionary.cs new file mode 100644 index 0000000..6d2b4ce --- /dev/null +++ b/WotBlitzStatisticsPro.Common/Dictionaries/AchievementDictionary.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; + +namespace WotBlitzStatisticsPro.Common.Dictionaries +{ + /// + /// Achievement dictionary item + /// + public class AchievementDictionary + { + /// + /// id + /// + public string AchievementId { get; set; } + + /// + /// Achievement condition + /// + public List Condition { get; set; } + + /// + /// Achievement description + /// + public List Description { get; set; } + + /// + /// Historical info + /// + public List HeroInfo { get; set; } + + /// + /// Image link + /// + public string Image { get; set; } + + /// + /// Image 180x180px link + /// + public string ImageBig { get; set; } + + /// + /// Achievement name + /// + public List Name { get; set; } + + /// + /// Sort order + /// + public long? Order { get; set; } + + /// + /// Is outdated achievement + /// + public bool Outdated { get; set; } + + /// + /// Achievement section + /// + public string SectionId { get; set; } + + /// + /// Achievement section order + /// + public long? SectionOrder { get; set; } + + /// + /// Achievement Type + /// + public string Type { get; set; } + + /// + /// Achievement options + /// + public List Options { get; set; } + + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs b/WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs new file mode 100644 index 0000000..08264aa --- /dev/null +++ b/WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace WotBlitzStatisticsPro.Common.Dictionaries +{ + /// + /// Achievement option + /// + public class AchievementOption + { + /// + /// Achievement option description + /// + public List Description { get; set; } + + /// + /// Image link + /// + public string Image { get; set; } + + /// + /// Image 180x180px link + /// + public string ImageBig { get; set; } + + /// + /// Achievement option name + /// + public List Name { get; set; } + + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/DictionariesDataAccessor.cs b/WotBlitzStatisticsPro.DataAccess/DictionariesDataAccessor.cs index 4cd4a64..b7bd5f0 100644 --- a/WotBlitzStatisticsPro.DataAccess/DictionariesDataAccessor.cs +++ b/WotBlitzStatisticsPro.DataAccess/DictionariesDataAccessor.cs @@ -13,6 +13,7 @@ namespace WotBlitzStatisticsPro.DataAccess private const string VehicleTypesCollectionName = "dictionary-vehicle-types"; private const string ClanRolesCollectionName = "dictionary-clan-roles"; private const string AchievementsSectionsCollectionName = "dictionary-achievements-sections"; + private const string AchievementsCollectionName = "dictionary-achievements"; private readonly IMongoDatabase _database; @@ -62,5 +63,14 @@ namespace WotBlitzStatisticsPro.DataAccess await dbAchievementSections.DeleteManyAsync(Builders.Filter.Empty); await dbAchievementSections.InsertManyAsync(achievementSections); } + + public async Task UpdateAchievements(List achievementDictionary) + { + var dbAchievementSections = + _database.GetCollection(AchievementsCollectionName); + + await dbAchievementSections.DeleteManyAsync(Builders.Filter.Empty); + await dbAchievementSections.InsertManyAsync(achievementDictionary); + } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/IDictionariesDataAccessor.cs b/WotBlitzStatisticsPro.DataAccess/IDictionariesDataAccessor.cs index 85d9796..add465b 100644 --- a/WotBlitzStatisticsPro.DataAccess/IDictionariesDataAccessor.cs +++ b/WotBlitzStatisticsPro.DataAccess/IDictionariesDataAccessor.cs @@ -15,5 +15,7 @@ namespace WotBlitzStatisticsPro.DataAccess Task UpdateClanRoles(List clanRoles); Task UpdateAchievementsSections(List achievementSections); + + Task UpdateAchievements(List achievementDictionary); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs b/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs index 1687ec1..e9c7e51 100644 --- a/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs +++ b/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs @@ -1,9 +1,13 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using AutoMapper; +using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Model; using WotBlitzStatisticsPro.DataAccess; using WotBlitzStatisticsPro.WgApiClient; +using WotBlitzStatisticsPro.WgApiClient.Model; namespace WotBlitzStatisticsPro.Logic.Dictionaries { @@ -26,9 +30,71 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries _mapper = mapper; } - public virtual Task Update() + public virtual async Task Update() { - throw new System.NotImplementedException(); + var achievementDictionary = await GetAndMapAchievementsDictionary(); + + await _dataAccessor.UpdateAchievements(achievementDictionary); + + return new UpdateDictionariesResponseItem + { + DictionaryType = DictionaryType.Achievements, + Description = $"Got and saved {achievementDictionary.Count} achievement dictionary items" + }; + } + + private async Task> GetAndMapAchievementsDictionary() + { + var defaultRealmType = RealmType.Eu; + + var achievements = new List(); + + foreach (var requestLanguage in (RequestLanguage[])Enum.GetValues(typeof(RequestLanguage))) + { + var wgAchievements = + await _wargamingDictionariesApiClient.GetAchievementsDictionary(defaultRealmType, requestLanguage); + foreach (var wgAchievement in wgAchievements) + { + var mappedAchievement = + achievements.FirstOrDefault(a => a.AchievementId == wgAchievement.AchievementId); + if (mappedAchievement == null) + { + mappedAchievement = + _mapper.Map(wgAchievement); + achievements.Add(mappedAchievement); + } + mappedAchievement.Name.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Name }); + mappedAchievement.Condition.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Condition }); + mappedAchievement.Description.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Description }); + mappedAchievement.HeroInfo.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.HeroInfo }); + + if (wgAchievement.Options != null) + { + if (mappedAchievement.Options == null) + { + mappedAchievement.Options = new List(); + } + + foreach (var wgAchievementOption in wgAchievement.Options) + { + // image is the only unique identifier + var mappedOption = + mappedAchievement.Options.FirstOrDefault(o => o.Image == wgAchievementOption.Image); + if (mappedOption == null) + { + mappedOption = + _mapper.Map( + wgAchievementOption); + mappedAchievement.Options.Add(mappedOption); + } + mappedOption.Name.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Name }); + mappedOption.Description.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Description }); + } + } + } + } + + return achievements; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/Mappers/AchievementDictionaryProfile.cs b/WotBlitzStatisticsPro.Logic/Mappers/AchievementDictionaryProfile.cs new file mode 100644 index 0000000..dff6897 --- /dev/null +++ b/WotBlitzStatisticsPro.Logic/Mappers/AchievementDictionaryProfile.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using AutoMapper; +using WotBlitzStatisticsPro.Common.Dictionaries; +using WotBlitzStatisticsPro.WgApiClient.Model; + +namespace WotBlitzStatisticsPro.Logic.Mappers +{ + public class AchievementDictionaryProfile : Profile + { + public AchievementDictionaryProfile() + { + CreateMap() + .ForMember(d => d.Name, o => o.MapFrom(_ => new List())) + .ForMember(d => d.Condition, o => o.MapFrom(_ => new List())) + .ForMember(d => d.Description, o => o.MapFrom(_ => new List())) + .ForMember(d => d.HeroInfo, o => o.MapFrom(_ => new List())) + .ForMember(d => d.SectionId, o => o.MapFrom(s => s.Section)) + .ForMember(d => d.Options, o => o.Ignore()); + + } + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/Mappers/AchievementOptionProfile.cs b/WotBlitzStatisticsPro.Logic/Mappers/AchievementOptionProfile.cs new file mode 100644 index 0000000..12f2235 --- /dev/null +++ b/WotBlitzStatisticsPro.Logic/Mappers/AchievementOptionProfile.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using AutoMapper; +using WotBlitzStatisticsPro.Common.Dictionaries; +using WotBlitzStatisticsPro.WgApiClient.Model; + +namespace WotBlitzStatisticsPro.Logic.Mappers +{ + public class AchievementOptionProfile : Profile + { + public AchievementOptionProfile() + { + CreateMap() + .ForMember(d => d.Name, o => o.MapFrom(_ => new List())) + .ForMember(d => d.Description, o => o.MapFrom(_ => new List())); + } + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Tests/DictionariesTests/AchievementsDictionaryUpdaterTests.cs b/WotBlitzStatisticsPro.Tests/DictionariesTests/AchievementsDictionaryUpdaterTests.cs new file mode 100644 index 0000000..bc10f84 --- /dev/null +++ b/WotBlitzStatisticsPro.Tests/DictionariesTests/AchievementsDictionaryUpdaterTests.cs @@ -0,0 +1,263 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AutoMapper; +using AutoMapper.Configuration; +using Bogus; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using WotBlitzStatisticsPro.Common.Dictionaries; +using WotBlitzStatisticsPro.Common.Model; +using WotBlitzStatisticsPro.DataAccess; +using WotBlitzStatisticsPro.Logic.Dictionaries; +using WotBlitzStatisticsPro.Logic.Mappers; +using WotBlitzStatisticsPro.WgApiClient; +using WotBlitzStatisticsPro.WgApiClient.Model; + +namespace WotBlitzStatisticsPro.Tests.DictionariesTests +{ + [TestFixture] + public class AchievementsDictionaryUpdaterTests + { + private AchievementsDictionaryUpdater _achievementDictionariesUpdater; + private Mock _wargamingDictionariesApiClientMock; + private Mock _dataAccessorMock; + + private List _achievementsInfoResponseEn; + private List _achievementsInfoResponseRu; + private List _achievementsInfoResponseDe; + + [SetUp] + public void Init() + { + // Generating fake data + _achievementsInfoResponseEn = GetAchievementsInfoResponse("en"); + _achievementsInfoResponseRu = GetAchievementsInfoResponse("ru", _achievementsInfoResponseEn); + _achievementsInfoResponseDe = GetAchievementsInfoResponse("de", _achievementsInfoResponseEn); + + + // Real mapper instance + var configurationExp = new MapperConfigurationExpression(); + configurationExp.AddProfile(); + configurationExp.AddProfile(); + var mapperConfiguration = new MapperConfiguration(configurationExp); + IMapper mapper = new Mapper(mapperConfiguration); + + // Wargaming client mock + _wargamingDictionariesApiClientMock = new Mock(); + _wargamingDictionariesApiClientMock.Setup(w => + w.GetAchievementsDictionary(It.IsAny(), RequestLanguage.En)) + .ReturnsAsync(_achievementsInfoResponseEn); + _wargamingDictionariesApiClientMock.Setup(w => + w.GetAchievementsDictionary(It.IsAny(), RequestLanguage.Ru)) + .ReturnsAsync(_achievementsInfoResponseRu); + _wargamingDictionariesApiClientMock.Setup(w => + w.GetAchievementsDictionary(It.IsAny(), RequestLanguage.De)) + .ReturnsAsync(_achievementsInfoResponseDe); + + // MongoDb data accessor mock + _dataAccessorMock = new Mock(); + + _achievementDictionariesUpdater = new AchievementsDictionaryUpdater( + _wargamingDictionariesApiClientMock.Object, + _dataAccessorMock.Object, + mapper); + + } + + [Test] + public async Task ShouldCallWargamingApi3Times() + { + await _achievementDictionariesUpdater.Update(); + + // Should call wargaming API once for each language + _wargamingDictionariesApiClientMock.Verify(d => d.GetAchievementsDictionary(It.IsAny(), RequestLanguage.En), Times.Once); + _wargamingDictionariesApiClientMock.Verify(d => d.GetAchievementsDictionary(It.IsAny(), RequestLanguage.Ru), Times.Once); + _wargamingDictionariesApiClientMock.Verify(d => d.GetAchievementsDictionary(It.IsAny(), RequestLanguage.De), Times.Once); + } + + [Test] + public async Task ShouldSaveAppropriateAchievementsDictionary() + { + List targetAchievementDictionaries = null; + _dataAccessorMock + .Setup(d => d.UpdateAchievements(It.IsAny>())) + .Callback((List dictionary) => targetAchievementDictionaries = dictionary); + + await _achievementDictionariesUpdater.Update(); + + targetAchievementDictionaries.Should().NotBeNull(); + targetAchievementDictionaries.Should().HaveCount(targetAchievementDictionaries.Count); + + for (var i = 0; i < targetAchievementDictionaries.Count; i++) + { + targetAchievementDictionaries[i].AchievementId.Should() + .Be(_achievementsInfoResponseEn[i].AchievementId); + targetAchievementDictionaries[i].Name.First(n => n.Language == RequestLanguage.En).Value.Should() + .Be(_achievementsInfoResponseEn[i].Name); + targetAchievementDictionaries[i].Name.First(n => n.Language == RequestLanguage.Ru).Value.Should() + .Be(_achievementsInfoResponseRu[i].Name); + targetAchievementDictionaries[i].Name.First(n => n.Language == RequestLanguage.De).Value.Should() + .Be(_achievementsInfoResponseDe[i].Name); + targetAchievementDictionaries[i].Description.First(n => n.Language == RequestLanguage.En).Value.Should() + .Be(_achievementsInfoResponseEn[i].Description); + targetAchievementDictionaries[i].Description.First(n => n.Language == RequestLanguage.Ru).Value.Should() + .Be(_achievementsInfoResponseRu[i].Description); + targetAchievementDictionaries[i].Description.First(n => n.Language == RequestLanguage.De).Value.Should() + .Be(_achievementsInfoResponseDe[i].Description); + targetAchievementDictionaries[i].Condition.First(n => n.Language == RequestLanguage.En).Value.Should() + .Be(_achievementsInfoResponseEn[i].Condition); + targetAchievementDictionaries[i].Condition.First(n => n.Language == RequestLanguage.Ru).Value.Should() + .Be(_achievementsInfoResponseRu[i].Condition); + targetAchievementDictionaries[i].Condition.First(n => n.Language == RequestLanguage.De).Value.Should() + .Be(_achievementsInfoResponseDe[i].Condition); + + if (_achievementsInfoResponseEn[i].Options == null) + { + targetAchievementDictionaries[i].Options.Should().BeNull(); + } + else + { + targetAchievementDictionaries[i].Options.Should().NotBeNull(); + targetAchievementDictionaries[i].Options.Count.Should() + .Be(_achievementsInfoResponseEn[i].Options.Length); + + } + } + + } + + + #region Fixtures + + private static List GetAchievementsInfoResponse(string language, List baseEncyclopedia = null) + { + var result = new List(); + var faker = new Faker(language); + + if (baseEncyclopedia == null) + { + var random = faker.Random; + for (int i = 0; i < random.Number(200); i++) + { + result.Add(FakeNewDictionaryItem(faker)); + } + } + else + { + foreach (var achievementsResponse in baseEncyclopedia) + { + result.Add(FakeDictionaryItem(faker, achievementsResponse)); + } + } + + return result; + } + + private static WotEncyclopediaAchievementsResponse FakeNewDictionaryItem(Faker faker) + { + return new WotEncyclopediaAchievementsResponse + { + Name = faker.Commerce.ProductName(), + AchievementId = faker.Lorem.Word(), + Description = faker.Lorem.Sentence(), + Condition = faker.Lorem.Sentence(), + Options = faker.Random.Bool() ? FakeOptions(faker) : null + }; + } + + private static WotEncyclopediaAchievementsResponse FakeDictionaryItem(Faker faker, WotEncyclopediaAchievementsResponse baseResponse) + { + return new WotEncyclopediaAchievementsResponse + { + Name = faker.Commerce.ProductName(), + AchievementId = baseResponse.AchievementId, + Description = faker.Lorem.Sentence(), + Condition = faker.Lorem.Sentence(), + Options = baseResponse.Options + }; + } + + private static WotEncyclopediaAchievementsOptions[] FakeOptions(Faker faker) + { + var result = new WotEncyclopediaAchievementsOptions[4]; + for (int i = 0; i < 4; i++) + { + result[i] = new WotEncyclopediaAchievementsOptions + { + Name = faker.Lorem.Word(), + Description = faker.Lorem.Sentence(), + Image = faker.Internet.Url() + }; + } + + return result; + } + + private static WotClanMembersDictionaryResponse GetClanMembersDictionaryResponse(string language, WotClanMembersDictionaryResponse baseClanRoles = null) + { + return new WotClanMembersDictionaryResponse + { + ClanRoles = baseClanRoles == null ? FakeDictionary(3, language) : FakeDictionary(language, baseClanRoles.ClanRoles) + }; + } + + private static Dictionary FakeDictionary(int elementsCount, string language = "en") + { + var result = new Dictionary(); + var faker = new Faker(language); + + for (int i = 0; i < elementsCount; i++) + { + result[faker.Lorem.Word()] = faker.Lorem.Word(); + } + + return result; + } + + private static Dictionary FakeDictionary(string language, + Dictionary baseDictionary) + { + var result = new Dictionary(); + var faker = new Faker(language); + + foreach (var baseValue in baseDictionary) + { + result[baseValue.Key] = faker.Lorem.Word(); + } + + return result; + } + + private static Dictionary FakeAchievementSections(int elementsCount, string language = "en") + { + var result = new Dictionary(); + var faker = new Faker(language); + + for (int i = 0; i < elementsCount; i++) + { + result[faker.Lorem.Word()] = new WotEncyclopediaInfoAchievementSection { Name = faker.Lorem.Word() }; + } + + return result; + } + + private static Dictionary FakeAchievementSections(string language, + Dictionary baseDictionary) + { + var result = new Dictionary(); + var faker = new Faker(language); + + foreach (var baseValue in baseDictionary) + { + result[baseValue.Key] = new WotEncyclopediaInfoAchievementSection { Name = faker.Lorem.Word() }; + } + + return result; + } + + #endregion + + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs index 17d47ee..af3260a 100644 --- a/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using WotBlitzStatisticsPro.Common.Model; using WotBlitzStatisticsPro.WgApiClient.Model; @@ -11,5 +12,9 @@ namespace WotBlitzStatisticsPro.WgApiClient WotClanMembersDictionaryResponse)> GetStaticDictionariesAsync( RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); + + Task> GetAchievementsDictionary( + RealmType realmType = RealmType.Ru, + RequestLanguage language = RequestLanguage.En); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs new file mode 100644 index 0000000..1e85a26 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs @@ -0,0 +1,108 @@ +using System; +using Newtonsoft.Json; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class WotEncyclopediaAchievementsResponse + { + [JsonProperty("achievement_id")] + public string AchievementId { get; set; } + + /// + /// Achievement condition + /// + [JsonProperty("condition")] + public string Condition { get; set; } + + /// + /// Achievement description + /// + [JsonProperty("description")] + public string Description { get; set; } + + /// + /// Historical info + /// + [JsonProperty("hero_info")] + public string HeroInfo { get; set; } + + /// + /// Image link + /// + [JsonProperty("image")] + public string Image { get; set; } + + /// + /// Image 180x180px link + /// + [JsonProperty("image_big")] + public string ImageBig { get; set; } + + /// + /// Achievement name + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// Sort order + /// + [JsonProperty("order")] + public long? Order { get; set; } + + /// + /// Is outdated achievement + /// + [JsonProperty("outdated")] + public bool Outdated { get; set; } + + /// + /// Achievement section + /// + [JsonProperty("section")] + public string Section { get; set; } + + /// + /// Achievement section order + /// + [JsonProperty("section_order")] + public long? SectionOrder { get; set; } + + /// + /// Achievement Type + /// + [JsonProperty("type")] + public string Type { get; set; } + + /// + /// Achievement options + /// + [JsonProperty("options")] + public WotEncyclopediaAchievementsOptions[] Options { get; set; } + } + + public class WotEncyclopediaAchievementsOptions + { + + /// + /// Achievement description + /// + [JsonProperty("description")] + public string Description { get; set; } + + /// + /// Image link + /// + [JsonProperty("image")] + public string Image { get; set; } + + /// + /// Image 180x180px link + /// + [JsonProperty("image_big")] + public string ImageBig { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs index 7f6f38c..9c825a6 100644 --- a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using WotBlitzStatisticsPro.Common; @@ -65,6 +66,15 @@ namespace WotBlitzStatisticsPro.WgApiClient return (encyclopedia, clanGlossaryResponse); } + public async Task> GetAchievementsDictionary(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) + { + var response = await GetFromBlitzApi>( + realmType, + language, + "encyclopedia/achievements/").ConfigureAwait(false); + + return response.Values.ToList(); + } #endregion