For accessing custom format JSON data using a local Git clone instead of using the Github API. The Github API has limitations on the number of times you can use it, which causes intermittent failures.recyclarr
parent
bd6bd0b225
commit
a6dfb1e220
@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NUnit.Framework;
|
||||
using TrashLib.Radarr.CustomFormat.Guide;
|
||||
|
||||
namespace TrashLib.Tests.Radarr.CustomFormat.Guide
|
||||
{
|
||||
[TestFixture]
|
||||
[Parallelizable(ParallelScope.All)]
|
||||
public class GithubCustomFormatJsonRequesterTest
|
||||
{
|
||||
[Test]
|
||||
public async Task Requesting_json_from_github_works()
|
||||
{
|
||||
var requester = new GithubCustomFormatJsonRequester();
|
||||
|
||||
var jsonList = (await requester.GetCustomFormatJson()).ToList();
|
||||
|
||||
Action act = () => JObject.Parse(jsonList.First());
|
||||
|
||||
// As of the time this test was written, there are around 58 custom format JSON files.
|
||||
// This number can fluctuate over time, but I'm only interested in verifying we get a handful
|
||||
// of files in the response.
|
||||
jsonList.Should().HaveCountGreaterOrEqualTo(5);
|
||||
|
||||
act.Should().NotThrow();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
namespace TrashLib.Config
|
||||
{
|
||||
public interface IResourcePaths
|
||||
{
|
||||
string RepoPath { get; }
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Flurl.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace TrashLib.Radarr.CustomFormat.Guide
|
||||
{
|
||||
internal class GithubCustomFormatJsonRequester : IRadarrGuideService
|
||||
{
|
||||
private readonly ISerializer _flurlSerializer;
|
||||
|
||||
public GithubCustomFormatJsonRequester()
|
||||
{
|
||||
// In addition to setting the naming strategy, this also serves as a mechanism to avoid inheriting the
|
||||
// global Flurl serializer setting: MissingMemberHandling. We do not want missing members to error out
|
||||
// since we're only deserializing a subset of the github response object.
|
||||
_flurlSerializer = new NewtonsoftJsonSerializer(new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new SnakeCaseNamingStrategy()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetCustomFormatJson()
|
||||
{
|
||||
var response = await "https://api.github.com/repos/TRaSH-/Guides/contents/docs/json/radarr"
|
||||
.WithHeader("User-Agent", "Trash Updater")
|
||||
.ConfigureRequest(settings => settings.JsonSerializer = _flurlSerializer)
|
||||
.GetJsonAsync<List<RepoContentEntry>>();
|
||||
|
||||
var tasks = response
|
||||
.Where(o => o.Type == "file" && o.Name.EndsWith(".json"))
|
||||
.Select(o => DownloadJsonContents(o.DownloadUrl));
|
||||
|
||||
return await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
private async Task<string> DownloadJsonContents(string jsonUrl)
|
||||
{
|
||||
return await jsonUrl.GetStringAsync();
|
||||
}
|
||||
|
||||
[UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]
|
||||
private record RepoContentEntry
|
||||
{
|
||||
public string Name { get; init; } = default!;
|
||||
public string Type { get; init; } = default!;
|
||||
public string DownloadUrl { get; init; } = default!;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LibGit2Sharp;
|
||||
using TrashLib.Config;
|
||||
|
||||
namespace TrashLib.Radarr.CustomFormat.Guide
|
||||
{
|
||||
internal class LocalRepoCustomFormatJsonParser : IRadarrGuideService
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly string _repoPath;
|
||||
|
||||
public LocalRepoCustomFormatJsonParser(IFileSystem fileSystem, IResourcePaths paths)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_repoPath = paths.RepoPath;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetCustomFormatJson()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (!Repository.IsValid(_repoPath))
|
||||
{
|
||||
_fileSystem.Directory.Delete(_repoPath, true);
|
||||
Repository.Clone("https://github.com/TRaSH-/Guides.git", _repoPath, new CloneOptions
|
||||
{
|
||||
RecurseSubmodules = false
|
||||
});
|
||||
}
|
||||
|
||||
using var repo = new Repository(_repoPath);
|
||||
Commands.Checkout(repo, "master", new CheckoutOptions
|
||||
{
|
||||
CheckoutModifiers = CheckoutModifiers.Force
|
||||
});
|
||||
|
||||
var origin = repo.Network.Remotes["origin"];
|
||||
Commands.Fetch(repo, origin.Name, origin.FetchRefSpecs.Select(s => s.Specification), null, "");
|
||||
|
||||
repo.Reset(ResetMode.Hard, repo.Branches["origin/master"].Tip);
|
||||
});
|
||||
|
||||
var jsonDir = Path.Combine(_repoPath, "docs/json/radarr");
|
||||
var tasks = _fileSystem.Directory.GetFiles(jsonDir, "*.json")
|
||||
.Select(async f => await _fileSystem.File.ReadAllTextAsync(f));
|
||||
|
||||
return await Task.WhenAll(tasks);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue