Smash test

test debug

Result

Disctinct by selector
Refactoring Smash/Challonge

Test Resultat

Html for Kiouze
This commit is contained in:
2022-03-11 01:14:56 +01:00
parent 45768fff80
commit aebc60d17f
16 changed files with 459 additions and 22 deletions

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using LaDOSE.Business.Interface;
using LaDOSE.DTO;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace LaDOSE.Api.Controllers
{
#if DEBUG
[AllowAnonymous]
#endif
[Produces("application/json")]
[Route("api/[controller]")]
public class SmashController : Controller
{
private ITournamentService _service;
private IMapper _mapper;
// GET
public SmashController(IMapper mapper, ITournamentService service)
{
_mapper = mapper;
_service = service;
}
//This may be a get , but i dont know what the RFC State for Get request with Body
//As i don't like to populate GET request with body this will be a post (and i think
//it will be easier to proxy.
[HttpGet("GetTournament/{tournamentSlug}")]
public async Task<IActionResult> GetSmashTournament(string tournamentSlug)
{
if (!String.IsNullOrEmpty(tournamentSlug))
{
var tournaments = await _service.GetSmashResult(tournamentSlug);
return Ok(tournaments);
}
return null;
}
//[HttpPost("GetResults")]
//public async Task<TournamentsResultDTO> GetResults([FromBody] List<int> ids)
//{
// if (ids == null)
// {
// throw new Exception("Invalid arguments");
// }
// var tournamentsResult = await _service.GetTournamentsResult(ids);
// return _mapper.Map<TournamentsResultDTO>(tournamentsResult);
//}
}
}

View File

@@ -37,11 +37,9 @@ namespace LaDOSE.Api.Controllers
return _mapper.Map<List<TournamentDTO>>(tournaments); return _mapper.Map<List<TournamentDTO>>(tournaments);
} }
return null; return null;
} }
[HttpPost("GetResults")] [HttpPost("GetResults")]
public async Task<TournamentsResultDTO> GetResults([FromBody] List<int> ids) public async Task<TournamentsResultDTO> GetResults([FromBody] List<int> ids)
{ {
@@ -54,5 +52,7 @@ namespace LaDOSE.Api.Controllers
return _mapper.Map<TournamentsResultDTO>(tournamentsResult); return _mapper.Map<TournamentsResultDTO>(tournamentsResult);
} }
} }
} }

View File

@@ -26,6 +26,8 @@ using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
using AutoMapper; using AutoMapper;
using LaDOSE.Api.Helpers; using LaDOSE.Api.Helpers;
using LaDOSE.Business.Helper; using LaDOSE.Business.Helper;
using LaDOSE.Business.Provider.ChallongProvider;
using LaDOSE.Business.Provider.SmashProvider;
using LaDOSE.Entity.Challonge; using LaDOSE.Entity.Challonge;
using LaDOSE.Entity.Wordpress; using LaDOSE.Entity.Wordpress;
@@ -140,6 +142,7 @@ namespace LaDOSE.Api
{ {
services.AddTransient<IChallongeProvider>(p => new ChallongeProvider(this.Configuration["ApiKey:ChallongeApiKey"])); services.AddTransient<IChallongeProvider>(p => new ChallongeProvider(this.Configuration["ApiKey:ChallongeApiKey"]));
services.AddTransient<ISmashProvider>(p => new SmashProvider(this.Configuration["ApiKey:SmashApiKey"]));
services.AddScoped<IUserService, UserService>(); services.AddScoped<IUserService, UserService>();
services.AddScoped<IGameService, GameService>(); services.AddScoped<IGameService, GameService>();
services.AddScoped<IEventService, EventService>(); services.AddScoped<IEventService, EventService>();

View File

@@ -44,6 +44,17 @@ namespace LaDOSE.DesktopApp.ViewModels
} }
} }
private string _slug;
public String Slug
{
get { return _slug; }
set
{
_slug = value;
NotifyOfPropertyChange(() => Slug);
}
}
private String _html; private String _html;
public String Html public String Html
@@ -213,7 +224,17 @@ namespace LaDOSE.DesktopApp.ViewModels
ComputeHtml(); ComputeHtml();
}); });
} }
public void GetSmash()
{
WpfUtil.Await(() =>
{
var resultsDto = this.RestService.GetSmashResults(Slug);
this.Results = resultsDto;
ComputeDataGrid();
ComputeHtml();
});
}
public void SelectYear() public void SelectYear()
{ {
@@ -318,7 +339,7 @@ namespace LaDOSE.DesktopApp.ViewModels
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.Append("<table style=\"text-align: center; margin-top: 15px;\" align=\"center\"><tbody>"); sb.Append("<table class=\"table table-responsive-md table-dark table-striped mt-lg-4 mt-3\">");
int columns = 0; int columns = 0;
foreach (var game in Results.Games) foreach (var game in Results.Games)
@@ -329,14 +350,19 @@ namespace LaDOSE.DesktopApp.ViewModels
sb.Append("<tr>"); sb.Append("<tr>");
} }
columns++; columns++;
sb.Append("<td colspan=\"1\" width=\"50 % \">" + sb.Append("<td colspan=\"1\" width=\"50%\">" +
"<span style=\"color: #ff0000;\">" + "<span style=\"color: #ff0000;\">" +
$"<strong>{game.LongName} ({Results.Results.Count(e => e.GameId == game.Id)} participants) :</strong>" + $"<strong>{game.LongName} ({Results.Results.Count(e => e.GameId == game.Id)} participants) :</strong>" +
"</span>"); "</span>");
List<ResultDTO> enumerable = Results.Results.Where(r => r.GameId == game.Id).ToList(); List<ResultDTO> enumerable = Results.Results.Where(r => r.GameId == game.Id).ToList();
List<string> top3 = enumerable.OrderBy(e => e.Rank).Take(3).Select(e => e.Player).ToList(); List<string> top3 = enumerable.OrderBy(e => e.Rank).Take(3).Select(e => e.Player).ToList();
sb.AppendLine($"<br> 1/ {top3[0]}<br> 2/ {top3[1]}<br> 3/ {top3[2]}<p></p>"); if (top3.Count >= 3)
{
sb.AppendLine($"<br> 1/ {top3[0]}<br> 2/ {top3[1]}<br> 3/ {top3[2]} <br>");
sb.AppendLine($"<a href=\"https://challonge.com/fr/{enumerable.First().TournamentUrl}\" target=\"_blank\">https://challonge.com/fr/{enumerable.First().TournamentUrl}</a></p></td>"); sb.AppendLine($"<a href=\"https://challonge.com/fr/{enumerable.First().TournamentUrl}\" target=\"_blank\">https://challonge.com/fr/{enumerable.First().TournamentUrl}</a></p></td>");
}
if (columns % 2 == 0) if (columns % 2 == 0)
{ {
sb.Append("</tr>"); sb.Append("</tr>");

View File

@@ -18,6 +18,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="2*" /> <RowDefinition Height="2*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
@@ -84,6 +85,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -171,7 +173,12 @@
</TabControl> </TabControl>
<Button Grid.Row="4" Grid.ColumnSpan="3" x:Name="Export">Export</Button> <Button Grid.Row="4" Grid.ColumnSpan="3" x:Name="Export">Export</Button>
</Grid>
</Grid> </Grid>
<StackPanel Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal">
<TextBlock> Slug :</TextBlock>
<TextBox Width="200" Text="{Binding Slug}"></TextBox>
<Button x:Name="GetSmash" >Get Smash Tournaments Result</Button>
</StackPanel>
</Grid>
</UserControl> </UserControl>

View File

@@ -11,8 +11,18 @@ namespace LaDOSE.Entity
public int Order { get; set; } public int Order { get; set; }
public string WordPressTag { get; set; } public string WordPressTag { get; set; }
public string WordPressTagOs { get; set; } public string WordPressTagOs { get; set; }
public int? SmashId { get; set; }
public virtual IEnumerable<SeasonGame> Seasons { get; set; } public virtual IEnumerable<SeasonGame> Seasons { get; set; }
public virtual IEnumerable<EventGame> Events { get; set; } public virtual IEnumerable<EventGame> Events { get; set; }
}
public class SmashParticipent : Context.Entity
{
public string Name { get; set; }
public string Tag { get; set; }
public int? SmashId{ get; set; }
} }
} }

View File

@@ -267,6 +267,14 @@ namespace LaDOSE.REST
} }
public TournamentsResultDTO GetSmashResults(string slug)
{
CheckToken();
var restRequest = new RestRequest($"Api/Smash/GetTournament/{slug}", Method.GET);
var restResponse = Client.Get<TournamentsResultDTO>(restRequest);
return restResponse.Data;
}
#endregion #endregion
} }

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace LaDOSE.Business.Helper
{
public static class DataHelper
{
public static IEnumerable<T> DistinctBy<T,TKey>(this IEnumerable<T> lst,Func<T,TKey> dist)
{
var seen = new HashSet<TKey>();
foreach (var e in lst)
{
if (!seen.Contains(dist(e)))
{
seen.Add(dist(e));
yield return e;
}
}
}
}
}

View File

@@ -18,4 +18,5 @@ namespace LaDOSE.Business.Interface
Task<ChallongeTournament> GetTournament(int idTournament); Task<ChallongeTournament> GetTournament(int idTournament);
Task<ChallongeTournament> GetTournament(string urlTournament); Task<ChallongeTournament> GetTournament(string urlTournament);
} }
} }

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LaDOSE.Business.Provider.SmashProvider;
using LaDOSE.Entity.Challonge;
namespace LaDOSE.Business.Interface
{
public interface ISmashProvider
{
Task<List<ChallongeTournament>> GetTournaments(DateTime? start, DateTime? end);
Task<ResponseType> GetTournament(string sludge);
}
}

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LaDOSE.Business.Provider.SmashProvider;
using LaDOSE.Entity.Challonge; using LaDOSE.Entity.Challonge;
namespace LaDOSE.Business.Interface namespace LaDOSE.Business.Interface
@@ -10,5 +11,6 @@ namespace LaDOSE.Business.Interface
Task<List<ChallongeTournament>> GetTournaments(DateTime? start, DateTime? end); Task<List<ChallongeTournament>> GetTournaments(DateTime? start, DateTime? end);
Task<TournamentsResult> GetTournamentsResult(List<int> ids); Task<TournamentsResult> GetTournamentsResult(List<int> ids);
Task<TournamentsResult> GetSmashResult(string tournamentSlug);
} }
} }

View File

@@ -7,6 +7,11 @@
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="GraphQL.Client" Version="4.0.2" />
<PackageReference Include="GraphQL.Client.Serializer.Newtonsoft" Version="4.0.2" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\LaDOSE.Entity\LaDOSE.Entity.csproj" /> <ProjectReference Include="..\LaDOSE.Entity\LaDOSE.Entity.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -10,7 +10,7 @@ using ChallongeCSharpDriver.Core.Results;
using LaDOSE.Business.Interface; using LaDOSE.Business.Interface;
using LaDOSE.Entity.Challonge; using LaDOSE.Entity.Challonge;
namespace LaDOSE.Business.Provider namespace LaDOSE.Business.Provider.ChallongProvider
{ {
public class ChallongeProvider : IChallongeProvider public class ChallongeProvider : IChallongeProvider
{ {
@@ -30,9 +30,9 @@ namespace LaDOSE.Business.Provider
DernierTournois = "Aucun tournois."; DernierTournois = "Aucun tournois.";
} }
public async Task<TournamentResult> CreateTournament(string name, string url,DateTime? startAt = null) public async Task<TournamentResult> CreateTournament(string name, string url, DateTime? startAt = null)
{ {
var result = await new CreateTournamentQuery(name, startAt , TournamentType.Double_Elimination, url).call(ApiCaller); var result = await new CreateTournamentQuery(name, startAt, TournamentType.Double_Elimination, url).call(ApiCaller);
return result; return result;
@@ -70,7 +70,7 @@ namespace LaDOSE.Business.Provider
public async Task<List<ChallongeParticipent>> GetParticipents(int idTournament) public async Task<List<ChallongeParticipent>> GetParticipents(int idTournament)
{ {
var participentResults = await new ParticipantsQuery(){tournamentID = idTournament }.call(ApiCaller); var participentResults = await new ParticipantsQuery() { tournamentID = idTournament }.call(ApiCaller);
List<ChallongeParticipent> participants = new List<ChallongeParticipent>(); List<ChallongeParticipent> participants = new List<ChallongeParticipent>();
participentResults.ForEach(w => participentResults.ForEach(w =>

View File

@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using GraphQL;
using GraphQL.Client.Http;
using GraphQL.Client.Serializer.Newtonsoft;
using LaDOSE.Business.Interface;
using LaDOSE.Entity.Challonge;
namespace LaDOSE.Business.Provider.SmashProvider
{
public class SmashProvider : ISmashProvider
{
public string ApiKey { get; set; }
public SmashProvider(string apiKey)
{
this.ApiKey = apiKey;
}
public Task<List<ChallongeTournament>> GetTournaments(DateTime? start, DateTime? end)
{
var list = new List<ChallongeTournament>();
var personAndFilmsRequest = new GraphQLRequest
{
Query = @"
query TournamentsByOwner($perPage: Int!, $ownerId: ID!) {
tournaments(query: {
perPage: $perPage
filter: {
ownerId: $ownerId
}
}) {
nodes {
id
name
slug
}
}
}",
OperationName = "PersonAndFilms",
Variables = new
{
ownerId = "161429",
perPage = "4"
}
};
return Task.FromResult(list);
}
public async Task<ResponseType> GetTournament(string slug)
{
var graphQLClient = new GraphQLHttpClient("https://api.smash.gg/gql/alpha", new NewtonsoftJsonSerializer());
graphQLClient.HttpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
var Event = new GraphQLRequest
{
Query = @"query TournamentQuery($slug: String) {
tournament(slug: $slug){
id
name
events {
id
name,
state,
videogame {
id,
name,
displayName
}
standings(query: {page:0,perPage:500}){
nodes{
id,
player{
id,
gamerTag,
user {
id,
name,
player {
id
}
}
}
placement
}
}
}
}
}",
OperationName = "TournamentQuery",
Variables = new
{
slug = slug,
}
};
//GraphQLHttpRequest preprocessedRequest = await graphQLClient.Options.PreprocessRequest(Event, graphQLClient);
//var x = preprocessedRequest.ToHttpRequestMessage(graphQLClient.Options, new NewtonsoftJsonSerializer());
//System.Diagnostics.Trace.WriteLine(x.Content.ReadAsStringAsync().Result);
//var sendAsync = await graphQLClient.HttpClient.SendAsync(x);
//System.Diagnostics.Trace.WriteLine(sendAsync.Content.ReadAsStringAsync().Result);
var graphQLResponse = await graphQLClient.SendQueryAsync<ResponseType>(Event);
if (graphQLResponse.Errors != null)
{
//Event not done ?
//throw new Exception("Error");
}
System.Diagnostics.Trace.Write(graphQLResponse.Data.Tournament.Name);
return graphQLResponse.Data;
}
}
}

View File

@@ -0,0 +1,66 @@
using System.Collections.Generic;
namespace LaDOSE.Business.Provider.SmashProvider
{
public class ResponseType
{
public TournamentType Tournament { get; set; }
public class TournamentType
{
public int id { get; set; }
public string Name { get; set; }
public List<Event> Events { get; set; }
}
public class Event
{
public int id { get; set; }
public string name { get; set; }
public string state { get; set; }
public VideoGame videogame { get; set; }
public Node<Standing> standings { get; set; }
}
public class VideoGame
{
public int id { get; set; }
public string Name { get; set; }
}
public class Node<T>
{
public List<T> nodes { get; set; }
}
public class Standing
{
public int id { get; set; }
public int placement { get; set; }
public Player player { get; set; }
}
public class Player
{
public int id { get; set; }
public string gamerTag { get; set; }
public User user { get; set; }
}
public class User
{
public int id { get; set; }
public string name { get; set; }
}
}
}

View File

@@ -2,7 +2,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using LaDOSE.Business.Helper;
using LaDOSE.Business.Interface; using LaDOSE.Business.Interface;
using LaDOSE.Business.Provider.SmashProvider;
using LaDOSE.Entity; using LaDOSE.Entity;
using LaDOSE.Entity.Challonge; using LaDOSE.Entity.Challonge;
using LaDOSE.Entity.Context; using LaDOSE.Entity.Context;
@@ -50,12 +52,16 @@ namespace LaDOSE.Business.Service
new Rules(16, 32, 12, 8, 5, 3, 2), new Rules(16, 32, 12, 8, 5, 3, 2),
new Rules(32, Int32.MaxValue, 18, 12, 8, 5, 3), new Rules(32, Int32.MaxValue, 18, 12, 8, 5, 3),
}; };
private ISmashProvider _smashProvider;
#endregion #endregion
public TournamentService(LaDOSEDbContext context, IChallongeProvider challongeProvider) : base(context) public TournamentService(LaDOSEDbContext context, IChallongeProvider challongeProvider, ISmashProvider _smashProvider) : base(context)
{ {
this._context = context; this._context = context;
this._challongeProvider = challongeProvider; this._challongeProvider = challongeProvider;
this._smashProvider = _smashProvider;
} }
public async Task<List<ChallongeTournament>> GetTournaments(DateTime? start, DateTime? end) public async Task<List<ChallongeTournament>> GetTournaments(DateTime? start, DateTime? end)
@@ -147,6 +153,89 @@ namespace LaDOSE.Business.Service
return result; return result;
} }
public async Task<TournamentsResult> GetSmashResult(string tournamentSlug)
{
var tournaments = await _smashProvider.GetTournament(tournamentSlug);
var players = tournaments.Tournament.Events.Where(e=>e.standings != null ).SelectMany(e => e.standings.nodes.Select(e => e.player)).ToList();
var distinctp = players.DistinctBy(e=>new {e.user.id}).ToList();
var games = _context.Game.ToList();
TournamentsResult result = new TournamentsResult();
result.Results = new List<Result>();
result.Games = new List<Game>();
result.Participents = new List<ChallongeParticipent>();
distinctp.ForEach(e =>
{
var x = new ChallongeParticipent()
{
Name = e.gamerTag,
ChallongeId = e.id,
Id = e.id
};
result.Participents.Add(x);
});
games.ForEach(e =>
{
e.Id = e.SmashId ?? e.Id;
result.Games.Add(e);
});
foreach (var tournament in tournaments.Tournament.Events.Where(e=>e.standings!=null).ToList())
{
var playerCount = tournament.standings.nodes.Count;
var lesSacs = tournament.standings.nodes;
var currentRule = TournamentRules.FirstOrDefault(rules =>
rules.PlayerMin < playerCount && rules.PlayerMax >= playerCount
);
if (currentRule == null)
{
throw new Exception("Unable to find rules");
}
var first = tournament.standings.nodes.First(p => p.placement == 1);
var second = tournament.standings.nodes.First(p => p.placement == 2);
var thirdFourth = tournament.standings.nodes.Where(p => p.placement == 3 || p.placement == 4).ToList();
var Top8 = tournament.standings.nodes.Where(p => p.placement > 4 && p.placement < 9).ToList();
var Top16 = tournament.standings.nodes.Where(p => p.placement > 8 && p.placement <= 16).ToList();
result.Results.Add(new Result(first.player.gamerTag, tournament.videogame.id, tournament.id, tournament.name, currentRule.FirstPoint, first.placement));
lesSacs.Remove(first);
result.Results.Add(new Result(second.player.gamerTag, tournament.videogame.id, tournament.id, tournament.name, currentRule.SecondPoint, second.placement));
lesSacs.Remove(second);
thirdFourth.ForEach(r =>
result.Results.Add(new Result(r.player.gamerTag, tournament.videogame.id, tournament.id, tournament.name,
currentRule.ThirdFourthPoint, r.placement)));
thirdFourth.ForEach(p => lesSacs.Remove(p));
if (currentRule.Top8Point != 0)
{
Top8.ForEach(r =>
result.Results.Add(new Result(r.player.gamerTag, tournament.videogame.id, tournament.id, tournament.name,
currentRule.ThirdFourthPoint, r.placement)));
Top8.ForEach(p => lesSacs.Remove(p));
}
if (currentRule.Top16Point != 0)
{
Top16.ForEach(r =>
result.Results.Add(
new Result(r.player.gamerTag, tournament.videogame.id, tournament.id, tournament.name,
currentRule.ThirdFourthPoint, r.placement)));
Top16.ForEach(p => lesSacs.Remove(p));
}
lesSacs.ForEach(r =>
result.Results.Add(new Result(r.player.gamerTag, tournament.videogame.id, tournament.id, tournament.name,
currentRule.ThirdFourthPoint, r.placement)));
}
return await Task.FromResult(result);
}
/// <summary> /// <summary>
/// Check if the tournament exist in database otherwise call Challonge. /// Check if the tournament exist in database otherwise call Challonge.
/// </summary> /// </summary>