public void GetSize_Name_Large_NonValidLength() { var input = ThumbnailNameHelper.Combine("non_valid_length", ThumbnailSize.Large); var result2 = ThumbnailNameHelper.GetSize(input); Assert.AreEqual(ThumbnailSize.Unknown, result2); }
private async Task LoopThoughChunk(IEnumerable <string> itemsInChunk, List <string> deletedFileHashes) { var fileIndexItems = await _query.GetObjectsByFileHashAsync(itemsInChunk.ToList()); foreach (var result in fileIndexItems.Where(result => result.Status == FileIndexItem.ExifStatus.NotFoundNotInIndex )) { var fileHashesToDelete = new List <string> { ThumbnailNameHelper.Combine(result.FileHash, ThumbnailSize.TinyMeta), ThumbnailNameHelper.Combine(result.FileHash, ThumbnailSize.ExtraLarge), ThumbnailNameHelper.Combine(result.FileHash, ThumbnailSize.TinyMeta), ThumbnailNameHelper.Combine(result.FileHash, ThumbnailSize.Large) }; foreach (var fileHash in fileHashesToDelete) { _thumbnailStorage.FileDelete(fileHash); } _logger.LogInformation("$"); deletedFileHashes.Add(result.FileHash); } }
public void GetSize_Name_Large() { var input = ThumbnailNameHelper.Combine("01234567890123456789123456", ThumbnailSize.Large); var result2 = ThumbnailNameHelper.GetSize(input); Assert.AreEqual(ThumbnailSize.Large, result2); }
public void GetSize_Name_NonValidLength() { var input = "01234567890123456789123456@859693845"; var result2 = ThumbnailNameHelper.GetSize(input); Assert.AreEqual(ThumbnailSize.Unknown, result2); }
public void Combine_Compare() { var result = ThumbnailNameHelper.Combine("test_hash", 2000); var result2 = ThumbnailNameHelper.Combine("test_hash", ThumbnailSize.ExtraLarge); Assert.AreEqual(result, result2); }
public async Task CreateThumbTest_FileHash_SkipExtraLarge() { var storage = new FakeIStorage(new List <string> { "/" }, new List <string> { _fakeIStorageImageSubPath }, new List <byte[]> { CreateAnImage.Bytes }); var fileHash = "test_hash"; // skip xtra large var isCreated = await new Thumbnail(storage, storage, new FakeIWebLogger()).CreateThumb( _fakeIStorageImageSubPath, fileHash, true); Assert.AreEqual(true, isCreated); Assert.AreEqual(true, storage.ExistFile(fileHash)); Assert.AreEqual(true, storage.ExistFile( ThumbnailNameHelper.Combine(fileHash, ThumbnailSize.Small))); Assert.AreEqual(false, storage.ExistFile( ThumbnailNameHelper.Combine(fileHash, ThumbnailSize.ExtraLarge))); }
private IActionResult ReturnThumbnailResult(string f, bool json, ThumbnailSize size) { Response.Headers.Add("x-image-size", new StringValues(size.ToString())); var stream = _thumbnailStorage.ReadStream(ThumbnailNameHelper.Combine(f, size), 50); var imageFormat = ExtensionRolesHelper.GetImageFormat(stream); if (imageFormat == ExtensionRolesHelper.ImageFormat.unknown) { SetExpiresResponseHeadersToZero(); return(NoContent()); // 204 } // When using the api to check using javascript // use the cached version of imageFormat, otherwise you have to check if it deleted if (json) { return(Json("OK")); } stream = _thumbnailStorage.ReadStream( ThumbnailNameHelper.Combine(f, size)); // thumbs are always in jpeg Response.Headers.Add("x-filename", new StringValues(FilenamesHelper.GetFileName(f + ".jpg"))); return(File(stream, "image/jpeg")); }
public void GetSize_Name_UnknownSize() { var input = "test_hash@4789358"; var result2 = ThumbnailNameHelper.GetSize(input); Assert.AreEqual(ThumbnailSize.Unknown, result2); }
public async Task CreateThumbTest_1arg_ThumbnailAlreadyExist() { var storage = new FakeIStorage(new List <string> { "/" }, new List <string> { _fakeIStorageImageSubPath }, new List <byte[]> { CreateAnImage.Bytes }); var hash = (await new FileHash(storage).GetHashCodeAsync(_fakeIStorageImageSubPath)).Key; await storage.WriteStreamAsync( new PlainTextFileHelper().StringToStream("not 0 bytes"), ThumbnailNameHelper.Combine(hash, ThumbnailSize.ExtraLarge)); await storage.WriteStreamAsync( new PlainTextFileHelper().StringToStream("not 0 bytes"), ThumbnailNameHelper.Combine(hash, ThumbnailSize.Large)); await storage.WriteStreamAsync( new PlainTextFileHelper().StringToStream("not 0 bytes"), ThumbnailNameHelper.Combine(hash, ThumbnailSize.Small)); var isCreated = await new Thumbnail(storage, storage, new FakeIWebLogger()).CreateThumb( _fakeIStorageImageSubPath); Assert.AreEqual(false, isCreated[0].Item2); }
[ProducesResponseType(typeof(List <ImportIndexItem>), 415)] // wrong input public async Task <IActionResult> Thumbnail() { var tempImportPaths = await Request.StreamFile(_appSettings, _selectorStorage); var thumbnailNames = new List <string>(); // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator foreach (var tempImportSinglePath in tempImportPaths) { var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(tempImportSinglePath); var thumbToUpperCase = fileNameWithoutExtension.ToUpperInvariant(); _logger.LogInformation($"[Import/Thumbnail] - {thumbToUpperCase}"); if (ThumbnailNameHelper.GetSize(thumbToUpperCase) == ThumbnailSize.Unknown) { continue; } // remove existing thumbnail if exist if (_thumbnailStorage.ExistFile(thumbToUpperCase)) { _thumbnailStorage.FileDelete(thumbToUpperCase); } thumbnailNames.Add(thumbToUpperCase); } // Status if there is nothing uploaded if (tempImportPaths.Count != thumbnailNames.Count) { Response.StatusCode = 415; return(Json(thumbnailNames)); } for (var i = 0; i < tempImportPaths.Count; i++) { if (!_hostFileSystemStorage.ExistFile(tempImportPaths[i])) { _logger.LogInformation($"[Import/Thumbnail] ERROR {tempImportPaths[i]} does not exist"); continue; } await _thumbnailStorage.WriteStreamAsync( _hostFileSystemStorage.ReadStream(tempImportPaths[i]), thumbnailNames[i]); // Remove from temp folder to avoid long list of files RemoveTempAndParentStreamFolder(tempImportPaths[i]); } return(Json(thumbnailNames)); }
public async Task <bool> WriteAndCropFile(string fileHash, OffsetModel offsetData, int sourceWidth, int sourceHeight, FileIndexItem.Rotation rotation, string reference = null) { try { using (var thumbnailStream = new MemoryStream(offsetData.Data, offsetData.Index, offsetData.Count)) using (var smallImage = await Image.LoadAsync(thumbnailStream)) using (var outputStream = new MemoryStream()) { var smallImageWidth = smallImage.Width; var smallImageHeight = smallImage.Height; var result = NewImageSize.NewImageSizeCalc(smallImageWidth, smallImageHeight, sourceWidth, sourceHeight); smallImage.Mutate( i => i.Resize(smallImageWidth, smallImageHeight, KnownResamplers.Lanczos3) .Crop(new Rectangle(result.DestX, result.DestY, result.DestWidth, result.DestHeight))); var larger = (int)Math.Round(result.DestWidth * 1.2, 0); smallImage.Mutate( i => i.Resize(larger, 0, KnownResamplers.Lanczos3)); var rotate = RotateEnumToDegrees(rotation); smallImage.Mutate( i => i.Rotate(rotate)); await smallImage.SaveAsJpegAsync(outputStream); await _thumbnailStorage.WriteStreamAsync(outputStream, ThumbnailNameHelper.Combine(fileHash, ThumbnailSize.TinyMeta)); if (_appSettings.ApplicationType == AppSettings.StarskyAppType.WebController) { _logger.LogInformation($"[WriteAndCropFile] fileHash: {fileHash} is written"); } } return(true); } catch (Exception ex) { var message = ex.Message; if (message.StartsWith("Image cannot be loaded")) { message = "Image cannot be loaded"; } _logger.LogError($"[WriteFile@meta] Exception {reference} {message}", ex); return(false); } }
/// <summary> /// This list will be included in the zip /// </summary> /// <param name="fileIndexResultsList">the items</param> /// <param name="thumbnail">add the thumbnail or the source image</param> /// <returns>list of file paths</returns> public async Task <List <string> > CreateListToExport(List <FileIndexItem> fileIndexResultsList, bool thumbnail) { var filePaths = new List <string>(); foreach (var item in fileIndexResultsList.Where(p => p.Status == FileIndexItem.ExifStatus.Ok).ToList()) { if (thumbnail) { var sourceThumb = Path.Combine(_appSettings.ThumbnailTempFolder, ThumbnailNameHelper.Combine(item.FileHash, ThumbnailSize.Large, true)); await new Thumbnail(_iStorage, _thumbnailStorage, _logger) .CreateThumb(item.FilePath, item.FileHash, true); filePaths.Add(sourceThumb); continue; } var sourceFile = _appSettings.DatabasePathToFilePath(item.FilePath, false); if (!_hostFileSystemStorage.ExistFile(sourceFile)) { continue; } // the jpeg file for example filePaths.Add(sourceFile); // when there is .xmp sidecar file (but only when file is a RAW file, ignored when for example jpeg) if (!ExtensionRolesHelper.IsExtensionForceXmp(item.FilePath) || !_iStorage.ExistFile( ExtensionRolesHelper.ReplaceExtensionWithXmp( item.FilePath))) { continue; } var xmpFileFullPath = _appSettings.DatabasePathToFilePath( ExtensionRolesHelper.ReplaceExtensionWithXmp( item.FilePath), false); if (!_hostFileSystemStorage.ExistFile(xmpFileFullPath)) { continue; } filePaths.Add(xmpFileFullPath); } return(filePaths); }
public async Task ThumbnailCleanerTestAsync_Cleaner_WithDifferentSizes() { var fakeStorage = new FakeIStorage(new List <string> { "/" }, new List <string> { ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.Large), ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.ExtraLarge), ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.TinyMeta), ThumbnailNameHelper.Combine("exist", ThumbnailSize.TinyMeta), ThumbnailNameHelper.Combine("exist", ThumbnailSize.ExtraLarge), ThumbnailNameHelper.Combine("exist", ThumbnailSize.TinyMeta), ThumbnailNameHelper.Combine("exist", ThumbnailSize.Large), ThumbnailNameHelper.Combine("12234456677", ThumbnailSize.ExtraLarge), }); var fakeQuery = new FakeIQuery(new List <FileIndexItem> { new FileIndexItem("/test.jpg") { FileHash = "exist" } }); var thumbnailCleaner = new ThumbnailCleaner(fakeStorage, fakeQuery, new FakeIWebLogger()); await thumbnailCleaner.CleanAllUnusedFilesAsync(1); Assert.IsTrue(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("exist", ThumbnailSize.TinyMeta))); Assert.IsTrue(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("exist", ThumbnailSize.ExtraLarge))); Assert.IsTrue(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("exist", ThumbnailSize.Large))); Assert.IsTrue(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("exist", ThumbnailSize.TinyMeta))); Assert.IsFalse(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.TinyMeta))); Assert.IsFalse(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.ExtraLarge))); Assert.IsFalse(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.Large))); Assert.IsFalse(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("12234456677", ThumbnailSize.ExtraLarge))); }
public async Task WriteAndCropFile_FileIsWritten() { var storage = new FakeIStorage(); var service = new WriteMetaThumbnailService(new FakeSelectorStorage(storage), new FakeIWebLogger(), new AppSettings()); var result = await service.WriteAndCropFile("test", new OffsetModel { Count = CreateAnImage.Bytes.Length, Data = CreateAnImage.Bytes, Index = 0 }, 6, 6, FileIndexItem.Rotation.Horizontal); Assert.IsTrue(result); Assert.IsTrue(storage.ExistFile(ThumbnailNameHelper.Combine("test", ThumbnailSize.TinyMeta))); }
public void Thumbnail_GetExtraLargeSecondChoiceResult() { var storage = new FakeIStorage(new List <string> { "/" }, new List <string> { ThumbnailNameHelper.Combine("test", ThumbnailSize.ExtraLarge) }); var controller = new ThumbnailController(_query, new FakeSelectorStorage(storage)); controller.ControllerContext.HttpContext = new DefaultHttpContext(); controller.Thumbnail("test", true, false, false); controller.Response.Headers.TryGetValue("x-image-size", out var value); Assert.AreEqual(ThumbnailSize.ExtraLarge.ToString(), value.ToString()); }
/// <summary> /// Check if the image has the right first bytes, if not remove /// </summary> /// <param name="fileHash">the fileHash file</param> /// <param name="thumbnailToSourceSize">size of output thumbnail Large/ExtraLarge</param> internal bool RemoveCorruptImage(string fileHash, ThumbnailSize thumbnailToSourceSize) { if (!_thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(fileHash, thumbnailToSourceSize))) { return(false); } var imageFormat = ExtensionRolesHelper.GetImageFormat(_thumbnailStorage.ReadStream( ThumbnailNameHelper.Combine(fileHash, thumbnailToSourceSize), 160)); if (imageFormat != ExtensionRolesHelper.ImageFormat.unknown) { return(false); } _thumbnailStorage.FileDelete(ThumbnailNameHelper.Combine(fileHash, thumbnailToSourceSize)); return(true); }
public void ThumbnailSmallOrTinyMeta_GetLargeResultWhenAllAreMissing() { var storage = new FakeIStorage(new List <string> { "/" }, new List <string> { ThumbnailNameHelper.Combine("test", ThumbnailSize.Large) }); var controller = new ThumbnailController(_query, new FakeSelectorStorage(storage)); controller.ControllerContext.HttpContext = new DefaultHttpContext(); controller.ThumbnailSmallOrTinyMeta("test"); controller.Response.Headers.TryGetValue("x-image-size", out var value); Assert.AreEqual(ThumbnailSize.Large.ToString(), value.ToString()); }
public void RemoveCorruptImage_RemoveCorruptImage() { var storage = new FakeIStorage( new List <string> { "/" }, new List <string> { ThumbnailNameHelper.Combine("test", ThumbnailSize.ExtraLarge) }, new List <byte[]> { new byte[0] }); var result = new Thumbnail(storage, storage, new FakeIWebLogger()).RemoveCorruptImage("test", ThumbnailSize.ExtraLarge); Assert.IsTrue(result); }
public void RemoveCorruptImage_ShouldIgnore() { var storage = new FakeIStorage( new List <string> { "/" }, new List <string> { ThumbnailNameHelper.Combine("test", ThumbnailSize.ExtraLarge) }, new List <byte[]> { CreateAnImage.Bytes }); var result = new Thumbnail( storage, storage, new FakeIWebLogger()).RemoveCorruptImage("test", ThumbnailSize.Large); Assert.IsFalse(result); }
[ProducesResponseType(404)] // not found public IActionResult ListSizesByHash(string f) { // For serving jpeg files f = FilenamesHelper.GetFileNameWithoutExtension(f); // Restrict the fileHash to letters and digits only // I/O function calls should not be vulnerable to path injection attacks if (!Regex.IsMatch(f, "^[a-zA-Z0-9_-]+$")) { return(BadRequest()); } var data = new ThumbnailSizesExistStatusModel { TinyMeta = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.TinyMeta)), Small = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.Small)), Large = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.Large)), ExtraLarge = _thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.ExtraLarge)) }; // Success has all items (except tinyMeta) if (data.Small && data.Large && data.ExtraLarge) { return(Json(data)); } var sourcePath = _query.GetSubPathByHash(f); var isThumbnailSupported = ExtensionRolesHelper.IsExtensionThumbnailSupported(sourcePath); switch (isThumbnailSupported) { case true when !string.IsNullOrEmpty(sourcePath): Response.StatusCode = 202; return(Json(data)); case false when !string.IsNullOrEmpty(sourcePath): Response.StatusCode = 210; // A conflict, that the thumb is not generated yet return(Json("Thumbnail is not supported; for example you try to view a raw or video file")); default: return(NotFound("not in index")); } }
public async Task ThumbnailCleanerTestAsync_CatchException() { var fakeStorage = new FakeIStorage(new List <string> { "/" }, new List <string> { ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.Large), }); var fakeQuery = new FakeIQueryException(new Microsoft.EntityFrameworkCore.Storage.RetryLimitExceededException()); var thumbnailCleaner = new ThumbnailCleaner(fakeStorage, fakeQuery, new FakeIWebLogger()); await thumbnailCleaner.CleanAllUnusedFilesAsync(); // the file is there even the connection is crashed Assert.IsTrue(fakeStorage.ExistFile( ThumbnailNameHelper.Combine("hash1234", ThumbnailSize.Large))); }
public async Task Thumbnail_CorruptImage_NoContentResult_Test() { // Arrange var storage = ArrangeStorage(); var plainTextStream = new PlainTextFileHelper().StringToStream("CorruptImage"); await storage.WriteStreamAsync(plainTextStream, ThumbnailNameHelper.Combine( "hash-corrupt-image", ThumbnailSize.ExtraLarge)); await _query.AddItemAsync(new FileIndexItem("/test2.jpg"){ FileHash = "hash-corrupt-image" }); // Act var controller = new ThumbnailController(_query, new FakeSelectorStorage(storage)); controller.ControllerContext.HttpContext = new DefaultHttpContext(); var actionResult = controller.Thumbnail("hash-corrupt-image", false, true) as NoContentResult; Assert.AreEqual(204, actionResult.StatusCode); // remove files + database item await _query.RemoveItemAsync(await _query.GetObjectByFilePathAsync("/test2.jpg")); }
/// <summary> /// Resize image with overlay /// </summary> /// <param name="outputPath">absolute path of output on host disk</param> /// <param name="profile">size of output, overlay size, must contain metaData </param> /// <param name="item">database item with filePath</param> /// <returns>true when success</returns> /// <exception cref="DecodingException">when output is not valid</exception> private async Task <bool> Resizer(string outputPath, AppSettingsPublishProfiles profile, FileIndexItem item) { // for less than 1000px if (profile.SourceMaxWidth <= 1000 && _thumbnailStorage.ExistFile(ThumbnailNameHelper. Combine(item.FileHash, ThumbnailSize.Large))) { await _overlayImage.ResizeOverlayImageThumbnails(item.FileHash, outputPath, profile); } else if (profile.SourceMaxWidth <= 2000 && _thumbnailStorage.ExistFile(ThumbnailNameHelper. Combine(item.FileHash, ThumbnailSize.ExtraLarge))) { await _overlayImage.ResizeOverlayImageThumbnails( ThumbnailNameHelper.Combine(item.FileHash, ThumbnailSize.ExtraLarge), outputPath, profile); } else if (_subPathStorage.ExistFile(item.FilePath)) { // Thumbs are 2000 px (and larger) await _overlayImage.ResizeOverlayImageLarge(item.FilePath, outputPath, profile); } if (profile.MetaData) { await MetaData(item, outputPath); } var imageFormat = ExtensionRolesHelper.GetImageFormat(_hostFileSystemStorage.ReadStream(outputPath, 160)); if (imageFormat == ExtensionRolesHelper.ImageFormat.jpg) { return(true); } _hostFileSystemStorage.FileDelete(outputPath); throw new DecodingException("[WebHtmlPublishService] image output is not valid"); }
public void ListSizesByHash_AllExist_exceptTinyMeta() { var hash = "01234567890123456789123456"; var item = _query.AddItem(new FileIndexItem("/test123.jpg") { FileHash = hash }); // Arrange var storage = new FakeIStorage(new List <string>(), new List <string> { ThumbnailNameHelper.Combine(hash, ThumbnailSize.Large), ThumbnailNameHelper.Combine(hash, ThumbnailSize.Small), ThumbnailNameHelper.Combine(hash, ThumbnailSize.ExtraLarge), }); // Check if exist var controller = new ThumbnailController(_query, new FakeSelectorStorage(storage)); controller.ControllerContext.HttpContext = new DefaultHttpContext(); var actionResult = controller.ListSizesByHash(hash) as JsonResult; // Thumbnail exist Assert.AreNotEqual(actionResult, null); var thumbnailAnswer = actionResult.Value as ThumbnailSizesExistStatusModel; Assert.AreEqual(200, controller.Response.StatusCode); Assert.AreEqual(true, thumbnailAnswer.Large); Assert.AreEqual(true, thumbnailAnswer.ExtraLarge); Assert.AreEqual(true, thumbnailAnswer.Small); // > TinyMeta is optional and not needed Assert.AreEqual(false, thumbnailAnswer.TinyMeta); _query.RemoveItem(item); }
[ResponseCache(Duration = 29030400)] // 4 weeks public IActionResult ThumbnailSmallOrTinyMeta(string f) { f = FilenamesHelper.GetFileNameWithoutExtension(f); // Restrict the fileHash to letters and digits only // I/O function calls should not be vulnerable to path injection attacks if (!Regex.IsMatch(f, "^[a-zA-Z0-9_-]+$")) { return(BadRequest()); } if (_thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.Small))) { var stream = _thumbnailStorage.ReadStream(ThumbnailNameHelper.Combine(f, ThumbnailSize.Small)); Response.Headers.TryAdd("x-image-size", new StringValues(ThumbnailSize.Small.ToString())); return(File(stream, "image/jpeg")); } if (_thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.TinyMeta))) { var stream = _thumbnailStorage.ReadStream(ThumbnailNameHelper.Combine(f, ThumbnailSize.TinyMeta)); Response.Headers.TryAdd("x-image-size", new StringValues(ThumbnailSize.TinyMeta.ToString())); return(File(stream, "image/jpeg")); } if (!_thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, ThumbnailSize.Large))) { SetExpiresResponseHeadersToZero(); return(NotFound("hash not found")); } var streamDefaultThumbnail = _thumbnailStorage.ReadStream(ThumbnailNameHelper.Combine(f, ThumbnailSize.Large)); Response.Headers.TryAdd("x-image-size", new StringValues(ThumbnailSize.Large.ToString())); return(File(streamDefaultThumbnail, "image/jpeg")); }
/// <summary> /// Private use => CreateThumb /// Create a Thumbnail file to load it faster in the UI. Use FileIndexItem or database style path, Feature used by the cli tool /// </summary> /// <param name="subPath">relative path to find the file in the storage folder</param> /// <param name="fileHash">the base32 hash of the subPath file</param> /// <param name="skipExtraLarge">skip the extra large image</param> /// <returns>true, if successful</returns> private async Task <bool> CreateThumbInternal(string subPath, string fileHash, bool skipExtraLarge = false) { // FileType=supported + subPath=exit + fileHash=NOT exist if (!ExtensionRolesHelper.IsExtensionThumbnailSupported(subPath) || !_iStorage.ExistFile(subPath)) { return(false); } // File is already tested if (_iStorage.ExistFile(GetErrorLogItemFullPath(subPath))) { return(false); } var thumbnailToSourceSize = ThumbnailSize.ExtraLarge; if (skipExtraLarge) { thumbnailToSourceSize = ThumbnailSize.Large; } var largeThumbnailHash = ThumbnailNameHelper.Combine(fileHash, thumbnailToSourceSize); if (!_thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine( fileHash, thumbnailToSourceSize))) { // run resize sync var(_, resizeSuccess, resizeMessage) = (await ResizeThumbnailFromSourceImage(subPath, ThumbnailNameHelper.GetSize(thumbnailToSourceSize), largeThumbnailHash)); // check if output any good RemoveCorruptImage(fileHash, thumbnailToSourceSize); if (!resizeSuccess || !_thumbnailStorage.ExistFile( ThumbnailNameHelper.Combine(fileHash, thumbnailToSourceSize))) { _logger.LogError($"[ResizeThumbnailFromSourceImage] " + $"output is null or corrupt for subPath {subPath}"); await WriteErrorMessageToBlockLog(subPath, resizeMessage); return(false); } Console.Write("."); } var thumbnailFromThumbnailUpdateList = new List <ThumbnailSize>(); void Add(ThumbnailSize size) { if (!_thumbnailStorage.ExistFile( ThumbnailNameHelper.Combine( fileHash, size)) ) { thumbnailFromThumbnailUpdateList.Add(size); } } new List <ThumbnailSize> { ThumbnailSize.Small, ThumbnailSize.Large // <- will be false when skipExtraLarge = true }.ForEach(Add); await(thumbnailFromThumbnailUpdateList).ForEachAsync( async(size) => await ResizeThumbnailFromThumbnailImage( largeThumbnailHash, ThumbnailNameHelper.GetSize(size), ThumbnailNameHelper.Combine(fileHash, size)), 10); Console.Write("."); return(thumbnailFromThumbnailUpdateList.Any()); }
public void GetSize_ExtraLarge_Int() { var result = ThumbnailNameHelper.GetSize(2000); Assert.AreEqual(ThumbnailSize.ExtraLarge, result); }
[ResponseCache(Duration = 29030400)] // 4 weeks public IActionResult Thumbnail( string f, bool isSingleItem = false, bool json = false, bool extraLarge = true) { // f is Hash // isSingleItem => detailView // Retry thumbnail => is when you press reset thumbnail // json, => to don't waste the users bandwidth. // For serving jpeg files f = FilenamesHelper.GetFileNameWithoutExtension(f); // Get the text before at (@) so replace @2000 with nothing to match fileHash var beforeAt = Regex.Match(f, ".*(?=@)", RegexOptions.None, TimeSpan.FromSeconds(1)).Value; if (!string.IsNullOrEmpty(beforeAt)) { f = beforeAt; } // Restrict the fileHash to letters and digits only // I/O function calls should not be vulnerable to path injection attacks if (!Regex.IsMatch(f, "^[a-zA-Z0-9_-]+$")) { return(BadRequest()); } var preferredSize = ThumbnailSize.ExtraLarge; var altSize = ThumbnailSize.Large; if (!extraLarge) { preferredSize = ThumbnailSize.Large; altSize = ThumbnailSize.ExtraLarge; } if (_thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, preferredSize))) { return(ReturnThumbnailResult(f, json, preferredSize)); } if (_thumbnailStorage.ExistFile(ThumbnailNameHelper.Combine(f, altSize))) { return(ReturnThumbnailResult(f, json, altSize)); } // Cached view of item var sourcePath = _query.GetSubPathByHash(f); if (sourcePath == null) { SetExpiresResponseHeadersToZero(); return(NotFound("not in index")); } // Need to check again for recently moved files if (!_iStorage.ExistFile(sourcePath)) { // remove from cache _query.ResetItemByHash(f); // query database again sourcePath = _query.GetSubPathByHash(f); SetExpiresResponseHeadersToZero(); if (sourcePath == null) { return(NotFound("not in index")); } } if (!_iStorage.ExistFile(sourcePath)) { return(NotFound("There is no thumbnail image " + f + " and no source image " + sourcePath)); } if (!isSingleItem) { // "Photo exist in database but " + "isSingleItem flag is Missing" SetExpiresResponseHeadersToZero(); Response.StatusCode = 202; // A conflict, that the thumb is not generated yet return(Json("Thumbnail is not ready yet")); } if (ExtensionRolesHelper.IsExtensionThumbnailSupported(sourcePath)) { var fs1 = _iStorage.ReadStream(sourcePath); var fileExt = FilenamesHelper.GetFileExtensionWithoutDot(sourcePath); var fileName = HttpUtility.UrlEncode(FilenamesHelper.GetFileName(sourcePath)); Response.Headers.TryAdd("x-filename", new StringValues(fileName)); return(File(fs1, MimeHelper.GetMimeType(fileExt))); } Response.StatusCode = 210; // A conflict, that the thumb is not generated yet return(Json("Thumbnail is not supported; for example you try to view a raw file")); }
public void GetSize_Small_Int() { var result = ThumbnailNameHelper.GetSize(300); Assert.AreEqual(ThumbnailSize.Small, result); }
public void GetSize_TinyMeta_Enum() { var result = ThumbnailNameHelper.GetSize(ThumbnailSize.TinyMeta); Assert.AreEqual(150, result); }