mirror of
https://github.com/claunia/marechai.git
synced 2025-12-16 19:14:25 +00:00
Compare commits
5 Commits
80791a8cc9
...
4d30530ef0
| Author | SHA1 | Date | |
|---|---|---|---|
|
4d30530ef0
|
|||
|
e0689684e1
|
|||
|
cfdef93787
|
|||
|
c6cac9e04a
|
|||
|
e2f86b76db
|
@@ -2,6 +2,7 @@ using System.Net.Http;
|
|||||||
using Marechai.App.Presentation.ViewModels;
|
using Marechai.App.Presentation.ViewModels;
|
||||||
using Marechai.App.Presentation.Views;
|
using Marechai.App.Presentation.Views;
|
||||||
using Marechai.App.Services;
|
using Marechai.App.Services;
|
||||||
|
using Marechai.App.Services.Caching;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Uno.Extensions;
|
using Uno.Extensions;
|
||||||
using Uno.Extensions.Configuration;
|
using Uno.Extensions.Configuration;
|
||||||
@@ -106,6 +107,8 @@ public partial class App : Application
|
|||||||
.ConfigureServices((context, services) =>
|
.ConfigureServices((context, services) =>
|
||||||
{
|
{
|
||||||
// Register application services
|
// Register application services
|
||||||
|
services.AddSingleton<FlagCache>();
|
||||||
|
services.AddSingleton<CompanyLogoCache>();
|
||||||
services.AddSingleton<NewsService>();
|
services.AddSingleton<NewsService>();
|
||||||
services.AddSingleton<NewsViewModel>();
|
services.AddSingleton<NewsViewModel>();
|
||||||
services.AddSingleton<ComputersService>();
|
services.AddSingleton<ComputersService>();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
Navigation;
|
Navigation;
|
||||||
ThemeService;
|
ThemeService;
|
||||||
SkiaRenderer;
|
SkiaRenderer;
|
||||||
|
Svg;
|
||||||
</UnoFeatures>
|
</UnoFeatures>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,13 +3,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Marechai.App.Helpers;
|
using Marechai.App.Helpers;
|
||||||
using Marechai.App.Presentation.Models;
|
using Marechai.App.Presentation.Models;
|
||||||
using Marechai.App.Services;
|
using Marechai.App.Services;
|
||||||
|
using Marechai.App.Services.Caching;
|
||||||
using Marechai.Data;
|
using Marechai.Data;
|
||||||
|
using Microsoft.UI.Xaml.Media.Imaging;
|
||||||
using Uno.Extensions.Navigation;
|
using Uno.Extensions.Navigation;
|
||||||
|
|
||||||
namespace Marechai.App.Presentation.ViewModels;
|
namespace Marechai.App.Presentation.ViewModels;
|
||||||
@@ -17,8 +20,10 @@ namespace Marechai.App.Presentation.ViewModels;
|
|||||||
public partial class CompanyDetailViewModel : ObservableObject
|
public partial class CompanyDetailViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
private readonly CompanyDetailService _companyDetailService;
|
private readonly CompanyDetailService _companyDetailService;
|
||||||
|
private readonly FlagCache _flagCache;
|
||||||
private readonly IStringLocalizer _localizer;
|
private readonly IStringLocalizer _localizer;
|
||||||
private readonly ILogger<CompanyDetailViewModel> _logger;
|
private readonly ILogger<CompanyDetailViewModel> _logger;
|
||||||
|
private readonly CompanyLogoCache _logoCache;
|
||||||
private readonly INavigator _navigator;
|
private readonly INavigator _navigator;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
@@ -48,6 +53,9 @@ public partial class CompanyDetailViewModel : ObservableObject
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private ObservableCollection<CompanyDetailMachine> _filteredConsoles = [];
|
private ObservableCollection<CompanyDetailMachine> _filteredConsoles = [];
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private SvgImageSource? _flagImageSource;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _hasError;
|
private bool _hasError;
|
||||||
|
|
||||||
@@ -57,13 +65,19 @@ public partial class CompanyDetailViewModel : ObservableObject
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isLoading;
|
private bool _isLoading;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private SvgImageSource? _logoImageSource;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private CompanyDto? _soldToCompany;
|
private CompanyDto? _soldToCompany;
|
||||||
|
|
||||||
public CompanyDetailViewModel(CompanyDetailService companyDetailService, IStringLocalizer localizer,
|
public CompanyDetailViewModel(CompanyDetailService companyDetailService, FlagCache flagCache,
|
||||||
|
CompanyLogoCache logoCache, IStringLocalizer localizer,
|
||||||
ILogger<CompanyDetailViewModel> logger, INavigator navigator)
|
ILogger<CompanyDetailViewModel> logger, INavigator navigator)
|
||||||
{
|
{
|
||||||
_companyDetailService = companyDetailService;
|
_companyDetailService = companyDetailService;
|
||||||
|
_flagCache = flagCache;
|
||||||
|
_logoCache = logoCache;
|
||||||
_localizer = localizer;
|
_localizer = localizer;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_navigator = navigator;
|
_navigator = navigator;
|
||||||
@@ -82,6 +96,16 @@ public partial class CompanyDetailViewModel : ObservableObject
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string CompanyFoundedDateDisplay => Company != null ? GetFoundedDateDisplay(Company) : string.Empty;
|
public string CompanyFoundedDateDisplay => Company != null ? GetFoundedDateDisplay(Company) : string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether flag content is available
|
||||||
|
/// </summary>
|
||||||
|
public bool HasFlagContent => FlagImageSource != null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether logo content is available
|
||||||
|
/// </summary>
|
||||||
|
public bool HasLogoContent => LogoImageSource != null;
|
||||||
|
|
||||||
public IAsyncRelayCommand LoadData { get; }
|
public IAsyncRelayCommand LoadData { get; }
|
||||||
public ICommand GoBackCommand { get; }
|
public ICommand GoBackCommand { get; }
|
||||||
public IAsyncRelayCommand<CompanyDetailMachine> NavigateToMachineCommand { get; }
|
public IAsyncRelayCommand<CompanyDetailMachine> NavigateToMachineCommand { get; }
|
||||||
@@ -94,6 +118,18 @@ public partial class CompanyDetailViewModel : ObservableObject
|
|||||||
OnPropertyChanged(nameof(CompanyFoundedDateDisplay));
|
OnPropertyChanged(nameof(CompanyFoundedDateDisplay));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void OnFlagImageSourceChanged(SvgImageSource? oldValue, SvgImageSource? newValue)
|
||||||
|
{
|
||||||
|
// Notify that HasFlagContent has changed
|
||||||
|
OnPropertyChanged(nameof(HasFlagContent));
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void OnLogoImageSourceChanged(SvgImageSource? oldValue, SvgImageSource? newValue)
|
||||||
|
{
|
||||||
|
// Notify that HasLogoContent has changed
|
||||||
|
OnPropertyChanged(nameof(HasLogoContent));
|
||||||
|
}
|
||||||
|
|
||||||
partial void OnComputersFilterTextChanged(string value)
|
partial void OnComputersFilterTextChanged(string value)
|
||||||
{
|
{
|
||||||
FilterComputers(value);
|
FilterComputers(value);
|
||||||
@@ -282,10 +318,12 @@ public partial class CompanyDetailViewModel : ObservableObject
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IsLoading = true;
|
IsLoading = true;
|
||||||
ErrorMessage = string.Empty;
|
ErrorMessage = string.Empty;
|
||||||
HasError = false;
|
HasError = false;
|
||||||
IsDataLoaded = false;
|
IsDataLoaded = false;
|
||||||
|
FlagImageSource = null;
|
||||||
|
LogoImageSource = null;
|
||||||
|
|
||||||
if(CompanyId <= 0)
|
if(CompanyId <= 0)
|
||||||
{
|
{
|
||||||
@@ -306,13 +344,57 @@ public partial class CompanyDetailViewModel : ObservableObject
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load sold-to company if applicable
|
// Load flag if country is available
|
||||||
|
if(Company.CountryId is not null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var countryCode = (short)UntypedNodeExtractor.ExtractInt(Company.CountryId);
|
||||||
|
Stream? flagStream = await _flagCache.GetFlagAsync(countryCode);
|
||||||
|
|
||||||
|
var flagSource = new SvgImageSource();
|
||||||
|
await flagSource.SetSourceAsync(flagStream.AsRandomAccessStream());
|
||||||
|
FlagImageSource = flagSource;
|
||||||
|
|
||||||
|
_logger.LogInformation("Successfully loaded flag for country code {CountryCode}", countryCode);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("Failed to load flag for country {CountryId}: {Exception}",
|
||||||
|
Company.CountryId,
|
||||||
|
ex.Message);
|
||||||
|
|
||||||
|
// Continue without flag if loading fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(Company.SoldToId != null)
|
if(Company.SoldToId != null)
|
||||||
{
|
{
|
||||||
int soldToId = UntypedNodeExtractor.ExtractInt(Company.SoldToId);
|
int soldToId = UntypedNodeExtractor.ExtractInt(Company.SoldToId);
|
||||||
if(soldToId > 0) SoldToCompany = await _companyDetailService.GetSoldToCompanyAsync(soldToId);
|
if(soldToId > 0) SoldToCompany = await _companyDetailService.GetSoldToCompanyAsync(soldToId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load logo if available
|
||||||
|
if(Company.LastLogo.HasValue)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Stream? logoStream = await _logoCache.GetFlagAsync(Company.LastLogo.Value);
|
||||||
|
|
||||||
|
var logoSource = new SvgImageSource();
|
||||||
|
await logoSource.SetSourceAsync(logoStream.AsRandomAccessStream());
|
||||||
|
LogoImageSource = logoSource;
|
||||||
|
|
||||||
|
_logger.LogInformation("Successfully loaded logo for company {CompanyId}", CompanyId);
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError("Failed to load logo for company {CompanyId}: {Exception}", CompanyId, ex.Message);
|
||||||
|
|
||||||
|
// Continue without logo if loading fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load computers and consoles made by this company
|
// Load computers and consoles made by this company
|
||||||
List<MachineDto> machines = await _companyDetailService.GetComputersByCompanyAsync(CompanyId);
|
List<MachineDto> machines = await _companyDetailService.GetComputersByCompanyAsync(CompanyId);
|
||||||
Computers.Clear();
|
Computers.Clear();
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
NavigationCacheMode="Required"
|
NavigationCacheMode="Required"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
|
<Page.Resources>
|
||||||
|
</Page.Resources>
|
||||||
|
|
||||||
<Grid utu:SafeArea.Insets="VisibleBounds">
|
<Grid utu:SafeArea.Insets="VisibleBounds">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
@@ -29,6 +32,16 @@
|
|||||||
<StackPanel Padding="16"
|
<StackPanel Padding="16"
|
||||||
Spacing="16">
|
Spacing="16">
|
||||||
|
|
||||||
|
<!-- Logo Display (Top Center) -->
|
||||||
|
<Image MaxWidth="96"
|
||||||
|
MaxHeight="96"
|
||||||
|
Stretch="Uniform"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,0,0,8"
|
||||||
|
Source="{Binding LogoImageSource}"
|
||||||
|
Visibility="{Binding HasLogoContent, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||||
|
|
||||||
<!-- Loading State -->
|
<!-- Loading State -->
|
||||||
<StackPanel Visibility="{Binding IsLoading}"
|
<StackPanel Visibility="{Binding IsLoading}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
@@ -113,14 +126,35 @@
|
|||||||
<!-- Country -->
|
<!-- Country -->
|
||||||
<StackPanel Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
<StackPanel Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||||
CornerRadius="8"
|
CornerRadius="8"
|
||||||
Padding="12"
|
Padding="12">
|
||||||
Spacing="8">
|
<Grid ColumnSpacing="12">
|
||||||
<TextBlock Text="Country"
|
<Grid.ColumnDefinitions>
|
||||||
FontSize="14"
|
<ColumnDefinition Width="*" />
|
||||||
FontWeight="SemiBold"
|
<ColumnDefinition Width="Auto" />
|
||||||
Foreground="{ThemeResource SystemBaseMediumColor}" />
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock Text="{Binding Company.Country}"
|
|
||||||
FontSize="14" />
|
<!-- Country Name and Label -->
|
||||||
|
<StackPanel Grid.Column="0"
|
||||||
|
Spacing="4">
|
||||||
|
<TextBlock Text="Country"
|
||||||
|
FontSize="14"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="{ThemeResource SystemBaseMediumColor}" />
|
||||||
|
<TextBlock Text="{Binding Company.Country}"
|
||||||
|
FontSize="14"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- Country Flag -->
|
||||||
|
<Image Grid.Column="1"
|
||||||
|
Width="48"
|
||||||
|
Height="32"
|
||||||
|
Stretch="UniformToFill"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Source="{Binding FlagImageSource}"
|
||||||
|
Visibility="{Binding HasFlagContent, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||||
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Address -->
|
<!-- Address -->
|
||||||
|
|||||||
64
Marechai.App/Services/Caching/FlagCache.cs
Normal file
64
Marechai.App/Services/Caching/FlagCache.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
namespace Marechai.App.Services.Caching;
|
||||||
|
|
||||||
|
public sealed class FlagCache
|
||||||
|
{
|
||||||
|
readonly IConfiguration _configuration;
|
||||||
|
StorageFolder _flagsFolder;
|
||||||
|
|
||||||
|
public FlagCache(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
_ = EnsureFolderExistAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task EnsureFolderExistAsync()
|
||||||
|
{
|
||||||
|
StorageFolder localFolder = ApplicationData.Current.LocalCacheFolder;
|
||||||
|
_flagsFolder = await localFolder.CreateFolderAsync("flags", CreationCollisionOption.OpenIfExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Stream> GetFlagAsync(short countryCode)
|
||||||
|
{
|
||||||
|
var filename = $"{countryCode:D3}.svg";
|
||||||
|
|
||||||
|
Stream retStream;
|
||||||
|
|
||||||
|
if(await _flagsFolder.TryGetItemAsync(filename) is StorageFile file)
|
||||||
|
{
|
||||||
|
retStream = await file.OpenStreamForReadAsync();
|
||||||
|
|
||||||
|
return retStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
await CacheFlagAsync(countryCode);
|
||||||
|
|
||||||
|
file = await _flagsFolder.GetFileAsync(filename);
|
||||||
|
|
||||||
|
retStream = await file.OpenStreamForReadAsync();
|
||||||
|
|
||||||
|
return retStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task CacheFlagAsync(short countryCode)
|
||||||
|
{
|
||||||
|
var filename = $"{countryCode:D3}.svg";
|
||||||
|
string baseUrl = _configuration.GetSection("ApiClient:Url").Value;
|
||||||
|
string flagUrl = baseUrl + $"/assets/flags/countries/{filename}";
|
||||||
|
using var httpClient = new HttpClient();
|
||||||
|
using HttpResponseMessage response = await httpClient.GetAsync(flagUrl);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
using Stream stream = await response.Content.ReadAsStreamAsync();
|
||||||
|
StorageFile file = await _flagsFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
|
||||||
|
|
||||||
|
using Stream fileStream = await file.OpenStreamForWriteAsync();
|
||||||
|
await stream.CopyToAsync(fileStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
64
Marechai.App/Services/Caching/LogoCache.cs
Normal file
64
Marechai.App/Services/Caching/LogoCache.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
namespace Marechai.App.Services.Caching;
|
||||||
|
|
||||||
|
public sealed class CompanyLogoCache
|
||||||
|
{
|
||||||
|
readonly IConfiguration _configuration;
|
||||||
|
StorageFolder _flagsFolder;
|
||||||
|
|
||||||
|
public CompanyLogoCache(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
_ = EnsureFolderExistAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task EnsureFolderExistAsync()
|
||||||
|
{
|
||||||
|
StorageFolder localFolder = ApplicationData.Current.LocalCacheFolder;
|
||||||
|
_flagsFolder = await localFolder.CreateFolderAsync("logos", CreationCollisionOption.OpenIfExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Stream> GetFlagAsync(Guid companyLogoId)
|
||||||
|
{
|
||||||
|
var filename = $"{companyLogoId}.svg";
|
||||||
|
|
||||||
|
Stream retStream;
|
||||||
|
|
||||||
|
if(await _flagsFolder.TryGetItemAsync(filename) is StorageFile file)
|
||||||
|
{
|
||||||
|
retStream = await file.OpenStreamForReadAsync();
|
||||||
|
|
||||||
|
return retStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
await CacheFlagAsync(companyLogoId);
|
||||||
|
|
||||||
|
file = await _flagsFolder.GetFileAsync(filename);
|
||||||
|
|
||||||
|
retStream = await file.OpenStreamForReadAsync();
|
||||||
|
|
||||||
|
return retStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task CacheFlagAsync(Guid companyLogoId)
|
||||||
|
{
|
||||||
|
var filename = $"{companyLogoId}.svg";
|
||||||
|
string baseUrl = _configuration.GetSection("ApiClient:Url").Value;
|
||||||
|
string flagUrl = baseUrl + $"/assets/logos/{filename}";
|
||||||
|
using var httpClient = new HttpClient();
|
||||||
|
using HttpResponseMessage response = await httpClient.GetAsync(flagUrl);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
using Stream stream = await response.Content.ReadAsStreamAsync();
|
||||||
|
StorageFile file = await _flagsFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
|
||||||
|
|
||||||
|
using Stream fileStream = await file.OpenStreamForWriteAsync();
|
||||||
|
await stream.CopyToAsync(fileStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,11 +36,11 @@ public class Photos
|
|||||||
{
|
{
|
||||||
public delegate Task ConversionFinished(bool result);
|
public delegate Task ConversionFinished(bool result);
|
||||||
|
|
||||||
public static void EnsureCreated(string webRootPath, bool scan, string item)
|
public static void EnsureCreated(string assetRootPath, bool scan, string item)
|
||||||
{
|
{
|
||||||
List<string> paths = [];
|
List<string> paths = [];
|
||||||
|
|
||||||
string photosRoot = Path.Combine(webRootPath, "assets", scan ? "scan" : "photos");
|
string photosRoot = Path.Combine(assetRootPath, scan ? "scan" : "photos");
|
||||||
string itemPhotosRoot = Path.Combine(photosRoot, item);
|
string itemPhotosRoot = Path.Combine(photosRoot, item);
|
||||||
string itemThumbsRoot = Path.Combine(itemPhotosRoot, "thumbs");
|
string itemThumbsRoot = Path.Combine(itemPhotosRoot, "thumbs");
|
||||||
string itemOriginalPhotosRoot = Path.Combine(itemPhotosRoot, "originals");
|
string itemOriginalPhotosRoot = Path.Combine(itemPhotosRoot, "originals");
|
||||||
@@ -88,14 +88,14 @@ public class Photos
|
|||||||
foreach(string path in paths.Where(path => !Directory.Exists(path))) Directory.CreateDirectory(path);
|
foreach(string path in paths.Where(path => !Directory.Exists(path))) Directory.CreateDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Convert(string webRootPath, Guid id, string originalPath, string sourceFormat,
|
public static bool Convert(string assetRootPath, Guid id, string originalPath, string sourceFormat,
|
||||||
string outputFormat, string resolution, bool thumbnail, bool scan, string item)
|
string outputFormat, string resolution, bool thumbnail, bool scan, string item)
|
||||||
{
|
{
|
||||||
outputFormat = outputFormat.ToLowerInvariant();
|
outputFormat = outputFormat.ToLowerInvariant();
|
||||||
resolution = resolution.ToLowerInvariant();
|
resolution = resolution.ToLowerInvariant();
|
||||||
sourceFormat = sourceFormat.ToLowerInvariant();
|
sourceFormat = sourceFormat.ToLowerInvariant();
|
||||||
|
|
||||||
string outputPath = Path.Combine(webRootPath, "assets", scan ? "scans" : "photos", item);
|
string outputPath = Path.Combine(assetRootPath, scan ? "scans" : "photos", item);
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
if(thumbnail) outputPath = Path.Combine(outputPath, "thumbs");
|
if(thumbnail) outputPath = Path.Combine(outputPath, "thumbs");
|
||||||
@@ -268,12 +268,12 @@ public class Photos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConversionWorker(string webRootPath, Guid id, string originalFilePath, string sourceFormat, bool scan,
|
public void ConversionWorker(string assetRootPath, Guid id, string originalFilePath, string sourceFormat, bool scan,
|
||||||
string item)
|
string item)
|
||||||
{
|
{
|
||||||
List<Task> pool =
|
List<Task> pool =
|
||||||
[
|
[
|
||||||
new(() => FinishedRenderingJpeg4kThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJpeg4kThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -282,7 +282,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJpeg1440Thumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJpeg1440Thumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -291,7 +291,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJpegHdThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJpegHdThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -300,7 +300,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJpeg4K?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJpeg4K?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -309,7 +309,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJpeg1440?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJpeg1440?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -318,7 +318,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJpegHd?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJpegHd?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -327,7 +327,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJp2k4kThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJp2k4kThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -336,7 +336,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJp2k1440Thumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJp2k1440Thumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -345,7 +345,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJp2kHdThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJp2kHdThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -354,7 +354,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJp2k4k?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJp2k4k?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -363,7 +363,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJp2k1440?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJp2k1440?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -372,7 +372,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingJp2kHd?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingJp2kHd?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -381,7 +381,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingWebp4kThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingWebp4kThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -390,7 +390,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingWebp1440Thumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingWebp1440Thumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -399,7 +399,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingWebpHdThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingWebpHdThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -408,7 +408,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingWebp4k?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingWebp4k?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -417,7 +417,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingWebp1440?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingWebp1440?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -426,7 +426,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingWebpHd?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingWebpHd?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -435,7 +435,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingHeif4kThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingHeif4kThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -444,7 +444,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingHeif1440Thumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingHeif1440Thumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -453,7 +453,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingHeifHdThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingHeifHdThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -462,7 +462,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingHeif4K?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingHeif4K?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -471,7 +471,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingHeif1440?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingHeif1440?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -480,7 +480,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingHeifHd?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingHeifHd?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -489,7 +489,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingAvif4kThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingAvif4kThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -498,7 +498,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingAvif1440Thumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingAvif1440Thumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -507,7 +507,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingAvifHdThumbnail?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingAvifHdThumbnail?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -516,7 +516,7 @@ public class Photos
|
|||||||
true,
|
true,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingAvif4K?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingAvif4K?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -525,7 +525,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingAvif1440?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingAvif1440?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
@@ -534,7 +534,7 @@ public class Photos
|
|||||||
false,
|
false,
|
||||||
scan,
|
scan,
|
||||||
item))),
|
item))),
|
||||||
new(() => FinishedRenderingAvifHd?.Invoke(Convert(webRootPath,
|
new(() => FinishedRenderingAvifHd?.Invoke(Convert(assetRootPath,
|
||||||
id,
|
id,
|
||||||
originalFilePath,
|
originalFilePath,
|
||||||
sourceFormat,
|
sourceFormat,
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ namespace Marechai.Server.Helpers;
|
|||||||
|
|
||||||
public static class SvgRender
|
public static class SvgRender
|
||||||
{
|
{
|
||||||
public static void RenderCountries()
|
public static void RenderCountries(string assetRootPath)
|
||||||
{
|
{
|
||||||
if(!Directory.Exists("wwwroot/assets/flags/countries")) return;
|
if(!Directory.Exists($"{assetRootPath}/flags/countries")) return;
|
||||||
|
|
||||||
foreach(string file in Directory.GetFiles("wwwroot/assets/flags/countries/",
|
foreach(string file in Directory.GetFiles($"{assetRootPath}/flags/countries/",
|
||||||
"*.svg",
|
"*.svg",
|
||||||
SearchOption.TopDirectoryOnly))
|
SearchOption.TopDirectoryOnly))
|
||||||
{
|
{
|
||||||
@@ -50,8 +50,8 @@ public static class SvgRender
|
|||||||
"png", "webp"
|
"png", "webp"
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
if(!Directory.Exists(Path.Combine("wwwroot/assets/flags/countries", format)))
|
if(!Directory.Exists(Path.Combine($"{assetRootPath}/flags/countries", format)))
|
||||||
Directory.CreateDirectory(Path.Combine("wwwroot/assets/flags/countries", format));
|
Directory.CreateDirectory(Path.Combine($"{assetRootPath}/flags/countries", format));
|
||||||
|
|
||||||
SKEncodedImageFormat skFormat;
|
SKEncodedImageFormat skFormat;
|
||||||
|
|
||||||
@@ -72,14 +72,14 @@ public static class SvgRender
|
|||||||
1, 2, 3
|
1, 2, 3
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
if(!Directory.Exists(Path.Combine("wwwroot/assets/flags/countries", format, $"{multiplier}x")))
|
if(!Directory.Exists(Path.Combine($"{assetRootPath}/flags/countries", format, $"{multiplier}x")))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.Combine("wwwroot/assets/flags/countries",
|
Directory.CreateDirectory(Path.Combine($"{assetRootPath}/flags/countries",
|
||||||
format,
|
format,
|
||||||
$"{multiplier}x"));
|
$"{multiplier}x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
string rendered = Path.Combine("wwwroot/assets/flags/countries",
|
string rendered = Path.Combine($"{assetRootPath}/flags/countries",
|
||||||
format,
|
format,
|
||||||
$"{multiplier}x",
|
$"{multiplier}x",
|
||||||
flagName + $".{format}");
|
flagName + $".{format}");
|
||||||
@@ -102,11 +102,11 @@ public static class SvgRender
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ImportCompanyLogos(MarechaiContext context)
|
public static void ImportCompanyLogos(string assetRootPath, MarechaiContext context)
|
||||||
{
|
{
|
||||||
if(!Directory.Exists("wwwroot/assets/incoming")) return;
|
if(!Directory.Exists($"{assetRootPath}/incoming")) return;
|
||||||
|
|
||||||
foreach(string file in Directory.GetFiles("wwwroot/assets/incoming",
|
foreach(string file in Directory.GetFiles($"{assetRootPath}/incoming",
|
||||||
"company_*.svg",
|
"company_*.svg",
|
||||||
SearchOption.TopDirectoryOnly))
|
SearchOption.TopDirectoryOnly))
|
||||||
{
|
{
|
||||||
@@ -153,8 +153,8 @@ public static class SvgRender
|
|||||||
})
|
})
|
||||||
{
|
{
|
||||||
string outDir = minSize == 32
|
string outDir = minSize == 32
|
||||||
? Path.Combine("wwwroot/assets/logos/thumbs", format)
|
? Path.Combine($"{assetRootPath}/logos/thumbs", format)
|
||||||
: Path.Combine("wwwroot/assets/logos", format);
|
: Path.Combine($"{assetRootPath}/logos", format);
|
||||||
|
|
||||||
if(!Directory.Exists(outDir)) Directory.CreateDirectory(outDir);
|
if(!Directory.Exists(outDir)) Directory.CreateDirectory(outDir);
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ public static class SvgRender
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File.Move(file, $"wwwroot/assets/logos/{guid}.svg");
|
File.Move(file, $"{assetRootPath}/logos/{guid}.svg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
@@ -12,9 +13,11 @@ using Markdig;
|
|||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Microsoft.AspNetCore.StaticFiles;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Version = Marechai.Server.Interop.Version;
|
using Version = Marechai.Server.Interop.Version;
|
||||||
@@ -140,14 +143,36 @@ file class Program
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
string assetRootPath = builder.Configuration["AssetRootPath"];
|
||||||
|
|
||||||
|
if(string.IsNullOrEmpty(assetRootPath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("\e[31;1mAsset root path not set, cannot continue, check configuration...\e[0m");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory.CreateDirectory(assetRootPath);
|
||||||
|
|
||||||
DateTime start = DateTime.Now;
|
DateTime start = DateTime.Now;
|
||||||
Console.WriteLine("\e[31;1mRendering new country flags...\e[0m");
|
Console.WriteLine("\e[31;1mRendering new country flags...\e[0m");
|
||||||
SvgRender.RenderCountries();
|
SvgRender.RenderCountries(assetRootPath);
|
||||||
DateTime end = DateTime.Now;
|
DateTime end = DateTime.Now;
|
||||||
|
|
||||||
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
||||||
|
|
||||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
start = DateTime.Now;
|
||||||
|
Console.WriteLine("\e[31;1mEnsuring photo folders exist...\e[0m");
|
||||||
|
Photos.EnsureCreated(assetRootPath, false, "machines");
|
||||||
|
Console.WriteLine("\e[31;1mEnsuring scan folders exist...\e[0m");
|
||||||
|
Photos.EnsureCreated(assetRootPath, true, "books");
|
||||||
|
Photos.EnsureCreated(assetRootPath, true, "documents");
|
||||||
|
Photos.EnsureCreated(assetRootPath, true, "magazines");
|
||||||
|
end = DateTime.Now;
|
||||||
|
|
||||||
|
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddControllers()
|
builder.Services.AddControllers()
|
||||||
@@ -210,8 +235,7 @@ file class Program
|
|||||||
builder.Services.AddScoped<TokenService, TokenService>();
|
builder.Services.AddScoped<TokenService, TokenService>();
|
||||||
|
|
||||||
// Read allowed CORS origins from configuration
|
// Read allowed CORS origins from configuration
|
||||||
string[] allowedOrigins = builder.Configuration.GetSection("CORS:AllowedOrigins").Get<string[]>() ??
|
string[] allowedOrigins = builder.Configuration.GetSection("CORS:AllowedOrigins").Get<string[]>() ?? [];
|
||||||
Array.Empty<string>();
|
|
||||||
|
|
||||||
builder.Services.AddCors(options =>
|
builder.Services.AddCors(options =>
|
||||||
{
|
{
|
||||||
@@ -241,6 +265,28 @@ file class Program
|
|||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
|
// Set up custom content types - associating file extension to MIME type
|
||||||
|
var provider = new FileExtensionContentTypeProvider
|
||||||
|
{
|
||||||
|
Mappings =
|
||||||
|
{
|
||||||
|
// Add new mappings
|
||||||
|
[".avif"] = "image/avif", // AVIF image format
|
||||||
|
[".heic"] = "image/heic", // HEIC image format
|
||||||
|
[".heif"] = "image/heif", // HEIF image format
|
||||||
|
[".jxl"] = "image/jxl", // JPEG-XL image format
|
||||||
|
[".webp"] = "image/webp", // WebP image format
|
||||||
|
[".svg"] = "image/svg+xml" // SVG image format
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
app.UseStaticFiles(new StaticFileOptions
|
||||||
|
{
|
||||||
|
FileProvider = new PhysicalFileProvider(assetRootPath),
|
||||||
|
RequestPath = "/assets",
|
||||||
|
ContentTypeProvider = provider
|
||||||
|
});
|
||||||
|
|
||||||
using(IServiceScope scope = app.Services.CreateScope())
|
using(IServiceScope scope = app.Services.CreateScope())
|
||||||
{
|
{
|
||||||
IServiceProvider services = scope.ServiceProvider;
|
IServiceProvider services = scope.ServiceProvider;
|
||||||
@@ -257,7 +303,7 @@ file class Program
|
|||||||
|
|
||||||
start = DateTime.Now;
|
start = DateTime.Now;
|
||||||
Console.WriteLine("\e[31;1mImporting company logos...\e[0m");
|
Console.WriteLine("\e[31;1mImporting company logos...\e[0m");
|
||||||
SvgRender.ImportCompanyLogos(context);
|
SvgRender.ImportCompanyLogos(assetRootPath, context);
|
||||||
end = DateTime.Now;
|
end = DateTime.Now;
|
||||||
|
|
||||||
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
||||||
@@ -278,20 +324,6 @@ file class Program
|
|||||||
end = DateTime.Now;
|
end = DateTime.Now;
|
||||||
|
|
||||||
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
||||||
|
|
||||||
start = DateTime.Now;
|
|
||||||
Console.WriteLine("\e[31;1mEnsuring photo folders exist...\e[0m");
|
|
||||||
Photos.EnsureCreated("wwwroot", false, "machines");
|
|
||||||
end = DateTime.Now;
|
|
||||||
|
|
||||||
start = DateTime.Now;
|
|
||||||
Console.WriteLine("\e[31;1mEnsuring scan folders exist...\e[0m");
|
|
||||||
Photos.EnsureCreated("wwwroot", true, "books");
|
|
||||||
Photos.EnsureCreated("wwwroot", true, "documents");
|
|
||||||
Photos.EnsureCreated("wwwroot", true, "magazines");
|
|
||||||
end = DateTime.Now;
|
|
||||||
|
|
||||||
Console.WriteLine("\e[31;1mTook \e[32;1m{0} seconds\e[31;1m...\e[0m", (end - start).TotalSeconds);
|
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,5 +64,6 @@
|
|||||||
"Name": "NormalUser",
|
"Name": "NormalUser",
|
||||||
"Description": "A normal user role."
|
"Description": "A normal user role."
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"AssetRootPath": "/var/marechai/assets"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user