예제 #1
0
        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"));
        }
예제 #2
0
 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)}");
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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
            });
        }
예제 #5
0
        /// <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)));
        }
예제 #6
0
        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);
        }
예제 #8
0
        [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"));
        }
예제 #9
0
        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));
        }
예제 #10
0
        [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"));
        }
예제 #11
0
        public void FilenamesHelper_GetFilePath()
        {
            var result = FilenamesHelper.GetFileName("sdfsdf/test.jpg");

            Assert.AreEqual("test.jpg", result);
        }