using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Pf2e.Scrapper.Helpers;
using Pf2e.Scrapper.Importers.Repositories;
namespace Pf2e.Scrapper.Importers.Implementations.Aonprd;
///
/// Основной класс для работы с репозиторием данных Aonprd.
///
internal class AonprdRepository(AonprdImporter importer) : AbstractImporterRepository(importer)
{
///
/// URL для доступа к API Aonprd.
///
public const string SearchUrl = "https://elasticsearch.aonprd.com";
///
/// Текущая ревизия данных. Значение обновляется при обновлении репозитория.
///
public int Revision { get; private set; }
///
/// Метод для загрузки данных из API Aonprd.
///
private string Load(string url)
{
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
{
url = SearchUrl + url;
}
using HttpClient client = new();
using Task stream = client.GetStreamAsync(url);
using StreamReader reader = new(stream.Result);
return reader.ReadToEnd();
}
///
public override void Update(ProcessProgress progress)
{
if (CheckRevision())
{
progress.Local.Complete();
progress.Information($"Данные Aonprd актуальны, текущая ревизия {Revision}.");
return;
}
progress.Information(
$"Данные Aonprd устарели, обновляем {RepositoryDirPath} до ревизии {Revision}..."
);
progress.Local.Reset(1);
if (Directory.Exists(RepositoryDirPath))
{
Directory.Delete(RepositoryDirPath, true);
}
Directory.CreateDirectory(RepositoryDirPath);
WriteFile("revision.txt", Revision.ToString());
progress.Local.Start("Загрузка индекса...");
string indexContent = Load($"/json-data/aon{Revision}-index.json");
WriteFile("index.json", indexContent);
JObject indexJson = JObject.Parse(indexContent);
progress.Local.Reset(indexJson.Count + 1);
progress.Local.End();
foreach (KeyValuePair kvp in indexJson)
{
string fileName = kvp.Key;
progress.Local.Start(fileName);
string fileContent = Load($"/json-data/{fileName}.json");
WriteFile($"{fileName}.json", fileContent);
progress.Local.End();
}
progress.Local.Complete();
}
///
/// Проверка актуальности данных.
///
/// true - актуальная ревизия, false - устаревшая/отсутсвует.
private bool CheckRevision()
{
JObject page = JObject.Parse(Load("/aon/_doc/feat-1"));
Revision = Convert.ToInt32(
page.SelectToken("_index")?.ToObject()?.Replace("aon", "")
?? throw new("Не удаётся получить ревизию Архивов Нефиса.")
);
string revisionFile = Path.Combine(RepositoryDirPath, "revision.txt");
if (!File.Exists(revisionFile))
{
return false;
}
using StreamReader reader = new(revisionFile);
string lastRevision = reader.ReadToEnd();
return lastRevision == Revision.ToString();
}
///
/// Запись данных в файл.
///
/// Путь к файлу.
/// Содержимое, которе требуется записать в файл.
private void WriteFile(string path, string content)
{
string filePath = Path.Combine(RepositoryDirPath, path);
if (File.Exists(filePath))
{
File.Delete(filePath);
}
using StreamWriter writer = new(filePath);
writer.Write(content);
}
}