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); } }