Пример #1
0
        public RylobotModel(Robot robot)
        {
            m_sym_cache = new Cache <string, Symbol> {
                ThreadSafe = true, Mode = CacheMode.StandardCache
            };
            Robot = robot;

            var settings_filepath = Util.ResolveAppDataPath("Rylogic", "Rylobot", "Settings.xml");

            Settings = new Settings(settings_filepath)
            {
                AutoSaveOnChanges = true
            };

            // Ensure the instrument settings directory exists
            if (!Path_.DirExists(Settings.General.InstrumentSettingsDir))
            {
                Directory.CreateDirectory(Settings.General.InstrumentSettingsDir);
            }

            // Create the account
            Acct = new Account(this, Robot.Account);

            // Create the instrument
            Instrument = new Instrument(this);

            // Create a strategy
            Strategy = new StrategyPotLuck(this);

            // ToDo:
            // Restore SnR levels + other indicators
        }
Пример #2
0
        public History(MainModel model)
        {
            Model = model;

            // Ensure the acct data cache directory exists
            if (!Path_.DirExists(Model.Settings.General.AcctDataCacheDir))
            {
                Directory.CreateDirectory(Model.Settings.General.AcctDataCacheDir);
            }
        }
Пример #3
0
        /// <summary>Write this string to a file</summary>
        public static void ToFile(this string str, string filepath, bool append = false, bool create_dir_if_necessary = true)
        {
            // Ensure the directory exists
            var dir = Path_.Directory(filepath);

            if (create_dir_if_necessary && !Path_.DirExists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            using (var f = new StreamWriter(new FileStream(filepath, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.ReadWrite)))
                f.Write(str);
        }
Пример #4
0
        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);

            // On first time startup, display the settings before creating the data directory
            if (!Path_.DirExists(Settings.Instance.DataPath))
            {
                ShowSettings.Execute();

                // Ensure the data directory exists
                Path_.CreateDirs(Settings.Instance.DataPath);
            }

            // Apply settings
            Settings.Instance.NotifySettingChanged(nameof(Settings.Origin));
            Settings.Instance.NotifySettingChanged(nameof(Settings.Destination));
        }
Пример #5
0
        /// <summary>Write an ldr string to a file</summary>
        public static void Write(string ldr_str, string filepath, bool append = false)
        {
            try
            {
                // Ensure the directory exists
                var dir = Path_.Directory(filepath);
                if (!Path_.DirExists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                // Lock, then write the file
                using (Path_.LockFile(filepath))
                    using (var f = new StreamWriter(new FileStream(filepath, append ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.Read)))
                        f.Write(ldr_str);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Failed to write Ldr script to '{filepath}'. {ex.Message}");
            }
        }
Пример #6
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);
            }
        }
Пример #7
0
        /// <summary>Load and parse the startup options</summary>
        public StartupOptions(string[] args)
        {
            var exe_dir = Util.ResolveAppPath();

            if (!Directory.Exists(exe_dir))
            {
                throw new ArgumentException("Cannot determine the current executable directory");
            }

            // Check the command line options
            for (int i = 0, iend = args.Length; i != iend; ++i)
            {
                var arg = args[i].ToLowerInvariant();

                // No option character implies the file to load
                if (arg[0] != '-' && arg[0] != '/')
                {
                    if (FileToLoad != null)
                    {
                        throw new ArgumentException("Command line should specify a single file path only. If the file path contains white space, remember to use quotes. e.g. RyLogViewer \"my file.txt\"");
                    }
                    FileToLoad = arg;
                    continue;
                }

                // Helper for comparing option strings
                bool IsOption(string opt) => string.CompareOrdinal(arg, 0, opt, 0, opt.Length) == 0;

                // (order these by longest option first)
                if (IsOption(CmdLineOption.RDelim))
                {
                    RowDelim = arg.Substring(CmdLineOption.RDelim.Length);
                }
                else if (IsOption(CmdLineOption.CDelim))
                {
                    ColDelim = arg.Substring(CmdLineOption.CDelim.Length);
                }
                else if (IsOption(CmdLineOption.NoGUI))
                {
                    NoGUI = true;
                }
                else if (IsOption(CmdLineOption.Silent))
                {
                    Silent = true;
                }
                else if (IsOption(CmdLineOption.PatternSet))
                {
                    PatternSetFilepath = arg.Substring(CmdLineOption.PatternSet.Length);
                }
                else if (IsOption(CmdLineOption.SettingsPath))
                {
                    SettingsPath = arg.Substring(CmdLineOption.SettingsPath.Length);
                }
                else if (IsOption(CmdLineOption.LogFilePath))
                {
                    LogFilePath = arg.Substring(CmdLineOption.LogFilePath.Length);
                }
                else if (IsOption(CmdLineOption.Export))
                {
                    ExportPath = arg.Substring(CmdLineOption.Export.Length);
                }
                else if (IsOption(CmdLineOption.Portable))
                {
                    PortableMode = true;
                }
                else if (IsOption(CmdLineOption.ShowHelp))
                {
                    ShowHelp = true;
                }
                else if (IsOption(CmdLineOption.ShowHelp2))
                {
                    ShowHelp = true;
                }
                else
                {
                    throw new ArgumentException("Unknown command line option '" + arg + "'.");
                }
            }

            // Determine whether to run the app in portable mode
            PortableMode |= Path_.FileExists(Path.Combine(exe_dir, "portable"));

            // Set the UserDataDir based on whether we're running in portable mode or not
            UserDataDir = Path.GetFullPath(PortableMode ? exe_dir : Util.ResolveUserDocumentsPath(Application.CompanyName, Application.ProductName));

            // If we're in portable mode, check that we have write access to the local directory
            if (PortableMode)
            {
                if (!Path_.DirExists(UserDataDir) || (new DirectoryInfo(UserDataDir).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    throw new IOException("Unable to run in portable mode as the directory ('" + UserDataDir + "') is readonly.");
                }
            }
            // If not in portable mode, check the UserDataDir directory exists (or can be created)
            else
            {
                if (!Path_.DirExists(UserDataDir))
                {
                    Directory.CreateDirectory(UserDataDir);
                }
            }

            // If the export option is given, a 'FileToLoad' must also be given
            if (ExportPath != null && FileToLoad == null)
            {
                throw new ArgumentException("A file to export must be given if the '-e' option is used");
            }

            // If a settings path has not been given, use the defaults
            if (SettingsPath == null)
            {
                SettingsPath = Path.Combine(UserDataDir, "settings.xml");
            }

            // Set the licence file path
            LicenceFilepath = PortableMode
                                ? Path.Combine(exe_dir, "licence.xml")
                                : Path.Combine(UserDataDir, "licence.xml");

            // If no licence file exists, create the free one
            if (!Path_.FileExists(LicenceFilepath))
            {
                new Licence().WriteLicenceFile(LicenceFilepath);
            }
        }
Пример #8
0
        // Notes:
        //  - Parsed command line options

        public StartupOptions(string[] args)
        {
            FilesToLoad  = new List <string>();
            SettingsPath = null !;

            var exe_dir = Util.ResolveAppPath();

            if (!Path_.DirExists(exe_dir))
            {
                throw new ArgumentException("Cannot determine the current executable directory");
            }

            // Check the command line options
            for (int i = 0, iend = args.Length; i != iend; ++i)
            {
                var arg = args[i].ToLowerInvariant();

                // No option character implies the file to load
                if (arg[0] != '-' && arg[0] != '/')
                {
                    FilesToLoad.Add(arg);
                    continue;
                }

                // Helper for comparing option strings
                bool IsOption(string opt) => string.CompareOrdinal(arg, 0, opt, 0, opt.Length) == 0;

                // (order these by longest option first)
                if (IsOption(CmdLine.SettingsPath))
                {
                    SettingsPath = arg.Substring(CmdLine.SettingsPath.Length);
                }
                else if (IsOption(CmdLine.Portable))
                {
                    PortableMode = true;
                }
                else if (IsOption(CmdLine.ShowHelp))
                {
                    ShowHelp = true;
                }
                else if (IsOption(CmdLine.ShowHelp2))
                {
                    ShowHelp = true;
                }
                else
                {
                    throw new ArgumentException($"Unknown command line option '{arg}'.");
                }
            }

            // Determine whether to run the app in portable mode
            PortableMode |= Path_.FileExists(Path_.CombinePath(exe_dir, "portable"));

            // Set the UserDataDir based on whether we're running in portable mode or not
            UserDataDir = Path.GetFullPath(PortableMode ? Path_.CombinePath(exe_dir, "UserData") : Util.ResolveUserDocumentsPath("Rylogic", "LDraw"));
            Path_.CreateDirs(UserDataDir);

            // Check that we have write access to the user data directory
            if (!Path_.DirExists(UserDataDir) || (new DirectoryInfo(UserDataDir).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            {
                throw new IOException($"The user data directory ('{UserDataDir}') is readonly.");
            }

            // If a settings path has not been given, use the defaults
            SettingsPath ??= Path_.CombinePath(UserDataDir, "settings2.xml");
        }
Пример #9
0
        /// <summary>Watch for settings changes</summary>
        private async void HandleSettingChange(object sender, SettingChangeEventArgs e)
        {
            if (e.Before)
            {
                return;
            }
            Log.Write(ELogLevel.Debug, $"Setting {e.Key} changed to {e.Value}");

            switch (e.Key)
            {
            case nameof(Settings.JournalFilesDir):
            {
                // Enable the journal file monitor if the ED journal path is set
                m_journal_monitor.Run = Path_.DirExists(Settings.Instance.JournalFilesDir);
                break;
            }

            case nameof(Settings.Origin):
            {
                // If a origin station is selected but the current system id is
                // still null, set it to the system that owns the station.
                if (Settings.Instance.Origin.StationID != null &&
                    Settings.Instance.Origin.StarSystemID == null)
                {
                    var station = Src.GetStation(Settings.Instance.Origin.StationID.Value).Result;
                    Settings.Instance.Origin = new LocationID(station.SystemID, station.ID);
                }
                InvalidateTradeRoutes();
                break;
            }

            case nameof(Settings.Destination):
            {
                // If a destination station is selected but the current system id is
                // still null, set it to the system that owns the station.
                if (Settings.Instance.Destination.StationID != null &&
                    Settings.Instance.Destination.StarSystemID == null)
                {
                    var station = Src.GetStation(Settings.Instance.Destination.StationID.Value).Result;
                    Settings.Instance.Destination = new LocationID(station.SystemID, station.ID);
                }
                InvalidateTradeRoutes();
                break;
            }

            case nameof(Settings.UseCurrentLocation):
            {
                if (Settings.Instance.UseCurrentLocation)
                {
                    await SetLocationFromJournal();
                }

                InvalidateTradeRoutes();
                break;
            }

            case nameof(Settings.ReadCargoCapacityFromLoadout):
            {
                if (Settings.Instance.ReadCargoCapacityFromLoadout && JournalMonitor.CargoCapacity != null)
                {
                    Settings.Instance.CargoCapacity = JournalMonitor.CargoCapacity.Value;
                }

                InvalidateTradeRoutes();
                break;
            }

            case nameof(Settings.ReadMaxJumpRangeFromLoadout):
            {
                if (Settings.Instance.ReadMaxJumpRangeFromLoadout && JournalMonitor.MaxJumpRange != null)
                {
                    Settings.Instance.MaxJumpRange = JournalMonitor.MaxJumpRange.Value;
                }

                InvalidateTradeRoutes();
                break;
            }
            }
        }
Пример #10
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);
                }
            }
        }
Пример #11
0
        public static IEnumerable <FileData> EnumFileSystem(string path, SearchOption search_flags = SearchOption.TopDirectoryOnly, string?regex_filter = null, RegexOptions regex_options = RegexOptions.IgnoreCase, FileAttributes exclude = FileAttributes.Hidden, Func <string, bool>?progress = null)
        {
            /// <remarks>
            /// A fast enumerator of files in a directory.
            /// Use this if you need to get attributes for all files in a directory.
            /// This enumerator is substantially faster than using <see cref="Directory.GetFiles(string)"/>
            /// and then creating a new FileInfo object for each path.  Use this version when you
            /// will need to look at the attributes of each file returned (for example, you need
            /// to check each file in a directory to see if it was modified after a specific date).
            /// </remarks>

            Debug.Assert(Path_.DirExists(path), "Attempting to enumerate an invalid directory path");

            // Default progress callback
            if (progress == null)
            {
                progress = s => true;
            }

            // File/Directory name filter
            var filter = regex_filter != null ? new Regex(regex_filter, regex_options) : null;

            // For drive letters, add a \, 'FileIOPermission' needs it
            if (path.EndsWith(":"))
            {
                path += "\\";
            }

            // Local stack for recursion
            var stack = new Stack <string>(20);

            for (stack.Push(path); stack.Count != 0;)
            {
                // Report progress
                var dir = stack.Pop();
                if (!progress(dir))
                {
                    break;
                }

                // Skip paths we don't have access to
                try { new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dir).Demand(); }
                catch { continue; }

                // Use the win32 find files
                var pattern   = Path.Combine(dir, "*");
                var find_data = new Win32.WIN32_FIND_DATA();
                using (var handle = FindFirstFile(pattern, ref find_data))
                {
                    for (var more = !handle.IsInvalid; more; more = FindNextFile(handle, ref find_data))
                    {
                        // Exclude files with any of the exclude attributes
                        if ((find_data.Attributes & exclude) != 0)
                        {
                            continue;
                        }

                        // Filter if provided
                        if (find_data.FileName != "." && find_data.FileName != "..")
                        {
                            Match m;
                            if (filter == null)
                            {
                                yield return(new FileData(dir, ref find_data));
                            }
                            else if ((m = filter.Match(find_data.FileName)).Success)
                            {
                                yield return(new FileData(dir, ref find_data, m));
                            }
                        }

                        // If the found object is a directory, see if we should be recursing
                        if (search_flags == SearchOption.AllDirectories && (find_data.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
                        {
                            if (find_data.FileName == "." || find_data.FileName == "..")
                            {
                                continue;
                            }

                            stack.Push(Path.Combine(dir, find_data.FileName));
                        }
                    }
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Delete a directory and all contained files/subdirectories.
        /// Returns true if successful and not interrupted</summary>
        public static bool DelTree(string root, EDelTreeOpts opts, Func <string, EAbortIgnoreRetry> prompt, int timeout_ms = 1000)
        {
            prompt = prompt ?? (_ => EAbortIgnoreRetry.Abort);
            for (;;)
            {
                try
                {
                    // Generate a list of all contained files
                    var files = Directory.GetFiles(root, "*", SearchOption.AllDirectories);
                    if (files.Length != 0)
                    {
                        if (!opts.HasFlag(EDelTreeOpts.FilesOnly) && !opts.HasFlag(EDelTreeOpts.EvenIfNotEmpty))
                        {
                            throw new IOException($"Cannot delete {root}, directory still contains {files.Length} files");
                        }

                        // Check for processes holding locks on the files
                        for (;;)
                        {
                            // Find the lock holding processes/services
                            var lockers = FileLockHolders(files);
                            if (!lockers.Any())
                            {
                                break;
                            }

                            // Prompt the user, Abort, Retry or Ignore
                            var r = prompt(
                                $"The following processes hold locks on files within {root}:\r\n" +
                                $"\t{string.Join("\r\n\t", lockers.Select(x => x.ProcessName))}");
                            if (r == EAbortIgnoreRetry.Abort)
                            {
                                return(false);
                            }
                            if (r == EAbortIgnoreRetry.Ignore)
                            {
                                break;
                            }
                        }

                        // Delete the contained files
                        if (opts.HasFlag(EDelTreeOpts.FilesOnly) || opts.HasFlag(EDelTreeOpts.EvenIfNotEmpty))
                        {
                            foreach (var file in files)
                            {
                                if (Path_.FileExists(file))
                                {
                                    File.Delete(file);
                                }
                            }
                        }
                    }

                    // Try to delete the root directory. This can fail because the file system
                    // doesn't necessarily update as soon as the files are deleted. Try to delete,
                    // if that fails, wait a bit, then try again. If that fails, defer to the user.
                    const int Attempts = 3;
                    for (int retries = Attempts; retries-- != 0;)
                    {
                        try
                        {
                            if (opts.HasFlag(EDelTreeOpts.DeleteRoot))
                            {
                                Directory.Delete(root, true);
                            }
                            else
                            {
                                // Delete the contained directories
                                var dirs = System.IO.Directory.GetDirectories(root, "*", SearchOption.TopDirectoryOnly);
                                foreach (var dir in dirs)
                                {
                                    if (Path_.DirExists(dir))
                                    {
                                        Directory.Delete(dir, true);
                                    }
                                }
                            }
                            return(true);
                        }
                        catch (IOException)
                        {
                            if (retries == 0)
                            {
                                throw;
                            }
                            Thread.Sleep(Math.Max(100, timeout_ms / Attempts));
                        }
                    }
                }
                catch (Exception ex)
                {
                    var r = prompt(
                        $"Failed to delete directory '{root}'\r\n" +
                        $"{ex.Message}\r\n");
                    if (r == EAbortIgnoreRetry.Abort)
                    {
                        return(false);
                    }
                    if (r == EAbortIgnoreRetry.Ignore)
                    {
                        return(true);
                    }
                }
            }
        }
Пример #13
0
        /// <summary>Search for duplicate files using the command line parameters</summary>
        private int RunCmdline()
        {
            try
            {
                // Build a map of the files in 'm_dst_dir'
                Console.WriteLine("Building a map of existing files");
                var existing = BuildMap(m_dst_dir, m_regex_ignore);

                // Get the files that might be duplicates
                Console.WriteLine("Building a map of potentially duplicate files");
                var newfiles = BuildMap(m_src_dir, null);

                // Ensure the duplicates directory exists
                if (m_mv_dir != null)
                {
                    if (!Path_.DirExists(m_mv_dir))
                    {
                        Directory.CreateDirectory(m_mv_dir);
                    }
                }

                // Create the file that contains the duplicates list
                var lst = (m_lst != null) ? new StreamWriter(m_lst) : null;

                Console.WriteLine("Finding Duplicates");
                foreach (var finfo in newfiles)
                {
                    if (existing.TryGetValue(finfo.Key, out var original))
                    {
                        if (m_show_dups)
                        {
                            Console.WriteLine($"{finfo.Value.FullName} is a duplicate of {original.FullName}");
                        }

                        if (lst != null)
                        {
                            lst.WriteLine(finfo.Value.FullName);
                        }

                        if (m_mv_dir != null)
                        {
                            var dstfile = Path.Combine(m_mv_dir, finfo.Value.Name);
                            if (File.Exists(dstfile))
                            {
                                File.Delete(dstfile);
                            }
                            File.Move(finfo.Value.FullName, dstfile);
                        }
                    }
                }

                if (lst != null)
                {
                    lst.Dispose();
                }

                return(0);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
                return(-1);
            }
        }