Пример #1
0
        /// <summary>Return the child nodes for 'node'</summary>
        private static IEnumerable <TreeNode> GetChildNodes(TreeNode node)
        {
            var path = new Path(node.FullPath);

            return(Path_.EnumFileSystem(path.Name, SearchOption.TopDirectoryOnly)
                   .Where(fi => fi.IsDirectory())
                   .Select(fi => new TreeNode(fi.Name, node.TriState)));
        }
Пример #2
0
        /// <summary>Does the work of finding and identifying duplicates</summary>
        private void FindDuplicates(ProgressForm dlg, object ctx, ProgressForm.Progress progress)         // worker thread context
        {
            // Build a map of file data
            var dir = string.Empty;

            foreach (var path in Settings.SearchPaths)
            {
                if (dlg.CancelPending)
                {
                    break;
                }
                foreach (var fi in Path_.EnumFileSystem(path, search_flags:SearchOption.AllDirectories, exclude:FileAttributes.Directory).Cast <System.IO.FileInfo>())
                {
                    if (dlg.CancelPending)
                    {
                        break;
                    }

                    // Report progress whenever the directory changes
                    var d = Path_.Directory(fi.FullName) ?? string.Empty;
                    if (d != dir)
                    {
                        dir = d;
                        progress(new ProgressForm.UserState {
                            Description = $"Scanning files...\r\n{dir}"
                        });
                    }

                    try
                    {
                        // Create file info for the file and look for a duplicate
                        var      finfo    = new FileInfo(fi);
                        FileInfo existing = FInfoMap.TryGetValue(finfo.Key, out existing) ? existing : null;
                        if (existing != null)
                        {
                            Dispatcher.Invoke(() =>
                            {
                                existing.Duplicates.Add(finfo);
                                var idx = Duplicates.BinarySearch(existing, FileInfo.Compare);
                                if (idx < 0)
                                {
                                    Duplicates.Insert(~idx, existing);
                                }
                            });
                        }
                        else
                        {
                            FInfoMap.Add(finfo.Key, finfo);
                        }
                    }
                    catch (Exception ex)
                    {
                        Errors.Add($"Failed to add {fi.FullName} to the map. {ex.Message}");
                    }
                }
            }
        }
Пример #3
0
        /// <summary></summary>
        private void InitJournalFiles()
        {
            // Parse all of the available journal files, in order
            var journal_files = Path_.EnumFileSystem(Settings.Instance.JournalFilesDir, SearchOption.TopDirectoryOnly, JournalRegex).OrderBy(x => x.Name);

            foreach (var file in journal_files)
            {
                JournalFilepath = file.FullName;
                JournalOffset   = Parse(JournalFilepath, 0L);
            }
        }
Пример #4
0
            public WatchedDir(string dirpath, ChangedHandler onchange, int id, object?ctx)
            {
                m_files    = new Dictionary <string, WatchedFile>();
                Path       = dirpath;
                m_onchange = onchange;
                m_ctx      = ctx;
                Id         = id;

                // Get the files in the directory and create a watcher for each
                var files = Path_.EnumFileSystem(Path, SearchOption.TopDirectoryOnly, exclude: FileAttributes.Hidden | FileAttributes.Directory).ToList();

                m_files = files.ToDictionary(x => x.FullName.ToLowerInvariant(), x => new WatchedFile(x.FullName, onchange, id, ctx));
            }
Пример #5
0
        /// <summary>Called after 'path' has been removed from the collection</summary>
        private void HandlePathRemoved(Path path)
        {
            // Remember, 'path' may not have been in the collection, but may be a child
            // of a path that is in the collection.
            var p     = new StringBuilder();
            var parts = path.Name.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);

            // Look for a path that is an ancestral parent of 'path'
            var part_idx = 0;

            for (; part_idx != parts.Length; ++part_idx)
            {
                p.Append(parts[part_idx]).Append("\\");

                // If the parent path is in the collection, we need to replace
                // it with its children except for 'p.Append(parts[i+1])'
                var idx = Paths.BinarySearch(p.ToString(), Path.Compare);
                if (idx >= 0)
                {
                    break;
                }
            }

            // If a parent is found, we need to add child paths for the ancestral siblings of 'path'
            if (part_idx != parts.Length)
            {
                // Remove the parent path
                var idx = Paths.BinarySearch(p.ToString(), Path.Compare);
                Paths.RemoveAt(idx);

                // Add the child paths for the ancestral siblings of 'path'
                for (++part_idx; part_idx != parts.Length; ++part_idx)
                {
                    var siblings = Path_.EnumFileSystem(path.Text.Substring(0, p.Length), SearchOption.TopDirectoryOnly).Where(x => x.IsDirectory());
                    foreach (var sib in siblings)
                    {
                        if (string.CompareOrdinal(parts[part_idx], sib.Name.ToLowerInvariant()) == 0)
                        {
                            continue;
                        }
                        Paths.AddOrdered(sib.FullName, Path.Compare);
                    }
                    p.Append(parts[part_idx]).Append("\\");
                }
            }

            // Update the check boxes
            UpdateTree();
        }
Пример #6
0
        /// <summary>Enumerate the types that implement the interface 'TInterface'</summary>
        public static IEnumerable <PluginFile> Enumerate(string directory, SearchOption search = SearchOption.TopDirectoryOnly, string regex_filter = DefaultRegexPattern)
        {
            // Build a list of assemblies to check
            var filedata = Path_.EnumFileSystem(directory, search, regex_filter, exclude: FileAttributes.Directory).ToList();

            // Load each assembly and look for types that are flagged with the Plugin attribute
            foreach (var fd in filedata)
            {
                var ass = Assembly.LoadFile(fd.FullName);
                foreach (var plugin in Enumerate(ass))
                {
                    yield return(plugin);
                }
            }
        }
Пример #7
0
            /// <summary>Notify observers about the changed items</summary>
            public bool NotifyChanged()
            {
                // Scan the directory and notify about created, deleted, or changed files
                var current_files = Path_.EnumFileSystem(Path, SearchOption.TopDirectoryOnly, exclude: FileAttributes.Hidden | FileAttributes.Directory)
                                    .Select(x => x.FullName).ToList();
                var existing = current_files
                               .ToHashSet(x => x.ToLowerInvariant());

                foreach (var path in current_files)
                {
                    // If there is an existing watcher for the file, simply check for changed
                    if (m_files.TryGetValue(path.ToLowerInvariant(), out var file))
                    {
                        // File unchanged
                        if (!file.HasChanged)
                        {
                            continue;
                        }

                        // File changed, but change not handled
                        if (!file.NotifyChanged())
                        {
                            continue;
                        }

                        // File no longer exists, remove from 'm_files'
                        if (!Path_.FileExists(file.Path))
                        {
                            m_files.Remove(file.Path.ToLowerInvariant());
                        }

                        continue;
                    }

                    // If this is a new file, notify then add
                    file = new WatchedFile(path, m_onchange, Id, m_ctx);
                    if (file.NotifyChanged())
                    {
                        m_files[path.ToLowerInvariant()] = file;
                    }
                }

                return(true);
            }
Пример #8
0
        /// <summary>Build a map of the files in 'root'</summary>
        private Dictionary <string, FileSystemInfo> BuildMap(string root, string ignore_patn)
        {
            var dir = root.ToLowerInvariant();

            var map = new Dictionary <string, FileSystemInfo>();

            foreach (var finfo in Path_.EnumFileSystem(root, search_flags:SearchOption.AllDirectories))
            {
                var d = (Path.GetDirectoryName(finfo.FullName) ?? string.Empty).ToLowerInvariant();
                if (d != dir)
                {
                    Console.WriteLine(d);
                    dir = d;
                }

                // If the file matches the ignore pattern, skip it
                if (ignore_patn != null && Regex.IsMatch(finfo.FullName, ignore_patn, RegexOptions.IgnoreCase))
                {
                    continue;
                }

                try
                {
                    var k = MakeKey(finfo);
                    if (map.TryGetValue(k, out var existing))
                    {
                        Console.WriteLine($"Existing duplicate found:\n  {finfo.FullName}\n  {existing.FullName}\n");
                        continue;
                    }
                    map.Add(k, finfo);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Failed to add {finfo.FullName} to the map");
                    Console.WriteLine($"Reason: {ex.Message}");
                }
            }

            return(map);
        }
Пример #9
0
        // Market data contains a set of 'Instruments' (currency pairs).
        // Each pair has a separate database containing tables of candles for
        // each time frame

        public MarketData(MainModel model)
        {
            Model       = model;
            Instruments = new BindingSource <Instrument> {
                DataSource = new BindingListEx <Instrument>(), PerItemClear = true
            };

            // Ensure the price data cache directory exists
            if (!Path_.DirExists(Model.Settings.General.PriceDataCacheDir))
            {
                Directory.CreateDirectory(Model.Settings.General.PriceDataCacheDir);
            }

            // Add instruments for the price data we know about
            const string price_data_file_pattern = @"PriceData_(\w+)\.db";

            foreach (var fd in Path_.EnumFileSystem(Model.Settings.General.PriceDataCacheDir, regex_filter:price_data_file_pattern))
            {
                var sym = fd.FileName.SubstringRegex(price_data_file_pattern, RegexOptions.IgnoreCase)[0];
                GetOrCreateInstrument(sym);
            }
        }
Пример #10
0
        /// <summary>Called after 'path' has been added to the collection</summary>
        private void HandlePathAdded(Path path)
        {
            // Look for paths that would include 'path' already
            var p     = new StringBuilder();
            var parts = path.Name.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0, iend = parts.Length - 1; i < iend; ++i)
            {
                p.Append(parts[i]).Append("\\");

                // If a parent path is in the collection already, we don't need 'path'
                var idx = Paths.BinarySearch(p.ToString(), Path.Compare);
                if (idx >= 0)
                {
                    idx = Paths.BinarySearch(path, Path.Compare);
                    if (idx >= 0)
                    {
                        Paths.RemoveAt(idx);
                    }
                    return;
                }
            }

            // Remove any paths that are children of 'path'
            {
                var idx = Paths.BinarySearch(path, Path.Compare);
                if (idx < 0)
                {
                    idx = ~idx;
                }
                else
                {
                    ++idx;
                }

                // Find the range of paths to remove
                var count = Paths.Skip(idx).Count(x => x.Name.StartsWith(path.Name));
                Paths.RemoveRange(idx, count);
            }

            // Check the siblings of 'path', if all are in 'Paths' then we can remove
            // all of these child paths and replace it with the parent path
            p.Clear().Append(path.Name);
            for (int i = parts.Length; i-- != 0;)
            {
                p.Length -= parts[i].Length + 1;
                if (p.Length == 0 ||
                    !Path_.EnumFileSystem(p.ToString(), SearchOption.TopDirectoryOnly)
                    .Where(x => Bit.AllSet(x.Attributes, FileAttributes.Directory))
                    .All(x => Paths.BinarySearch(x.FullName, Path.Compare) >= 0))
                {
                    break;                     // Not all child paths of 'p' are in 'Paths'
                }
                // Do this as we go, because the test above needs paths we add here
                using (Paths.SuspendEvents(true))
                {
                    var parent = new Path(path.Text.Substring(0, p.Length));
                    var idx    = Paths.BinarySearch(parent, Path.Compare);
                    if (idx < 0)
                    {
                        idx = ~idx;
                    }
                    else
                    {
                        throw new Exception($"Paths contains {parent} and {Paths[idx]}. {Paths[idx]} should not be in 'Paths' as it's covered by {parent}");
                    }

                    // Remove all children of 'parent'
                    var count = Paths.Skip(idx).Count(x => x.Name.StartsWith(parent.Name));
                    Paths.RemoveRange(idx, count);

                    // Add 'parent'
                    Paths.Insert(idx, parent);
                }
            }

            // Update the check boxes
            UpdateTree();
        }
Пример #11
0
        /// <summary>
        /// Smart copy from 'src' to 'dst'. Loosely like XCopy.
        /// 'src' can be a single file, a comma separated list of files, or a directory<para/>
        /// 'dst' can be a
        /// if 'src' is a directory, </summary>
        public static void Copy(string src, string dst, bool overwrite = false, bool only_if_modified = false, bool ignore_non_existing = false, Action <string>?feedback = null, bool show_unchanged = false)
        {
            var src_is_dir = Path_.IsDirectory(src);
            var dst_is_dir = Path_.IsDirectory(dst) || dst.EndsWith("/") || dst.EndsWith("\\") || src_is_dir;

            // Find the names of the source files to copy
            var files = new List <string>();

            if (src_is_dir)
            {
                files = Path_.EnumFileSystem(src, SearchOption.AllDirectories).Select(x => x.FullName).ToList();
            }
            else if (Path_.FileExists(src))
            {
                files = new List <string>()
                {
                    src
                }
            }
            ;
            else if (src.Contains('*') || src.Contains('?'))
            {
                files = Path_.EnumFileSystem(src, SearchOption.AllDirectories, new Pattern(EPattern.Wildcard, src).RegexString).Select(x => x.FullName).ToList();
            }
            else if (!ignore_non_existing)
            {
                throw new FileNotFoundException($"'{src}' does not exist");
            }

            // If the 'src' represents multiple files, 'dst' must be a directory
            if (src_is_dir || files.Count > 1)
            {
                // if 'dst' doesn't exist, assume it's a directory
                if (!Path_.DirExists(dst))
                {
                    dst_is_dir = true;
                }

                // or if it does exist, check that it is actually a directory
                else if (!dst_is_dir)
                {
                    throw new FileNotFoundException($"'{dst}' is not a valid directory");
                }
            }

            // Ensure that 'dstdir' exists. (Canonicalise fixes the case where 'dst' is a drive, e.g. 'C:\')
            var dstdir = Path_.Canonicalise((dst_is_dir ? dst : Path_.Directory(dst)).TrimEnd('/', '\\'));

            if (!Path_.DirExists(dstdir))
            {
                Directory.CreateDirectory(dstdir);
            }

            // Copy the file(s) to 'dst'
            foreach (var srcfile in files)
            {
                // If 'dst' is a directory, use the same filename from 'srcfile'
                var dstfile = string.Empty;
                if (dst_is_dir)
                {
                    var spath = src_is_dir ? Path_.RelativePath(src, srcfile) : Path_.FileName(srcfile);
                    dstfile = Path_.CombinePath(dstdir, spath);
                }
                else
                {
                    dstfile = dst;
                }

                // If 'srcfile' is a directory, ensure the directory exists at the destination
                if (Path_.IsDirectory(srcfile))
                {
                    if (!dst_is_dir)
                    {
                        throw new Exception($"ERROR: {dst} is not a directory");
                    }

                    // Create the directory at the destination
                    if (!Path_.DirExists(dstfile))
                    {
                        System.IO.Directory.CreateDirectory(dstfile);
                    }
                    if (feedback != null)
                    {
                        feedback(srcfile + " --> " + dstfile);
                    }
                }
                else
                {
                    // Copy if modified or always based on the flag
                    if (only_if_modified && !Path_.DiffContent(srcfile, dstfile))
                    {
                        if (feedback != null && show_unchanged)
                        {
                            feedback(srcfile + " --> unchanged");
                        }
                        continue;
                    }

                    // Ensure the directory path exists
                    var d = Path_.Directory(dstfile);
                    var f = Path_.FileName(dstfile);
                    if (!Path_.DirExists(d))
                    {
                        System.IO.Directory.CreateDirectory(d);
                    }
                    if (feedback != null)
                    {
                        feedback(srcfile + " --> " + dstfile);
                    }
                    File.Copy(srcfile, dstfile, overwrite);
                }
            }
        }
Пример #12
0
        /// <summary>Search for the full path of adb.exe</summary>
        private void AutoDetectAdbPath()
        {
            // If the full path is saved in the settings, use that (if it's valid)
            if (Path_.FileExists(m_settings.AdbFullPath))
            {
                SetAdbPath(m_settings.AdbFullPath);
                return;
            }

            // Quick check the most likely spot
            var likely_path = Path.Combine(Environment.GetEnvironmentVariable("ANDROID_HOME") ?? string.Empty, @"platform-tools\adb.exe");

            if (Path_.FileExists(likely_path))
            {
                SetAdbPath(likely_path);
                return;
            }

            // Not found? longer search...
            const string msg =
                "Searching for the Android Debugging Bridge application...\r\n" +
                "\r\n" +
                "Trying Path: {0}...\r\n" +
                "\r\n" +
                "Click cancel to locate it manually.";

            var adb_path     = string.Empty;
            var search_paths = new[]
            {
                Environment.GetEnvironmentVariable("ANDROID_HOME"),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + @"\Android\android-sdk\platform-tools",
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\Android\android-sdk\platform-tools",
                @"D:\Program Files (x86)\Android\android-sdk\platform-tools",
                @"D:\Program Files\Android\android-sdk\platform-tools",
                @"E:\Program Files (x86)\Android\android-sdk\platform-tools",
                @"E:\Program Files\Android\android-sdk\platform-tools",
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
                Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
                @"C:\"
            };

            var res = DialogResult.Cancel;

            try
            {
                // Search for 'adb.exe'
                var find_adb = new ProgressForm("Locating 'adb.exe'...", string.Format(msg, string.Empty), Icon, ProgressBarStyle.Marquee, (s, a, cb) =>
                {
                    foreach (var path in search_paths)
                    {
                        if (s.CancelPending || adb_path.HasValue())
                        {
                            break;
                        }

                        if (path == null || !Directory.Exists(path))
                        {
                            continue;
                        }

                        cb(new ProgressForm.UserState {
                            Description = string.Format(msg, path), ForceLayout = false
                        });
                        Func <string, bool> progress = dir =>
                        {
                            cb(ProgressForm.UserState.Empty);
                            return(!s.CancelPending);
                        };

                        foreach (var fi in Path_.EnumFileSystem(path, SearchOption.AllDirectories, regex_filter:@"adb\.exe", progress:progress))
                        {
                            // Found one!
                            adb_path = fi.FullName;
                            return;
                        }
                    }
                })
                {
                    StartPosition = FormStartPosition.CenterParent,
                    ClientSize    = new Size(640, 280),
                };
                using (find_adb)
                    res = find_adb.ShowDialog(this);
            }
            catch (OperationCanceledException) {}
            catch (Exception ex) { Misc.ShowMessage(this, "An error occurred while searching for 'adb.exe'", "Locating 'adb.exe' failed", MessageBoxIcon.Error, ex); }
            if (res != DialogResult.OK)
            {
                return;
            }

            SetAdbPath(adb_path);
        }