コード例 #1
0
ファイル: ReadMetaXmp.cs プロジェクト: qdraw/starsky
        public FileIndexItem XmpGetSidecarFile(FileIndexItem databaseItem)
        {
            if (databaseItem == null)
            {
                databaseItem = new FileIndexItem();
            }

            // Parse an xmp file for this location
            var xmpSubPath =
                ExtensionRolesHelper.ReplaceExtensionWithXmp(databaseItem.FilePath);

            // also add when the file is a jpeg, we are not writing to it then
            if (_iStorage.ExistFile(xmpSubPath))
            {
                databaseItem.AddSidecarExtension("xmp");
            }

            // Read content from sidecar xmp file
            if (!ExtensionRolesHelper.IsExtensionForceXmp(databaseItem.FilePath) ||
                !_iStorage.ExistFile(xmpSubPath))
            {
                return(databaseItem);
            }

            // Read the text-content of the xmp file.
            var xmp = new PlainTextFileHelper().StreamToString(_iStorage.ReadStream(xmpSubPath));

            // Get the data from the xmp
            databaseItem = GetDataFromString(xmp, databaseItem);
            return(databaseItem);
        }
コード例 #2
0
        /// <summary>
        /// Update compared values
        /// </summary>
        /// <param name="sourceIndexItem">the source object</param>
        /// <param name="updateObject">the item with changed values</param>
        /// <param name="differenceList">typeName of item</param>
        /// <returns></returns>
        public static FileIndexItem SetCompare(FileIndexItem sourceIndexItem, FileIndexItem updateObject, List <string> differenceList)
        {
            if (updateObject == null)
            {
                updateObject = new FileIndexItem();
            }
            PropertyInfo[] propertiesA = sourceIndexItem.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo[] propertiesB = updateObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            int count = propertiesA.Length;

            for (int i = 0; i < count; i++)
            {
                if ((!propertiesA[i].CanRead) || (!propertiesB[i].CanRead))
                {
                    continue;
                }
                if (!differenceList.Contains(propertiesA[i].Name))
                {
                    continue;
                }

                var newRotationValue = propertiesB [i].GetValue(updateObject, null);

                sourceIndexItem.GetType().GetProperty(propertiesA[i].Name).SetValue(sourceIndexItem, newRotationValue, null);
            }

            return(sourceIndexItem);
        }
コード例 #3
0
        public static List <FileIndexItem> SearchAndReplace(List <FileIndexItem> fileIndexResultsList,
                                                            string fieldName, string search, string replace)
        {
            foreach (var fileIndexItem in fileIndexResultsList.Where(
                         p => p.Status == FileIndexItem.ExifStatus.Ok ||
                         p.Status == FileIndexItem.ExifStatus.Deleted))
            {
                var searchInObject   = FileIndexCompareHelper.Get(fileIndexItem, fieldName);
                var replacedToObject = new object();

                PropertyInfo[] propertiesA = new FileIndexItem().GetType().GetProperties(
                    BindingFlags.Public | BindingFlags.Instance);
                PropertyInfo property = propertiesA.FirstOrDefault(p => string.Equals(
                                                                       p.Name, fieldName, StringComparison.InvariantCultureIgnoreCase));

                if (property.PropertyType == typeof(string))
                {
                    var searchIn = ( string )searchInObject;

                    // Replace Ignore Case
                    replacedToObject = Regex.Replace(
                        searchIn,
                        Regex.Escape(search),
                        replace.Replace("$", "$$"),
                        RegexOptions.IgnoreCase
                        );
                }

                // only string types are added here, other types are ignored for now
                FileIndexCompareHelper.Set(fileIndexItem, fieldName, replacedToObject);
            }

            return(fileIndexResultsList);
        }
コード例 #4
0
        /// <summary>
        /// Set values by string name. fieldContent must by the right type
        /// wrong types are ignored by default
        /// </summary>
        /// <param name="sourceIndexItem">fileIndexItem to add to</param>
        /// <param name="fieldName">name e.g. tags or description</param>
        /// <param name="fieldContent">the content, type must match exact</param>
        /// <returns>fileIndexItem</returns>
        public static FileIndexItem Set(FileIndexItem sourceIndexItem, string fieldName, object fieldContent)
        {
            if (sourceIndexItem == null)
            {
                sourceIndexItem = new FileIndexItem();
            }
            if (!CheckIfPropertyExist(fieldName))
            {
                return(sourceIndexItem);
            }

            // Compare input types, fieldType(object=string) fileIndexType(FileIndexItem.field=string)
            // wrong types are ignored by default

            PropertyInfo[] propertiesA = new FileIndexItem().GetType().GetProperties(
                BindingFlags.Public | BindingFlags.Instance);
            var property = propertiesA.FirstOrDefault(p =>
                                                      string.Equals(p.Name, fieldName, StringComparison.InvariantCultureIgnoreCase));

            var fieldType     = fieldContent.GetType();
            var fileIndexType = property.PropertyType;

            if (fileIndexType == fieldType)
            {
                property.SetValue(sourceIndexItem, fieldContent, null);
            }
            return(sourceIndexItem);
        }
コード例 #5
0
 /// <summary>
 /// Check if property exist in FileIndexItem
 /// </summary>
 /// <param name="fieldName">name e.g. Tags</param>
 /// <returns>bool, true=exist</returns>
 public static bool CheckIfPropertyExist(string fieldName)
 {
     PropertyInfo[] propertiesA = new FileIndexItem().GetType().GetProperties(
         BindingFlags.Public | BindingFlags.Instance);
     return(propertiesA.Any(p => string.Equals(p.Name,
                                               fieldName, StringComparison.InvariantCultureIgnoreCase)));
 }
コード例 #6
0
ファイル: ExifToolCmdHelper.cs プロジェクト: qdraw/starsky
        /// <summary>
        /// Create a XMP file when it not exist
        /// </summary>
        /// <param name="updateModel">model</param>
        /// <param name="inputSubPaths">list of paths</param>
        /// <returns>void</returns>
        internal async Task CreateXmpFileIsNotExist(FileIndexItem updateModel, List <string> inputSubPaths)
        {
            foreach (var subPath in inputSubPaths)
            {
                // only for raw files
                if (!ExtensionRolesHelper.IsExtensionForceXmp(subPath))
                {
                    return;
                }

                var withXmp = ExtensionRolesHelper.ReplaceExtensionWithXmp(subPath);

                if (_iStorage.IsFolderOrFile(withXmp) !=
                    FolderOrFileModel.FolderOrFileTypeList.Deleted)
                {
                    continue;
                }

                new ExifCopy(_iStorage, _thumbnailStorage, _exifTool, _readMeta).XmpCreate(withXmp);

                var comparedNames = FileIndexCompareHelper.Compare(new FileIndexItem(), updateModel);
                var command       = ExifToolCommandLineArgs(updateModel, comparedNames, true);

                await _exifTool.WriteTagsAsync(withXmp, command);
            }
        }
コード例 #7
0
ファイル: ExifToolCmdHelper.cs プロジェクト: qdraw/starsky
        /// <summary>
        /// Update Async with ExifTool
        /// </summary>
        /// <param name="updateModel">data</param>
        /// <param name="inputSubPaths">paths</param>
        /// <param name="comparedNames">changed</param>
        /// <param name="includeSoftware">overwrite Starsky name</param>
        /// <param name="renameThumbnail">update name</param>
        /// <returns>Tuple (command, hash)</returns>
        public async Task <ValueTuple <string, List <string> > > UpdateAsync(FileIndexItem updateModel,
                                                                             List <string> inputSubPaths, List <string> comparedNames, bool includeSoftware, bool renameThumbnail)
        {
            // Creation and update .xmp file with all available content
            await CreateXmpFileIsNotExist(updateModel, inputSubPaths);

            // Rename .dng files .xmp to update in exifTool
            var subPathsList = PathsListTagsFromFile(inputSubPaths);

            var command = ExifToolCommandLineArgs(updateModel, comparedNames, includeSoftware);

            var fileHashes = new List <string>();

            foreach (var path in subPathsList.Where(path => _iStorage.ExistFile(path)))
            {
                // to rename to filename of the thumbnail to the new hash
                if (!renameThumbnail)
                {
                    await _exifTool.WriteTagsAsync(path, command);

                    continue;
                }
                fileHashes.Add((await _exifTool.WriteTagsAndRenameThumbnailAsync(path, command)).Value);
            }

            if (!string.IsNullOrEmpty(updateModel.FileHash) && _thumbnailStorage.ExistFile(updateModel.FileHash))
            {
                await _exifTool.WriteTagsThumbnailAsync(updateModel.FileHash, command);
            }

            return(new ValueTuple <string, List <string> >(command, fileHashes));
        }
コード例 #8
0
ファイル: QueryGetAllFilesTest.cs プロジェクト: qdraw/starsky
        public void GetAllFiles_DisposedItem()
        {
            var serviceScope = CreateNewScope();
            var scope        = serviceScope.CreateScope();
            var dbContext    = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
            var query        = new Query(dbContext, new AppSettings(), serviceScope, new FakeIWebLogger(), _memoryCache);

            // item sub folder
            var item = new FileIndexItem("/test_821827/test_0191919.jpg");

            dbContext.FileIndex.Add(item);
            dbContext.SaveChanges();

            // Important to dispose!
            dbContext.Dispose();

            item.Tags = "test";
            query.UpdateItem(item);

            var getItem = query.GetAllFiles("/test_821827");

            Assert.IsNotNull(getItem);
            Assert.AreEqual("test", getItem.FirstOrDefault().Tags);

            query.RemoveItem(getItem.FirstOrDefault());
        }
コード例 #9
0
        /// <summary>
        /// Copy the metaData over the output path
        /// </summary>
        /// <param name="item">all the meta data</param>
        /// <param name="outputPath">absolute path on host disk</param>
        private async Task MetaData(FileIndexItem item, string outputPath)
        {
            if (!_subPathStorage.ExistFile(item.FilePath))
            {
                return;
            }

            // Write the metadata to the new created file
            var comparedNames = FileIndexCompareHelper.Compare(
                new FileIndexItem(), item);

            // Output has already rotated the image
            var rotation = nameof(FileIndexItem.Orientation).ToLowerInvariant();

            if (comparedNames.Contains(rotation))
            {
                comparedNames.Remove(rotation);
            }

            // Write it back
            await new ExifToolCmdHelper(_exifTool, _hostFileSystemStorage,
                                        _thumbnailStorage, null).UpdateAsync(item,
                                                                             new List <string> {
                outputPath
            }, comparedNames,
                                                                             false, false);
        }
コード例 #10
0
ファイル: Query.cs プロジェクト: qdraw/starsky
        /// <summary>
        /// Add a new item to the database
        /// </summary>
        /// <param name="updateStatusContent">the item</param>
        /// <returns>item with id</returns>
        public FileIndexItem AddItem(FileIndexItem updateStatusContent)
        {
            if (string.IsNullOrWhiteSpace(updateStatusContent.FileName) &&
                updateStatusContent.IsDirectory == false)
            {
                throw new MissingFieldException("use filename (exception: the root folder can have no name)");
            }

            try
            {
                _context.FileIndex.Add(updateStatusContent);
                _context.SaveChanges();
            }
            catch (ObjectDisposedException)
            {
                var context = new InjectServiceScope(_scopeFactory).Context();
                context.FileIndex.Add(updateStatusContent);
                context.SaveChanges();
            }
            catch (DbUpdateConcurrencyException e)
            {
                _logger?.LogInformation("AddItem catch-ed DbUpdateConcurrencyException (ignored)", e);
            }

            AddCacheItem(updateStatusContent);

            return(updateStatusContent);
        }
コード例 #11
0
ファイル: ReadMetaXmp.cs プロジェクト: qdraw/starsky
        public FileIndexItem GetDataFromString(string xmpDataAsString, FileIndexItem databaseItem = null)
        {
            // Does not require appSettings

            if (databaseItem == null)
            {
                databaseItem = new FileIndexItem();
            }

            try
            {
                var xmp = XmpMetaFactory.ParseFromString(xmpDataAsString);
                // ContentNameSpace is for example : Namespace=http://...
                databaseItem = GetDataContentNameSpaceTypes(xmp, databaseItem);
                // NullNameSpace is for example : string.Empty
                databaseItem = GetDataNullNameSpaceTypes(xmp, databaseItem);
            }
            catch (XmpException e)
            {
                Console.WriteLine($"XmpException {databaseItem.FilePath} >>\n{e}\n <<XmpException");
                databaseItem.Tags       = "XmpException";
                databaseItem.ColorClass = ColorClassParser.Color.None;
            }


            return(databaseItem);
        }
コード例 #12
0
        /// <summary>
        /// Compare Rotation and All other tags
        /// </summary>
        /// <param name="changedFileIndexItemName">Per file stored  string{FilePath},
        /// List*string*{FileIndexItem.name (e.g. Tags) that are changed}</param>
        /// <param name="collectionsFileIndexItem">DetailView input, only to display changes</param>
        /// <param name="statusModel">object that include the changes</param>
        /// <param name="append">true= for tags to add</param>
        /// <param name="rotateClock">rotation value 1 left, -1 right, 0 nothing</param>
        public void CompareAllLabelsAndRotation(Dictionary <string, List <string> > changedFileIndexItemName,
                                                FileIndexItem collectionsFileIndexItem, FileIndexItem statusModel, bool append, int rotateClock)
        {
            if (changedFileIndexItemName == null)
            {
                throw new MissingFieldException(nameof(changedFileIndexItemName));
            }

            // compare and add changes to collectionsDetailView
            var comparedNamesList = FileIndexCompareHelper
                                    .Compare(collectionsFileIndexItem, statusModel, append);

            // if requested, add changes to rotation
            collectionsFileIndexItem =
                RotationCompare(rotateClock, collectionsFileIndexItem, comparedNamesList);

            if (!changedFileIndexItemName.ContainsKey(collectionsFileIndexItem.FilePath))
            {
                // add to list
                changedFileIndexItemName.Add(collectionsFileIndexItem.FilePath, comparedNamesList);
                return;
            }

            // overwrite list if already exist
            changedFileIndexItemName[collectionsFileIndexItem.FilePath] = comparedNamesList;
        }
コード例 #13
0
        public void ExifToolCmdHelper_Update_UpdateLocationAltitudeCommandTest()
        {
            var updateModel = new FileIndexItem
            {
                LocationAltitude = -41,
            };
            var comparedNames = new List <string> {
                nameof(FileIndexItem.LocationAltitude).ToLowerInvariant(),
            };

            var folderPaths = new List <string> {
                "/"
            };

            var inputSubPaths = new List <string> {
                "/test.jpg"
            };

            var storage =
                new FakeIStorage(folderPaths, inputSubPaths, null);
            var fakeExifTool = new FakeExifTool(storage, _appSettings);

            var helperResult = new ExifToolCmdHelper(fakeExifTool,
                                                     storage, storage,
                                                     new FakeReadMeta()).Update(updateModel, inputSubPaths, comparedNames);

            Assert.AreEqual(true, helperResult.Contains("-GPSAltitude=\"-41"));
            Assert.AreEqual(true, helperResult.Contains("gpsaltituderef#=\"1"));
        }
コード例 #14
0
        public async Task Update_Write_GPX()
        {
            var changedFileIndexItemName = new Dictionary <string, List <string> > {
                {
                    "/test.gpx", new List <string> {
                        "Tags"
                    }
                }
            };

            await _iStorageFake.WriteStreamAsync(new MemoryStream(CreateAnGpx.Bytes), "/test.gpx");

            var updateItem = new FileIndexItem("/test.gpx")
            {
                Tags   = "test",
                Status = FileIndexItem.ExifStatus.Ok
            };

            var query = new FakeIQuery();
            await query.AddItemAsync(updateItem);

            var fileIndexResultsList = new List <FileIndexItem> {
                updateItem
            };

            var readMeta = new FakeReadMetaSubPathStorage();
            var service  = new MetaUpdateService(query, _exifTool,
                                                 new FakeSelectorStorage(_iStorageFake), new FakeMetaPreflight(),
                                                 new FakeIWebLogger(), readMeta);

            await service.UpdateAsync(changedFileIndexItemName, fileIndexResultsList, updateItem, false, false, 0);

            Assert.IsTrue(_iStorageFake.ExistFile("/.starsky.test.gpx.json"));
        }
コード例 #15
0
        public async Task GetAllObjectsAsync_DisposedItem()
        {
            var serviceScope = CreateNewScope();
            var scope        = serviceScope.CreateScope();
            var dbContext    = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
            var query        = new Query(dbContext, new AppSettings(), serviceScope, new FakeIWebLogger(), _memoryCache);

            // item sub folder
            var item = new FileIndexItem("/test_3457834583/test_0191919.jpg");
            await dbContext.FileIndex.AddAsync(item);

            await dbContext.SaveChangesAsync();

            // Important to dispose!
            await dbContext.DisposeAsync();

            item.Tags = "test";
            await query.UpdateItemAsync(item);

            var getItem = await query.GetAllObjectsAsync("/test_3457834583");

            Assert.IsNotNull(getItem);
            Assert.AreEqual("test", getItem.FirstOrDefault().Tags);

            await query.RemoveItemAsync(getItem.FirstOrDefault());
        }
コード例 #16
0
        private void InsertSearchData()
        {
            if (!string.IsNullOrEmpty(
                    _query.GetSubPathByHash("09876543456789")))
            {
                return;
            }

            _insertSearchDatahiJpgInput = _query.AddItem(new FileIndexItem
            {
                FileName        = "hi.jpg",
                ParentDirectory = "/basic",
                FileHash        = "09876543456789",
                ColorClass      = ColorClassParser.Color.Winner,            // 1
                Tags            = "",
                Title           = "",
                IsDirectory     = false
            });

            _insertSearchDatahi2JpgInput = _query.AddItem(new FileIndexItem
            {
                FileName        = "hi2.jpg",
                Tags            = "!delete!",
                ParentDirectory = "/basic",
                IsDirectory     = false
            });

            _insertSearchDatahi2SubfolderJpgInput = _query.AddItem(new FileIndexItem
            {
                FileName        = "hi2.jpg",
                ParentDirectory = "/basic/subfolder",
                FileHash        = "234567876543",
                IsDirectory     = false
            });
        }
コード例 #17
0
        public async Task <FileIndexItem.ExifStatus> ManualSync(string subPath,
                                                                string operationId = null)
        {
            var fileIndexItem = await _query.GetObjectByFilePathAsync(subPath);

            // on a new database ->
            if (subPath == "/" && fileIndexItem == null)
            {
                fileIndexItem = new FileIndexItem();
            }
            if (fileIndexItem == null)
            {
                _logger.LogInformation($"[ManualSync] NotFoundNotInIndex skip for: {subPath}");
                return(FileIndexItem.ExifStatus.NotFoundNotInIndex);
            }

            if (_cache.TryGetValue(ManualSyncCacheName + subPath, out _))
            {
                // also used in removeCache
                _query.RemoveCacheParentItem(subPath);
                _logger.LogInformation($"[ManualSync] Cache hit skip for: {subPath}");
                return(FileIndexItem.ExifStatus.OperationNotSupported);
            }

            _cache.Set(ManualSyncCacheName + subPath, true,
                       new TimeSpan(0, 1, 0));

            _bgTaskQueue.QueueBackgroundWorkItem(async _ =>
            {
                await BackgroundTask(fileIndexItem.FilePath, operationId);
            });

            return(FileIndexItem.ExifStatus.Ok);
        }
コード例 #18
0
ファイル: Query.cs プロジェクト: qdraw/starsky
        /// <summary>
        /// Cache Only! Private api within Query to remove cached items
        /// This Does remove a SINGLE item from the cache NOT from the database
        /// </summary>
        /// <param name="updateStatusContent"></param>
        public void RemoveCacheItem(FileIndexItem updateStatusContent)
        {
            // Add protection for disabled caching
            if (_cache == null || _appSettings?.AddMemoryCache == false)
            {
                return;
            }

            var queryCacheName = CachingDbName(nameof(FileIndexItem),
                                               updateStatusContent.ParentDirectory);

            if (!_cache.TryGetValue(queryCacheName, out var objectFileFolders))
            {
                return;
            }

            var displayFileFolders = (List <FileIndexItem>)objectFileFolders;

            // Order by filename
            displayFileFolders = displayFileFolders
                                 .Where(p => p.FilePath != updateStatusContent.FilePath)
                                 .OrderBy(p => p.FileName).ToList();

            _cache.Remove(queryCacheName);
            // generate list again
            _cache.Set(queryCacheName, displayFileFolders, new TimeSpan(1, 0, 0));
        }
コード例 #19
0
        /// <summary>
        /// When the file is not supported or does not exist return status
        /// </summary>
        /// <param name="subPath">relative path</param>
        /// <returns>item with status</returns>
        private FileIndexItem CheckForStatusNotOk(string subPath)
        {
            var statusItem = new FileIndexItem(subPath)
            {
                Status = FileIndexItem.ExifStatus.Ok
            };

            // File extension is not supported
            if (!ExtensionRolesHelper.IsExtensionSyncSupported(subPath))
            {
                statusItem.Status = FileIndexItem.ExifStatus.OperationNotSupported;
                return(statusItem);
            }

            // File check if jpg #not corrupt
            var imageFormat = ExtensionRolesHelper.GetImageFormat(_subPathStorage.ReadStream(subPath, 160));

            if (imageFormat == ExtensionRolesHelper.ImageFormat.notfound)
            {
                statusItem.Status = FileIndexItem.ExifStatus.NotFoundSourceMissing;
                return(statusItem);
            }

            // ReSharper disable once InvertIf
            if (!ExtensionRolesHelper.ExtensionSyncSupportedList.Contains(imageFormat.ToString()))
            {
                statusItem.Status = FileIndexItem.ExifStatus.OperationNotSupported;
                return(statusItem);
            }
            return(statusItem);
        }
コード例 #20
0
        public void UpdateService_Update_defaultTest()
        {
            var item0 = _query.AddItem(new FileIndexItem
            {
                Status          = FileIndexItem.ExifStatus.Ok,
                Tags            = "thisKeywordHasChanged",
                FileName        = "test_default.jpg",
                Description     = "noChanges",
                ParentDirectory = "/"
            });

            var changedFileIndexItemName = new Dictionary <string, List <string> >
            {
                {
                    "/test_default.jpg", new List <string>
                    {
                        nameof(FileIndexItem.Tags)
                    }
                },
            };

            var fileIndexResultsList = new List <FileIndexItem>
            {
                new FileIndexItem
                {
                    Status          = FileIndexItem.ExifStatus.Ok,
                    Tags            = "initial tags (from database)",
                    FileName        = "test_default.jpg",
                    ParentDirectory = "/",
                    Description     = "keep",
                }
            };

            var updateItem = new FileIndexItem
            {
                Status          = FileIndexItem.ExifStatus.Ok,
                Tags            = "only used when Caching is disabled",
                FileName        = "test_default.jpg",
                Description     = "noChanges",
                ParentDirectory = "/"
            };

            var readMeta = new ReadMetaSubPathStorage(
                new FakeSelectorStorage(_iStorageFake), _appSettings,
                _memoryCache);
            var service = new MetaUpdateService(_query, _exifTool,
                                                new FakeSelectorStorage(_iStorageFake), new FakeMetaPreflight(),
                                                new FakeIWebLogger(), readMeta);

            service.UpdateAsync(changedFileIndexItemName, fileIndexResultsList, updateItem, false, false, 0);

            // check for item (Referenced)
            Assert.AreEqual("thisKeywordHasChanged", item0.Tags);
            // db
            Assert.AreEqual("thisKeywordHasChanged", _query.SingleItem("/test_default.jpg").FileIndexItem.Tags);

            Assert.AreEqual("noChanges", _query.SingleItem("/test_default.jpg").FileIndexItem.Description);

            _query.RemoveItem(item0);
        }
コード例 #21
0
        public async Task ExportControllerTest__ThumbFalse_CreateListToExport()
        {
            var selectorStorage       = _serviceProvider.GetRequiredService <ISelectorStorage>();
            var hostFileSystemStorage =
                selectorStorage.Get(SelectorStorage.StorageServices
                                    .HostFilesystem);

            var export = new ExportService(_query, _appSettings, selectorStorage, new FakeIWebLogger());

            var createAnImageNoExif = new CreateAnImageNoExif();

            var item = new FileIndexItem
            {
                FileName        = createAnImageNoExif.FileName,
                ParentDirectory = "/",
                FileHash        = createAnImageNoExif.FileName.Replace(".jpg", "-test"),
                Status          = FileIndexItem.ExifStatus.Ok
            };

            await _query.AddItemAsync(item);

            var fileIndexResultsList = new List <FileIndexItem> {
                item
            };

            var filePaths = await export.CreateListToExport(fileIndexResultsList, false);

            Assert.AreEqual(true, filePaths.FirstOrDefault().Contains(item.FileName));

            Assert.AreEqual(FolderOrFileModel.FolderOrFileTypeList.File,
                            hostFileSystemStorage.IsFolderOrFile(filePaths.FirstOrDefault()));

            hostFileSystemStorage.FileDelete(createAnImageNoExif.FullFilePathWithDate);
        }
コード例 #22
0
ファイル: Query.cs プロジェクト: qdraw/starsky
        /// <summary>
        /// Add child item to parent cache
        /// Private api within Query to add cached items
        /// Assumes that the parent directory already exist in the cache
        /// @see: AddCacheParentItem to add parent item
        /// </summary>
        /// <param name="updateStatusContent">the content to add</param>
        internal void AddCacheItem(FileIndexItem updateStatusContent)
        {
            // If cache is turned of
            if (_cache == null || _appSettings?.AddMemoryCache == false)
            {
                return;
            }

            var queryCacheName = CachingDbName(nameof(FileIndexItem),
                                               updateStatusContent.ParentDirectory);

            if (!_cache.TryGetValue(queryCacheName, out var objectFileFolders))
            {
                return;
            }

            var displayFileFolders = (List <FileIndexItem>)objectFileFolders;

            displayFileFolders.Add(updateStatusContent);
            // Order by filename
            displayFileFolders = displayFileFolders.OrderBy(p => p.FileName).ToList();

            _cache.Remove(queryCacheName);
            _cache.Set(queryCacheName, displayFileFolders, new TimeSpan(1, 0, 0));
        }
コード例 #23
0
        private static RelativeObjects GetNextPrevInSubFolder(
            FileIndexItem currentFileIndexItem,
            List <FileIndexItem> fileIndexItemsList, SortType sortType)
        {
            // Check if this is item is not !deleted! yet
            if (currentFileIndexItem == null)
            {
                return(new RelativeObjects());
            }

            fileIndexItemsList = SortHelper.Helper(fileIndexItemsList, sortType).ToList();

            var currentIndex   = fileIndexItemsList.FindIndex(p => p.FilePath == currentFileIndexItem.FilePath);
            var relativeObject = new RelativeObjects();

            if (currentIndex != fileIndexItemsList.Count - 1)
            {
                relativeObject.NextFilePath = fileIndexItemsList[currentIndex + 1].FilePath;
                relativeObject.NextHash     = fileIndexItemsList[currentIndex + 1].FileHash;
            }

            if (currentIndex >= 1)
            {
                relativeObject.PrevFilePath = fileIndexItemsList[currentIndex - 1].FilePath;
                relativeObject.PrevHash     = fileIndexItemsList[currentIndex - 1].FileHash;
            }

            return(relativeObject);
        }
コード例 #24
0
        public async Task UpdateAsync_ShouldUpdate_IncludeFileHash()
        {
            var updateModel = new FileIndexItem
            {
                Tags        = "tags",
                Description = "Description",
                FileHash    = "_hash_test"      // < - - - - include here
            };
            var comparedNames = new List <string> {
                nameof(FileIndexItem.Tags).ToLowerInvariant(),
                nameof(FileIndexItem.Description).ToLowerInvariant(),
            };

            var storage = new FakeIStorage(new List <string> {
                "/"
            }, new List <string> {
                "/test.jpg"
            }, new List <byte[]>());

            var fakeExifTool = new FakeExifTool(storage, _appSettings);
            var helperResult = (await new ExifToolCmdHelper(fakeExifTool, storage, storage,
                                                            new FakeReadMeta()).UpdateAsync(updateModel, comparedNames, true));

            Assert.IsTrue(helperResult.Item1.Contains("tags"));
            Assert.IsTrue(helperResult.Item1.Contains("Description"));
        }
コード例 #25
0
ファイル: FileIndexItemTest.cs プロジェクト: qdraw/starsky
        public void FileIndexItemTest_SetMakeModel_WrongPipeLength()
        {
            var item = new FileIndexItem();

            item.SetMakeModel("Apple", 95);
            // this index (95) never exist
        }
コード例 #26
0
        public async Task Inflate_Test()
        {
            // Minimal 10 items
            var testContent = new FileIndexItem {
                Tags = "test, testung"
            };

            _dbContext.FileIndex.AddRange(new List <FileIndexItem> {
                testContent, testContent, testContent,
                testContent, testContent, testContent, testContent, testContent, testContent, testContent, testContent, testContent, testContent
            });
            await _dbContext.SaveChangesAsync();

            await new SearchSuggestionsInflateHostedService(_scopeFactory, _memoryCache,
                                                            new FakeIWebLogger(),
                                                            new AppSettings()).StartAsync(new CancellationToken());

            var allSuggestions = await new SearchSuggestionsService(_dbContext,
                                                                    _memoryCache, new FakeIWebLogger(), new AppSettings())
                                 .GetAllSuggestions();

            var result = allSuggestions.FirstOrDefault(p => p.Key == "test");

            Assert.IsNotNull(result);
        }
コード例 #27
0
ファイル: FileIndexItemTest.cs プロジェクト: qdraw/starsky
        public void FileIndexItemTest_GetColorClassListString()
        {
            var input  = "string";
            var output = FileIndexItem.GetColorClassList(input);

            Assert.AreEqual(0, output.Count);            // <= 0
        }
コード例 #28
0
ファイル: SearchViewModel.cs プロジェクト: qdraw/starsky
        /// <summary>
        /// Filter for WideSearch
        /// Always after wideSearch
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public SearchViewModel NarrowSearch(SearchViewModel model)
        {
            if (model.FileIndexItems == null)
            {
                model = new SearchViewModel();
            }

            for (var i = 0; i < model.SearchIn.Count; i++)
            {
                var propertyStringName = FileIndexItem.FileIndexPropList().FirstOrDefault(p =>
                                                                                          String.Equals(p, model.SearchIn[i], StringComparison.InvariantCultureIgnoreCase));
                if (string.IsNullOrEmpty(propertyStringName))
                {
                    continue;
                }

                PropertyInfo property = new FileIndexItem().GetType().GetProperty(propertyStringName);

                // skip OR searches
                if (!model.SearchOperatorContinue(i, model.SearchIn.Count))
                {
                    continue;
                }
                PropertySearch(model, property, model.SearchFor[i], model.SearchForOptions[i]);
            }

            return(model);
        }
コード例 #29
0
        //private Synchronize _sync;

        private void CreateFoldersAndFilesInDatabase()
        {
            _folderExist = _query.AddItem(new FileIndexItem
            {
                FileName        = "exist",
                ParentDirectory = "/",
                AddToDatabase   = DateTime.UtcNow,
                FileHash        = "34567898765434567487984785487",
                IsDirectory     = true
            });

            _fileInExist = _query.AddItem(new FileIndexItem
            {
                FileName        = "file.jpg",
                ParentDirectory = "/exist",
                IsDirectory     = false
            });

            _folder1Exist = _query.AddItem(new FileIndexItem
            {
                FileName        = "folder1",
                ParentDirectory = "/",
                IsDirectory     = true,
                FileHash        = "3497867df894587",
            });

            _parentFolder = _query.AddItem(new FileIndexItem
            {
                FileName        = "/",
                ParentDirectory = "/",
                IsDirectory     = true,
            });
        }
コード例 #30
0
        private FileIndexItem ReadExifAndXmpFromFileDirect(string subPath)
        {
            if (_iStorage.ExistFile(subPath) &&
                ExtensionRolesHelper.IsExtensionForceGpx(subPath))
            {
                return(ReadMetaGpx.ReadGpxFromFileReturnAfterFirstField(_iStorage.ReadStream(subPath), subPath));
            }

            var fileIndexItemWithPath = new FileIndexItem(subPath);

            // Read first the sidecar file
            var xmpFileIndexItem = _readXmp.XmpGetSidecarFile(fileIndexItemWithPath.Clone());

            if (xmpFileIndexItem.IsoSpeed == 0 ||
                string.IsNullOrEmpty(xmpFileIndexItem.Make) ||
                xmpFileIndexItem.DateTime.Year == 0 || xmpFileIndexItem.ImageHeight == 0)
            {
                // so the sidecar file is not used
                var fileExifItemFile = _readExif.ReadExifFromFile(subPath, fileIndexItemWithPath);

                // overwrite content with incomplete sidecar file (this file can contain tags)
                FileIndexCompareHelper.Compare(fileExifItemFile, xmpFileIndexItem);
                return(fileExifItemFile);
            }

            return(xmpFileIndexItem);
        }
コード例 #31
0
		} // proc CloseZipStream

		private void ZipFileItem(CmdletNotify notify, CmdletProgress bar, Stream src, ZipOutputStream zip, FileIndexItem item)
		{
			var entry = new ZipEntry(ZipEntry.CleanName(item.RelativePath));

			entry.DateTime = item.LastWriteTimeUtc;
			entry.Size = src.Length;
			entry.Comment = item.GetComment();
			entry.CompressionMethod = ZipFile(item.RelativePath) ? CompressionMethod.Deflated : CompressionMethod.Stored;
			zip.PutNextEntry(entry);

			Stuff.CopyRawBytes(bar, item.RelativePath, src.Length, src, zip);

			zip.CloseEntry();
			zip.Flush();
		} // proc ZipFileItem
コード例 #32
0
		} // proc ZipFileItem

		private void GZipFileItem(CmdletNotify notify, CmdletProgress bar, Stream src, DirectoryInfo targetPath, FileIndexItem item)
		{
			using (var dst = new FileWrite(notify, new FileInfo(Path.Combine(targetPath.FullName, item.ArchiveName)), false, CompressMode.Auto))
			{
				Stuff.CopyRawBytes(bar, item.RelativePath, src.Length, src, dst.Stream);
				dst.Commit();
			}
		} // proc GZipFileItem