Exemple #1
0
 /// <summary>Writes the specified <see cref="ConsoleColoredString"/> to the console.</summary>
 public static void Write(ConsoleColoredString value, bool stdErr = false)
 {
     if (value != null)
     {
         value.writeTo(stdErr ? Console.Error : Console.Out);
     }
 }
Exemple #2
0
        /// <summary>
        ///     Outputs the specified coloured message, marked up using EggsML, to the console window, treating newlines as
        ///     paragraph breaks. All paragraphs are word-wrapped to fit in the console buffer, or to a sensible width if
        ///     redirected to a file. Each paragraph is indented by the number of spaces at the start of the corresponding
        ///     line.</summary>
        /// <param name="message">
        ///     The message to output.</param>
        /// <param name="hangingIndent">
        ///     Specifies a number of spaces by which the message is indented in all but the first line of each paragraph.</param>
        /// <remarks>
        ///     See <see cref="EggsNode.ToConsoleColoredStringWordWrap"/> for the colour syntax.</remarks>
        public static void WriteParagraphs(EggsNode message, int hangingIndent = 0)
        {
            int width;

            try
            {
                width = WrapToWidth();
            }
            catch
            {
                // Fall back to non-word-wrapping
                WriteLine(ConsoleColoredString.FromEggsNode(message));
                return;
            }
            bool any = false;

            foreach (var line in message.ToConsoleColoredStringWordWrap(width, hangingIndent))
            {
                WriteLine(line);
                any = true;
            }

            // Special case: if the input is empty, output an empty line
            if (!any)
            {
                Console.WriteLine();
            }
        }
Exemple #3
0
        /// <summary>
        ///     Invokes the command, blocking until the command finishes. Returns the command's exit code. Does not throw if
        ///     the command failed.</summary>
        public int GoGetExitCode()
        {
            var invokeCount = Interlocked.Increment(ref _invokeCount) + 1;
            var startTime   = DateTime.UtcNow;

            if (_printCommandOutput && _printAugmented)
            {
                var prefix = (_printInvokeCount ? "    Cmd {0} at {1:HH:mm}> " : "    {1:HH:mm}> ").Color(ConsoleColor.White);
                ConsoleUtil.WriteLine("Running command: ".Color(ConsoleColor.Yellow) + _runner.Command.Color(ConsoleColor.Cyan));
                ConsoleUtil.Write(ConsoleColoredString.Format(prefix, invokeCount, DateTime.UtcNow));
                _runner.StdoutText += txt => { ConsoleUtil.Write(ConsoleColoredString.Format(txt.Color(ConsoleColor.Gray).Replace("\n", "\n" + prefix), invokeCount, DateTime.UtcNow)); };
                _runner.StderrText += txt => { ConsoleUtil.Write(ConsoleColoredString.Format(txt.Color(ConsoleColor.Red).Replace("\n", "\n" + prefix), invokeCount, DateTime.UtcNow)); };
            }
            else if (_printCommandOutput)
            {
                _runner.StdoutText += txt => { Console.Write(txt); };
                _runner.StderrText += txt => { ConsoleUtil.Write(txt.Color(ConsoleColor.Red)); };
            }
            _runner.Start();
            _runner.EndedWaitHandle.WaitOne();
            if (_printCommandOutput && _printAugmented)
            {
                Console.WriteLine();
                var ranFor = "Ran for {0:#,0} seconds".Fmt((DateTime.UtcNow - startTime).TotalSeconds);
                if (isSuccess(_runner.ExitCode))
                {
                    ConsoleUtil.WriteLine("Command succeeded. {0}\r\n\r\n".Fmt(ranFor).Color(ConsoleColor.Green));
                }
                else
                {
                    ConsoleUtil.WriteLine("Command failed with error code {0}. {1}\r\n\r\n".Fmt(_runner.ExitCode, ranFor).Color(ConsoleColor.Red));
                }
            }
            return(_runner.ExitCode);
        }
Exemple #4
0
        private static void tellUser(ConsoleColoredString message)
        {
#if CONSOLE
            ConsoleUtil.WriteLine(message);
#else
            new RT.Util.Dialogs.DlgMessage()
            {
                Message = message.ToString(), Type = RT.Util.Dialogs.DlgType.Warning, Font = new System.Drawing.Font("Consolas", 9)
            }.Show();
#endif
        }
Exemple #5
0
        /// <summary>
        ///     Word-wraps the current <see cref="ConsoleColoredString"/> to a specified width. Supports UNIX-style newlines
        ///     and indented paragraphs.</summary>
        /// <remarks>
        ///     <para>
        ///         The supplied text will be split into "paragraphs" at the newline characters. Every paragraph will begin on
        ///         a new line in the word-wrapped output, indented by the same number of spaces as in the input. All
        ///         subsequent lines belonging to that paragraph will also be indented by the same amount.</para>
        ///     <para>
        ///         All multiple contiguous spaces will be replaced with a single space (except for the indentation).</para></remarks>
        /// <param name="text">
        ///     Text to be word-wrapped.</param>
        /// <param name="maxWidth">
        ///     The maximum number of characters permitted on a single line, not counting the end-of-line terminator.</param>
        /// <param name="hangingIndent">
        ///     The number of spaces to add to each line except the first of each paragraph, thus creating a hanging
        ///     indentation.</param>
        public static IEnumerable <ConsoleColoredString> WordWrap(this ConsoleColoredString text, int maxWidth, int hangingIndent = 0)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }
            if (maxWidth < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(maxWidth), maxWidth, "maxWidth cannot be less than 1");
            }
            if (hangingIndent < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(hangingIndent), hangingIndent, "hangingIndent cannot be negative.");
            }
            if (text == null || text.Length == 0)
            {
                return(Enumerable.Empty <ConsoleColoredString>());
            }

            return(StringExtensions.wordWrap(
                       text.Split(new string[] { "\r\n", "\r", "\n" }),
                       maxWidth,
                       hangingIndent,
                       (txt, substrIndex) => txt.Substring(substrIndex).Split(new string[] { " " }, options: StringSplitOptions.RemoveEmptyEntries),
                       cc => cc.Length,
                       txt =>
            {
                // Count the number of spaces at the start of the paragraph
                int indentLen = 0;
                while (indentLen < txt.Length && txt.CharAt(indentLen) == ' ')
                {
                    indentLen++;
                }
                return indentLen;
            },
                       num => new string(' ', num),
                       () => new List <ConsoleColoredString>(),
                       list => list.Sum(c => c.Length),
                       (list, cc) => { list.Add(cc); },
                       list => new ConsoleColoredString(list),
                       (str, start, length) => length == null ? str.Substring(start) : str.Substring(start, length.Value),
                       (str1, str2) => str1 + str2));
        }
Exemple #6
0
        static int Main(string[] args)
        {
            if (args.Length == 2 && args[0] == "--post-build-check")
            {
                return(Ut.RunPostBuildChecks(args[1], Assembly.GetExecutingAssembly()));
            }

            var settingsFile = PathUtil.AppPathCombine("MySrvMon.xml");

            if (!File.Exists(settingsFile))
            {
                var sample = new Settings();
                sample.Modules.Add(new SmartModule());
                ClassifyXml.SerializeToFile(sample, settingsFile + ".sample");
                Console.WriteLine("Sample settings file saved: " + settingsFile + ".sample");
                Console.WriteLine("Edit and rename to " + settingsFile);
                return(1);
            }
            var settings = ClassifyXml.DeserializeFile <Settings>(settingsFile);

            ClassifyXml.SerializeToFile(settings, settingsFile + ".rewrite"); // for SMTP password encryption

            foreach (var module in settings.Modules)
            {
                module.Execute();
            }

            foreach (var module in settings.Modules.OrderByDescending(m => m.Status))
            {
                ConsoleColoredString report =
                    "===========================\r\n" +
                    "=== " + module.Name + "\r\n" +
                    "===========================\r\n\r\n";
                report  = report.Color(module.Status.GetConsoleColor());
                report += module.ConsoleReport + "\r\n";
                ConsoleUtil.Write(report);
            }

            var worstStatus = settings.Modules.Max(v => v.Status);

            return((int)worstStatus);
        }
Exemple #7
0
        /// <summary>
        ///     Writes the specified <see cref="ConsoleColoredString"/> followed by a newline to the console.</summary>
        /// <param name="value">
        ///     The string to print to the console.</param>
        /// <param name="stdErr">
        ///     <c>true</c> to print to Standard Error instead of Standard Output.</param>
        /// <param name="align">
        ///     Horizontal alignment of the string within the remaining space of the current line. If the string does not fit,
        ///     it will be printed as if left-aligned.</param>
        public static void WriteLine(ConsoleColoredString value, bool stdErr = false, HorizontalTextAlignment align = HorizontalTextAlignment.Left)
        {
            var output = stdErr ? Console.Error : Console.Out;

            if (value != null)
            {
                var cursorLeft = 0;
                try { cursorLeft = Console.CursorLeft; }
                catch { }
                var width = WrapToWidth() - cursorLeft;
                if (align == HorizontalTextAlignment.Center && width > value.Length)
                {
                    output.Write(new string(' ', (width - value.Length) / 2));
                }
                else if (align == HorizontalTextAlignment.Right && width > value.Length)
                {
                    output.Write(new string(' ', width - value.Length));
                }
                value.writeTo(output);
            }
            output.WriteLine();
        }
Exemple #8
0
        /// <summary>
        ///     Outputs the specified message to the console window, treating newlines as paragraph breaks. All paragraphs are
        ///     word-wrapped to fit in the console buffer, or to a sensible width if redirected to a file. Each paragraph is
        ///     indented by the number of spaces at the start of the corresponding line.</summary>
        /// <param name="message">
        ///     The message to output.</param>
        /// <param name="hangingIndent">
        ///     Specifies a number of spaces by which the message is indented in all but the first line of each paragraph.</param>
        public static void WriteParagraphs(ConsoleColoredString message, int hangingIndent = 0)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            int width;

            try
            {
                width = WrapToWidth();
            }
            catch
            {
                ConsoleUtil.WriteLine(message);
                return;
            }
            foreach (var line in message.WordWrap(width, hangingIndent))
            {
                ConsoleUtil.WriteLine(line);
            }
        }
Exemple #9
0
        private void toString(int?maxWidth, Action <string> outputString, Action <ConsoleColoredString> outputColoredString)
        {
            int rows = _cells.Count;

            if (rows == 0)
            {
                return;
            }
            int cols = _cells.Max(row => row.Count);

            // Create a lookup array which, for each column, and for each possible value of colspan, tells you which cells in that column have this colspan and end in this column
            var cellsByColspan = new SortedDictionary <int, List <int> > [cols];

            for (var col = 0; col < cols; col++)
            {
                var cellsInThisColumn = new SortedDictionary <int, List <int> >();
                for (int row = 0; row < rows; row++)
                {
                    if (col >= _cells[row].Count)
                    {
                        continue;
                    }
                    var cel = _cells[row][col];
                    if (cel == null)
                    {
                        continue;
                    }
                    if (cel is surrogateCell && ((surrogateCell)cel).RealRow != row)
                    {
                        continue;
                    }
                    int realCol  = cel is surrogateCell ? ((surrogateCell)cel).RealCol : col;
                    var realCell = (trueCell)_cells[row][realCol];
                    if (realCol + realCell.ColSpan - 1 != col)
                    {
                        continue;
                    }
                    cellsInThisColumn.AddSafe(realCell.ColSpan, row);
                }
                cellsByColspan[col] = cellsInThisColumn;
            }

            // Find out the width that each column would have if the text wasn't wrapped.
            // If this fits into the total width, then we want each column to be at least this wide.
            var columnWidths = generateColumnWidths(cols, cellsByColspan, c => Math.Max(1, c.LongestParagraph()));
            var unwrapped    = true;

            // If the table is now too wide, use the length of the longest word, or longest paragraph if nowrap
            if (maxWidth != null && columnWidths.Sum() > maxWidth - (cols - 1) * ColumnSpacing)
            {
                columnWidths = generateColumnWidths(cols, cellsByColspan, c => Math.Max(1, c.MinWidth()));
                unwrapped    = false;
            }

            // If the table is still too wide, use the length of the longest paragraph if nowrap, otherwise 0
            if (maxWidth != null && columnWidths.Sum() > maxWidth - (cols - 1) * ColumnSpacing)
            {
                columnWidths = generateColumnWidths(cols, cellsByColspan, c => c.NoWrap ? Math.Max(1, c.LongestParagraph()) : 1);
            }

            // If the table is still too wide, we will have to wrap like crazy.
            if (maxWidth != null && columnWidths.Sum() > maxWidth - (cols - 1) * ColumnSpacing)
            {
                columnWidths = new int[cols];
                for (int i = 0; i < cols; i++)
                {
                    columnWidths[i] = 1;
                }
            }

            // If the table is STILL too wide, all bets are off.
            if (maxWidth != null && columnWidths.Sum() > maxWidth - (cols - 1) * ColumnSpacing)
            {
                throw new InvalidOperationException(@"The specified table width is too narrow. It is not possible to fit the {0} columns and the column spacing of {1} per column into a total width of {2} characters.".Fmt(cols, ColumnSpacing, maxWidth));
            }

            // If we have any extra width to spare...
            var missingTotalWidth = maxWidth == null ? 0 : maxWidth - columnWidths.Sum() - (cols - 1) * ColumnSpacing;

            if (missingTotalWidth > 0 && (UseFullWidth || !unwrapped))
            {
                // Use the length of the longest paragraph in each column to calculate a proportion by which to enlarge each column
                var widthProportionByCol = new int[cols];
                for (var col = 0; col < cols; col++)
                {
                    foreach (var kvp in cellsByColspan[col])
                    {
                        distributeEvenly(
                            widthProportionByCol,
                            col,
                            kvp.Key,
                            kvp.Value.Max(row => ((trueCell)_cells[row][col - kvp.Key + 1]).LongestParagraph()) - widthProportionByCol.Skip(col - kvp.Key + 1).Take(kvp.Key).Sum() - (unwrapped ? 0 : columnWidths.Skip(col - kvp.Key + 1).Take(kvp.Key).Sum())
                            );
                    }
                }
                var widthProportionTotal = widthProportionByCol.Sum();

                // Adjust the width of the columns according to the calculated proportions so that they fill the missing width.
                // We do this in two steps. Step one: enlarge the column widths by the integer part of the calculated portion (round down).
                // After this the width remaining will be smaller than the number of columns, so each column is missing at most 1 character.
                var widthRemaining  = missingTotalWidth;
                var fractionalParts = new double[cols];
                for (int col = 0; col < cols; col++)
                {
                    var widthToAdd  = (double)(widthProportionByCol[col] * missingTotalWidth) / widthProportionTotal;
                    var integerPart = (int)widthToAdd;
                    columnWidths[col]   += integerPart;
                    fractionalParts[col] = widthToAdd - integerPart;
                    widthRemaining      -= integerPart;
                }

                // Step two: enlarge a few more columns by 1 character so that we reach the desired width.
                // The columns with the largest fractional parts here are the furthest from what we ideally want, so we favour those.
                foreach (var elem in fractionalParts.Select((frac, col) => new { Value = frac, Col = col }).OrderByDescending(e => e.Value))
                {
                    if (widthRemaining < 1)
                    {
                        break;
                    }
                    columnWidths[elem.Col]++;
                    widthRemaining--;
                }
            }

            // Word-wrap all the contents of all the cells
            trueCell truCel;

            foreach (var row in _cells)
            {
                for (int col = 0; col < row.Count; col++)
                {
                    if ((truCel = row[col] as trueCell) != null)
                    {
                        truCel.Wordwrap(columnWidths.Skip(col).Take(truCel.ColSpan).Sum() + (truCel.ColSpan - 1) * ColumnSpacing);
                    }
                }
            }

            // Calculate the string index for each column
            var strIndexByCol = new int[cols + 1];

            for (var i = 0; i < cols; i++)
            {
                strIndexByCol[i + 1] = strIndexByCol[i] + columnWidths[i] + ColumnSpacing;
            }
            var realWidth = strIndexByCol[cols] - ColumnSpacing;

            // Make sure we don't render rules if we can't
            bool verticalRules   = VerticalRules && ColumnSpacing > 0;
            bool horizontalRules = HorizontalRules && RowSpacing > 0;

            // If we do render vertical rules, where should it be (at which string offset, counted backwards from the end of the column spacing)
            var vertRuleOffset = (ColumnSpacing + 1) / 2;

            // Finally, render the entire output
            List <ConsoleColoredString> currentLine = null;

            for (int row = 0; row < rows; row++)
            {
                var  rowList          = _cells[row];
                var  extraRows        = RowSpacing + 1;
                var  isFirstIteration = true;
                bool anyMoreContentInThisRow;
                do
                {
                    ConsoleColoredString previousLine = currentLine == null ? null : new ConsoleColoredString(currentLine.ToArray());
                    currentLine             = new List <ConsoleColoredString>();
                    anyMoreContentInThisRow = false;
                    for (int col = 0; col < cols; col++)
                    {
                        var cel = col < rowList.Count ? rowList[col] : null;

                        // For cells with colspan, consider only the first cell they're spanning and skip the rest
                        if (cel is surrogateCell && ((surrogateCell)cel).RealCol != col)
                        {
                            continue;
                        }

                        // If the cell has rowspan, what row did this cell start in?
                        var valueRow = cel is surrogateCell ? ((surrogateCell)cel).RealRow : row;

                        // Retrieve the data for the cell
                        var realCell      = col < _cells[valueRow].Count ? (trueCell)_cells[valueRow][col] : null;
                        var colspan       = realCell == null ? 1 : realCell.ColSpan;
                        var rowspan       = realCell == null ? 1 : realCell.RowSpan;
                        var rowBackground = row >= _rowBackgrounds.Count ? null : _rowBackgrounds[row];

                        // Does this cell end in this row?
                        var isLastRow = valueRow + rowspan - 1 == row;

                        // If we are inside the cell, render one line of the contents of the cell
                        if (realCell != null && realCell.WordwrappedValue.Length > realCell.WordwrappedIndex)
                        {
                            var align          = realCell.Alignment ?? DefaultAlignment;
                            var curLineLength  = currentLine.Sum(c => c.Length);
                            var cellBackground = realCell.Background ?? rowBackground;
                            if (strIndexByCol[col] > curLineLength)
                            {
                                currentLine.Add(new string(' ', strIndexByCol[col] - curLineLength).Color(null, cellBackground));
                            }
                            object textRaw            = realCell.WordwrappedValue[realCell.WordwrappedIndex];
                            ConsoleColoredString text = textRaw is ConsoleColoredString ? (ConsoleColoredString)textRaw : (string)textRaw;    // implicit conversion to ConsoleColoredString
                            if (align == HorizontalTextAlignment.Center)
                            {
                                currentLine.Add(new string(' ', (strIndexByCol[col + colspan] - strIndexByCol[col] - ColumnSpacing - text.Length) / 2).Color(null, cellBackground));
                            }
                            else if (align == HorizontalTextAlignment.Right)
                            {
                                currentLine.Add(new string(' ', strIndexByCol[col + colspan] - strIndexByCol[col] - ColumnSpacing - text.Length).Color(null, cellBackground));
                            }
                            if (cellBackground == null)
                            {
                                currentLine.Add(text);
                            }
                            else
                            {
                                currentLine.Add(text.ColorBackgroundWhereNull(cellBackground.Value));
                                if (align == HorizontalTextAlignment.Center)
                                {
                                    currentLine.Add(new string(' ', (strIndexByCol[col + colspan] - strIndexByCol[col] - ColumnSpacing - text.Length + 1) / 2).Color(null, cellBackground));
                                }
                                else if (align == HorizontalTextAlignment.Left)
                                {
                                    currentLine.Add(new string(' ', strIndexByCol[col + colspan] - strIndexByCol[col] - ColumnSpacing - text.Length).Color(null, cellBackground));
                                }
                            }
                            realCell.WordwrappedIndex++;
                        }

                        // If we are at the end of a row, render horizontal rules
                        var horizRuleStart           = col > 0 ? strIndexByCol[col] - vertRuleOffset + 1 : 0;
                        var horizRuleEnd             = (col + colspan < cols) ? strIndexByCol[col + colspan] - vertRuleOffset + (verticalRules ? 0 : 1) : realWidth;
                        var renderingHorizontalRules = horizontalRules && isLastRow && extraRows == 1;
                        if (renderingHorizontalRules)
                        {
                            currentLine.Add(new string(' ', horizRuleStart - currentLine.Sum(c => c.Length)));
                            currentLine.Add(new string((row == HeaderRows - 1) ? '=' : '-', horizRuleEnd - horizRuleStart));
                        }
                        else
                        {
                            var subtract = (col + colspan == cols ? ColumnSpacing : vertRuleOffset) + currentLine.Sum(c => c.Length);
                            currentLine.Add(new string(' ', strIndexByCol[col + colspan] - subtract).Color(null, (realCell == null ? null : realCell.Background) ?? rowBackground));
                        }

                        // If we are at the beginning of a row, render the horizontal rules for the row above by modifying the previous line.
                        // We want to do this because it may have an unwanted vertical rule if this is a cell with colspan and there are
                        // multiple cells with smaller colspans above it.
                        if (isFirstIteration && horizontalRules && row > 0 && cel is trueCell)
                        {
                            previousLine = new ConsoleColoredString(previousLine.Substring(0, horizRuleStart), new string((row == HeaderRows) ? '=' : '-', horizRuleEnd - horizRuleStart), previousLine.Substring(horizRuleEnd));
                        }

                        // Render vertical rules
                        if (verticalRules && (col + colspan < cols))
                        {
                            currentLine.Add((new string(' ', strIndexByCol[col + colspan] - vertRuleOffset - currentLine.Sum(c => c.Length)) + "|").Color(null, renderingHorizontalRules ? null : rowBackground));
                        }

                        // Does this cell still contain any more content that needs to be output before this row can be finished?
                        anyMoreContentInThisRow = anyMoreContentInThisRow || (realCell != null && isLastRow && realCell.WordwrappedValue.Length > realCell.WordwrappedIndex);
                    }

                    if (previousLine != null)
                    {
                        if (LeftMargin > 0)
                        {
                            outputString(new string(' ', LeftMargin));
                        }
                        outputColoredString(previousLine);
                        outputString(Environment.NewLine);
                    }

                    isFirstIteration = false;

                    // If none of the cells in this row contain any more content, start counting down the row spacing
                    if (!anyMoreContentInThisRow)
                    {
                        extraRows--;
                    }
                }while (anyMoreContentInThisRow || (extraRows > 0 && row < rows - 1));
            }

            // Output the last line
            if (LeftMargin > 0)
            {
                outputString(new string(' ', LeftMargin));
            }
            outputColoredString(new ConsoleColoredString(currentLine.ToArray()));
            outputString(Environment.NewLine);
        }
Exemple #10
0
 /// <summary>
 ///     Places the specified content into the cell at the specified co-ordinates.</summary>
 /// <param name="col">
 ///     Column where to place the content.</param>
 /// <param name="row">
 ///     Row where to place the content.</param>
 /// <param name="content">
 ///     The content to place.</param>
 /// <param name="colSpan">
 ///     The number of columns to span.</param>
 /// <param name="rowSpan">
 ///     The number of rows to span.</param>
 /// <param name="noWrap">
 ///     If true, indicates that this cell should not be automatically word-wrapped except at explicit newlines in
 ///     <paramref name="content"/>. The cell is word-wrapped only if doing so is necessary to fit all no-wrap cells
 ///     into the table's total width. If false, the cell is automatically word-wrapped to optimise the table's layout.</param>
 /// <param name="alignment">
 ///     How to align the contents within the cell, or null to use <see cref="DefaultAlignment"/>.</param>
 /// <param name="background">
 ///     Specifies a background color for the whole cell, including its empty space. Characters with background colors
 ///     in the input string take precedence for those characters only.</param>
 public void SetCell(int col, int row, ConsoleColoredString content, int colSpan = 1, int rowSpan = 1, bool noWrap = false, HorizontalTextAlignment?alignment = null, ConsoleColor?background = null)
 {
     setCell(col, row, content, colSpan, rowSpan, noWrap, alignment, background);
 }
Exemple #11
0
        static void Main()
        {
            Console.OutputEncoding = Encoding.UTF8;
            Console.WindowWidth    = 200;
            Console.WindowHeight   = 40;

            var curUser = Environment.UserName;

            curUser = curUser.Substring(0, 1).ToUpper() + curUser.Substring(1).ToLower();
            Settings settings;

            SettingsUtil.LoadSettings(out settings);
            var highscore = settings.Highscores[curUser];

            var recent = new AutoDictionary <string, Highscore>(_ => new Highscore());
            int cur    = 0;
            ConsoleColoredString lastAttemptOutcome = null;

            while (true)
            {
                Console.Clear();
                Console.WriteLine("Current highscores, in milliseconds:");
                WriteToConsole(settings.Highscores.Concat(recent).ToDictionary());

                if (lastAttemptOutcome != null)
                {
                    Console.WriteLine();
                    ConsoleUtil.WriteLine("Last attempt: " + lastAttemptOutcome);
                }

                Console.WriteLine();
                Console.WriteLine("Type every letter A-Z exactly once, either alphabetically or in any order. Wait 1 second when done, or press space to restart.");
                Console.WriteLine();

                var pressed = new Dictionary <char, DateTime>();
                Console.Title = string.Join(" ", Enumerable.Range('A', 26).Select(x => (char)x).Except(pressed.Keys).OrderBy(x => x));
                while (true)
                {
                    var key = Console.ReadKey(true);
                    Console.Write((key.KeyChar + " ").ToUpper());

                    if (key.KeyChar < 'a' || key.KeyChar > 'z')
                    {
                        break;
                    }
                    var chr = char.ToUpper(key.KeyChar);

                    if (pressed.ContainsKey(chr))
                    {
                        break;
                    }
                    pressed[chr]  = DateTime.UtcNow;
                    Console.Title = string.Join(" ", Enumerable.Range('A', 26).Select(x => (char)x).Except(pressed.Keys).OrderBy(x => x));

                    if (pressed.Count == 26)
                    {
                        break;
                    }
                }

                Console.WriteLine();
                Console.WriteLine('\x7');

                if (pressed.Count == 26)
                {
                    Console.WriteLine("Don't press anything now, to confirm you've typed just the 26 letters accurately and nothing else!");
                    var wait = DateTime.UtcNow;
                    while (DateTime.UtcNow < wait + TimeSpan.FromSeconds(1) && !Console.KeyAvailable)
                    {
                        Thread.Sleep(10);
                    }
                }

                if (pressed.Count == 26 && !Console.KeyAvailable)
                {
                    UpdateHighscore(highscore, pressed);
                    cur++;
                    UpdateHighscore(recent[$"Recent: {cur:00}"], pressed);
                    if (recent.ContainsKey($"Recent: {cur - 20:00}"))
                    {
                        recent.Remove($"Recent: {cur - 20:00}");
                    }

                    lastAttemptOutcome = "";
                    char expected   = 'A';
                    bool alphabetic = true;
                    foreach (var kvp in pressed.OrderBy(kvp => kvp.Value))
                    {
                        if (kvp.Key != expected)
                        {
                            alphabetic = false;
                        }
                        lastAttemptOutcome += $"{kvp.Key} ".Color(kvp.Key != expected ? ConsoleColor.Red : alphabetic ? ConsoleColor.Green : ConsoleColor.White);
                        expected            = (char)(kvp.Key + 1);
                    }
                    lastAttemptOutcome = (alphabetic ? "ALPHABETIC" : "any order") + " " + lastAttemptOutcome;

                    settings.Save();
                }
                else
                {
                    lastAttemptOutcome = "OOPS!...".Color(ConsoleColor.Magenta);
                }

                Console.WriteLine();
                Console.WriteLine();
            }
        }
Exemple #12
0
        /// <summary>Equivalent to <see cref="IEnumerableExtensions.JoinString{T}"/>, but for <see cref="ConsoleColoredString"/>s.</summary>
        public static ConsoleColoredString JoinColoredString <T>(this IEnumerable <T> values, ConsoleColoredString separator = null, ConsoleColoredString prefix = null, ConsoleColoredString suffix = null, ConsoleColor defaultColor = ConsoleColor.Gray)
        {
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }

            using (var enumerator = values.GetEnumerator())
            {
                if (!enumerator.MoveNext())
                {
                    return(ConsoleColoredString.Empty);
                }

                var  list  = new List <ConsoleColoredString>(values is ICollection <T>?((ICollection <T>)values).Count * 4 : 8);
                bool first = true;
                do
                {
                    if (!first && separator != null)
                    {
                        list.Add(separator);
                    }
                    first = false;
                    if (prefix != null)
                    {
                        list.Add(prefix);
                    }
                    if (enumerator.Current != null)
                    {
                        list.Add(enumerator.Current.ToConsoleColoredString(defaultColor));
                    }
                    if (suffix != null)
                    {
                        list.Add(suffix);
                    }
                }while (enumerator.MoveNext());
                return(new ConsoleColoredString(list));
            }
        }
Exemple #13
0
        protected override ExecuteResult ExecuteCore()
        {
            var drives = SMART.GetDrivesWithSMART();

            var result = new ExecuteResult();

            result.ConsoleReport = "";

            foreach (var drive in drives)
            {
                var driveStatus = Status.Healthy;
                ConsoleColoredString smartReport = "";
                bool any = false;
                foreach (var smart in drive.SmartReadings)
                {
                    var reportables = ReportRules.Where(ra => ra.AttributeId == smart.Id && (ra.MediaTypeFilter == null || ra.MediaTypeFilter.Count == 0 || ra.MediaTypeFilter.Contains(drive.MediaType))).ToList();
                    if (reportables.Count == 0)
                    {
                        continue;
                    }

                    any = true;
                    var statusCur = Status.Healthy;
                    var statusRaw = Status.Healthy;
                    foreach (var reportable in reportables)
                    {
                        if (smart.Worst <= smart.Threshold)
                        {
                            statusCur = statusCur.WorstStatus(reportable.Severity);
                        }
                        if (reportable.RawThreshold != null && smart.Raw >= reportable.RawThreshold)
                        {
                            statusRaw = statusCur.WorstStatus(reportable.Severity);
                        }
                    }
                    driveStatus = driveStatus.WorstStatus(statusCur).WorstStatus(statusRaw);
                    result.UpdateStatus(statusCur.WorstStatus(statusRaw));

                    var clrCur = statusCur.GetConsoleColor();
                    var clrRaw = reportables.All(r => r.RawThreshold == null) ? ConsoleColor.Gray : statusRaw.GetConsoleColor();
                    smartReport += $"    {smart.Id:X2}  {smart.Name.SubstringSafe(0, 30),-30}  :  " + smart.Raw.ToString().PadRight(8, ' ').Color(clrRaw) + $" (cur {smart.Current,3}, worst {smart.Worst,3}, thresh {smart.Threshold,3})\r\n".Color(clrCur);
                }

                result.ConsoleReport += drive.Model.Color(ConsoleColor.Cyan) + "   " + $"{drive.Size / 1_000_000_000.0:#,0} GB   ".Color(ConsoleColor.Magenta) + drive.MediaType.ToString().Color(ConsoleColor.White)
                                        + $"   s/n: {drive.SerialNumber}\r\n";
                result.ConsoleReport += "SMART prediction: " + (drive.SmartPredictFailure ? "FAILURE IMMINENT".Color(ConsoleColor.Red) : "Healthy".Color(ConsoleColor.Green)) + "\r\n";
                if (drive.SmartPredictFailure)
                {
                    result.UpdateStatus(Status.RedAlert);
                }
                if (any)
                {
                    result.ConsoleReport += "Our prediction: " + driveStatus.ToString().Color(driveStatus.GetConsoleColor()) + "\r\n\r\n";
                    result.ConsoleReport += smartReport;
                }
                else
                {
                    result.ConsoleReport += "\r\n    No relevant SMART attributes found for this drive.\r\n".Color(ConsoleColor.Yellow);
                    result.UpdateStatus(Status.Warning);
                }
                result.ConsoleReport += "\r\n\r\n";
            }

            return(result);
        }