-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from timia2109/feature/providers
Feature/providers
- Loading branch information
Showing
3,321 changed files
with
409 additions
and
3,519 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -482,4 +482,5 @@ $RECYCLE.BIN/ | |
|
||
# Vim temporary swap files | ||
*.swp | ||
appsettings.Local.json | ||
appsettings.Local.json | ||
Resources/* |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using System.Collections.Frozen; | ||
using Microsoft.Extensions.Options; | ||
using SkiaSharp; | ||
|
||
namespace DisplayUtil.Providers; | ||
|
||
/// <summary> | ||
/// Holds the Fonts | ||
/// </summary> | ||
public class FontProvider(IReadOnlyDictionary<string, string> fontPathes) | ||
{ | ||
/// <summary> | ||
/// Returns the font by the internal name | ||
/// </summary> | ||
/// <param name="fontName">Name of the font</param> | ||
/// <returns>The Font</returns> | ||
/// <exception cref="Exception">Font not defined</exception> | ||
public SKTypeface GetFont(string fontName) | ||
{ | ||
if (!fontPathes.TryGetValue(fontName, out var font)) | ||
{ | ||
throw new Exception($"Font {fontName} not defined!"); | ||
} | ||
|
||
return SKTypeface.FromFile(font); | ||
} | ||
|
||
public static FontProvider CreateFontProvider(IServiceProvider serviceProvider) | ||
{ | ||
var options = serviceProvider | ||
.GetRequiredService<IOptions<ProviderSettings>>(); | ||
|
||
var fonts = new Dictionary<string, string>(options.Value.Fonts); | ||
|
||
// Handle GFonts | ||
var gfontDownloader = ActivatorUtilities | ||
.CreateInstance<GFontDownloader>(serviceProvider); | ||
|
||
var gfonts = fonts | ||
.Where(kv => gfontDownloader.IsGFont(kv.Value)); | ||
|
||
foreach (var (k, v) in gfonts) | ||
{ | ||
var path = gfontDownloader.DownloadFontAsync(v).Result; | ||
fonts[k] = path; | ||
} | ||
|
||
// Check if fonts exists | ||
var missingFiles = fonts | ||
.Except(gfonts) | ||
.Where(e => !File.Exists(e.Value)) | ||
.ToArray(); | ||
|
||
if (missingFiles.Length != 0) | ||
{ | ||
throw new Exception($"Missing fonts detected. Please check existence of: {string.Join(", ", missingFiles)}"); | ||
} | ||
|
||
return new FontProvider(fonts.ToFrozenDictionary()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Text.RegularExpressions; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace DisplayUtil.Providers; | ||
|
||
/// <summary> | ||
/// Responsible to download from Google Fonts | ||
/// </summary> | ||
internal partial class GFontDownloader( | ||
IOptions<ProviderSettings> options, | ||
ILogger<GFontDownloader> logger, | ||
IHttpClientFactory httpClientFactory | ||
) | ||
{ | ||
private readonly ILogger _logger = logger; | ||
private readonly HttpClient _httpClient | ||
= httpClientFactory.CreateClient(nameof(GFontDownloader)); | ||
|
||
private static readonly Dictionary<string, int> _fontWeights = new() | ||
{ | ||
{"thin", 100}, | ||
{"extra-light", 200}, | ||
{"light", 300}, | ||
{"regular", 400}, | ||
{"medium", 500}, | ||
{"semi-bold", 600}, | ||
{"bold", 700}, | ||
{"extra-bold", 800}, | ||
{"black", 900}, | ||
}; | ||
|
||
public bool IsGFont(string fontPath) | ||
{ | ||
return GetGFontRegex().IsMatch(fontPath); | ||
} | ||
|
||
private DownloadData ParseExpression(string fontPath) | ||
{ | ||
var matches = GetGFontRegex().Match(fontPath); | ||
|
||
var download = new DownloadData( | ||
matches.Groups[1].Value, | ||
"regular" | ||
); | ||
|
||
if (matches.Groups.Count >= 3) | ||
download = download with | ||
{ | ||
Weight = matches.Groups[2].Value[1..] | ||
}; | ||
|
||
return download; | ||
} | ||
|
||
private string GeneratePath(DownloadData downloadData) | ||
{ | ||
var basePath = options.Value.GoogleFontsCachePath; | ||
return Path.Combine(basePath, downloadData.FileName); | ||
} | ||
|
||
private static Uri BuildUri(DownloadData downloadData) | ||
{ | ||
var name = $"{downloadData.FontFamily}:wght@{downloadData.Weight}"; | ||
var uri = $"https://fonts.googleapis.com/css2?family={name}"; | ||
|
||
return new Uri(uri); | ||
} | ||
|
||
private async Task HandleDownloadAsync(DownloadData downloadData, string path) | ||
{ | ||
var uri = BuildUri(downloadData); | ||
LogStartDownload(downloadData, uri); | ||
|
||
var response = await _httpClient.GetAsync(uri); | ||
if (!response.IsSuccessStatusCode) | ||
{ | ||
throw new Exception($"Error on downloading font {downloadData}"); | ||
} | ||
var text = await response.Content.ReadAsStringAsync(); | ||
|
||
var ttfUri = GetCssRegex().Match(text); | ||
if (ttfUri is null) | ||
{ | ||
throw new Exception($"Could not parse GFont Response on font {downloadData}"); | ||
} | ||
|
||
var fontResponse = await _httpClient.GetAsync(ttfUri.Groups[1].Value); | ||
await fontResponse.Content.CopyToAsync(File.OpenWrite(path)); | ||
} | ||
|
||
public async Task<string> DownloadFontAsync(string gfontFormat) | ||
{ | ||
var data = ParseExpression(gfontFormat); | ||
|
||
// Check if weight is number | ||
if (!GetNumberRegex().IsMatch(data.Weight)) | ||
{ | ||
data = data with | ||
{ | ||
Weight = _fontWeights[data.Weight].ToString() | ||
}; | ||
} | ||
|
||
var path = GeneratePath(data); | ||
|
||
// Already downloaded. Skip | ||
if (File.Exists(path)) | ||
{ | ||
LogExists(data); | ||
return path; | ||
} | ||
|
||
await HandleDownloadAsync(data, path); | ||
LogFinishDownload(data); | ||
return path; | ||
} | ||
|
||
[GeneratedRegex("^gfonts://([^@]+)(@.+)?$")] | ||
private partial Regex GetGFontRegex(); | ||
|
||
[GeneratedRegex(@"src:\s+url\((.+)\)\s+format\('truetype'\);")] | ||
private partial Regex GetCssRegex(); | ||
|
||
[GeneratedRegex(@"^\d+$")] | ||
private partial Regex GetNumberRegex(); | ||
|
||
[LoggerMessage(LogLevel.Information, "Font {data} already exists. Skip.")] | ||
private partial void LogExists(DownloadData data); | ||
|
||
[LoggerMessage(LogLevel.Information, "Start download font {data} from {uri}")] | ||
private partial void LogStartDownload(DownloadData data, Uri uri); | ||
|
||
[LoggerMessage(LogLevel.Information, "Finished download font {data}")] | ||
private partial void LogFinishDownload(DownloadData data); | ||
|
||
private record DownloadData( | ||
string FontFamily, | ||
string Weight | ||
) | ||
{ | ||
public string FileName => $"gfont_{FontFamily}_{Weight}_v1.ttf"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using DisplayUtil.Utils; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace DisplayUtil.Providers; | ||
|
||
/// <summary> | ||
/// Provides the path to an icon | ||
/// </summary> | ||
public class IconPathProvider(IOptions<ProviderSettings> options) | ||
{ | ||
private const char _separator = ':'; | ||
|
||
private ProviderSettings _settings => options.Value; | ||
|
||
public string ResolvePath(string path) | ||
{ | ||
var (domain, icon) = path.SpiltDomain(_settings.DefaultIcons); | ||
return ResolvePath(domain, icon); | ||
} | ||
|
||
public string ResolvePath(string domain, string iconName) | ||
{ | ||
var basePath = _settings.Icons[domain]; | ||
|
||
return Path.Combine(basePath, $"{iconName}.svg"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
namespace DisplayUtil.Providers; | ||
|
||
public record ProviderSettings | ||
{ | ||
/// <summary> | ||
/// Fonts. | ||
/// Key = Internal name | ||
/// Value = Font Path || gfonts://font-name (downloaded once) | ||
/// </summary> | ||
public IReadOnlyDictionary<string, string> Fonts { get; init; } | ||
= new Dictionary<string, string>(); | ||
|
||
/// <summary> | ||
/// Path where Google Fonts gets cached to | ||
/// </summary> | ||
public string GoogleFontsCachePath { get; init; } = null!; | ||
|
||
/// <summary> | ||
/// Specifies the available icons | ||
/// Key = Protocol | ||
/// Value = Path to SVG Folder | ||
/// </summary> | ||
public IReadOnlyDictionary<string, string> Icons { get; init; } | ||
= new Dictionary<string, string>(); | ||
|
||
/// <summary> | ||
/// Defines the default Icons | ||
/// </summary> | ||
public string? DefaultIcons { get; init; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System.Collections.Frozen; | ||
using DisplayUtil.Utils; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace DisplayUtil.Providers; | ||
|
||
public static class ProvidersInitalizer | ||
{ | ||
|
||
public static IHostApplicationBuilder AddProviders(this IHostApplicationBuilder builder) | ||
{ | ||
builder.ConfigureAndGet<ProviderSettings>("Providers"); | ||
|
||
builder.Services | ||
.AddSingleton(FontProvider.CreateFontProvider) | ||
.AddSingleton<IconPathProvider>(); | ||
|
||
return builder; | ||
} | ||
|
||
|
||
|
||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.