summaryrefslogtreecommitdiff
path: root/Services
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2023-10-20 14:26:02 +1100
committerJake Mannens <jake@asger.xyz>2023-10-20 14:26:02 +1100
commit02670870b2711db0984f492d452a90477c67608a (patch)
treea6c15f627535dd962042d2e000c093cf2ae63956 /Services
parent07728d1048f34e1d048da63684b341ab30bc1d06 (diff)
Gallery
Diffstat (limited to 'Services')
-rw-r--r--Services/FeedService.cs117
-rw-r--r--Services/MediaService.cs27
-rw-r--r--Services/SecurityService.cs6
3 files changed, 98 insertions, 52 deletions
diff --git a/Services/FeedService.cs b/Services/FeedService.cs
index c66b9ee..b664d62 100644
--- a/Services/FeedService.cs
+++ b/Services/FeedService.cs
@@ -1,78 +1,109 @@
using Microsoft.EntityFrameworkCore;
-using System.Data.Common;
+using Microsoft.EntityFrameworkCore.Query;
namespace HyperBooru.Services;
-public enum FeedOrder {
+public enum FeedSortOrder {
+ Ascending,
+ Descending
+}
+
+public enum FeedSortType {
Chronological,
Rating
}
+public record FeedOptions {
+ public FeedSortType SortType { get; set; }
+ public FeedSortOrder SortOrder { get; set; }
+ public bool RandomPosition { get; set; }
+
+ public Func<IQueryable<Media>, IQueryable<Media>>? IncludeProperties { get; set; }
+}
+
public interface IFeedService {
public IEnumerable<Media> Feed { get; }
-
- public void InitializeFeed(
- FeedOrder order = FeedOrder.Chronological,
- bool descending = true,
- bool randomPosition = false);
+ public void InitializeFeed(FeedOptions feedOptions);
+ public Media[] Next(int count);
}
public class FeedService : IFeedService {
- private FeedConfiguration? feedConfig;
+ private const int FeedChunkSize = 50;
+
+ private FeedOptions? feedOptions;
+ private Media? last;
private IDbContextFactory<HBContext> dbFactory;
public FeedService(IDbContextFactory<HBContext> dbFactory) =>
this.dbFactory = dbFactory;
- public void InitializeFeed(
- FeedOrder order,
- bool descending,
- bool randomPosition) {
-
- feedConfig = new() {
- Order = order,
- Descending = descending,
- RandomPosition = randomPosition
- };
+ public void InitializeFeed(FeedOptions feedOptions) {
+ this.feedOptions = feedOptions;
+ last = null;
}
public IEnumerable<Media> Feed {
get {
- if(feedConfig is null)
- throw new InvalidOperationException("Feed must be initialized first");
-
+ last = null;
while(true) {
- var db = dbFactory.CreateDbContext();
+ var media = Next(FeedChunkSize);
+ if(media.Count() == 0)
+ break;
+ foreach(var m in media)
+ yield return m;
+ }
+ }
+ }
- IOrderedQueryable<Media> media;
+ public Media[] Next(int count) =>
+ NextDbChunk(Math.Abs(count), count < 0);
- switch(feedConfig.Order) {
- default:
- case FeedOrder.Chronological:
- if(feedConfig.Descending)
- media = db.Media.OrderByDescending(m => m.ObjectId);
+ private Media[] NextDbChunk(int chunkSize, bool reverse = false) {
+ if(feedOptions is null)
+ throw new InvalidOperationException("Feed must be initialized first");
+
+ while(true) {
+ var db = dbFactory.CreateDbContext();
+
+ IQueryable<Media> media = db.Media;
+
+ if(feedOptions.IncludeProperties is not null)
+ media = feedOptions.IncludeProperties(media);
+
+ var sortOrder = feedOptions.SortOrder;
+ if(reverse)
+ sortOrder = sortOrder == FeedSortOrder.Ascending
+ ? FeedSortOrder.Descending
+ : FeedSortOrder.Ascending;
+
+ if(last is not null) {
+ switch(feedOptions.SortType) {
+ case FeedSortType.Chronological:
+ if(sortOrder == FeedSortOrder.Descending)
+ media = media.Where(m => m.ObjectId < last.ObjectId);
else
- media = db.Media.OrderBy(m => m.ObjectId);
+ media = media.Where(m => m.ObjectId > last.ObjectId);
break;
}
+ media = media.Where(m => m.ObjectId != last.ObjectId);
+ }
- Media[] mediaArray = media.Take(50).ToArray();
-
- db.Dispose();
-
- if(mediaArray.Count() == 0)
+ switch(feedOptions.SortType) {
+ case FeedSortType.Chronological:
+ if(sortOrder == FeedSortOrder.Descending)
+ media = media.OrderByDescending(m => m.ObjectId);
+ else
+ media = media.OrderBy(m => m.ObjectId);
break;
-
- foreach(var m in mediaArray)
- yield return m;
}
- }
- }
- private record FeedConfiguration {
- public FeedOrder Order { get; set; }
- public bool Descending { get; set; }
- public bool RandomPosition { get; set; }
+ Media[] mediaArray = media
+ .Take(chunkSize)
+ .ToArray();
+
+ if(mediaArray.Count() != 0)
+ last = mediaArray.Last();
+ }
}
}
diff --git a/Services/MediaService.cs b/Services/MediaService.cs
index abc026f..a9e744e 100644
--- a/Services/MediaService.cs
+++ b/Services/MediaService.cs
@@ -132,6 +132,7 @@ public class MediaService : IMediaService {
using var magickImage = new MagickImage(fileData);
var media = db.UploadedFiles
+ .Include(uf => uf.Media)
.FirstOrDefault(uf => uf.Checksum == hash)?
.Media;
@@ -154,28 +155,35 @@ public class MediaService : IMediaService {
.First(td => td.Guid == HBObjectGuid.IngestTag);
media = new() {
- CurrentUploadedFile = fileRecord,
- UploadedFiles = new() {
- fileRecord
+ UploadedFiles = new() {
+ fileRecord,
},
Tags = new() {
new() { TagDefinition = ingestTagDef }
}
};
- using var newFile = System.IO.File.Create(GetPath(media));
+ using var newFile = File.Create(GetPath(media));
fileData.Seek(0, SeekOrigin.Begin);
fileData.CopyTo(newFile);
newFile.Flush();
db.Media.Add(media);
+ db.SaveChanges();
+ media.CurrentUploadedFile = fileRecord;
+ db.SaveChanges();
} else {
- media.UploadedFiles.Add(fileRecord);
+ db.Entry(media).Collection(m => m.UploadedFiles).Load();
+ var fileHashes = media.UploadedFiles
+ .Select(uf => GetUploadedFileHash(uf));
+ // Only add the uploaded file record if it contains new information
+ if(!fileHashes.Contains(GetUploadedFileHash(fileRecord)))
+ media.UploadedFiles.Add(fileRecord);
db.Update(media);
+ db.SaveChanges();
}
- db.SaveChanges();
transaction.Commit();
return media;
@@ -305,4 +313,11 @@ public class MediaService : IMediaService {
Directory.CreateDirectory(fileInfo.Directory.FullName);
return fileInfo.FullName;
}
+
+ private int GetUploadedFileHash(UploadedFile uf) => (
+ uf.CreateTime,
+ uf.LastWriteTime,
+ uf.Filename,
+ uf.Length,
+ uf.Checksum).GetHashCode();
}
diff --git a/Services/SecurityService.cs b/Services/SecurityService.cs
index 85513ec..1a0c445 100644
--- a/Services/SecurityService.cs
+++ b/Services/SecurityService.cs
@@ -64,13 +64,13 @@ public class SecurityService : ISecurityService {
principalProvider.SearchPrincipals(name);
public IPrincipal? GetPrincipal(string name) =>
- principalProvider.GetPrincipal(name);
+ principalProvider.GetPrincipal(name.Trim());
public IUser? GetUser(string name) =>
- principalProvider.GetUser(name);
+ principalProvider.GetUser(name.Trim());
public IGroup? GetGroup(string name) =>
- principalProvider.GetGroup(name);
+ principalProvider.GetGroup(name.Trim());
public bool ValidatePassword(IUser user, string password) =>
principalProvider.ValidatePassword(user, password);