Use InMemory db driver at testing
This commit is contained in:
parent
3b4376a5f0
commit
95dec3636a
24 changed files with 474 additions and 139 deletions
|
|
@ -4,9 +4,10 @@
|
|||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId>
|
||||
<RootNamespace>Yavsc.Api</RootNamespace>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -115,7 +115,7 @@ namespace Yavsc.ApiControllers
|
|||
}
|
||||
if (Request.Form.Files.Count!=1)
|
||||
return new BadRequestResult();
|
||||
User.ReceiveProSignature(billingCode,id,Request.Form.Files[0],"pro");
|
||||
await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"pro");
|
||||
estimate.ProviderValidationDate = DateTime.Now;
|
||||
dbContext.SaveChanges(User.GetUserId());
|
||||
// Notify the client
|
||||
|
|
@ -160,7 +160,7 @@ namespace Yavsc.ApiControllers
|
|||
}
|
||||
if (Request.Form.Files.Count!=1)
|
||||
return new BadRequestResult();
|
||||
User.ReceiveProSignature(billingCode,id,Request.Form.Files[0],"cli");
|
||||
await User.ReceiveProSignatureAsync(billingCode,id,Request.Form.Files[0],"cli");
|
||||
estimate.ClientValidationDate = DateTime.Now;
|
||||
dbContext.SaveChanges(User.GetUserId());
|
||||
return Ok (new { ClientValidationDate = estimate.ClientValidationDate });
|
||||
|
|
|
|||
|
|
@ -66,12 +66,15 @@ namespace Yavsc.WebApi.Controllers
|
|||
/// Updates the avatar
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("~/api/setavatar")]
|
||||
[HttpPost("~/api/set-avatar")]
|
||||
public async Task<IActionResult> SetAvatar()
|
||||
{
|
||||
var user = await GetUserData(User.GetUserId());
|
||||
if (Request.Form.Files.Count!=1)
|
||||
return new BadRequestResult();
|
||||
if (!Request.Form.Files[0].ContentType.StartsWith("image/png"))
|
||||
return new BadRequestResult();
|
||||
|
||||
var info = user.ReceiveAvatar(Request.Form.Files[0]);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return Ok(info);
|
||||
|
|
|
|||
12
src/PostIt/App.axaml
Normal file
12
src/PostIt/App.axaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="PostIt.App"
|
||||
RequestedThemeVariant="Default">
|
||||
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
|
||||
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
23
src/PostIt/App.axaml.cs
Normal file
23
src/PostIt/App.axaml.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace PostIt;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.MainWindow = new MainWindow();
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
27
src/PostIt/MainWindow.axaml
Normal file
27
src/PostIt/MainWindow.axaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:AvaloniaEdit="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="PostIt.MainWindow"
|
||||
Title="PostIt">
|
||||
<Window.Content>
|
||||
<StackPanel>
|
||||
<Label>Welcome to Avalonia !!!</Label>
|
||||
|
||||
<Label x:Name="Greeting">
|
||||
Hello !
|
||||
</Label>
|
||||
<AvaloniaEdit:TextEditor
|
||||
ShowLineNumbers="True"
|
||||
FontFamily="Cascadia Code,Consolas,Menlo,Monospace"
|
||||
Background="AliceBlue"
|
||||
Foreground="Black"
|
||||
Watermark="Hit me strong!"
|
||||
/>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Window.Content>
|
||||
</Window>
|
||||
12
src/PostIt/MainWindow.axaml.cs
Normal file
12
src/PostIt/MainWindow.axaml.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using Avalonia.Controls;
|
||||
|
||||
namespace PostIt;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Greeting.Content="Hello Joe!";
|
||||
}
|
||||
}
|
||||
21
src/PostIt/PostIt.csproj
Normal file
21
src/PostIt/PostIt.csproj
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" />
|
||||
<PackageReference Include="Avalonia.AvaloniaEdit" />
|
||||
<PackageReference Include="Avalonia.Desktop" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" />
|
||||
<PackageReference Include="AvaloniaUI.DiagnosticsSupport">
|
||||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Yavsc.Abstract" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
24
src/PostIt/Program.cs
Normal file
24
src/PostIt/Program.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using Avalonia;
|
||||
using System;
|
||||
|
||||
namespace PostIt;
|
||||
|
||||
class Program
|
||||
{
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
#if DEBUG
|
||||
.WithDeveloperTools()
|
||||
#endif
|
||||
.WithInterFont()
|
||||
.LogToTrace();
|
||||
}
|
||||
18
src/PostIt/app.manifest
Normal file
18
src/PostIt/app.manifest
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<!-- This manifest is used on Windows only.
|
||||
Don't remove it as it might cause problems with window transparency and embedded controls.
|
||||
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
|
||||
<assemblyIdentity version="1.0.0.0" name="PostIt.Desktop"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
|
|
@ -6,8 +6,9 @@
|
|||
</Description>
|
||||
<RootNamespace>Yavsc.Abstract</RootNamespace>
|
||||
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -5,9 +5,10 @@
|
|||
<UserSecretsId>1c73094f-959f-4211-b1a1-6a69b236c283</UserSecretsId>
|
||||
<RootNamespace>Yavsc.Api</RootNamespace>
|
||||
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<ProjectReference Include="../Yavsc.Server/Yavsc.Server.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -37,6 +37,7 @@ namespace Yavsc.Extensions;
|
|||
|
||||
public static class HostingExtensions
|
||||
{
|
||||
private const string InMemoryProviderName = "InMemory";
|
||||
|
||||
public static WebApplication ConfigureWebAppServices(this WebApplicationBuilder builder)
|
||||
{
|
||||
|
|
@ -140,11 +141,19 @@ public static class HostingExtensions
|
|||
public static IdentityBuilder AddIdentityDBAndStores(this WebApplicationBuilder builder)
|
||||
{
|
||||
IServiceCollection services = builder.Services;
|
||||
var connectionString = builder.Configuration.GetConnectionString(Constants.YavscConnectionStringName);
|
||||
|
||||
services.AddDbContext<ApplicationDbContext>(options =>
|
||||
{
|
||||
options.UseNpgsql(builder.Configuration.GetConnectionString(Constants.YavscConnectionStringName),
|
||||
options => options.MigrationsAssembly(typeof(Program).Assembly));
|
||||
if (UsesInMemoryProvider(connectionString))
|
||||
{
|
||||
options.UseInMemoryDatabase(connectionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.UseNpgsql(connectionString,
|
||||
options => options.MigrationsAssembly(typeof(Program).Assembly));
|
||||
}
|
||||
});
|
||||
|
||||
var identityBuilder = services.AddIdentity<ApplicationUser, IdentityRole>(
|
||||
|
|
@ -285,14 +294,35 @@ public static class HostingExtensions
|
|||
.AddResourceStore<ResourceStore>()
|
||||
.AddConfigurationStore(options =>
|
||||
{
|
||||
options.ConfigureDbContext = b => b.UseNpgsql(connectionString,
|
||||
sql => sql.MigrationsAssembly(migrationsAssembly))
|
||||
.UseSeeding(EnsureDefaultApplicationScopes());
|
||||
options.ConfigureDbContext = b =>
|
||||
{
|
||||
if (UsesInMemoryProvider(connectionString))
|
||||
{
|
||||
b.UseInMemoryDatabase(connectionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
b.UseNpgsql(connectionString,
|
||||
sql => sql.MigrationsAssembly(migrationsAssembly));
|
||||
}
|
||||
|
||||
b.UseSeeding(EnsureDefaultApplicationScopes());
|
||||
};
|
||||
})
|
||||
.AddOperationalStore(options =>
|
||||
{
|
||||
options.ConfigureDbContext = b => b.UseNpgsql(connectionString,
|
||||
sql => sql.MigrationsAssembly(migrationsAssembly));
|
||||
options.ConfigureDbContext = b =>
|
||||
{
|
||||
if (UsesInMemoryProvider(connectionString))
|
||||
{
|
||||
b.UseInMemoryDatabase(connectionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
b.UseNpgsql(connectionString,
|
||||
sql => sql.MigrationsAssembly(migrationsAssembly));
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -303,6 +333,11 @@ public static class HostingExtensions
|
|||
return identityServerBuilder;
|
||||
}
|
||||
|
||||
private static bool UsesInMemoryProvider(string connectionString)
|
||||
{
|
||||
return string.Equals(connectionString, InMemoryProviderName, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static Action<DbContext, bool> EnsureDefaultApplicationScopes()
|
||||
{
|
||||
return (context, _) =>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<PackageLicenseExpression>WTFPL</PackageLicenseExpression>
|
||||
<UserSecretsId>76e56fc2-1619-40d8-8393-365258b7a21d</UserSecretsId>
|
||||
<RootNamespace>Yavsc</RootNamespace>
|
||||
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -21,7 +21,6 @@
|
|||
<PackageReference Include="HigginsSoft.IdentityServer8.EntityFramework.Storage" />
|
||||
<PackageReference Include="HigginsSoft.IdentityServer8.Security" />
|
||||
<PackageReference Include="HigginsSoft.IdentityServer8.Storage" />
|
||||
<PackageReference Include="Serilog.AspNetCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
|
||||
|
|
@ -33,6 +32,7 @@
|
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
|
||||
<PackageReference Include="Google.Apis.Compute.v1" />
|
||||
|
|
@ -44,7 +44,6 @@
|
|||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||
<PackageReference Include="AsciiDocSharp" />
|
||||
<PackageReference Include="AsciiDocSharp.Converters.Html" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -7,38 +7,34 @@ using Yavsc.Models;
|
|||
using Yavsc.Models.FileSystem;
|
||||
using Yavsc.Models.Streaming;
|
||||
using Yavsc.ViewModels;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Yavsc.Exceptions;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Abstract.Helpers;
|
||||
using ImageMagick;
|
||||
namespace Yavsc.Server.Helpers
|
||||
{
|
||||
public static class FileSystemHelpers
|
||||
public static class FileSystemHelpers
|
||||
{
|
||||
public static async Task SaveAsAsync(this IFormFile formFile, string path)
|
||||
{
|
||||
if (formFile.Length > 0) {
|
||||
using (Stream fileStream = new FileStream(path, FileMode.Create)) {
|
||||
if (formFile.Length > 0)
|
||||
{
|
||||
using (Stream fileStream = new FileStream(path, FileMode.Create))
|
||||
{
|
||||
await formFile.CopyToAsync(fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static FileReceivedInfo ReceiveProSignature(this ClaimsPrincipal user, string billingCode, long estimateId, IFormFile formFile, string signType)
|
||||
public static async Task<FileReceivedInfo> ReceiveProSignatureAsync(this ClaimsPrincipal user, string billingCode, long estimateId, IFormFile formFile, string signType)
|
||||
{
|
||||
var item = new FileReceivedInfo(
|
||||
Config.SiteSetup.Bills,
|
||||
Config.SiteSetup.Bills,
|
||||
AbstractFileSystemHelpers.SignFileNameFormat("pro", billingCode, estimateId));
|
||||
|
||||
var fi = new FileInfo(item.FullName);
|
||||
if (fi.Exists) item.Overridden = true;
|
||||
|
||||
using (var org = formFile.OpenReadStream())
|
||||
{
|
||||
using Image image = Image.Load(org);
|
||||
image.Save(fi.FullName);
|
||||
}
|
||||
await formFile.SaveAsAsync(fi.FullName);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
@ -76,67 +72,70 @@ namespace Yavsc.Server.Helpers
|
|||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
var fi = new FileInfo(Path.Combine(root, fileName));
|
||||
if (!fi.Exists) return ;
|
||||
if (!fi.Exists) return;
|
||||
fi.Delete();
|
||||
user.DiskUsage -= fi.Length;
|
||||
}
|
||||
|
||||
|
||||
public static FsOperationInfo DeleteUserDirOrFile(this ApplicationUser user, string dirName)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
if (string.IsNullOrEmpty(dirName))
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "specify a directory or file name"} ;
|
||||
if (string.IsNullOrEmpty(dirName))
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "specify a directory or file name" };
|
||||
|
||||
var di = new DirectoryInfo(Path.Combine(root, dirName));
|
||||
if (!di.Exists) {
|
||||
if (!di.Exists)
|
||||
{
|
||||
var fi = new FileInfo(Path.Combine(root, dirName));
|
||||
if (!fi.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "non existent"} ;
|
||||
if (!fi.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "non existent" };
|
||||
fi.Delete();
|
||||
user.DiskUsage -= fi.Length;
|
||||
}
|
||||
else {
|
||||
if (di.GetDirectories().Length>0 || di.GetFiles().Length>0)
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "dir is not empty, refusing to remove it"} ;
|
||||
else
|
||||
{
|
||||
if (di.GetDirectories().Length > 0 || di.GetFiles().Length > 0)
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "dir is not empty, refusing to remove it" };
|
||||
di.Delete();
|
||||
}
|
||||
return new FsOperationInfo { Done = true };
|
||||
}
|
||||
|
||||
|
||||
public static FsOperationInfo MoveUserDir(this ApplicationUser user, string fromDirName, string toDirName)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
if (string.IsNullOrEmpty(fromDirName))
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest , ErrorMessage = "specify a dir name "} ;
|
||||
if (string.IsNullOrEmpty(fromDirName))
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "specify a dir name " };
|
||||
|
||||
var di = new DirectoryInfo(Path.Combine(root, fromDirName));
|
||||
if (!di.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "fromDirName: non existent"} ;
|
||||
|
||||
if (!di.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "fromDirName: non existent" };
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(toDirName)) toDirName = ".";
|
||||
var destPath = Path.Combine(root, toDirName);
|
||||
|
||||
|
||||
var fout = new FileInfo(destPath);
|
||||
if (fout.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "destination is a regular file" } ;
|
||||
if (fout.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "destination is a regular file" };
|
||||
|
||||
|
||||
var dout = new DirectoryInfo(destPath);
|
||||
if (dout.Exists) {
|
||||
destPath = Path.Combine(destPath, dout.Name);
|
||||
var dOut = new DirectoryInfo(destPath);
|
||||
if (dOut.Exists)
|
||||
{
|
||||
destPath = Path.Combine(destPath, dOut.Name);
|
||||
}
|
||||
di.MoveTo(destPath);
|
||||
di.MoveTo(destPath);
|
||||
return new FsOperationInfo { Done = true };
|
||||
}
|
||||
public static FsOperationInfo MoveUserFileToDir(this ApplicationUser user, string fileNameFrom, string fileNameDest)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
var fi = new FileInfo(Path.Combine(root, fileNameFrom));
|
||||
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" } ;
|
||||
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" };
|
||||
string dest;
|
||||
if (!string.IsNullOrEmpty(fileNameDest)) dest = Path.Combine(root, fileNameDest);
|
||||
else dest = root;
|
||||
var fo = new FileInfo(dest);
|
||||
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists , ErrorMessage = "destination file name is an existing file" } ;
|
||||
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists, ErrorMessage = "destination file name is an existing file" };
|
||||
var dout = new DirectoryInfo(dest);
|
||||
if (!dout.Exists) dout.Create();
|
||||
fi.MoveTo(Path.Combine(dout.FullName, fi.Name));
|
||||
|
|
@ -146,9 +145,9 @@ namespace Yavsc.Server.Helpers
|
|||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
var fi = new FileInfo(Path.Combine(root, fileNameFrom));
|
||||
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" } ;
|
||||
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" };
|
||||
var fo = new FileInfo(Path.Combine(root, fileNameDest));
|
||||
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists , ErrorMessage = "destination file name is an existing file" } ;
|
||||
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists, ErrorMessage = "destination file name is an existing file" };
|
||||
fi.MoveTo(fo.FullName);
|
||||
return new FsOperationInfo { Done = true };
|
||||
}
|
||||
|
|
@ -158,7 +157,7 @@ namespace Yavsc.Server.Helpers
|
|||
// form-data_ name=_file__ filename=_Constants.Private.cs_
|
||||
var parts = disposition.Split(' ');
|
||||
var filename = parts[2].Split('=')[1];
|
||||
filename = filename.Substring(1,filename.Length-2);
|
||||
filename = filename.Substring(1, filename.Length - 2);
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +169,7 @@ namespace Yavsc.Server.Helpers
|
|||
{
|
||||
return ReceiveUserFile(user, root, f.OpenReadStream(), destFileName ?? ParseFileNameFromDisposition(f.ContentDisposition), f.ContentType, CancellationToken.None);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the user's disk usage
|
||||
/// </summary>
|
||||
|
|
@ -203,7 +202,7 @@ namespace Yavsc.Server.Helpers
|
|||
{
|
||||
item.Overridden = true;
|
||||
usage -= fi.Length;
|
||||
}
|
||||
}
|
||||
using (var dest = fi.OpenWrite())
|
||||
{
|
||||
using (inputStream)
|
||||
|
|
@ -211,7 +210,7 @@ namespace Yavsc.Server.Helpers
|
|||
const int blen = 1024;
|
||||
byte[] buffer = new byte[blen];
|
||||
int len = 0;
|
||||
while (!token.IsCancellationRequested && (len=inputStream.Read(buffer, 0, blen))>0)
|
||||
while (!token.IsCancellationRequested && (len = inputStream.Read(buffer, 0, blen)) > 0)
|
||||
{
|
||||
dest.Write(buffer, 0, len);
|
||||
usage += len;
|
||||
|
|
@ -222,7 +221,8 @@ namespace Yavsc.Server.Helpers
|
|||
inputStream.Close();
|
||||
}
|
||||
}
|
||||
if (usage >= user.DiskQuota) {
|
||||
if (usage >= user.DiskQuota)
|
||||
{
|
||||
item.QuotaOffense = true;
|
||||
}
|
||||
user.DiskUsage = usage;
|
||||
|
|
@ -231,15 +231,15 @@ namespace Yavsc.Server.Helpers
|
|||
|
||||
public static HtmlString FileLink(this RemoteFileInfo info, string username, string subpath)
|
||||
{
|
||||
return new HtmlString(
|
||||
$"{Config.UserFilesOptions.RequestPath}/{username}/{subpath}/{info.Name}" );
|
||||
return new HtmlString(
|
||||
$"{Config.UserFilesOptions.RequestPath}/{username}/{subpath}/{info.Name}");
|
||||
}
|
||||
|
||||
public static RemoteFileInfo FileInfo(this ApplicationUser user, string path)
|
||||
{
|
||||
IFileInfo info = Config.UserFilesOptions.FileProvider.GetFileInfo($"{user.UserName}/{path}");
|
||||
if (!info.Exists) return null;
|
||||
return new RemoteFileInfo{ Name = info.Name, Size = info.Length, LastModified = info.LastModified.UtcDateTime };
|
||||
return new RemoteFileInfo { Name = info.Name, Size = info.Length, LastModified = info.LastModified.UtcDateTime };
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -248,32 +248,43 @@ namespace Yavsc.Server.Helpers
|
|||
var item = new FileReceivedInfo
|
||||
(Config.AvatarsOptions.RequestPath.ToUriComponent(),
|
||||
user.UserName + ".png");
|
||||
|
||||
using (var org = formFile.OpenReadStream())
|
||||
{
|
||||
using Image image = Image.Load(org);
|
||||
image.Mutate(x=>x.Resize(128,128));
|
||||
image.Save(Path.Combine(Config.SiteSetup.Avatars,item.FileName));
|
||||
image.Mutate(x=>x.Resize(64,64));
|
||||
image.Save(Path.Combine(Config.SiteSetup.Avatars,user.UserName + ".s.png"));
|
||||
image.Mutate(x=>x.Resize(32,32));
|
||||
image.Save(Path.Combine(Config.SiteSetup.Avatars,user.UserName + ".xs.png"));
|
||||
|
||||
var size = new MagickGeometry(128, 128);
|
||||
size.IgnoreAspectRatio = false;
|
||||
using var image = new MagickImage(org);
|
||||
|
||||
image.Resize(size);
|
||||
image.Write(Path.Combine(Config.SiteSetup.Avatars, item.FileName));
|
||||
size.X = 64;
|
||||
size.Y = 64;
|
||||
image.Resize(size);
|
||||
image.Write(Path.Combine(Config.SiteSetup.Avatars, user.UserName + ".s.png"));
|
||||
size.X = 32;
|
||||
size.Y = 32;
|
||||
image.Resize(size);
|
||||
image.Write(Path.Combine(Config.SiteSetup.Avatars, user.UserName + ".xs.png"));
|
||||
|
||||
}
|
||||
|
||||
user.Avatar = $"{item.DestDir}/{item.FileName}";
|
||||
return item;
|
||||
}
|
||||
|
||||
public static string GetFileUrl (this LiveFlow flow)
|
||||
public static string GetFileUrl(this LiveFlow flow)
|
||||
{
|
||||
// no server-side backup for this stream
|
||||
return $"{Config.UserFilesOptions.RequestPath}/{flow.Owner.UserName}/live/"+GetFileName(flow);
|
||||
return $"{Config.UserFilesOptions.RequestPath}/{flow.Owner.UserName}/live/" + GetFileName(flow);
|
||||
}
|
||||
|
||||
public static string GetFileName (this LiveFlow flow)
|
||||
|
||||
public static string GetFileName(this LiveFlow flow)
|
||||
{
|
||||
var fileInfo = new FileInfo(flow.DifferedFileName);
|
||||
var ext = fileInfo.Extension;
|
||||
var namelen = flow.DifferedFileName.Length - ext.Length;
|
||||
var basename = flow.DifferedFileName.Substring(0,namelen);
|
||||
var basename = flow.DifferedFileName.Substring(0, namelen);
|
||||
return $"{basename}-{flow.SequenceNumber}{ext}";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@
|
|||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>53bd70e8-ff81-497a-847f-a15fd8ea7a09</UserSecretsId>
|
||||
<RootNamespace>Yavsc.Server</RootNamespace>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<RepositoryUrl>https://github.com/pazof/yavsc</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HigginsSoft.IdentityServer8.EntityFramework" />
|
||||
<PackageReference Include="Magick.NET-Q8-AnyCPU" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||
<PackageReference Include="HigginsSoft.IdentityServer8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
|
||||
|
|
@ -22,7 +24,6 @@
|
|||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" />
|
||||
<PackageReference Include="Google.Apis.Calendar.v3" />
|
||||
<PackageReference Include="PayPalMerchantSDK" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" />
|
||||
<PackageReference Include="RazorEngine.NetCore" />
|
||||
<PackageReference Include="MailKit" />
|
||||
<PackageReference Include="MimeKit" />
|
||||
|
|
@ -31,4 +32,4 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="../Yavsc.Abstract/Yavsc.Abstract.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -15,4 +15,4 @@
|
|||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>Yavsc.cli</RootNamespace>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor" />
|
||||
|
|
@ -18,4 +19,4 @@
|
|||
<ProjectReference Include="..\Yavsc.Abstract\Yavsc.Abstract.csproj" />
|
||||
<ProjectReference Include="..\Yavsc.Server\Yavsc.Server.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue