Skip to content

Commit

Permalink
Improvements detected in first field test (#9)
Browse files Browse the repository at this point in the history
Fix #2, #3, #4 and #5.
  • Loading branch information
eduherminio authored Apr 6, 2020
1 parent c4e1c54 commit 4365a6b
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;osx-x64</RuntimeIdentifiers>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<Version>0.1.2</Version>
<Version>0.2.0</Version>
<Authors>Eduardo Cáceres</Authors>
<Description>
Multiplatform desktop app that allows you to aggregate the results of multiple Lichess tournaments
Expand Down
19 changes: 13 additions & 6 deletions LichessTournamentAggregator.App/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class Program
{
private const string RepoUrl = "https://github.com/eduherminio/LichessTournamentAggregator";
private static readonly string FailureMessage = "The program has failed unexpectedly," +
$" please raise an issue in {RepoUrl}/issues (or just contact me)," +
$" please have a look at our FAQ: {RepoUrl}#faqs (or just contact me)," +
$" including the following info:{Environment.NewLine}";

public static async Task Main(string[] args)
Expand All @@ -32,7 +32,7 @@ public static async Task Main(string[] args)
catch (ArgumentException e)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Please make this is the tournament url you want to aggregate:");
Console.WriteLine("Please make sure this is the tournament url you want to aggregate:");
Console.WriteLine($"*\t{e.ParamName}");
}
catch (HttpRequestException)
Expand All @@ -41,6 +41,13 @@ public static async Task Main(string[] args)
Console.WriteLine("There may be some issues with Lichess server or you've reached the API limit.");
Console.WriteLine($"Please try again in a few minutes. If the problem persists, raise an issue in {RepoUrl}/issues");
}
catch (UnauthorizedAccessException)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"This app doesn't have permissions to write to {Path.GetFullPath(fileName)}");
Console.WriteLine("Please run it as administrator (right click -> run it as administrator)\n" +
"or move the executable somewhere under C:/Users/<your user>");
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Expand All @@ -57,8 +64,8 @@ public static async Task Main(string[] args)
}

Console.ResetColor();
Console.WriteLine("\nPress any key to close this window");
Console.ReadKey();
Console.WriteLine("\nPress intro to close this window");
Console.ReadLine();
}
}

Expand All @@ -81,13 +88,13 @@ private static IEnumerable<string> AskForTournaments()

private static async Task AggregateResultsAndCreateCsvFile(IEnumerable<string> args, string fileName)
{
var aggregator = new TournamentAggregator();
using FileStream fs = new FileStream(fileName, FileMode.Create);

var aggregator = new TournamentAggregator();
await aggregator.AggregateResultsAndExportToCsv(args, fs);

Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Aggregation finished, results can be found in {fileName}");
Console.WriteLine($"Aggregation finished, results can be found in {Path.GetFullPath(fileName)}");
}
}
}
45 changes: 45 additions & 0 deletions LichessTournamentAggregator.Test/TournamentAggregatorTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Linq;
using Xunit;

namespace LichessTournamentAggregator.Test
{
public class TournamentAggregatorTest
{
private readonly TournamentAggregator _aggregator;

public TournamentAggregatorTest()
{
_aggregator = new TournamentAggregator();
}

[Fact]
public void GetUrls()
{
const string tournamentId = "1op8aqN0";

var validInputs = new[]
{
$"https://lichess.org/tournament/{tournamentId}#",
$"https://lichess.org/tournament/{tournamentId}/",
$"https://lichess.org/tournament/{tournamentId}#/",
$"https://lichess.org/tournament/{tournamentId}/#",
$"lichess.org/tournament/{tournamentId}#",
$"lichess.org/tournament/{tournamentId}/",
$"lichess.org/tournament/{tournamentId}#/",
$"lichess.org/tournament/{tournamentId}/#",
tournamentId,
$"{tournamentId} ",
$"{tournamentId}#",
$"{tournamentId}/",
$"{tournamentId}#/",
$"{tournamentId}/#"
};

var results = _aggregator.GetUrls(validInputs).ToList();

Assert.Equal(
$"https://lichess.org/api/tournament/{tournamentId}/results",
results.ToHashSet().Single().OriginalString);
}
}
}
5 changes: 3 additions & 2 deletions LichessTournamentAggregator.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ VisualStudioVersion = 16.0.29911.84
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LichessTournamentAggregator", "LichessTournamentAggregator\LichessTournamentAggregator.csproj", "{059FA297-6226-4D84-98C3-D3001DDE142D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LichessTournamentAggregator.App", "LichessTournamentAggregator.App\LichessTournamentAggregator.App.csproj", "{B7DE2184-C3D7-42AE-A9BC-0955D49B3E90}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LichessTournamentAggregator.App", "LichessTournamentAggregator.App\LichessTournamentAggregator.App.csproj", "{B7DE2184-C3D7-42AE-A9BC-0955D49B3E90}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CA90D9FD-22B8-46CC-9FEB-4E7C959471C5}"
ProjectSection(SolutionItems) = preProject
azure-pipelines.yml = azure-pipelines.yml
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LichessTournamentAggregator.Test", "LichessTournamentAggregator.Test\LichessTournamentAggregator.Test.csproj", "{BB2E3C40-F996-4719-BEC4-D89BD415FEBF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LichessTournamentAggregator.Test", "LichessTournamentAggregator.Test\LichessTournamentAggregator.Test.csproj", "{BB2E3C40-F996-4719-BEC4-D89BD415FEBF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
2 changes: 1 addition & 1 deletion LichessTournamentAggregator/ITournamentAggregator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public interface ITournamentAggregator
/// <param name="tournamentIdsOrUrls"></param>
/// <param name="fileStream">Stream where data wants to be written into</param>
/// <param name="separator">; by default</param>
/// <returns></returns>
/// <returns>.csv FileStream with aggregated results, ordered by total scores</returns>
Task<FileStream> AggregateResultsAndExportToCsv(IEnumerable<string> tournamentIdsOrUrls, FileStream fileStream, string separator = ";");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<Title>LichessTournamentAggregator</Title>
<PackageId>LichessTournamentAggregator</PackageId>
<Version>0.1.1</Version>
<Version>0.2.0</Version>
<PackageTags>Chess, Lichess, Tournament, Aggregator</PackageTags>
<Tags>$(PackageTags)</Tags>
<Authors>Eduardo Cáceres</Authors>
Expand Down
3 changes: 3 additions & 0 deletions LichessTournamentAggregator/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("LichessTournamentAggregator.Test")]
42 changes: 27 additions & 15 deletions LichessTournamentAggregator/TournamentAggregator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,35 +29,30 @@ public async IAsyncEnumerable<AggregatedResult> AggregateResults(IEnumerable<str

public async Task<FileStream> AggregateResultsAndExportToCsv(IEnumerable<string> tournamentIdsOrUrls, FileStream fileStream, string separator = ";")
{
using StreamWriter sw = new StreamWriter(fileStream);

var headers = new List<string> { "Username", "Total Score", "Max Rating", "Ranks", "Scores", "Average Performance" };
var lines = new List<string> { string.Join(separator, headers) };

var internalSeparator = separator == ";" ? "," : ";";
string aggregate(IEnumerable<int> items) => $"[{string.Join(internalSeparator, items)}]";

var aggregatedResults = new List<AggregatedResult>();
await foreach (var result in AggregateResults(tournamentIdsOrUrls))
{
var columns = new string[] { result.Username, result.TotalScores.ToString(), result.MaxRating.ToString(), aggregate(result.Ranks), aggregate(result.Scores), result.AveragePerformance.ToString("F") };
lines.Add(string.Join(separator, columns));
aggregatedResults.Add(result);
}

lines.ForEach(sw.WriteLine);
aggregatedResults = aggregatedResults
.OrderByDescending(r => r.TotalScores)
.ThenByDescending(r => r.AveragePerformance)
.ToList();

return fileStream;
return PopulateCsvStream(fileStream, separator, aggregatedResults);
}

private IEnumerable<Uri> GetUrls(IEnumerable<string> tournamentIdsOrUrls)
internal IEnumerable<Uri> GetUrls(IEnumerable<string> tournamentIdsOrUrls)
{
const string lichessTournamentUrl = "lichess.org/tournament/";
foreach (var item in tournamentIdsOrUrls.Select(str => str.Trim()))
{
string tournamentId = item;
string tournamentId = item.Trim(new char[] { ' ', '/', '#' });

if (tournamentId.Contains(lichessTournamentUrl))
{
var reverse = string.Join("", item.Reverse());
var reverse = string.Join("", tournamentId.Reverse());
tournamentId = string.Join("", reverse.Take(reverse.IndexOf("/")).Reverse());
}

Expand All @@ -82,5 +77,22 @@ private async Task<IEnumerable<TournamentResult>> GetTournamentResults(Uri url)

return lines.Select(line => JsonSerializer.Deserialize<TournamentResult>(line));
}

private static FileStream PopulateCsvStream(FileStream fileStream, string separator, IEnumerable<AggregatedResult> aggregatedResults)
{
var headers = new List<string> { "Username", "Total Score", "Average Performance", "Max Rating", "Ranks", "Scores" };
using var sw = new StreamWriter(fileStream);
sw.WriteLine(string.Join(separator, headers));

var internalSeparator = separator == ";" ? "," : ";";
string aggregate(IEnumerable<int> items) => $"[{string.Join(internalSeparator, items)}]";
foreach (var result in aggregatedResults)
{
var columns = new string[] { result.Username, result.TotalScores.ToString(), result.AveragePerformance.ToString("F"), result.MaxRating.ToString(), aggregate(result.Ranks), aggregate(result.Scores) };
sw.WriteLine(string.Join(separator, columns));
}

return fileStream;
}
}
}
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@

**Lichess Tournament Aggregator** is a simple command line application that uses [Lichess API](https://github.com/lichess-org/api) to aggregate the results of multiple tournaments and write them to a `.csv` file.

It's currently available for **Windows** (10, 8.1 and 7, for both 32 and 64 bits), **Linux** (Ubuntu, CentOS, Debian, Fedora and derivatives) and **macOS** (macOS 10.12 Sierra and above).
If you happen to use another operating system, another architecture (arm) or an older version of macOS, please open an [issue](https://github.com/eduherminio/LichessTournamentAggregator/issues) and I'll be happy to try to help.

It's also available as a NuGet package.

## Usage

Executables for different operating systems can be found [here](https://github.com/eduherminio/LichessTournamentAggregator/releases).

- Download the appropiated version.
- Download the appropiated version [from here](https://github.com/eduherminio/LichessTournamentAggregator/releases)
- Run the executable.
- Enter the tournament urls or ids whose results you want to aggregate (one per line).
- Press double `enter` to start the process.
Expand All @@ -31,10 +32,6 @@ LichessTournamentAggregator-win-x64.exe 2nu1SO6E https://lichess.org/tournament/

## FAQs

> For which operating systems is the tool available?
It's currently available for **Windows** (10, 8.1 and 7, for both 32 and 64 bits), **Linux** (Ubuntu, CentOS, Debian, Fedora and derivatives) and **macOS** (macOS 10.12 Sierra and above). If you happen to use another operating system, another architecture (arm) or an older version of macOS, please open an [issue](https://github.com/eduherminio/LichessTournamentAggregator/issues) and I'll be happy to try to help.

> I'm a Windows user. How do I know which version to use?
You can check that in `System Information` -> `System type`. Although if you use a reasonably new computer, it's probably going to be x64.
Expand All @@ -43,12 +40,14 @@ You can check that in `System Information` -> `System type`. Although if you use
Try pressing enter again. If it still doesn't work and you get no further any other messages in the console, please fill an [issue](https://github.com/eduherminio/LichessTournamentAggregator/issues) and I'll do my best to help you.

> I'm seeing a red message
Please read it and follow the instructions there.

> I've imported the `*.csv` file and the format seems wrong :(
Please make sure to select `;` as separator when importing the file.

> The clasification isn't ordered.
This program won't order the stats of the different players following any specific criteria, you should do that yourself using your spreadsheet editor.
---

Feel free to contact or or fill an [issue](https://github.com/eduherminio/LichessTournamentAggregator/issues) if you're struggling to use the application or the NuGet package in any way, I'm always happy to help 😉

0 comments on commit 4365a6b

Please sign in to comment.