Files
Pf2eDataScrapper/Pf2e/Scrapper/Importers/Implementations/Aonprd/AonprdRepository.cs
T

132 lines
4.2 KiB
C#

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;
/// <summary>
/// Основной класс для работы с репозиторием данных Aonprd.
/// </summary>
public class AonprdRepository(AonprdImporter importer) : AbstractImporterRepository(importer)
{
/// <summary>
/// URL для доступа к API Aonprd.
/// </summary>
public const string SearchUrl = "https://elasticsearch.aonprd.com";
/// <summary>
/// Текущая ревизия данных. Значение обновляется при обновлении репозитория.
/// </summary>
public int Revision { get; private set; }
/// <summary>
/// Метод для загрузки данных из API Aonprd.
/// </summary>
private string Load(string url)
{
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
{
url = SearchUrl + url;
}
using HttpClient client = new();
using Task<Stream> stream = client.GetStreamAsync(url);
using StreamReader reader = new(stream.Result);
return reader.ReadToEnd();
}
/// <inheritdoc/>
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<string, JToken?> 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();
}
/// <summary>
/// Проверка актуальности данных.
/// </summary>
/// <returns>true - актуальная ревизия, false - устаревшая/отсутсвует.</returns>
private bool CheckRevision()
{
JObject page = JObject.Parse(Load("/aon/_doc/feat-1"));
Revision = Convert.ToInt32(
page.SelectToken("_index")?.ToObject<string>()?.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();
}
/// <summary>
/// Запись данных в файл.
/// </summary>
/// <param name="path">Путь к файлу.</param>
/// <param name="content">Содержимое, которе требуется записать в файл.</param>
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);
}
}