mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
Restructured folders and project names, ci should be fixed
This commit is contained in:
141
src/NadekoBot/Services/Common/ImageLoader.cs
Normal file
141
src/NadekoBot/Services/Common/ImageLoader.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
|
||||
namespace NadekoBot.Core.Services.Common
|
||||
{
|
||||
public class ImageLoader
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
private readonly ConnectionMultiplexer _con;
|
||||
|
||||
public Func<string, RedisKey> GetKey { get; }
|
||||
|
||||
private IDatabase _db => _con.GetDatabase();
|
||||
|
||||
private readonly List<Task<KeyValuePair<RedisKey, RedisValue>>> uriTasks = new List<Task<KeyValuePair<RedisKey, RedisValue>>>();
|
||||
|
||||
public ImageLoader(HttpClient http, ConnectionMultiplexer con, Func<string, RedisKey> getKey)
|
||||
{
|
||||
_http = http;
|
||||
_con = con;
|
||||
GetKey = getKey;
|
||||
}
|
||||
|
||||
private async Task<byte[]> GetImageData(Uri uri)
|
||||
{
|
||||
if (uri.IsFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bytes = await File.ReadAllBytesAsync(uri.LocalPath);
|
||||
return bytes;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "Failed reading image bytes");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return await _http.GetByteArrayAsync(uri);
|
||||
}
|
||||
}
|
||||
|
||||
async Task HandleJArray(JArray arr, string key)
|
||||
{
|
||||
var tasks = arr.Where(x => x.Type == JTokenType.String)
|
||||
.Select(async x =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return await GetImageData((Uri)x).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Error retreiving image for key {Key}: {Data}", key, x);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
byte[][] vals = Array.Empty<byte[]>();
|
||||
vals = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
if (vals.Any(x => x == null))
|
||||
vals = vals.Where(x => x != null).ToArray();
|
||||
|
||||
await _db.KeyDeleteAsync(GetKey(key)).ConfigureAwait(false);
|
||||
await _db.ListRightPushAsync(GetKey(key),
|
||||
vals.Where(x => x != null)
|
||||
.Select(x => (RedisValue)x)
|
||||
.ToArray()).ConfigureAwait(false);
|
||||
|
||||
if (arr.Count != vals.Length)
|
||||
{
|
||||
Log.Information("{2}/{1} URIs for the key '{0}' have been loaded. Some of the supplied URIs are either unavailable or invalid.", key, arr.Count, vals.Count());
|
||||
}
|
||||
}
|
||||
|
||||
async Task<KeyValuePair<RedisKey, RedisValue>> HandleUri(Uri uri, string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
RedisValue data = await GetImageData(uri).ConfigureAwait(false);
|
||||
return new KeyValuePair<RedisKey, RedisValue>(GetKey(key), data);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Information("Setting '{0}' image failed. The URI you provided is either unavailable or invalid.", key.ToLowerInvariant());
|
||||
return new KeyValuePair<RedisKey, RedisValue>("", "");
|
||||
}
|
||||
}
|
||||
|
||||
Task HandleJObject(JObject obj, string parent = "")
|
||||
{
|
||||
string GetParentString()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parent))
|
||||
return "";
|
||||
else
|
||||
return parent + "_";
|
||||
}
|
||||
List<Task> tasks = new List<Task>();
|
||||
Task t;
|
||||
// go through all of the kvps in the object
|
||||
foreach (var kvp in obj)
|
||||
{
|
||||
// if it's a JArray, resole it using jarray method which will
|
||||
// return task<byte[][]> aka an array of all images' bytes
|
||||
if (kvp.Value.Type == JTokenType.Array)
|
||||
{
|
||||
t = HandleJArray((JArray)kvp.Value, GetParentString() + kvp.Key);
|
||||
tasks.Add(t);
|
||||
}
|
||||
else if (kvp.Value.Type == JTokenType.String)
|
||||
{
|
||||
var uriTask = HandleUri((Uri)kvp.Value, GetParentString() + kvp.Key);
|
||||
uriTasks.Add(uriTask);
|
||||
}
|
||||
else if (kvp.Value.Type == JTokenType.Object)
|
||||
{
|
||||
t = HandleJObject((JObject)kvp.Value, GetParentString() + kvp.Key);
|
||||
tasks.Add(t);
|
||||
}
|
||||
}
|
||||
return Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
public async Task LoadAsync(JObject obj)
|
||||
{
|
||||
await HandleJObject(obj).ConfigureAwait(false);
|
||||
var results = await Task.WhenAll(uriTasks).ConfigureAwait(false);
|
||||
await _db.StringSetAsync(results.Where(x => x.Key != "").ToArray()).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user