You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
5.3 KiB

using System;
using System.IO;
using System.Net.Http;
using System.Linq;
namespace AdventOfCode.InputFetcher
{
class Program
{
private static readonly string AdventOfCodeEndpoint = "https://adventofcode.com/{YEAR}/day";
private static HttpClient _client;
static void Main(string[] args)
{
Console.WriteLine("Please select your year! Default: 2023");
var year = SanitizeInput(Console.ReadLine(), "2023");
Console.WriteLine("Please enter your session key for advent of code:");
var sessionKey = Console.ReadLine();
Console.WriteLine("Please input the target directory for the input files! Default: Current working directory");
var targetDir = SanitizeInput(Console.ReadLine(), Directory.GetCurrentDirectory());
Console.WriteLine("File Name Format? Default: \"{YEAR}_{TYPE}_Day_{DAY}{PART}.txt\" => 2022_Input_Day_1.txt or 2022_Answer_Day_1-PartB");
var format = SanitizeInput(Console.ReadLine(), "{YEAR}_{TYPE}_Day_{DAY}{PART}.txt");
Console.WriteLine("Pull Answers? (Y/N) Default: Y");
var answer = SanitizeInput(Console.ReadLine(), "Y");
Console.WriteLine("Overwrite? (Y/N) Default: N");
var overwrite = SanitizeInput(Console.ReadLine(), "N");
_client = new HttpClient();
_client.DefaultRequestHeaders.Add("Cookie", $"session={sessionKey}");
var filesOnDisk = new DirectoryInfo(targetDir);
for (int day = 1; day <= 25; day++)
{
var dataFileName = format.Replace("{DAY}", day.ToString()).Replace("{TYPE}", "Input").Replace("{PART}", "").Replace("{YEAR}", year);
var answerFileNameA = format.Replace("{DAY}", day.ToString()).Replace("{TYPE}", "Answer").Replace("{PART}", "A").Replace("{YEAR}", year);
var answerFileNameB = format.Replace("{DAY}", day.ToString()).Replace("{TYPE}", "Answer").Replace("{PART}", "B").Replace("{YEAR}", year);
bool dataFileExistsOnDisk = filesOnDisk.EnumerateFiles().Any(x => x.Name == dataFileName);
if (!dataFileExistsOnDisk || (overwrite.ToUpper() == "Y"))
{
try
{
File.WriteAllText(targetDir + Path.DirectorySeparatorChar + dataFileName, PullDataForDay(year, day));
}catch(FileNotFoundException e)
{
//Input data not available yet
continue;
}
}
if (answer.ToUpper() == "Y")
{
bool answerFileAExistsOnDisk = filesOnDisk.EnumerateFiles().Any(x => x.Name == answerFileNameA);
bool answerFileBExistsOnDisk = filesOnDisk.EnumerateFiles().Any(x => x.Name == answerFileNameB);
if ((!answerFileBExistsOnDisk && !answerFileBExistsOnDisk) || (overwrite.ToUpper() == "Y"))
{
var answers = PullAnswerForDay(year, day);
if (!string.IsNullOrWhiteSpace(answers.Item1))
File.WriteAllText(targetDir + Path.DirectorySeparatorChar + answerFileNameA, answers.Item1);
if (!string.IsNullOrWhiteSpace(answers.Item2))
File.WriteAllText(targetDir + Path.DirectorySeparatorChar + answerFileNameB, answers.Item2);
}
}
}
}
private static string PullDataForDay(string year, int day)
{
return ExecuteWebRequest(string.Format("{0}/{1}/input", AdventOfCodeEndpoint.Replace("{YEAR}", year), day));
}
private static readonly string SearchString = "Your puzzle answer was";
private static Tuple<string, string> PullAnswerForDay(string year, int day)
{
var html = ExecuteWebRequest(string.Format("{0}/{1}", AdventOfCodeEndpoint.Replace("{YEAR}", year), day));
var answerStart = html.IndexOf(SearchString);
if (answerStart < 0) return Tuple.Create("", "");
var startingIndex = html.IndexOf("<code>", answerStart) + "<code>".Length;
var endIndex = html.IndexOf("</code>", answerStart);
var partA = startingIndex < 0 || endIndex < 0 ? "No Answer Found yet." : html.Substring(startingIndex, (endIndex-startingIndex));
html = html.Substring(endIndex + 1);
answerStart = html.IndexOf(SearchString);
startingIndex = html.IndexOf("<code>", answerStart) + "<code>".Length;
endIndex = html.IndexOf("</code>", answerStart);
var partB = startingIndex < 0 || endIndex < 0 ? "No Answer Found yet." : html.Substring(startingIndex, (endIndex - startingIndex));
return Tuple.Create(partA, partB);
}
private static string ExecuteWebRequest(string url)
{
var resp = _client.GetAsync(url).Result;
if (resp.StatusCode == System.Net.HttpStatusCode.NotFound) throw new FileNotFoundException("No day input was found!");
return resp.Content.ReadAsStringAsync().Result;
}
private static string SanitizeInput(string input, string defaultText)
{
if (string.IsNullOrWhiteSpace(input)) return defaultText;
return input;
}
}
}