Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Webreaper committed Oct 28, 2021
2 parents 68c1374 + dc08727 commit abb351a
Show file tree
Hide file tree
Showing 83 changed files with 7,227 additions and 2,353 deletions.
Binary file modified .DS_Store
Binary file not shown.
17 changes: 16 additions & 1 deletion Damselfly.Core.DbModels/DBAbstractions/BaseModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Damselfly.Core.DbModels.Interfaces;
Expand Down Expand Up @@ -123,7 +124,21 @@ public async Task<int> BatchDelete<T>(IQueryable<T> query) where T : class
if (ReadOnly)
return 1;

return await Task.Run(() => DatabaseSpecialisation.BatchDelete(query));
return await DatabaseSpecialisation.BatchDelete(query);
}

/// <summary>
/// Wrapper to extract the underlying BatchDelete implementation depending on the
/// DB model being used.
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
public async Task<int> BatchUpdate<T>(IQueryable<T> query, Expression<Func<T, T>> updateExpression) where T : class
{
if (ReadOnly)
return 1;

return await DatabaseSpecialisation.BatchUpdate(query, updateExpression);
}

/// <summary>
Expand Down
11 changes: 9 additions & 2 deletions Damselfly.Core.DbModels/DBAbstractions/MySqlModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Damselfly.Core.DbModels.Interfaces;
using Damselfly.Core.Utils;
Expand Down Expand Up @@ -142,18 +143,24 @@ public async Task<bool> BulkInsertOrUpdate<T>(BaseDBModel db, DbSet<T> collectio
return result;
}

public async Task<int> BatchDelete<T>(IQueryable<T> query) where T : class
public Task<int> BatchDelete<T>(IQueryable<T> query) where T : class
{
throw new NotImplementedException();
}

public async Task<IQueryable<T>> Search<T>(string query, DbSet<T> collection) where T : class
public Task<IQueryable<T>> Search<T>(string query, DbSet<T> collection) where T : class
{
// Full text search not supported in MySQL
// TODO: Implement with a Like Query?
throw new NotImplementedException();
}


public Task<int> BatchUpdate<T>(IQueryable<T> query, Expression<Func<T, T>> updateExpression) where T : class
{
throw new NotImplementedException();
}

public void FlushDBWriteCache(BaseDBModel db)
{
// No-op
Expand Down
2 changes: 2 additions & 0 deletions Damselfly.Core.DbModels/Interfaces/IDataBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Linq.Expressions;
using System;
using Damselfly.Core.DbModels.DBAbstractions;
using System.Threading.Tasks;
Expand All @@ -22,6 +23,7 @@ public interface IDataBase
Task<bool> BulkDelete<T>(BaseDBModel db, DbSet<T> collection, List<T> itemsToDelete) where T : class;
Task<bool> BulkInsertOrUpdate<T>(BaseDBModel db, DbSet<T> collection, List<T> itemsToSave, Func<T, bool> isNew ) where T : class;
Task<int> BatchDelete<T>(IQueryable<T> query) where T : class;
Task<int> BatchUpdate<T>(IQueryable<T> query, Expression<Func<T, T>> updateExpression) where T : class;

IQueryable<T> ImageSearch<T>(DbSet<T> resultSet, string query, bool includeAITags) where T : class;
void CreateIndexes(ModelBuilder builder);
Expand Down
2 changes: 1 addition & 1 deletion Damselfly.Core.ImageProcessing/ImageMagickProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public async Task<ImageProcessResult> CreateThumbs(FileInfo source, IDictionary<
else
args = string.Format(" -define jpeg:size={0}x{1} \"{2}\" -quality 90 -unsharp 0.5x0.5+1.25+0.0 ", maxHeight, maxWidth, source.FullName);

FileInfo altSource = null;
FileInfo? altSource = null;

List<string> argsList = new List<string>();

Expand Down
6 changes: 4 additions & 2 deletions Damselfly.Core.ImageProcessing/ImageProcessorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public IHashProvider GetHashProvider()
/// </summary>
/// <param name="fileExtension"></param>
/// <returns></returns>
public IImageProcessor GetProcessor( string fileExtension )
public IImageProcessor? GetProcessor( string fileExtension )
{
if( ! fileExtension.StartsWith( "." ) )
{
Expand All @@ -65,7 +65,9 @@ public IImageProcessor GetProcessor( string fileExtension )
return isharpProcessor;
}

// ImageSharp next. As of 12-Aug-2021, it can do thumbs for 100 images in about 33 seconds. It can also handle HEIC
// ImageMagick last, because of the complexities of spawning a child process.
// As of 12-Aug-2021, it can do thumbs for 100 images in about 33 seconds.
// Main advantage: it can also handle HEIC
if (ImageMagickProcessor.SupportedFileExtensions.Any(x => x.Equals(fileExtension, StringComparison.OrdinalIgnoreCase)))
{
return imProcessor;
Expand Down
10 changes: 5 additions & 5 deletions Damselfly.Core.ImageProcessing/ImageSharpProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Damselfly.Core.ImageProcessing
{
public class ImageSharpProcessor : IImageProcessor, IHashProvider
{
private static FontCollection fontCollection;
private static FontCollection? fontCollection;
private static readonly string[] s_imageExtensions = { ".jpg", ".jpeg", ".png", ".webp", ".tga", ".gif", ".bmp" };

public static ICollection<string> SupportedFileExtensions { get { return s_imageExtensions; } }
Expand Down Expand Up @@ -91,7 +91,7 @@ public string GetPerceptualHash(string path)
/// <returns>String hash of the image data</returns>
public static string GetHash(Image<Rgba32> image)
{
string result = null;
string result = String.Empty;

try
{
Expand Down Expand Up @@ -153,11 +153,11 @@ public async Task<ImageProcessResult> CreateThumbs(FileInfo source, IDictionary<
// Other pixel formats use Image.Load<TPixel>(string path))
using var image = await Image.LoadAsync<Rgba32>(source.FullName);

load.Stop();

// We've got the image in memory. Create the hash.
result.ImageHash = GetHash(image);

load.Stop();

Stopwatch orient = new Stopwatch("ImageSharpOrient");

image.Mutate(x => x.AutoOrient());
Expand Down Expand Up @@ -242,7 +242,7 @@ public void TransformDownloadImage(string input, Stream output, IExportSettings
img.Mutate(x => x.AutoOrient());
}

if (!string.IsNullOrEmpty(config.WatermarkText))
if (!string.IsNullOrEmpty(config.WatermarkText) && fontCollection != null)
{
// Apply the watermark if one's been specified.
Font font = fontCollection.CreateFont("Arial", 10);
Expand Down
4 changes: 2 additions & 2 deletions Damselfly.Core.ImageProcessing/SkiaSharpProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public class SkiaSharpProcessor : IImageProcessor
/// </summary>
/// <param name="source"></param>
/// <returns>String hash of the image data</returns>
public static string GetHash(SKBitmap sourceBitmap)
public static string? GetHash(SKBitmap sourceBitmap)
{
string result = null;
string? result = null;

try
{
Expand Down
2 changes: 2 additions & 0 deletions Damselfly.Core.Interfaces/IImageProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Damselfly.Core.Utils.Images;
using System.Drawing;

namespace Damselfly.Core.Interfaces
{
Expand All @@ -22,6 +23,7 @@ public interface IImageProcessor
Task<ImageProcessResult> CreateThumbs(FileInfo source, IDictionary<FileInfo, ThumbConfig> destFiles );
Task GetCroppedFile(FileInfo source, int x, int y, int width, int height, FileInfo destFile);
void TransformDownloadImage(string input, Stream output, IExportSettings exportConfig);

static ICollection<string> SupportedFileExtensions { get; }
}
}
20 changes: 20 additions & 0 deletions Damselfly.Core.Interfaces/IProcessJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Damselfly.Core.Interfaces
{
public interface IProcessJob
{
Task Process();
bool CanProcess { get; }
string Description { get; }
}

public interface IProcessJobFactory
{
Task<ICollection<IProcessJob>> GetPendingJobs( int maxJobs );
int Priority { get; }
}
}

6 changes: 5 additions & 1 deletion Damselfly.Core.Utils/Constants/ConfigSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ public class ConfigSettings
public const string ImportSidecarKeywords = "ImportSidecarKeywords";
public const string LogLevel = "LogLevel";

public const string AIProcessingTimeRange = "AIProcessingTimeRange";
public const string AzureEndpoint = "AzureEndpoint";
public const string AzureApiKey = "AzureApiKey";
public const string AzureUseFreeTier = "UseFreeTier";
public const string AzureDetectionType = "AzureDetectionType";

public const string AltCPULimitEnabled = "AltCPULimitEnabled";
public const string CPULimit = "CPULimit";
public const string AltCPULimit = "AltCPULimit";
public const string AltCPULimitTimes = "AltCPULimitTimes";

public const string EnablePoliciesAndRoles = "EnablePoliciesAndRoles";
public const string ForceLogin = "ForceLogin";
public const string AllowExternalRegistration = "AllowExternalRegistration";
Expand Down
2 changes: 1 addition & 1 deletion Damselfly.Core.Utils/Damselfly.Core.Utils.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ItemGroup>
<PackageReference Include="Serilog" Version="2.11.0-dev-01371" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.1-dev-00947" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1-dev-00876" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1-dev-00879" />
<PackageReference Include="Humanizer" Version="2.11.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0-rc.2.21480.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
4 changes: 2 additions & 2 deletions Damselfly.Core.Utils/Images/ImageProcessResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ namespace Damselfly.Core.Utils.Images
public class ImageProcessResult
{
public bool ThumbsGenerated { get; set; }
public string ImageHash { get; set; }
public string PerceptualHash { get; set; }
public string? ImageHash { get; set; }
public string? PerceptualHash { get; set; }
}
}

12 changes: 12 additions & 0 deletions Damselfly.Core.Utils/Utils/ColorUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Drawing;

namespace Damselfly.Core.Utils
{
public static class ColorUtils
{
public static string ToHex(this Color c) => $"#{c.R:X2}{c.G:X2}{c.B:X2}";

public static string ToRgb(this Color c) => $"rgb({c.R}, {c.G}, {c.B})";
}
}

34 changes: 34 additions & 0 deletions Damselfly.Core.Utils/Utils/ConcurrentPriorityQueue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Damselfly.Core.Utils
{
public class ConcurrentPriorityQueue<T> where T : class
{
SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);

private PriorityQueue<T, int> _queue = new PriorityQueue<T, int>();

public void Enqueue( T obj, int priority )
{
lock( _queue )
{
_queue.Enqueue(obj, priority);
}
}

public T TryDequeue()
{
lock( _queue )
{
if (_queue.TryDequeue(out T obj, out var _))
return obj;
}

return default(T);
}
}
}

1 change: 1 addition & 0 deletions Damselfly.Core.Utils/Utils/HashExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static double Similarity(ulong hash1, ulong hash2)
{
return (64 - BitOperations.PopCount(hash1 ^ hash2)) / 64.0;
}

}
}

21 changes: 14 additions & 7 deletions Damselfly.Core.Utils/Utils/ThreadUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,22 @@ public static async Task ExecuteInParallel<T>(this IEnumerable<T> collection,
Func<T, Task> processor, int degreeOfParallelism)
{
var queue = new ConcurrentQueue<T>(collection);

await queue.ExecuteInParallel(processor, degreeOfParallelism);
}

public static async Task ExecuteInParallel<T>(this ConcurrentQueue<T> queue,
Func<T, Task> processor, int degreeOfParallelism)
{
var tasks = Enumerable.Range(0, degreeOfParallelism)
.Select(async _ =>
{
while (queue.TryDequeue(out var item))
{
await processor(item).ConfigureAwait(false);
await Task.Delay(100); // Don't thrash.
}
});
{
while (queue.TryDequeue(out var item))
{
await processor(item).ConfigureAwait(false);
// await Task.Delay(100); // Don't thrash.
}
});

Logging.LogTrace("Waiting for Parallel processing to complete...");

Expand Down
15 changes: 7 additions & 8 deletions Damselfly.Core/Damselfly.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,25 @@
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta13" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="font-awesome" Version="4.7.0" />
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.150" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.150" />
<PackageReference Include="FluentValidation" Version="10.3.3" />
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.152" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.152" />
<PackageReference Include="FluentValidation" Version="10.3.4" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.0-rc.2.21480.10" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.0-rc.2.21480.10" />
<PackageReference Include="SendGrid" Version="9.24.3" />
<PackageReference Include="SendGrid" Version="9.24.4" />
<PackageReference Include="MailKit" Version="3.0.0-preview1" />
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Version="5.8.64" />
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Version="6.0.5.128" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="6.0.0-rc.2.21480.10" />
<PackageReference Include="CoenM.ImageSharp.ImageHash" Version="1.0.0" />
<PackageReference Include="MudBlazor" Version="5.1.5" />
<PackageReference Include="MudBlazor" Version="5.2.0-rc5" />
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
<Folder Include="Models\" />
<Folder Include="Utils\" />
<Folder Include="ImageProcessing\" />
<Folder Include="Models\SideCars\" />
<Folder Include="Interfaces\" />
<Folder Include="ScopedServices\" />
</ItemGroup>
<ItemGroup>
Expand All @@ -53,6 +51,7 @@
<ProjectReference Include="..\Damselfly.ML.ObjectDetection.ML\Damselfly.ML.ObjectDetection.csproj" />
<ProjectReference Include="..\Damselfly.ML.AzureFace\Damselfly.ML.AzureFace.csproj" />
<ProjectReference Include="..\Damselfly.ML.EmguFace\Damselfly.ML.EmguFace.csproj" />
<ProjectReference Include="..\Damselfly.ML.ImageClassification\Damselfly.ML.ImageClassification.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="Microsoft.AspNetCore.Components.Authorization" />
Expand Down
Loading

0 comments on commit abb351a

Please sign in to comment.