Beispiel #1
0
        private static int QuickfindMultipleCopiesOnSameVolume(QuickfindMultipleOptions a)
        {
            ShouldPrint shouldPrint = (x) => x.Count >= 2 && (a.Subdir == null || x.Any((y) => y.Path.StartsWith(a.Subdir, true, System.Globalization.CultureInfo.InvariantCulture)));

            if (a.InteractiveDeleteMode)
            {
                return(RunInteractiveFileDeleteMode(a.DatabasePath, a.Volume, shouldPrint));
            }
            else
            {
                return(ListFiles(a.LogPath, a.DatabasePath, a.Volume, true, shouldPrint));
            }
        }
Beispiel #2
0
        private static IEnumerable <List <StorageFile> > CollectFiles(SQLiteConnection connection, List <StorageFile> files, ShouldPrint shouldPrint, long?onlyOnVolume = null)
        {
            ISet <long> seenIds = new HashSet <long>();

            foreach (var file in files)
            {
                if (seenIds.Contains(file.FileId))
                {
                    continue;
                }

                seenIds.Add(file.FileId);
                var sameFiles = GetStorageFilesForFileId(connection, file.FileId, onlyOnVolume);
                if (shouldPrint(sameFiles))
                {
                    yield return(sameFiles);
                }
            }
        }
Beispiel #3
0
        private static int ListFiles(string logPath, string databasePath, int?volume, bool selectedVolumeOnly, ShouldPrint shouldPrint)
        {
            using (TextWriterWrapper textWriterWrapper = new TextWriterWrapper(logPath))
                using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + databasePath)) {
                    connection.Open();

                    List <StorageFile> files   = GetKnownFilesOnVolume(connection, volume);
                    List <Volume>      volumes = VolumeOperations.GetKnownVolumes(connection);
                    foreach (var sameFiles in CollectFiles(connection, files, shouldPrint, selectedVolumeOnly ? volume : null))
                    {
                        PrintSameFileInformation(textWriterWrapper.Writer, sameFiles, volumes);
                    }

                    connection.Close();
                }

            return(0);
        }
Beispiel #4
0
        private static int RunInteractiveFileDeleteMode(string databasePath, long volumeId, ShouldPrint shouldPrint)
        {
            using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + databasePath)) {
                connection.Open();

                Volume volume;
                {
                    var volumes = VolumeOperations.FindAndInsertAttachedVolumes(connection);
                    volume = volumes.FirstOrDefault((x) => x.ID == volumeId);
                }
                if (volume == null)
                {
                    Console.WriteLine("Volume {0} is not attached.", volumeId);
                    return(-1);
                }


                List <StorageFile>         files    = GetKnownFilesOnVolume(connection, volumeId);
                List <List <StorageFile> > allfiles = CollectFiles(connection, files, shouldPrint, volumeId).ToList();
                for (int allfilesindex = 0; allfilesindex < allfiles.Count; allfilesindex++)
                {
                    allfiles[allfilesindex] = allfiles[allfilesindex].OrderBy(x => (x.Path + "/" + x.Filename)).ToList();
                }

                int more = 5;
                for (int allfilesindex = 0; allfilesindex < allfiles.Count; allfilesindex++)
                {
                    List <StorageFile> sameFiles         = allfiles[allfilesindex];
                    List <string>      existingFilenames = new List <string>();
                    foreach (StorageFile ssf in sameFiles)
                    {
                        if (!existingFilenames.Contains(ssf.Filename))
                        {
                            existingFilenames.Add(ssf.Filename);
                        }
                    }
                    existingFilenames.Sort();

                    int?selectedFilename = null;
                    while (true)
                    {
                        int prevfilesindex = allfilesindex - 1;
                        int nextfilesindex = allfilesindex + more;
                        if (prevfilesindex >= 0)
                        {
                            PrintFileInfoForInteractiveDelete(allfiles[prevfilesindex], "     ");
                            Console.WriteLine();
                        }
                        PrintFileInfoForInteractiveDelete(sameFiles, " >>> ");

                        if (existingFilenames.Count > 1)
                        {
                            Console.WriteLine(" >>> Available filenames:");
                            for (int i = 0; i < existingFilenames.Count; ++i)
                            {
                                Console.WriteLine(" >>> {2}Filename {0}: {1}", AsLetter(i), existingFilenames[i], selectedFilename == i ? "!" : " ");
                            }
                        }

                        for (int iiii = allfilesindex + 1; iiii <= nextfilesindex; ++iiii)
                        {
                            if (iiii < allfiles.Count)
                            {
                                Console.WriteLine();
                                PrintFileInfoForInteractiveDelete(allfiles[iiii], "     ");
                            }
                        }

                        Console.WriteLine();
                        Console.WriteLine(" [file {0}/{1}, {2} to go]", allfilesindex + 1, allfiles.Count, allfiles.Count - allfilesindex);

                        Console.WriteLine();
                        Console.WriteLine("Enter number of file to keep, lowercase letter for target filename, nothing to skip, Q to quit, +/- to show more/less files.");
                        Console.Write(" > ");

                        string input = Console.ReadLine();
                        if (input == "")
                        {
                            Console.Clear();
                            break;
                        }
                        if (input == "+")
                        {
                            ++more;
                            Console.Clear();
                            continue;
                        }
                        if (input == "-")
                        {
                            if (more > 0)
                            {
                                --more;
                            }
                            Console.Clear();
                            continue;
                        }
                        if (input == "Q")
                        {
                            return(-2);
                        }

                        int number;
                        if (int.TryParse(input, out number))
                        {
                            if (number >= 0 && number < sameFiles.Count)
                            {
                                List <(FileInfo fi, bool shouldDelete)> data = new List <(FileInfo fi, bool shouldDelete)>();
                                for (int i = 0; i < sameFiles.Count; ++i)
                                {
                                    var    sf = sameFiles[i];
                                    string path;
                                    if (sf.Path == "" || sf.Path == "/" || sf.Path == "\\")
                                    {
                                        path = Path.Combine(volume.DeviceID, sf.Filename);
                                    }
                                    else if (sf.Path[0] == '/' || sf.Path[0] == '\\')
                                    {
                                        path = Path.Combine(volume.DeviceID, sf.Path.Substring(1).Replace('/', '\\'), sf.Filename);
                                    }
                                    else
                                    {
                                        Console.WriteLine("Unexpected path in database: " + sf.Path);
                                        break;
                                    }
                                    data.Add((new FileInfo(path), i != number));
                                }

                                Console.Clear();

                                bool inconsistent = false;
                                foreach (var d in data)
                                {
                                    if (!d.fi.Exists)
                                    {
                                        Console.WriteLine("Inconsistent file state: File {0} does not actually exist on disk.", d.fi.FullName);
                                        inconsistent = true;
                                    }
                                }
                                if (!inconsistent)
                                {
                                    foreach (var d in data)
                                    {
                                        if (d.shouldDelete)
                                        {
                                            Console.WriteLine("Deleting {0}", d.fi.FullName);
                                            d.fi.Delete();
                                        }
                                        else
                                        {
                                            if (selectedFilename.HasValue)
                                            {
                                                string newpath = Path.Combine(Path.GetDirectoryName(d.fi.FullName), existingFilenames[selectedFilename.Value]);
                                                if (File.Exists(newpath))
                                                {
                                                    Console.WriteLine("Keeping {0}; renaming to {1} not possible, skipping it", d.fi.FullName, newpath);
                                                }
                                                else
                                                {
                                                    Console.WriteLine("Renaming {0} to {1}", d.fi.FullName, newpath);
                                                    File.Move(d.fi.FullName, newpath);
                                                }
                                            }
                                            else
                                            {
                                                Console.WriteLine("Keeping {0}", d.fi.FullName);
                                            }
                                        }
                                    }
                                }
                                break;
                            }
                        }

                        for (int i = 0; i < existingFilenames.Count; ++i)
                        {
                            if (AsLetter(i) == input)
                            {
                                selectedFilename = i;
                                break;
                            }
                        }
                    }
                }

                connection.Close();
            }

            return(0);
        }