diff options
| author | Jake Mannens <jake@asger.xyz> | 2023-08-29 15:47:37 +1000 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2025-08-20 00:48:44 +1000 |
| commit | 98053c0fc6e27998ccb8e0ad75900d2b48d6f70e (patch) | |
| tree | b552085007432de023e8f24a0d7417aa17a5bd48 /Services/MediaService.cs | |
| parent | d4f0eae4dc54f356f296ff26aba006e69d21ec0b (diff) | |
Moved thumbnail generation from media controller to media service
Diffstat (limited to 'Services/MediaService.cs')
| -rw-r--r-- | Services/MediaService.cs | 105 |
1 files changed, 87 insertions, 18 deletions
diff --git a/Services/MediaService.cs b/Services/MediaService.cs index f26d005..0b506b0 100644 --- a/Services/MediaService.cs +++ b/Services/MediaService.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore; using MimeDetective; using MimeDetective.Definitions; using System.Security.Cryptography; +using System.Text.RegularExpressions; namespace HyperBooru.Services; @@ -24,6 +25,10 @@ public interface IMediaService { public void Delete(Guid media); public void Delete(Media media); + public void DeleteThumbnails(Guid media); + public void DeleteThumbnails(Media media); + public Stream GetThumbnail(Guid media, int? width, int? height); + public Stream GetThumbnail(Media media, int? width, int? height); public string GetPath(Media media); public string GetPath(Media media, int width, int height); @@ -181,29 +186,22 @@ public class MediaService : IMediaService { using var db = dbFactory.CreateDbContext(); var m = db.Media.First(m => m.Guid == media); - try { - System.IO.File.Delete( - Path.Join( - config.MediaBasePath, - m.Guid.ToString().Substring(0, 2), - m.Guid.ToString().Substring(2, 2), - m.Guid.ToString())); - } catch(IOException) {} + var path = Path.Join( + config.MediaBasePath, + m.Guid.ToString().Substring(0, 2), + m.Guid.ToString().Substring(2, 2), + m.Guid.ToString()); try { - System.IO.Directory.Delete( - Path.Join( - config.MediaBasePath, - m.Guid.ToString().Substring(0, 2), - m.Guid.ToString().Substring(2, 2))); + var fileInfo = new FileInfo(path); + fileInfo.Delete(); + fileInfo.Directory?.Delete(); + fileInfo.Directory?.Parent?.Delete(); } catch(IOException) {} try { - System.IO.Directory.Delete( - Path.Join( - config.MediaBasePath, - m.Guid.ToString().Substring(0, 2))); - } catch(IOException) {} + DeleteThumbnails(media); + } catch {} db.Media.Remove(m); db.SaveChanges(); @@ -212,6 +210,77 @@ public class MediaService : IMediaService { public void Delete(Media media) => Delete(media.Guid); + public void DeleteThumbnails(Guid media) { + var dir = new DirectoryInfo(Path.Join( + config.ThumbnailBasePath, + media.ToString().Substring(0, 2), + media.ToString().Substring(2, 2))); + + var pattern = new Regex($"^{media}-[0-9]+-[0-9]+$"); + var toDelete = dir.GetFiles() + .Where(f => pattern.IsMatch(f.Name)) + .ToList(); + + List<Exception> exceptions = new(); + + foreach(var file in toDelete) { + try { + file.Delete(); + } catch(Exception e) { + exceptions.Add(e); + } + } + + try { + dir.Delete(); + dir.Parent?.Delete(); + } catch(Exception e) { + exceptions.Add(e); + } + + // TODO: wrap the AggregateException in a ThumbnailException + if(exceptions.Count() > 1) + throw new AggregateException(exceptions); + } + + public void DeleteThumbnails(Media media) => + DeleteThumbnails(media.Guid); + + public Stream GetThumbnail(Guid media, int? width, int? height) { + using var db = dbFactory.CreateDbContext(); + var m = db.Media.First(m => m.Guid == media); + if(m is null) + throw new ObjectNotFoundException(media); + + if(m.MimeType.Split("/")[0] != "image") + throw new ThumbnailException("Media object not an image", m); + + using var image = new MagickImage(GetPath(m)); + + if(width is null && height is null) + throw new ThumbnailException("Both width and height cannot be null!", m); + + if(width > image.Width || height > image.Height) + throw new ThumbnailException("Requested thumbnail size is larger than original media", m); + + #pragma warning disable CS8629 + int w = (int) (width is not null ? width : image.Width * height / image.Height); + int h = (int) (height is not null ? height : image.Height * width / image.Width); + #pragma warning restore CS8629 + + var thumbPath = GetPath(m, w, h); + + if(!System.IO.File.Exists(thumbPath)) { + image.Resize(w, h); + image.Write(thumbPath); + } + + return System.IO.File.OpenRead(thumbPath); + } + + public Stream GetThumbnail(Media media, int? width, int? height) => + GetThumbnail(media.Guid, width, height); + public string GetPath(Media media) { var fileInfo = new FileInfo( Path.Join( |
