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