11using System . Text . Json ;
2- using System . Text . RegularExpressions ;
32using GoogleMaterialDesignIconsGenerator . Model . Google ;
43
54namespace GoogleMaterialDesignIconsGenerator . Service ;
65
76public class IconHttpClientService : IDisposable
87{
98 public const string GoogleFontUrl = "http://fonts.google.com/" ;
10- public const string GoogleFontsCssApiUrl = "https://fonts.googleapis.com/css2" ;
11- private static readonly Regex Woff2UrlRegex = new ( @"url\((['""]?)(?<href>https://[^)'""]+?\.woff2)\1\)" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
9+ public const string GoogleMaterialDesignIconsRawUrl = "https://github.com/google/material-design-icons/raw/refs/heads/master/variablefont/" ;
1210
1311 private readonly HttpClient _httpClient ;
1412 private readonly JsonSerializerOptions _jsonSerializerOptions ;
15- private static readonly ( string FamilyName , string TargetFileName ) [ ] MaterialSymbolsFontFiles =
13+ private static readonly ( string SourceFileName , string TargetFileName ) [ ] MaterialSymbolsFontFiles =
1614 [
17- ( "Material Symbols Outlined " , "MaterialSymbolsOutlined.woff2" ) ,
18- ( "Material Symbols Rounded " , "MaterialSymbolsRounded.woff2" ) ,
19- ( "Material Symbols Sharp " , "MaterialSymbolsSharp.woff2" )
15+ ( "MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2 " , "MaterialSymbolsOutlined.woff2" ) ,
16+ ( "MaterialSymbolsRounded[FILL,GRAD,opsz,wght].woff2 " , "MaterialSymbolsRounded.woff2" ) ,
17+ ( "MaterialSymbolsSharp[FILL,GRAD,opsz,wght].woff2 " , "MaterialSymbolsSharp.woff2" )
2018 ] ;
2119
2220 public IconHttpClientService ( )
@@ -25,7 +23,6 @@ public IconHttpClientService()
2523 {
2624 BaseAddress = new Uri ( GoogleFontUrl )
2725 } ;
28- _httpClient . DefaultRequestHeaders . UserAgent . ParseAdd ( "Mozilla/5.0 (compatible; MudBlazor.FontIcons.MaterialSymbols generator)" ) ;
2926 _jsonSerializerOptions = new JsonSerializerOptions
3027 {
3128 TypeInfoResolver = IconMetadataJsonSerializerContext . Default
@@ -63,52 +60,22 @@ public async Task DownloadMaterialSymbolsFontsAsync(string destinationFolderPath
6360 throw new InvalidOperationException ( $ "Failed to prepare destination folder '{ destinationFolderPath } ' for Material Symbols fonts.", ex ) ;
6461 }
6562
66- foreach ( var ( familyName , targetFileName ) in MaterialSymbolsFontFiles )
63+ foreach ( var ( sourceFileName , targetFileName ) in MaterialSymbolsFontFiles )
6764 {
65+ var fileUrl = new Uri ( new Uri ( GoogleMaterialDesignIconsRawUrl ) , Uri . EscapeDataString ( sourceFileName ) ) ;
6866 try
6967 {
70- var cssFileUrl = BuildMaterialSymbolsCssUri ( familyName ) ;
71- var cssContent = await _httpClient . GetStringAsync ( cssFileUrl , cancellationToken ) . ConfigureAwait ( false ) ;
72- var fileUrl = ResolveWoff2Url ( cssContent , familyName ) ;
7368 var fileContent = await _httpClient . GetByteArrayAsync ( fileUrl , cancellationToken ) . ConfigureAwait ( false ) ;
7469 var destinationPath = Path . Combine ( destinationFolderPath , targetFileName ) ;
7570 await File . WriteAllBytesAsync ( destinationPath , fileContent , cancellationToken ) . ConfigureAwait ( false ) ;
7671 }
7772 catch ( Exception ex ) when ( ex is HttpRequestException or IOException )
7873 {
79- throw new InvalidOperationException ( $ "Failed to download and save Material Symbols font for ' { familyName } '.", ex ) ;
74+ throw new InvalidOperationException ( $ "Failed to download and save Material Symbols font ' { sourceFileName } ' from ' { fileUrl } '.", ex ) ;
8075 }
8176 }
8277 }
8378
84- private static Uri BuildMaterialSymbolsCssUri ( string familyName )
85- {
86- var encodedFamily = Uri . EscapeDataString ( familyName ) ;
87- return new Uri ( $ "{ GoogleFontsCssApiUrl } ?family={ encodedFamily } :opsz,wght,FILL,GRAD@24,400,0,0&display=block", UriKind . Absolute ) ;
88- }
89-
90- private static Uri ResolveWoff2Url ( string cssContent , string familyName )
91- {
92- var match = Woff2UrlRegex . Match ( cssContent ) ;
93- if ( ! match . Success )
94- {
95- throw new InvalidOperationException ( $ "Failed to resolve .woff2 URL from Google Fonts CSS for '{ familyName } '.") ;
96- }
97-
98- if ( ! Uri . TryCreate ( match . Groups [ "href" ] . Value , UriKind . Absolute , out var uri ) )
99- {
100- throw new InvalidOperationException ( $ "Resolved an invalid .woff2 URL from Google Fonts CSS for '{ familyName } '.") ;
101- }
102-
103- if ( ! uri . Scheme . Equals ( Uri . UriSchemeHttps , StringComparison . OrdinalIgnoreCase ) ||
104- ! uri . Host . Equals ( "fonts.gstatic.com" , StringComparison . OrdinalIgnoreCase ) )
105- {
106- throw new InvalidOperationException ( $ "Resolved an unexpected .woff2 URL host '{ uri . Host } ' from Google Fonts CSS for '{ familyName } '.") ;
107- }
108-
109- return uri ;
110- }
111-
11279 public void Dispose ( )
11380 {
11481 Dispose ( true ) ;
0 commit comments