132 lines
4.2 KiB
C#
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>
|
|
internal 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);
|
|
}
|
|
}
|