Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Webreaper committed Nov 15, 2021
2 parents fbb9b14 + 5c0b331 commit 2156a13
Show file tree
Hide file tree
Showing 36 changed files with 402 additions and 249 deletions.
2 changes: 1 addition & 1 deletion Accord/Accord.Imaging/Accord.Imaging.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<None Remove="System.Drawing.Common" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Properties\AssemblyInfo.cs" />
Expand Down
14 changes: 7 additions & 7 deletions Damselfly.Core.DbModels/Damselfly.Core.DbModels.csproj
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0-rc.2.21480.5">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0-rc.2.21480.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0-rc.2.21480.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 4 additions & 0 deletions Damselfly.Core.ImageProcessing/ImageSharpProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ public async Task<ImageProcessResult> CreateThumbs(FileInfo source, IDictionary<

public async Task GetCroppedFile( FileInfo source, int x, int y, int width, int height, FileInfo destFile )
{
Stopwatch watch = new Stopwatch("ImageSharpCrop");

// Image.Load(string path) is a shortcut for our default type.
// Other pixel formats use Image.Load<TPixel>(string path))
using var image = Image.Load<Rgba32>(source.FullName);
Expand All @@ -209,6 +211,8 @@ public async Task GetCroppedFile( FileInfo source, int x, int y, int width, int
image.Mutate(x => x.AutoOrient());
image.Mutate(x => x.Crop( rect ));
await image.SaveAsync(destFile.FullName);

watch.Stop();
}

/// <summary>
Expand Down
12 changes: 8 additions & 4 deletions Damselfly.Core.ImageProcessing/SkiaSharpProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,11 @@ public Task<ImageProcessResult> CreateThumbs(FileInfo source, IDictionary<FileIn
/// <returns></returns>
public Task GetCroppedFile(FileInfo source, int x, int y, int width, int height, FileInfo dest)
{
Stopwatch watch = new Stopwatch("SkiaSharpCrop");

try
{
SKCodec codec = SKCodec.Create(source.FullName);
SKImageInfo info = codec.Info;
using SKBitmap sourceBitmap = SKBitmap.Decode(codec);
using SKBitmap sourceBitmap = SKBitmap.Decode(source.FullName);

// setup crop rect
var cropRect = new SKRectI(x, y, x + width, y + height);
Expand All @@ -168,9 +168,13 @@ public Task GetCroppedFile(FileInfo source, int x, int y, int width, int height,
}
catch (Exception ex)
{
Logging.Log($"Exception during Crop processing: {ex.Message}");
Logging.LogError($"Exception during Skia Crop processing: {ex.Message}");
throw;
}
finally
{
watch.Stop();
}

return Task.CompletedTask;
}
Expand Down
2 changes: 1 addition & 1 deletion Damselfly.Core.Interfaces/Damselfly.Core.Interfaces.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<None Remove="Microsoft.EntityFrameworkCore.Tools" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0-rc.2.21480.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
13 changes: 12 additions & 1 deletion Damselfly.Core.Interfaces/IProcessJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,28 @@

namespace Damselfly.Core.Interfaces
{
public enum JobPriorities
{
FullIndexing = 0,
ExifService = 1,
Indexing = 2,
Metadata = 3,
Thumbnails = 4,
ImageRecognition = 5
};

public interface IProcessJob
{
Task Process();
bool CanProcess { get; }
string Description { get; }
JobPriorities Priority { get; }
}

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

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 @@ -4,7 +4,7 @@
<PackageReference Include="Serilog.Sinks.File" Version="5.0.1-dev-00947" />
<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">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
24 changes: 12 additions & 12 deletions Damselfly.Core/Damselfly.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="6.0.0-rc.2.21480.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0-rc.2.21480.5">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0-rc.2.21480.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand All @@ -26,16 +26,16 @@
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.155" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.155" />
<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="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.0" />
<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="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.2.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="CoenM.ImageSharp.ImageHash" Version="1.1.5" />
<PackageReference Include="MudBlazor" Version="6.0.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
Expand Down
63 changes: 63 additions & 0 deletions Damselfly.Core/ScopedServices/UserTagFavouritesService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Damselfly.Core.Services;
using Damselfly.Core.DbModels;

namespace Damselfly.Core.ScopedServices
{
public class UserTagFavouritesService : IDisposable
{
private readonly ExifService _exifService;
private readonly UserConfigService _configService;

public event Action OnRecentsChanged;
public List<string> RecentTags { get; private set; } = new List<string>();

public UserTagFavouritesService(ExifService exifService, UserConfigService configService)
{
_configService = configService;
_exifService = exifService;

_exifService.OnUserTagsAdded += AddRecentTags;

string recents = configService.Get("FavouriteTags");

if( ! string.IsNullOrEmpty( recents ) )
{
RecentTags.AddRange(recents.Split(",").Select(x => x.Trim()).ToList());
}
}

private void NotifyRecentsChanged()
{
OnRecentsChanged?.Invoke();
}

/// <summary>
/// Add most-recent tags to the list
/// </summary>
/// <param name="recentTags"></param>
private void AddRecentTags(ICollection<string> recentTags )
{
const int maxRecents = 5;

var newRecent = recentTags.Concat(RecentTags)
.Except(_exifService.FavouriteTags.Select(x => x.Keyword))
.Distinct()
.Take(maxRecents).ToList();

RecentTags.Clear();
RecentTags.AddRange(newRecent);

_configService.Set("FavouriteTags", string.Join(",",RecentTags));
NotifyRecentsChanged();
}

public void Dispose()
{
_exifService.OnUserTagsAdded -= AddRecentTags;
}
}
}

15 changes: 14 additions & 1 deletion Damselfly.Core/Services/ExifService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ public class ExifService : IProcessJobFactory

public List<Tag> FavouriteTags { get; private set; } = new List<Tag>();
public event Action OnFavouritesChanged;
public event Action<List<string>> OnUserTagsAdded;
private const int s_exifWriteDelay = 15;

private void NotifyFavouritesChanged()
{
OnFavouritesChanged?.Invoke();
}

private void NotifyUserTagsAdded( List<string> tagsAdded )
{
OnUserTagsAdded?.Invoke(tagsAdded);
}

public ExifService( StatusService statusService, WorkService workService,
IndexingService indexingService, ImageCache imageCache )
{
Expand All @@ -46,6 +52,7 @@ public ExifService( StatusService statusService, WorkService workService,
_workService = workService;

GetExifToolVersion();
LoadFavouriteTagsAsync().Wait();

_workService.AddJobSource(this);
}
Expand Down Expand Up @@ -94,6 +101,8 @@ public async Task UpdateTagsAsync(Image image, List<string> addTags, List<string
await UpdateTagsAsync(new[] { image }, addTags, removeTags, user);
}



/// <summary>
/// Takes an image and a set of keywords, and writes them to the DB queue for
/// keywords to be added. These will then be processed asynchronously.
Expand Down Expand Up @@ -166,6 +175,9 @@ public async Task UpdateTagsAsync(Image[] images, List<string> addTags, List<str
Logging.LogError($"Exception inserting keyword operations: {ex.Message}");
}

if( user != null )
NotifyUserTagsAdded(addTags);

// Trigger the work service to look for new jobs
_workService.HandleNewJobs(this, s_exifWriteDelay);
}
Expand Down Expand Up @@ -472,14 +484,15 @@ public class ExifProcess : IProcessJob
public ExifService Service { get; set; }
public bool CanProcess => true;
public string Description => "Keyword Updates";
public JobPriorities Priority => JobPriorities.ExifService;

public async Task Process()
{
await Service.ProcessExifOperations(ImageId, ExifOps);
}
}

public int Priority => 3;
public JobPriorities Priority => JobPriorities.ExifService;

public async Task<ICollection<IProcessJob>> GetPendingJobs(int maxCount)
{
Expand Down
3 changes: 3 additions & 0 deletions Damselfly.Core/Services/FolderWatcherService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ private async Task FolderQueueProcessor()
var uniqueFolders = folders.Distinct(StringComparer.OrdinalIgnoreCase);
var pendingFolders = db.Folders.Where(f => uniqueFolders.Contains(f.Path)).ToList();

// Call this method synchronously, we don't want to continue otherwise
// we'll end up with race conditions as the timer triggers while
// the method is completing.
_indexingService.MarkFoldersForScan(pendingFolders).Wait();
}
}
Expand Down
5 changes: 3 additions & 2 deletions Damselfly.Core/Services/ImageRecognitionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -567,8 +567,8 @@ public async Task MarkFolderForScan(Folder folder)
using var db = new ImageContext();

var queryable = db.ImageMetaData.Where(img => img.Image.FolderId == folder.FolderId);
int updated = await db.BatchUpdate(queryable, x => new ImageMetaData { AILastUpdated = null });

int updated = await db.BatchUpdate(queryable, x => new ImageMetaData { AILastUpdated = null });
_statusService.StatusText = $"Folder {folder.Name} ({updated} images) flagged for AI reprocessing.";

_workService.HandleNewJobs(this);
Expand Down Expand Up @@ -603,6 +603,7 @@ public class AIProcess : IProcessJob
public int ImageId { get; set; }
public ImageRecognitionService Service { get; set; }
public string Description => "AI processing";
public JobPriorities Priority => JobPriorities.ImageRecognition;

public async Task Process()
{
Expand All @@ -612,7 +613,7 @@ public async Task Process()
public bool CanProcess { get { return true; } }
}

public int Priority => 5;
public JobPriorities Priority => JobPriorities.ImageRecognition;

public async Task<ICollection<IProcessJob>> GetPendingJobs( int maxJobs )
{
Expand Down
3 changes: 2 additions & 1 deletion Damselfly.Core/Services/IndexingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ public class IndexProcess : IProcessJob
public IndexingService Service { get; set; }
public bool CanProcess => true;
public string Description { get; set; }
public JobPriorities Priority => IsFullIndex ? JobPriorities.FullIndexing : JobPriorities.Indexing;

public async Task Process()
{
Expand All @@ -475,7 +476,7 @@ public async Task Process()
}
}

public int Priority => 1;
public JobPriorities Priority => JobPriorities.Indexing;

public async Task<ICollection<IProcessJob>> GetPendingJobs( int maxCount )
{
Expand Down
3 changes: 2 additions & 1 deletion Damselfly.Core/Services/MetaDataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -738,14 +738,15 @@ public class MetadataProcess : IProcessJob
public MetaDataService Service { get; set; }
public bool CanProcess => true;
public string Description => "Metadata scanning";
public JobPriorities Priority => JobPriorities.Metadata;

public async Task Process()
{
await Service.ScanMetaData(ImageId);
}
}

public int Priority => 2;
public JobPriorities Priority => JobPriorities.Metadata;

public async Task<ICollection<IProcessJob>> GetPendingJobs(int maxJobs)
{
Expand Down
Loading

0 comments on commit 2156a13

Please sign in to comment.