Глобальный рефакторинг пространств имён
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Pf2e.Scrapper.Helpers;
|
||||
|
||||
namespace Pf2e.Scrapper.Importers.Repositories;
|
||||
|
||||
internal abstract class AbstractGitHubRepository(AbstractImporter importer)
|
||||
: AbstractImporterRepository(importer)
|
||||
{
|
||||
public abstract string Repository { get; }
|
||||
public abstract string AssetName { get; }
|
||||
|
||||
public override void Update(ProcessProgress progress)
|
||||
{
|
||||
ReleaseInformation releaseInformation = GetReleaseInformation();
|
||||
string? currentVersion = GetCurrentVersion();
|
||||
|
||||
if (currentVersion == releaseInformation.TagName)
|
||||
{
|
||||
progress.Local.Complete();
|
||||
progress.Information(
|
||||
$"Данные {Repository} актуальны, текущая версия {currentVersion}."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
progress.Information(
|
||||
$"Данные {Repository} устарели, обновляем {RepositoryDirPath} до версии {releaseInformation.TagName}..."
|
||||
);
|
||||
|
||||
string assetFile = DownloadAsset(progress, releaseInformation);
|
||||
|
||||
ExtractAsset(assetFile, RepositoryDirPath, progress);
|
||||
|
||||
File.WriteAllText(
|
||||
Path.Combine(RepositoryDirPath, "version.txt"),
|
||||
releaseInformation.TagName
|
||||
);
|
||||
}
|
||||
|
||||
private ReleaseInformation GetReleaseInformation()
|
||||
{
|
||||
string releasesUrl = $"https://api.github.com/repos/{Repository}/releases/latest";
|
||||
using HttpClient client = new();
|
||||
client.DefaultRequestHeaders.UserAgent.Add(
|
||||
new ProductInfoHeaderValue("Pf2eDataScrapper", "1.0")
|
||||
);
|
||||
string json = client.GetStringAsync(releasesUrl).Result;
|
||||
JObject jObject = JObject.Parse(json);
|
||||
|
||||
return new()
|
||||
{
|
||||
TagName = jObject.SelectToken("tag_name")!.ToObject<string>()!,
|
||||
DownloadUrl = jObject
|
||||
.SelectToken("assets[?(@.name == '" + AssetName + "')].browser_download_url")!
|
||||
.ToObject<string>()!,
|
||||
Size = jObject
|
||||
.SelectToken("assets[?(@.name == '" + AssetName + "')].size")!
|
||||
.ToObject<int>()!,
|
||||
};
|
||||
}
|
||||
|
||||
private string? GetCurrentVersion()
|
||||
{
|
||||
string versionFilePath = Path.Combine(RepositoryDirPath, "version.txt");
|
||||
if (File.Exists(versionFilePath))
|
||||
{
|
||||
return File.ReadAllText(versionFilePath).Trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private string DownloadAsset(ProcessProgress progress, ReleaseInformation releaseInformation)
|
||||
{
|
||||
string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".zip";
|
||||
using var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
|
||||
|
||||
progress.Local.Reset(releaseInformation.Size);
|
||||
progress.Local.Start(
|
||||
$"[1/2] Загрузка {releaseInformation.TagName} ({releaseInformation.Size / 1024 / 1024} МБ)..."
|
||||
);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
using HttpClient client = new();
|
||||
using var response = await client.GetAsync(
|
||||
releaseInformation.DownloadUrl,
|
||||
HttpCompletionOption.ResponseHeadersRead
|
||||
);
|
||||
|
||||
using var download = await response.Content.ReadAsStreamAsync();
|
||||
|
||||
var buffer = new byte[81920];
|
||||
int bytesRead;
|
||||
var t = CancellationToken.None;
|
||||
|
||||
while ((bytesRead = await download.ReadAsync(buffer, t).ConfigureAwait(false)) != 0)
|
||||
{
|
||||
await fileStream
|
||||
.WriteAsync(buffer.AsMemory(0, bytesRead), t)
|
||||
.ConfigureAwait(false);
|
||||
progress.Local.Current += bytesRead;
|
||||
}
|
||||
})
|
||||
.Wait();
|
||||
|
||||
progress.Local.Complete();
|
||||
return fileName;
|
||||
}
|
||||
|
||||
private void ExtractAsset(string assetFile, string targetDir, ProcessProgress progress)
|
||||
{
|
||||
using var zip = ZipFile.OpenRead(assetFile);
|
||||
|
||||
progress.Local.Reset(zip.Entries.Count);
|
||||
progress.Local.Start("[2/2] Распаковка архива...");
|
||||
|
||||
foreach (var entry in zip.Entries)
|
||||
{
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
continue; // Skip directories
|
||||
|
||||
string destinationPath = Path.Combine(targetDir, entry.FullName);
|
||||
|
||||
string directoryPath = Path.GetDirectoryName(destinationPath)!;
|
||||
if (!Directory.Exists(directoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
|
||||
entry.ExtractToFile(destinationPath, true);
|
||||
progress.Local.Current++;
|
||||
}
|
||||
|
||||
progress.Local.Complete();
|
||||
}
|
||||
|
||||
private class ReleaseInformation
|
||||
{
|
||||
public string TagName { get; init; } = null!;
|
||||
public string DownloadUrl { get; init; } = null!;
|
||||
public int Size { get; init; } = 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user