Example #1
0
        public static IEnumerable <R> JoinSimilar <T, S, R>(this List <T> outer, List <S> inner,
                                                            Func <T, string> outerKeySelector,
                                                            Func <S, string> innerKeySelector,
                                                            Func <T, S, int, R> resultSelector)
            where T : notnull
            where S : notnull
        {
            StringDistance sd = new StringDistance();
            Dictionary <Tuple <T, S>, int> distances = (from o in outer
                                                        from i in inner
                                                        select KeyValuePair.Create(Tuple.Create(o, i),
                                                                                   sd.LevenshteinDistance(outerKeySelector(o), innerKeySelector(i)))).ToDictionary();

            while (distances.Count > 0)
            {
                var kvp   = distances.WithMin(a => a.Value);
                var tuple = kvp.Key;

                distances.RemoveRange(distances.Keys.Where(a => a.Item1.Equals(tuple.Item1) || a.Item2.Equals(tuple.Item2)).ToList());
                outer.Remove(tuple.Item1);
                inner.Remove(tuple.Item2);

                yield return(resultSelector(tuple.Item1, tuple.Item2, kvp.Value));
            }
        }
Example #2
0
        WithDescription <V>?TryGetValue(string input)
        {
            var exact = dictionary.TryGetC(input);

            if (exact != null)
            {
                return(exact);
            }

            var sd   = new StringDistance();
            var best = dictionary.Keys.WithMin(a => sd.LevenshteinDistance(input.ToLowerInvariant(), a.ToLowerInvariant()));

            if (sd.LevenshteinDistance(input.ToLowerInvariant(), best.ToLowerInvariant()) <= 2)
            {
                if (SafeConsole.Ask($"Did you mean '{best}'?"))
                {
                    return(dictionary.GetOrThrow(best));
                }
            }

            return(null);
        }
Example #3
0
        public DiffLogResult GetOperationDiffLog(string id)
        {
            var operationLog = Database.Retrieve<OperationLogEntity>(PrimaryKey.Parse(id, typeof(OperationLogEntity)));

            var logs = DiffLogLogic.OperationLogNextPrev(operationLog);
            
            StringDistance sd = new StringDistance();

            var prevFinal = logs.Min?.Mixin<DiffLogMixin>().FinalState;

            string nextInitial = logs.Max != null ? logs.Max.Mixin<DiffLogMixin>().InitialState :
                operationLog.Target.Exists() ? GetDump(operationLog.Target) : null;
            
            return new DiffLogResult
            {
                prev = logs.Min?.ToLite(),
                diffPrev = prevFinal == null ? null : sd.DiffText(prevFinal, operationLog.Mixin<DiffLogMixin>().InitialState),
                diff = sd.DiffText(operationLog.Mixin<DiffLogMixin>().InitialState, operationLog.Mixin<DiffLogMixin>().FinalState),
                diffNext = nextInitial == null ? null : sd.DiffText(operationLog.Mixin<DiffLogMixin>().FinalState, nextInitial),
                next = logs.Max?.ToLite(),
            };
        }
        public static T MostSimilar <T>(this IEnumerable <T> collection, Func <T, string> stringSelector, string pattern)
        {
            StringDistance sd = new StringDistance();

            return(collection.WithMin(item => sd.LevenshteinDistance(stringSelector(item), pattern)));
        }
        internal static SqlPreCommand SynchronizeWordTemplate(Replacements replacements, WordTemplateEntity template, StringDistance sd)
        {
            try
            {
                if (template.Template == null)
                    return null;

                var queryName = QueryLogic.ToQueryName(template.Query.Key);

                QueryDescription qd = DynamicQueryManager.Current.QueryDescription(queryName);

                Console.Clear();

                SafeConsole.WriteLineColor(ConsoleColor.White, "WordTemplate: " + template.Name);
                Console.WriteLine(" Query: " + template.Query.Key);

                var file = template.Template.Retrieve();

                try
                {
                    using (var memory = new MemoryStream())
                    {
                        memory.WriteAllBytes(file.BinaryFile);

                        using (WordprocessingDocument document = WordprocessingDocument.Open(memory, true))
                        {
                            Dump(document, "0.Original.txt");

                            var parser = new WordTemplateParser(document, qd, template.SystemWordTemplate.ToType());
                            parser.ParseDocument(); Dump(document, "1.Match.txt");
                            parser.CreateNodes(); Dump(document, "2.BaseNode.txt");
                            parser.AssertClean();

                            SyncronizationContext sc = new SyncronizationContext
                            {
                                ModelType = template.SystemWordTemplate.ToType(),
                                QueryDescription = qd,
                                Replacements = replacements,
                                StringDistance = sd,
                                HasChanges = false,
                                Variables = new ScopedDictionary<string, ValueProviderBase>(null),
                            };


                            foreach (var root in document.RecursivePartsRootElements())
                            {
                                foreach (var node in root.Descendants<BaseNode>().ToList())
                                {
                                    node.Synchronize(sc);
                                }
                            }

                            if (!sc.HasChanges)
                                return null;

                            Dump(document, "3.Synchronized.txt");
                            var variables = new ScopedDictionary<string, ValueProviderBase>(null);
                            foreach (var root in document.RecursivePartsRootElements())
                            {
                                foreach (var node in root.Descendants<BaseNode>().ToList())
                                {
                                    node.RenderTemplate(variables);
                                }
                            }

                            Dump(document, "4.Rendered.txt");
                        }

                        file.AllowChange = true;
                        file.BinaryFile = memory.ToArray();

                        using (replacements.WithReplacedDatabaseName())
                            return Schema.Current.Table<FileEntity>().UpdateSqlSync(file, comment: "WordTemplate: " + template.Name);
                    }                 
                }
                catch (TemplateSyncException ex)
                {
                    if (ex.Result == FixTokenResult.SkipEntity)
                        return null;

                    if (ex.Result == FixTokenResult.DeleteEntity)
                        return SqlPreCommandConcat.Combine(Spacing.Simple,
                            Schema.Current.Table<WordTemplateEntity>().DeleteSqlSync(template),
                            Schema.Current.Table<FileEntity>().DeleteSqlSync(file));

                    if (ex.Result == FixTokenResult.ReGenerateEntity)
                        return Regenerate(template, replacements);

                    throw new InvalidOperationException("Unexcpected {0}".FormatWith(ex.Result));
                }
                finally
                {
                    Console.Clear();
                }
            }
            catch (Exception e)
            {
                return new SqlPreCommandSimple("-- Exception in {0}: {1}".FormatWith(template.BaseToString(), e.Message));
            }
        }
        static SqlPreCommand Schema_Synchronize_Tokens(Replacements replacements)
        {
            if (AvoidSynchronize)
                return null;

            StringDistance sd = new StringDistance();

            var emailTemplates = Database.Query<WordTemplateEntity>().ToList();

            SqlPreCommand cmd = emailTemplates.Select(uq => SynchronizeWordTemplate(replacements, uq, sd)).Combine(Spacing.Double);

            return cmd;
        }
Example #7
0
        public List <DiffPair <List <DiffPair <string> > > > DiffText(string?textOld, string?textNew, bool lineEndingDifferences = true)
        {
            textOld = textOld ?? "";
            textNew = textNew ?? "";

            var linesOld = lineEndingDifferences ? textOld.Split('\n') : textOld.Lines();
            var linesNew = lineEndingDifferences ? textNew.Split('\n') : textNew.Lines();

            List <DiffPair <string> > diff = this.Diff(linesOld, linesNew);

            List <IGrouping <bool, DiffPair <string> > > groups = diff.GroupWhenChange(a => a.Action == DiffAction.Equal).ToList();

            StringDistance sd = new StringDistance();

            return(groups.SelectMany(g =>
            {
                if (g.Key)
                {
                    return g.Select(dp => new DiffPair <List <DiffPair <string> > >(DiffAction.Equal, new List <DiffPair <string> > {
                        dp
                    }));
                }

                var removed = g.Where(a => a.Action == DiffAction.Removed).Select(a => a.Value).ToArray();
                var added = g.Where(a => a.Action == DiffAction.Added).Select(a => a.Value).ToArray();

                var choices = this.LevenshteinChoices <string>(removed, added, weight: c =>
                {
                    if (c.Type == ChoiceType.Add)
                    {
                        return c.Added.Length;
                    }

                    if (c.Type == ChoiceType.Remove)
                    {
                        return c.Removed.Length;
                    }

                    var distance = sd.LevenshteinDistance(c.Added, c.Removed);

                    return distance * 2;
                });

                return choices.Select(c =>
                {
                    if (c.Type == ChoiceType.Add)
                    {
                        return new DiffPair <List <DiffPair <string> > >(DiffAction.Added, new List <DiffPair <string> > {
                            new DiffPair <string>(DiffAction.Added, c.Added)
                        });
                    }

                    if (c.Type == ChoiceType.Remove)
                    {
                        return new DiffPair <List <DiffPair <string> > >(DiffAction.Removed, new List <DiffPair <string> > {
                            new DiffPair <string>(DiffAction.Removed, c.Removed)
                        });
                    }

                    var diffWords = sd.DiffWords(c.Removed, c.Added);

                    return new DiffPair <List <DiffPair <string> > >(DiffAction.Equal, diffWords);
                });
            }).ToList());
        }
Example #8
0
        public static string GetDefaultModuleName(Type[] selected, string solutionName)
        {
            StringDistance sd = new StringDistance();

            string name = null;
            foreach (var item in selected)
            {
                if (name == null)
                    name = item.FullName.RemovePrefix(solutionName + ".Entities");
                else
                {
                    int startName, rubbish;
                    int length = sd.LongestCommonSubstring(name, item.FullName, out startName, out rubbish);

                    name = name.Substring(startName, length);

                    if (name.IsEmpty())
                        return null;
                }
            }

            return name.Trim('.');
        }
        internal static SqlPreCommand ProcessEmailTemplate( Replacements replacements, Table table, EmailTemplateEntity et, StringDistance sd)
        {
            try
            {
                var queryName = QueryLogic.ToQueryName(et.Query.Key);

                QueryDescription qd = DynamicQueryManager.Current.QueryDescription(queryName);

                Console.Clear();

                SafeConsole.WriteLineColor(ConsoleColor.White, "EmailTemplate: " + et.Name);
                Console.WriteLine(" Query: " + et.Query.Key);

                if (et.From != null && et.From.Token != null)
                {
                    QueryTokenEntity token = et.From.Token;
                    switch (QueryTokenSynchronizer.FixToken(replacements, ref token, qd, SubTokensOptions.CanElement, " From", allowRemoveToken: false, allowReCreate: et.SystemEmail != null))
                    {
                        case FixTokenResult.Nothing: break;
                        case FixTokenResult.DeleteEntity: return table.DeleteSqlSync(et);
                        case FixTokenResult.SkipEntity: return null;
                        case FixTokenResult.Fix: et.From.Token = token; break;
                        case FixTokenResult.ReGenerateEntity: return Regenerate(et, replacements, table);
                        default: break;
                    }
                }

                if (et.Recipients.Any(a=>a.Token != null))
                {
                    Console.WriteLine(" Recipients:");
                    foreach (var item in et.Recipients.Where(a => a.Token != null).ToList())
                    {
                        QueryTokenEntity token = item.Token;
                        switch (QueryTokenSynchronizer.FixToken(replacements, ref token, qd, SubTokensOptions.CanElement, " Recipient", allowRemoveToken: false, allowReCreate: et.SystemEmail != null))
                        {
                            case FixTokenResult.Nothing: break;
                            case FixTokenResult.DeleteEntity: return table.DeleteSqlSync(et);
                            case FixTokenResult.RemoveToken: et.Recipients.Remove(item); break;
                            case FixTokenResult.SkipEntity: return null;
                            case FixTokenResult.Fix: item.Token = token; break;
                            case FixTokenResult.ReGenerateEntity: return Regenerate(et, replacements, table);
                            default: break;
                        }
                    }
                }

                try
                {

                    foreach (var item in et.Messages)
                    {
                        SyncronizationContext sc = new SyncronizationContext
                        {
                            ModelType = et.SystemEmail.ToType(),
                            QueryDescription = qd,
                            Replacements = replacements,
                            StringDistance = sd,
                            Variables = new ScopedDictionary<string, ValueProviderBase>(null)
                        };

                        item.Subject = Synchronize(item.Subject, sc);
                        item.Text = Synchronize(item.Text, sc);
                    }

                    using (replacements.WithReplacedDatabaseName())
                        return table.UpdateSqlSync(et, includeCollections: true, comment: "EmailTemplate: " + et.Name);
                }
                catch (TemplateSyncException ex)
                {
                    if (ex.Result == FixTokenResult.SkipEntity)
                        return null;

                    if (ex.Result == FixTokenResult.DeleteEntity)
                        return table.DeleteSqlSync(et);

                    if (ex.Result == FixTokenResult.ReGenerateEntity)
                        return Regenerate(et, replacements, table);

                    throw new InvalidOperationException("Unexcpected {0}".FormatWith(ex.Result));
                }
                finally
                {
                    Console.Clear();
                }
            }
            catch (Exception e)
            {
                return new SqlPreCommandSimple("-- Exception in {0}: {1}".FormatWith(et.BaseToString(), e.Message));
            }
        }
        static string AskTypeReplacement(Replacements replacements, string type)
        {
            return replacements.GetOrCreate("cleanNames").GetOrCreate(type, () =>
            {
                if (Replacements.AutoReplacement != null)
                {
                    Replacements.Selection? sel = Replacements.AutoReplacement(type, null);

                    if (sel != null && sel.Value.NewValue != null)
                        return sel.Value.NewValue;
                }

                Console.WriteLine("Type {0} has been renamed?".FormatWith(type));

                int startingIndex = 0;
                StringDistance sd = new StringDistance();
                var list = TypeLogic.NameToType.Keys.OrderBy(t => sd.LevenshteinDistance(t, type)).ToList();
            retry:
                int maxElements = Console.LargestWindowHeight - 11;

                list.Skip(startingIndex).Take(maxElements)
                           .Select((s, i) => "- {1,2}: {2} ".FormatWith(i + startingIndex == 0 ? ">" : " ", i + startingIndex, s)).ToConsole();
                Console.WriteLine();
                SafeConsole.WriteLineColor(ConsoleColor.White, "- n: None");

                int remaining = list.Count - startingIndex - maxElements;
                if (remaining > 0)
                    SafeConsole.WriteLineColor(ConsoleColor.White, "- +: Show more values ({0} remaining)", remaining);

                while (true)
                {
                    string answer = Console.ReadLine();

                    if (answer == null)
                        throw new InvalidOperationException("Impossible to synchronize interactively without Console");

                    answer = answer.ToLower();

                    if (answer == "+" && remaining > 0)
                    {
                        startingIndex += maxElements;
                        goto retry;
                    }

                    if (answer == "n")
                        return null;

                    int option = 0;
                    if (int.TryParse(answer, out option))
                    {
                        return list[option];
                    }

                    Console.WriteLine("Error");
                }
            });
        }
        public static TextBlock Diff(string oldStr, string newStr)
        {
            StringDistance sd = new StringDistance();

            var dif = sd.DiffText(oldStr, newStr);

            TextBlock tb = new TextBlock { FontFamily = font };
            foreach (var line in dif)
            {
                if (line.Action == StringDistance.DiffAction.Removed)
                {
                    tb.Inlines.Add(DiffLine(line.Value, lightRed));
                }
                if (line.Action == StringDistance.DiffAction.Added)
                {
                    tb.Inlines.Add(DiffLine(line.Value, lightGreen));
                }
                else if (line.Action == StringDistance.DiffAction.Equal)
                {
                    if (line.Value.Count == 1)
                    {
                        tb.Inlines.Add(DiffLine(line.Value, null));
                    }
                    else
                    {
                        tb.Inlines.Add(DiffLine(line.Value.Where(a => a.Action == StringDistance.DiffAction.Removed || a.Action == StringDistance.DiffAction.Equal), lightRed));
                        tb.Inlines.Add(DiffLine(line.Value.Where(a => a.Action == StringDistance.DiffAction.Added || a.Action == StringDistance.DiffAction.Equal), lightGreen));
                    }
                }
            }

            return tb;
        }