Skip to content

Commit

Permalink
version 2 update
Browse files Browse the repository at this point in the history
refactored code - more accurate SubmitAnswer() response
updated README.md
  • Loading branch information
antoniosubasic committed Dec 2, 2023
1 parent 59ed945 commit 0ded66e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 41 deletions.
48 changes: 28 additions & 20 deletions APIHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,40 @@ namespace AoC.API;

public class Session
{
private const string DOMAIN = "https://adventofcode.com";
private string _rawCookie { get; }
private string _cookie => $"session={_rawCookie}";
private int _year { get; }
private int _day { get; }

public string SessionCookie { get; private set; }
public int Year { get; private set; }
public int Day { get; private set; }

public Session(string sessionCookie, int year, int day)
public Session(string cookie, int year, int day)
{
SessionCookie = sessionCookie;
Year = year;
Day = day;
_rawCookie = cookie;
_year = year;
_day = day;
}

public Session(string sessionCookie, string input, Regex pattern)
public Session(string cookie, string input, Regex pattern)
{
SessionCookie = sessionCookie;
_rawCookie = cookie;

var match = pattern.Match(input);
if (match.Success)
{
Year = int.Parse(match.Groups["year"].Value);
Day = int.Parse(match.Groups["day"].Value);
_year = int.Parse(match.Groups["year"].Value);
_day = int.Parse(match.Groups["day"].Value);
}
else { throw new Exception("no regex match found"); }
}


private async Task<string> SendRequest(HttpMethod method, string uri, HttpContent? content = null)
{
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = method,
RequestUri = new Uri(uri),
Headers = { { "Cookie", $"session={SessionCookie}" } }
Headers = { { "Cookie", _cookie } }
};
if (content != null) { request.Content = content; }

Expand All @@ -49,12 +49,12 @@ private async Task<string> SendRequest(HttpMethod method, string uri, HttpConten
}
}

public async Task<string> GetInputText() => (await SendRequest(HttpMethod.Get, $"{DOMAIN}/{Year}/day/{Day}/input")).TrimEnd('\n');
public async Task<string> GetInputText() => (await SendRequest(HttpMethod.Get, $"https://www.adventofcode.com/{_year}/day/{_day}/input")).TrimEnd('\n');
public async Task<string[]> GetInputLines() => (await GetInputText()).Split('\n');

public async Task<Dictionary<int, int>> GetAllStars()
{
var response = (await SendRequest(HttpMethod.Get, $"{DOMAIN}/events"))
var response = (await SendRequest(HttpMethod.Get, $"https://www.adventofcode.com/events"))
.Split('\n')
.Where(line => line.StartsWith("<div class=\"eventlist-event\">"))
.ToArray();
Expand All @@ -71,14 +71,22 @@ public async Task<Dictionary<int, int>> GetAllStars()
}).ToDictionary(x => x.Year, x => x.Stars);
}

public async Task<bool> SubmitAnswer(int level, object answer)
public async Task<bool> SubmitAnswer(int part, object answer)
{
var content = new StringContent($"level={level}&answer={answer}")
var content = new StringContent($"level={part}&answer={answer}")
{
Headers = { ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded") }
};

var response = await SendRequest(HttpMethod.Post, $"{DOMAIN}/{Year}/day/{Day}/answer", content);
return response.Contains("That's the right answer!");
var response = await SendRequest(HttpMethod.Post, $"https://www.adventofcode.com/{_year}/day/{_day}/answer", content);

if (response.Contains("That's the right answer!")) { return true; }
else if (response.Contains("Your puzzle answer was"))
{
var regex = new Regex(@"<p>Your puzzle answer was <code>(?<answer>.*?)</code>.*?</p>");
var matches = regex.Matches(response);
return matches.Count >= part && answer.ToString() == matches[part - 1].Groups["answer"].Value;
}
else { return false; }
}
}
6 changes: 3 additions & 3 deletions AoC.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<Nullable>enable</Nullable>
<PackageId>AoCAPI</PackageId>
<Authors>Antonio Subašić</Authors>
<Description>Handle personal AoC data directly from your .NET project</Description>
<Description>a simple Advent of Code API</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>AoCAPI, Advent-of-Code-API</PackageTags>
<PackageTags>AoC, Advent-of-Code, API</PackageTags>
<RepositoryUrl>https://github.com/antonio-subasic/AoC.API</RepositoryUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageVersion>2.0.3</PackageVersion>
<PackageVersion>2.1.3</PackageVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
[![Version](https://img.shields.io/nuget/v/AoCAPI)](https://www.nuget.org/packages/AoCAPI)
[![Downloads](https://img.shields.io/nuget/dt/AoCAPI)](https://www.nuget.org/packages/AoCAPI)

A simple [NuGet](https://nuget.org) package to handle personal [AoC](https://adventofcode.com) data directly from your .NET project
a simple [Advent of Code](https://adventofcode.com) API

## Documentation

- [Add to your project](#add-to-your-project)
- [Initialization](#initialization)
- [Add NuGet package](#add-nuget-package)
- [Session initialization](#session-initialization)
- [Features](#features)
- [Get Input Files](#get-input-file)
- [Get Achieved Stars](#get-achieved-stars)
- [Submit Answer](#submit-answer)
- [Get input file](#get-input-file)
- [Get achieved stars](#get-achieved-stars)
- [Submit answer](#submit-answer)

<br><br>

# Add to your project
# Add NuGet package

```bash
dotnet add package AoCAPI
Expand All @@ -26,7 +26,7 @@ using AoC.API;

<br>

# Initialization
# Session initialization

```csharp
var client = new Session("session cookie", int year, int day);
Expand All @@ -40,11 +40,9 @@ var client = new Session("session cookie", string input, Regex pattern);
> <source media="(prefers-color-scheme: dark)" srcset="https://github.com/Mqxx/GitHub-Markdown/blob/main/blockquotes/badge/dark-theme/info.svg">
> <img alt="Info" src="https://github.com/Mqxx/GitHub-Markdown/blob/main/blockquotes/badge/dark-theme/Info">
> </picture><br>
> The Regex overload needs to have the group containing the year named "year" and the group containing the day named "day".
> [How to obtain session cookie](https://mmhaskell.com/blog/2023/1/30/advent-of-code-fetching-puzzle-input-using-the-api#authentication)
> [How to name Regex groups](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group)
> The Regex overload needs to have a regex group named "year" and a group named "day".
> <br> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group">How to name Regex groups</a>
> <br> <a href="https://mmhaskell.com/blog/2023/1/30/advent-of-code-fetching-puzzle-input-using-the-api#authentication">How to obtain session cookie</a>
<br>

Expand All @@ -54,25 +52,28 @@ var client = new Session("session cookie", string input, Regex pattern);

```csharp
string inputText = client.GetInputText(); // input file (raw text)
string inputLines = client.GetInputLines(); // input file (lines)
string inputLines = client.GetInputLines(); // input file (lines array)
```

<br>

## Get achieved stars

```csharp
Dictionary<int, int> allStars = client.GetAllStars(); // all user's achieved stars (key = year, value = stars)
Dictionary<int, int> achievedStars = client.GetAllStars(); // all user's achieved stars (key = year, value = stars)
```

<br>

## Submit answer

```csharp
bool succeeded = client.SubmitAnswer(int level, object answer); // submits answer to initialized year and day, returns true if answer is correct
bool succeeded = client.SubmitAnswer(int part, object answer); // submits answer to initialized year and day, returns true if answer is correct
```

<br><br>

> credits to:<br> > [Max](https://github.com/Mqxx) - markdown info icons<br> > [Monday Morning Haskell](https://mmhaskell.com/) - documentation on how to obtaining session cookie<br> > [Developer.Mozilla](https://developer.mozilla.org) - documentation on how to name Regex groups
*credits to:*
> [Max](https://github.com/Mqxx) - markdown info icons <br>
> [Monday Morning Haskell](https://mmhaskell.com/) - documentation on how to obtaining session cookie <br>
> [Developer.Mozilla](https://developer.mozilla.org) - documentation on how to name Regex groups
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
A simple [NuGet](https://nuget.org) package to handle personal [AoC](https://adventofcode.com) data directly from your .NET project
a simple [Advent of Code](https://adventofcode.com) API

[Read Documentation](https://github.com/antonio-subasic/AoC.API#readme)

0 comments on commit 0ded66e

Please sign in to comment.