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")); }
private static string GetFileName(string toFileSubPath, string inputFileSubPath) { // Needed to create SetFilePath() for item that is copied, not the folder // no double slash when moving to root folder return(toFileSubPath == "/" ? $"/{FilenamesHelper.GetFileName(inputFileSubPath)}" : $"{toFileSubPath}/{FilenamesHelper.GetFileName(inputFileSubPath)}"); }
/// <summary> /// Check if a currentChildFolderBuilder exist in the parentFolderBuilder /// </summary> /// <param name="parentFolderBuilder">parent folder (subPath style)</param> /// <param name="currentChildFolderBuilder">child folder with asterisk</param> /// <returns>SubPath without asterisk</returns> private StringBuilder MatchChildDirectories(StringBuilder parentFolderBuilder, StringBuilder currentChildFolderBuilder) { // should return a list of: </2019/10/2019_10_08> var childDirectories = _storage.GetDirectories(parentFolderBuilder.ToString()).ToList(); var matchingFoldersPath = childDirectories.FirstOrDefault(p => MatchChildFolderSearch(parentFolderBuilder, currentChildFolderBuilder, p) ); // When a new folder with asterisk is created if (matchingFoldersPath == null) { var defaultValue = RemoveAsteriskFromString(currentChildFolderBuilder); // When only using Asterisk in structure if (defaultValue == "/") { defaultValue = "/default"; } parentFolderBuilder.Append(defaultValue); return(parentFolderBuilder); } // When a regex folder is matched var childFolderName = PathHelper.PrefixDbSlash(FilenamesHelper.GetFileName(matchingFoldersPath)); parentFolderBuilder.Append(childFolderName); return(parentFolderBuilder); }
private async Task FromFileToDeleted(string inputFileSubPath, string toFileSubPath, List <FileIndexItem> fileIndexResultsList, List <FileIndexItem> fileIndexItems, DetailView detailView) { // when trying to rename something wrongs var fileName = FilenamesHelper.GetFileName(toFileSubPath); if (!FilenamesHelper.IsValidFileName(fileName)) { fileIndexResultsList.Add(new FileIndexItem { Status = FileIndexItem.ExifStatus.OperationNotSupported }); return; //next } // from/input cache should be cleared var inputParentSubFolder = FilenamesHelper.GetParentPath(inputFileSubPath); _query.RemoveCacheParentItem(inputParentSubFolder); var toParentSubFolder = FilenamesHelper.GetParentPath(toFileSubPath); if (string.IsNullOrEmpty(toParentSubFolder)) { toParentSubFolder = "/"; } // clear cache (to FileSubPath parents) _query.RemoveCacheParentItem(toParentSubFolder); // Check if the parent folder exist in the database await _query.AddParentItemsAsync(toParentSubFolder); // Save in database before change on disk await SaveToDatabaseAsync(fileIndexItems, fileIndexResultsList, detailView, toFileSubPath); // add folder to file system if (!_iStorage.ExistFolder(toParentSubFolder)) { _iStorage.CreateDirectory(toParentSubFolder); fileIndexResultsList.Add(new FileIndexItem(toParentSubFolder) { Status = FileIndexItem.ExifStatus.Ok }); } _iStorage.FileMove(inputFileSubPath, toFileSubPath); MoveSidecarFile(inputFileSubPath, toFileSubPath); // when renaming a folder it should warn the UI that it should remove the source item fileIndexResultsList.Add(new FileIndexItem(inputFileSubPath) { Status = FileIndexItem.ExifStatus.NotFoundSourceMissing }); }
/// <summary> /// Get the fileName from the structure and ignore the parent folders /// Does NOT check if the file already exist /// </summary> /// <param name="dateTime">DateTime to parse</param> /// <param name="fileNameBase">include fileName if requested in structure</param> /// <param name="extensionWithoutDot">fileExtension without dot</param> /// <returns>filename without starting slash</returns> public string ParseFileName(DateTime dateTime, string fileNameBase = "", string extensionWithoutDot = "") { CheckStructureFormat(); var fileNameStructure = PathHelper.PrefixDbSlash(FilenamesHelper.GetFileName(_structure)); var parsedStructuredList = ParseStructure(fileNameStructure, dateTime, fileNameBase, extensionWithoutDot); return(PathHelper.RemovePrefixDbSlash(ApplyStructureRangeToStorage(parsedStructuredList))); }
public Task <List <ImportIndexItem> > Preflight(List <string> inputFileFullPaths, ImportSettingsModel importSettings) { var results = new List <ImportIndexItem>(); foreach (var inputFileFullPath in inputFileFullPaths) { // if the item fails var importIndexFileError = new ImportIndexItem { FilePath = "/" + FilenamesHelper.GetFileName(inputFileFullPath), SourceFullFilePath = "~/temp/test", FileHash = "FAKE", MakeModel = "added if the item fails", Status = ImportStatus.FileError }; // Check if extension is correct if (!ExtensionRolesHelper.IsExtensionSyncSupported(inputFileFullPath)) { results.Add(importIndexFileError); } // Check if the file is correct var imageFormat = ExtensionRolesHelper.GetImageFormat( _selectorStorage.Get(SelectorStorage.StorageServices.HostFilesystem) .ReadStream(inputFileFullPath, 160)); if (!ExtensionRolesHelper.ExtensionSyncSupportedList.Contains($"{imageFormat}")) { results.Add(importIndexFileError); } results.Add(new ImportIndexItem { Id = 4, SourceFullFilePath = inputFileFullPath, FilePath = inputFileFullPath, Status = ImportStatus.Ok, FileHash = "FAKE", MakeModel = "added okay", FileIndexItem = new FileIndexItem() { FileHash = "FAKE_OK", FilePath = inputFileFullPath } }); } PreflightList.AddRange(results); return(Task.FromResult(results)); }
/// <summary> /// Uses Cache /// </summary> /// <param name="inputFilePaths">list of paths</param> /// <param name="collections">uses collections </param> /// <returns>list with items</returns> public async Task <List <FileIndexItem> > GetObjectsByFilePathAsync(List <string> inputFilePaths, bool collections) { var resultFileIndexItemsList = new List <FileIndexItem>(); var toQueryPaths = new List <string>(); foreach (var path in inputFilePaths) { var parentPath = FilenamesHelper.GetParentPath(path); var(success, cachedResult) = CacheGetParentFolder(parentPath); List <FileIndexItem> item = null; switch (collections) { case false: if (!success) { break; } item = cachedResult.Where(p => p.ParentDirectory == parentPath && p.FileName == FilenamesHelper.GetFileName(path)).ToList(); break; case true: if (!success) { break; } item = cachedResult.Where(p => p.ParentDirectory == parentPath && p.FileCollectionName == FilenamesHelper.GetFileNameWithoutExtension(path)).ToList(); break; } if (!success || !item.Any()) { toQueryPaths.Add(path); continue; } resultFileIndexItemsList.AddRange(item); } var fileIndexItemsList = await GetObjectsByFilePathQuery(toQueryPaths.ToArray(), collections); resultFileIndexItemsList.AddRange(fileIndexItemsList); return(resultFileIndexItemsList); }
[ProducesResponseType(210)] // raw public async Task <IActionResult> ByZoomFactor( string f, int z = 0, string filePath = "") { // 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()); } // Cached view of item var sourcePath = await _query.GetSubPathByHashAsync(f); if (sourcePath == null) { if (await _query.GetObjectByFilePathAsync(filePath) == null) { return(NotFound("not in index")); } sourcePath = filePath; } if (ExtensionRolesHelper.IsExtensionThumbnailSupported(sourcePath)) { var fs1 = _iStorage.ReadStream(sourcePath); var fileExt = FilenamesHelper.GetFileExtensionWithoutDot(sourcePath); Response.Headers.Add("x-filename", FilenamesHelper.GetFileName(sourcePath)); 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")); }
internal string GetParentDirectoryFromRequestHeader() { var to = Request.Headers["to"].ToString(); if (to == "/") { return("/"); } // only used for direct import if (_iStorage.ExistFolder(FilenamesHelper.GetParentPath(to)) && FilenamesHelper.IsValidFileName(FilenamesHelper.GetFileName(to))) { Request.Headers["filename"] = FilenamesHelper.GetFileName(to); return(FilenamesHelper.GetParentPath(PathHelper.RemoveLatestSlash(to))); } // ReSharper disable once ConvertIfStatementToReturnStatement if (!_iStorage.ExistFolder(PathHelper.RemoveLatestSlash(to))) { return(null); } return(PathHelper.RemoveLatestSlash(to)); }
[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 FilenamesHelper_GetFilePath() { var result = FilenamesHelper.GetFileName("sdfsdf/test.jpg"); Assert.AreEqual("test.jpg", result); }