Beispiel #1
0
        private static async Task Client_MessageUpdated(DiscordSocketClient client, Cacheable <IMessage, ulong> oldCache,
                                                        SocketMessage newMessage, ISocketMessageChannel channel)
        {
            if (newMessage.Author.IsBot)
            {
                return;
            }

            if (newMessage.Content == null)
            {
                return;
            }

            if (newMessage is IUserMessage userMessage)
            {
                var oldMessage = ToMessage(oldCache);

                var oldContent = oldMessage?.Content ?? string.Empty;
                var newContent = userMessage.Resolve();
                if (oldContent == newContent)
                {
                    return;
                }

                var diffMatchPatch = new diff_match_patch();
                var diffs          = diffMatchPatch.diff_main(oldContent, newContent);
                diffMatchPatch.diff_cleanupSemantic(diffs);

                var md = ToMarkdown(diffs);
                await PostEmbedAsync(client, "edited", new Color(0xF0E68C), userMessage.Author.Id, userMessage.Author,
                                     channel, md, oldMessage?.Attachment, userMessage.Id);
            }
        }
Beispiel #2
0
        private void button2_Click(object sender, EventArgs e)
        {
            Func f  = ef.FuncList[0];
            Func f1 = ef1.FuncList[0];


            diff_match_patch dfp      = new diff_match_patch();
            List <Diff>      dfresult = new List <Diff>();

            dfresult = dfp.diff_lineMode(f.BusinFlow.ToString(), f1.BusinFlow.ToString());
            //dfresult = dfp.diff_main("good well \r\ntest", "test well \r\ntest");
            foreach (Diff d in dfresult)
            {
                if (d.operation != Operation.EQUAL)
                {
                    rtbLog.AppendText(d.operation.ToString() + " " + d.text);
                }
            }


            //IDiffer df = new Differ();
            //DiffPlex.Model.DiffResult dfresult = df.CreateLineDiffs(f.BusinFlow.ToString(), f1.BusinFlow.ToString(), false);
            //DiffPlex.Model.d dfresult = df.CreateLineDiffs(f.BusinFlow.ToString(), f1.BusinFlow.ToString(), false);

            // 分析对比结果,怎么分析?
            // 以eques 为分界
            // 到下一个 equas 为止
            // 如何界定多少行
            //

            return;
        }
        public string GeneratePrettyHtmlDiff(string source, string target)
        {
            var dmp   = new diff_match_patch();
            var diffs = dmp.diff_main(source, target);

            return(dmp.diff_prettyHtml(diffs));
        }
        public Dictionary <LaboratoryWork, List <Similarity> > FindAndSaveSimilarities(LaboratoryWork laboratoryWork)
        {
            Dictionary <LaboratoryWork, List <Similarity> > laboratorySimilarities = new Dictionary <LaboratoryWork, List <Similarity> >();

            foreach (File sourceFile in laboratoryWork.Files)
            {
                var dmp = new diff_match_patch();
                foreach (LaboratoryWork anotherLaboratory in _context.LaboratoryWork.ToList())
                {
                    List <Similarity> similarities = new List <Similarity>();
                    foreach (File file in anotherLaboratory.Files)
                    {
                        var     diffs       = dmp.diff_main(file.Content, sourceFile.Content);
                        var     countEquals = CountEquals(diffs);
                        decimal similarity  = (countEquals / (decimal)Math.Max(sourceFile.Content.Length, file.Content.Length));
                        if (similarity >= (decimal)0.6)
                        {
                            Similarity s = new Similarity {
                                SimilarityToId = file.Id, Value = similarity, File = sourceFile
                            };
                            sourceFile.Similarities.Add(s);
                            similarities.Add(s);
                        }
                    }
                    if (!laboratorySimilarities.TryAdd(anotherLaboratory, similarities))
                    {
                        similarities.AddRange(laboratorySimilarities[anotherLaboratory]);
                        laboratorySimilarities[anotherLaboratory] = similarities;
                    }
                }
            }

            return(laboratorySimilarities);
        }
Beispiel #5
0
        /// <summary>
        /// Gets a list of the different words found under the "Different" operation.
        /// </summary>
        /// <param name="actual"></param>
        /// <param name="expected"></param>
        /// <returns></returns>
        private List <Diff> GetWrongWordsDifferentArray(string actual, string expected)
        {
            //Getting the original text string
            string originalText = expected;
            //Getting the ocr text string
            string           ocrText = actual;
            diff_match_patch diff_match_patchObject = new diff_match_patch();

            //Waits for comparison to finish without timeouts
            diff_match_patchObject.Diff_Timeout = 0;
            //Compares the original text of the txt file to the one produced by the OCR algorithm
            List <Diff> difference = diff_match_patchObject.diff_main(ocrText, originalText);

            //Deletes all the occurances that are the same so only the differences remain
            for (int i = 0; i < difference.Count; i++)
            {
                Diff diff = difference[i];
                difference[i].text = difference[i].text.Trim();
                if (diff.operation.Equals(Operation.EQUAL) || diff.text.Trim().Equals(""))
                {
                    difference.RemoveAt(i);
                }
            }
            return(difference);
        }
        protected override void ProcessRecord()
        {
            diff_match_patch dmp  = new diff_match_patch();
            List <Diff>      diff = dmp.diff_main(LeftText, RightText);

            dmp.diff_cleanupSemantic(diff);
            var output = new CompareTextDiff();

            output.Diff = diff;
            var psObj = new PSObject(output);

            if (_leftFile != null)
            {
                psObj.Properties.Add(new PSNoteProperty("LeftFile", _leftFile));
            }

            if (_rightFile != null)
            {
                psObj.Properties.Add(new PSNoteProperty("RightFile", _rightFile));
            }

            if (View == CompareTextView.SideBySide)
            {
                psObj.TypeNames.Insert(0, "Microsoft.PowerShell.TextUtility.CompareTextDiff#SideBySide");
            }

            WriteObject(psObj);
        }
Beispiel #7
0
        /// <summary>
        /// performs a google diff between stdin and the file identified by args[0] and outputs to stdout
        /// </summary>
        /// <param name="args"></param>
        private static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("modified file path argument is required");
            }

            diff_match_patch googleDiff = new diff_match_patch();

            // read stdin raw, including separators
            string source = ReadStdin();
            string target;

            using (StreamReader streamReader = new StreamReader(args[0], Encoding.UTF8))
            {
                target = streamReader.ReadToEnd();
            }

            // NOTE: do our own diffs so we just do semantic cleanup. We don't want to optimize for efficiency.
            List <Diff> diffs;

            if (args.Length > 1 && args[1] == "--reverse")
            {
                diffs = googleDiff.diff_main(target, source);
            }
            else
            {
                diffs = googleDiff.diff_main(source, target);
            }

            googleDiff.diff_cleanupSemantic(diffs);
            List <Patch> patches = googleDiff.patch_make(diffs);

            Console.Write(googleDiff.patch_toText(patches));
        }
Beispiel #8
0
        private static void ComparePDF(string source_file1, string source_file2, string destination_file)
        {
            //convert source files to plain text
            string source_file1_text = PDF2String(source_file1);
            string source_file2_text = PDF2String(source_file2);

            //backup
            if (source_file1_text == "")
            {
                source_file1_text = "This is a dog. Hint: your PDF file source 1 was not converted into text.....";
            }

            if (source_file2_text == "")
            {
                source_file2_text = "This is a cat. Hint: your PDF file source 2 was not converted into text.....";
            }

            //set up compare objects and perform compare
            diff_match_patch dmp  = new diff_match_patch();
            List <Diff>      diff = dmp.diff_main(source_file1_text, source_file2_text);

            //convert compare to HTML and output this file (saving) as HMTL file
            string _HTMLString = dmp.diff_prettyHtml(diff);

            _HTMLString = CleanUpHTMLstring(_HTMLString);



            ////write HTML file to disk
            //WriteHTMLFile(_HTMLString);

            WriteHTMLtoPDF(_HTMLString, destination_file);
        }
 public void Ensure_We_Can_Construct_A_Basic_Revision()
 {
     var previousRevision = new TestRevision("Test");
     var patches = new diff_match_patch().patch_make("Test", "Test2");
     var revison = new BasicRevision(previousRevision, patches);
     Assert.That(revison != null);
 }
Beispiel #10
0
        public List <string> Post([FromBody] JobModel jobList)//MAPPING CH PROBLEM
        {
            List <Diff>      diff   = new List <Diff>();
            List <string>    result = new List <string>();
            diff_match_patch dmp    = new diff_match_patch();

            string title    = jobList.JobClass[0].title;
            string newTitle = jobList.JobClass[1].title;

            string oldDescription = jobList.JobClass[0].description;
            string newDescription = jobList.JobClass[1].description;


            diff = dmp.diff_main(title, newTitle);
            dmp.diff_cleanupSemantic(diff);



            for (int j = 0; j < diff.Count; j++)
            {
                result.Add(diff[j].ToString());
            }

            //Compare description
            diff = dmp.diff_main(oldDescription, newDescription);
            dmp.diff_cleanupSemantic(diff);
            for (int j = 0; j < diff.Count; j++)
            {
                result.Add(diff[j].ToString());
            }

            return(result);
        }
Beispiel #11
0
        /// <summary>
        /// View a specific Content Version
        /// </summary>
        /// <returns></returns>
        public ActionResult Version(int? contentId)
        {
            var version = _entities.ContentVersions.FirstOrDefault(v => v.Id == contentId);

            if (version == null)
            {
                return RedirectToRoute("ContentIndex");
            }

            var previousVersion = _entities.ContentVersions
                .Where(v => v.Version < version.Version && v.ContentId == version.ContentId)
                .OrderByDescending(v => v.Version)
                .FirstOrDefault();

            var model = new ContentVersionViewModel
            {
                CurrentVersion = version,
                PreviousVersion = previousVersion
            };

            if (previousVersion != null)
            {
                var dmp = new diff_match_patch();
                var diffsContent = dmp.diff_main(previousVersion.UnparsedContent, version.UnparsedContent);
                var diffsStylesheet = dmp.diff_main(previousVersion.StylesheetCode, version.StylesheetCode);

                model.ContentDiff = dmp.diff_prettyHtml(diffsContent);
                model.StylesheetDiff = dmp.diff_prettyHtml(diffsStylesheet);
            }

            return View("~/Areas/mitarbeit/Views/Content/Version.cshtml", model);
        }
Beispiel #12
0
        /// <summary>
        /// Converts output from a command-line diff tool into LSP compatible text edits.
        /// </summary>
        public static TextEdit[] GetEdits(string documentText, string diffOutputText)
        {
            if (documentText == null)
            {
                throw new ArgumentNullException(nameof(documentText));
            }

            if (diffOutputText == null)
            {
                throw new ArgumentNullException(nameof(diffOutputText));
            }

            // Diff tools may print a header with the original/modified file names
            // and that header must be removed for diff_match_patch.
            if (diffOutputText.StartsWithOrdinal("---"))
            {
                var startIndex = diffOutputText.IndexOfOrdinal("@@");
                if (startIndex >= 0)
                {
                    diffOutputText = diffOutputText.Substring(startIndex);
                }

                // TODO: needed?
                // Remove the text added by unified_diff
                // # Work around missing newline (http://bugs.python.org/issue2142).
                //patch = patch.replace(/\\ No newline at end of file[\r\n] /, '');
            }

            var patches = new diff_match_patch().patch_fromText(diffOutputText);

            var edits = patches.SelectMany(p => GetEdits(documentText, p));

            return(edits.ToArray());
        }
Beispiel #13
0
        public static void Main()
        {
            var dmp = new diff_match_patch();

            while (true)
            {
                Console.Clear();
                Console.WriteLine("Enter 2 texts seperated by enter");
                var input1 = Console.ReadLine().Trim().Replace(" ", "");

                var input2 = Console.ReadLine().Trim().Replace(" ", "");
                var diff   = dmp.diff_main(input1, input2);
                var result = dmp.diff_levenshtein(diff);

                Console.WriteLine("Result = " + result);
                double similarity = 100 - ((double)result / Math.Max(input1.Length, input2.Length) * 100);
                Console.WriteLine("Similarity = " + similarity);

                Console.WriteLine("Insert 'q' and then press enter to exit");
                var input3 = Console.ReadLine().Trim().Replace(" ", "");

                if (input3 == "q")
                {
                    break;
                }
            }
        }
Beispiel #14
0
        public void StringDiffMatchPatch_Examples()
        {
            var originalText = "Hi, im a very long text";
            var editedText_1 = "Hi, i'm a very long text!";
            var editedText_2 = "Hi, im not such a long text";
            var expectedText = "Hi, i'm not such a long text!";

            var merge = MergeText.Merge(originalText, editedText_1, editedText_2);

            Assert.Equal(expectedText, merge.mergeResult);
            foreach (var patch in merge.patches)
            {
                Assert.True(patch.Value);
            }                                                                  // All patches were successful

            // diff_match_patch can also provide a detailed difference analysis:
            diff_match_patch dmp  = new diff_match_patch();
            List <Diff>      diff = dmp.diff_main(originalText, editedText_1);

            // The first section until the ' was unchanged:
            Assert.Equal("Hi, i", diff.First().text);
            Assert.Equal(Operation.EQUAL, diff.First().operation);
            // The last change was the insert of a !:
            Assert.Equal("!", diff.Last().text);
            Assert.Equal(Operation.INSERT, diff.Last().operation);
        }
Beispiel #15
0
        private void GetSummary()
        {
            _sheetDifferences.Clear();
            for (int i = 0; i < leftWorkbook.sheetNames.Count; i++)
            {
                string sheetName = leftWorkbook.sheetNames[i];
                if (rightWorkbook.sheetNames.Contains(sheetName))
                {
                    ExcelSheet leftExcelSheet  = leftWorkbook.LoadSheet(sheetName);
                    ExcelSheet rightExcelSheet = rightWorkbook.LoadSheet(sheetName);
                    int        columnCount     = Math.Max(leftExcelSheet.columnCount, rightExcelSheet.columnCount);
                    VSheet     leftSheet       = new VSheet(leftExcelSheet, columnCount);
                    VSheet     rightSheet      = new VSheet(rightExcelSheet, columnCount);

                    diff_match_patch comparer     = new diff_match_patch();
                    string           leftContent  = leftSheet.GetContent();
                    string           rightContent = rightSheet.GetContent();
                    List <Diff>      diffs        = comparer.diff_main(leftContent, rightContent, true);
                    comparer.diff_cleanupSemanticLossless(diffs);

                    bool isDifferent = false;
                    for (int diffIndex = 0; diffIndex < diffs.Count; diffIndex++)
                    {
                        if (diffs[diffIndex].operation != Operation.EQUAL)
                        {
                            isDifferent = true;
                            break;
                        }
                    }

                    _sheetDifferences.Add(sheetName, isDifferent);
                }
            }
        }
        protected override void Convert(PropertyInfo property, object newValue, object oldValue)
        {
            if (oldValue == null)
            {
                OldValue = "";
            }
            else
            {
                OldValue = AsString(property, oldValue);
            }

            if (newValue == null)
            {
                NewValue = "";
            }
            else
            {
                NewValue = AsString(property, newValue);
            }

            var diff   = new diff_match_patch();
            var diffs  = diff.diff_main(OldValue, NewValue);
            var asHtml = diffs.Select(ToHtml).ToArray();

            Message = $"$$$Изменено '{Name}'<br><div>{String.Join("", asHtml)}</div>";
        }
Beispiel #17
0
        private void getDiffInfo(FileHistoryDTO fileHistory, string newContent, string oldContent)
        {
            var dmp  = new diff_match_patch();
            var diff = dmp.diff_main(newContent, oldContent);

            dmp.diff_cleanupSemantic(diff);
            dmp.diff_prettyHtml(diff);

            var htmlContent    = new StringBuilder("");
            var linesIncreased = 0;
            var linesDecreased = 0;

            for (int i = 0; i < diff.Count; i++)
            {
                htmlContent.Append(diff[i]);
                if (diff[i].operation == Operation.DELETE)
                {
                    linesDecreased++;
                }
                if (diff[i].operation == Operation.INSERT)
                {
                    linesIncreased++;
                }
            }
            fileHistory.ContentDiffHtml = htmlContent.ToString();
            fileHistory.LinesDecreased  = linesDecreased;
            fileHistory.LinesIncreased  = linesIncreased;
            fileHistory.SizeDiff        = newContent.Length - oldContent.Length;
        }
Beispiel #18
0
    private void Awake()
    {
        diff_match_patch dmp    = new diff_match_patch();
        List <Patch>     patchs = dmp.patch_make("The cow is in the road", "The chicken is crossing the road");

        Debug.Log("Patch: " + patchs[0].ToString());
    }
 public void Ensure_When_We_Construct_A_Revision_It_Contains_A_Reference_To_The_Previous_Revision()
 {
     var previousRevision = new TestRevision("Test");
     var patches = new diff_match_patch().patch_make("Test", "Test2");
     var revison = new BasicRevision(previousRevision, patches);
     Assert.That(revison.PreviousRevisionAppliedTo != null);
 }
Beispiel #20
0
    void TestDiffMatchPatch()
    {
        var s1 = @"//.
using Au; using Au.Types; using System; using System.Collections.Generic;
class Script : AScript { [STAThread] static void Main(string[] a) => new Script(a); Script(string[] args) { //;;;
	
	var s=""one"";
";
        var s2 = @"/*/ role exeProgram;		outputPath %AFolders.Workspace%\bin; console true; /*/ //.
using Au; using Au.Types; using System; using System.Collections.Generic;
using My.NS1; //ąčę îôû
using My.NS2;
class Script : AScript { [STAThread] static void Main(string[] a) => new Script(a); Script(string[] args) { //;;;
	var i=2;
";

        var         dmp  = new diff_match_patch();
        List <Diff> diff = dmp.diff_main(s1, s2, true);

        dmp.diff_cleanupSemantic(diff);
        var delta = dmp.diff_toDelta(diff);

        AOutput.Write(delta);
        AOutput.Write("----");
        var d2 = dmp.diff_fromDelta(s1, delta);

        //AOutput.Write(d2);
        AOutput.Write(dmp.diff_text2(d2));
    }
Beispiel #21
0
 public FileService()
 {
     this.shadowCopy = new Dictionary <string, string>();
     this.ai         = new diff_match_patch();
     patchList       = new List <Patcher>();
     this.mainCopy   = "[]";
 }
Beispiel #22
0
        private void cmdCompare_Click(object sender, RoutedEventArgs e)
        {
            List <DiffColor> diffColors = new List <DiffColor>();

            diff_match_patch comparer = new diff_match_patch();
            var result = comparer.diff_main(textEditorA.Text, textEditorB.Text);

            txtResult.Document.Text = "";
            foreach (var diff in result)
            {
                if (diff.operation == Operation.INSERT)
                {
                    diffColors.Add(new DiffColor()
                    {
                        Color = Brushes.Green, StartOffset = txtResult.Document.Text.Length, EndOffset = txtResult.Document.Text.Length + diff.text.Length
                    });
                }
                else if (diff.operation == Operation.DELETE)
                {
                    diffColors.Add(new DiffColor()
                    {
                        Color = Brushes.Red, StartOffset = txtResult.Document.Text.Length, EndOffset = txtResult.Document.Text.Length + diff.text.Length
                    });
                }
                txtResult.Document.Text += diff.text;
            }
            //txtResult.TextArea.TextView.LineTransformers.Clear();
            txtResult.TextArea.TextView.LineTransformers.Add(new DiffColorizer(diffColors));
        }
Beispiel #23
0
 private static void Diff()
 {
     //var res = DiffUtiles.DiffText("abcbasdf sdfasdfasd", "abcdcb", true, true, false);
     var d    = new diff_match_patch();
     var res  = d.diff_main("abcabxyz bbb", "abcabxyz a bbb");
     var res2 = d.diff_prettyHtml(res);
 }
 public void Ensure_When_We_Construct_A_Revision_We_Can_Retrieve_The_Current_Document_Content_From_The_Revision_Object()
 {
     var previousRevision = new TestRevision("Test");
     var patches = new diff_match_patch().patch_make("Test", "Test2");
     var revison = new BasicRevision(previousRevision, patches);
     Assert.That(revison.GenerateEditedContent() != null);
 }
Beispiel #25
0
        public void UpdateRequestServer_ExistingIsXA1UpdateRequestXB1_PatchXA1B1()
        {
            const string memberIdA        = "1";
            const string memberIdB        = "2";
            const string documentId       = "MyDoc";
            const string initialContent   = "test";
            const string contentA1        = "tests";
            const string contentB1        = "testi";
            const string resultingContent = "testsi";
            const string owner            = "max";
            const string host             = "http://localhost:9000";
            SHA1         sha1             = new SHA1CryptoServiceProvider();

            byte[] hash          = sha1.ComputeHash(Encoding.UTF8.GetBytes(initialContent));
            var    diffMatchPath = new diff_match_patch();
            var    editor        = MockRepository.GenerateStub <SharedTextEditor>();

            editor.Stub(x => x.GetText(documentId)).Return(initialContent).Repeat.Once();
            editor.Stub(x => x.GetText(documentId)).Return(contentA1).Repeat.Once();
            var communication = MockRepository.GenerateStub <IClientServerCommunication>();

            //act
            var logic = new SharedTextEditorPatchingLogic(owner, host, editor, communication);

            editor.Raise(x => x.FindDocumentRequest += null, editor, documentId);
            logic.OpenDocument(new DocumentDto
            {
                DocumentId = documentId,
                Content    = initialContent,
                Owner      = owner,
                OwnerHost  = host,
                RevisionId = 1
            });

            logic.UpdateRequest(new UpdateDto
            {
                DocumentId         = documentId,
                MemberName         = memberIdA,
                PreviousRevisionId = 1,
                PreviousHash       = hash,
                Patch = diffMatchPath.patch_make(initialContent, contentA1)
            });

            logic.UpdateRequest(new UpdateDto
            {
                DocumentId         = documentId,
                MemberName         = memberIdB,
                PreviousRevisionId = 1,
                PreviousHash       = hash,
                Patch = diffMatchPath.patch_make(initialContent, contentB1)
            });


            //assert
            var args = editor.GetArgumentsForCallsMadeOn(x => x.UpdateText(null, null), x => x.IgnoreArguments());

            Assert.That(args[0][1], Is.EqualTo(initialContent));
            Assert.That(args[1][1], Is.EqualTo(contentA1));
            Assert.That(args[2][1], Is.EqualTo(resultingContent));
        }
Beispiel #26
0
        private void cmdCompare_Click(object sender, RoutedEventArgs e)
        {
            txtResult.TextArea.TextView.LineTransformers.Clear();

            var txt = "";
            diff_match_patch comparer = new diff_match_patch();
            var result = comparer.diff_main(textEditorA.Text, textEditorB.Text);

            txtResult.Document.Text = "";
            foreach (var diff in result)
            {
                if (diff.operation == Operation.INSERT)
                {
                    var st = txt.Length;
                    txt += diff.text;
                    var stp = txt.Length;

                    txtResult.TextArea.TextView.LineTransformers.Add(new TextColorizer(st, stp, Brushes.Green));
                }
                else if (diff.operation == Operation.DELETE)
                {
                    var st = txt.Length;
                    txt += diff.text;
                    var stp = txt.Length;

                    txtResult.TextArea.TextView.LineTransformers.Add(new TextColorizer(st, stp, Brushes.Red));
                }
                else
                {
                    txt += diff.text;
                }
            }
            txtResult.Document.Text = txt;
        }
Beispiel #27
0
        public DiffView(string LocalOld, string LocalNew)
        {
            InitializeComponent();

            HandleTheme(newContent);
            HandleTheme(oldContent);

            this.Text = "Diff " + Path.GetFileNameWithoutExtension(LocalNew) + " -> " + Path.GetFileNameWithoutExtension(LocalOld);

            var dmp   = new diff_match_patch();
            var diffs = dmp.diff_main(File.ReadAllText(LocalNew), File.ReadAllText(LocalOld), false);

            foreach (Diff aDiff in diffs)
            {
                switch (aDiff.operation)
                {
                case Operation.INSERT:
                    AppendText(newContent, aDiff.text, Color.Green);
                    break;

                case Operation.DELETE:
                    AppendText(oldContent, aDiff.text, Color.Red);
                    break;

                case Operation.EQUAL:
                    AppendText(oldContent, aDiff.text, textColor);
                    AppendText(newContent, aDiff.text, textColor);
                    break;
                }
            }

            oldContent.SelectionStart = 0;
            newContent.SelectionStart = 0;
        }
Beispiel #28
0
        public DMPCWMTHelper()
        {
            _diff      = new diff_match_patch();
            _htmlTags  = new Dictionary <string, char>();
            _finalDict = new Dictionary <char, string>();

            _unicodeIndex = 0xE000;
            _inOpenBlock  = false;
            _insTagList   = new List <Tuple <char, char> >();
            _delTagList   = new List <Tuple <char, char> >();
            _equalTagList = new List <Tuple <char, char> >();

            _insertTuple    = new Tuple <Operation, string>(Operation.INSERT, null);
            _deleteTuple    = new Tuple <Operation, string>(Operation.DELETE, null);
            _equalTuple     = new Tuple <Operation, string>(Operation.EQUAL, null);
            _stringComparer = StringComparer.InvariantCulture;
            _stringBuilder  = new StringBuilder();

            isBlockOpener = (x) => _stringComparer.Equals(x, "p") || _stringComparer.Equals(x, "ul") || _stringComparer.Equals(x, "ol") ||
                            _stringComparer.Equals(x, "h1") || _stringComparer.Equals(x, "h2") || _stringComparer.Equals(x, "h3") ||
                            _stringComparer.Equals(x, "h4") || _stringComparer.Equals(x, "h5") || _stringComparer.Equals(x, "h6") ||
                            _stringComparer.Equals(x, "address") || _stringComparer.Equals(x, "pre");
            isBlockCloser = (x) => _stringComparer.Equals(x, "/p") || _stringComparer.Equals(x, "/ul") || _stringComparer.Equals(x, "/ol") ||
                            _stringComparer.Equals(x, "/h1") || _stringComparer.Equals(x, "/h2") || _stringComparer.Equals(x, "/h3") ||
                            _stringComparer.Equals(x, "/h4") || _stringComparer.Equals(x, "/h5") || _stringComparer.Equals(x, "/h6") ||
                            _stringComparer.Equals(x, "/address") || _stringComparer.Equals(x, "/pre");
            firstInUnicodeRange = (x) => x >= 0xE000;
            isOpenTag           = (x) => !x[1].Equals('/');
        }
Beispiel #29
0
        private static string ApplyPatches(diff_match_patch googleDiff, string testInput, List <Patch> patches)
        {
            object[] results = googleDiff.patch_apply(patches, testInput, out List <Patch> effectivePatches);
            string   patched = (string)results[0];

            bool[] applied = (bool[])results[1];
            diff_match_patch.PatchResult[] resultCodes = (diff_match_patch.PatchResult[])results[2];
            for (int i = 0; i < applied.Length; i++)
            {
                if (!applied[i])
                {
                    throw new Exception($"failed to apply {effectivePatches[i]}: {resultCodes[i]}");
                }

                switch (resultCodes[i])
                {
                case diff_match_patch.PatchResult.UNKNOWN:
                    throw new Exception($"invalid result code from application of {effectivePatches[i]}");

                case diff_match_patch.PatchResult.APPLIED_PERFECT:
                    break;

                case diff_match_patch.PatchResult.APPLIED_IMPERFECT:
                    Debug.WriteLine("WARNING: patch imperfectly matched input, but was applied");
                    break;

                default:
                    throw new Exception(
                              $"patch should not have returned success with result code {resultCodes[i]}");
                }
            }

            return(patched);
        }
Beispiel #30
0
        private void button1_Click(object sender, EventArgs e)
        {
            // Get inputLeft and inputRight
            string left  = inputLeft.Text;
            string right = inputRight.Text;

            // store differences in the displaytext, and line number
            string diffs = "";

            //            for (int line = 1; line <= left.Length; line++) {

            //            }

            diff_match_patch dmp = new diff_match_patch();

            List <Diff> diff = dmp.diff_main(left, right);

            dmp.diff_cleanupSemantic(diff);


            for (int i = 0; i < diff.Count; i++)
            {
                Console.WriteLine(diff[i]);
                diffs = diffs + diff[i] + Environment.NewLine;
            }



            // display in display box
            resultText.Text = diffs;
            Console.Read();
        }
Beispiel #31
0
        /// <summary>
        /// Compares two files to see its difference
        /// </summary>
        /// <param name="dmp">The diff match path utility</param>
        /// <param name="projectFilePath">The project copy file path</param>
        /// <param name="serverFilePath">The server copy file path</param>
        /// <returns>The file differences</returns>
        public static List <Diff> CompareFiles(this diff_match_patch dmp, String projectFilePath, String serverFilePath)
        {
            String projectFile = String.Join("\r\n", File.ReadAllLines(projectFilePath)),
                   serverFile  = String.Join("\r\n", File.ReadAllLines(serverFilePath));

            return(dmp.diff_main(serverFile, projectFile));
        }
        private static List <Diff> GetMinimalDifferences(List <string> list1, List <string> list2)
        {
            diff_match_patch match = new diff_match_patch
            {
                Diff_Timeout = ContentComparerHelper.Diff_Timeout
            };
            //match.Patch_Margin

            int         minDiff  = int.MaxValue;
            List <Diff> selected = null;

            foreach (string str1 in list1)
            {
                foreach (string str2 in list2)
                {
                    List <Diff> diff = match.diff_main(str1, str2, false);

                    IEnumerable <Diff> changes = diff.Where(d => d.operation != Operation.EQUAL);

                    int changesLength = changes.Any() ? changes.Sum(d => d.text.Length) : 0;

                    if (changesLength < minDiff)
                    {
                        minDiff  = changesLength;
                        selected = diff;
                    }
                }
            }

            return(selected);
        }
Beispiel #33
0
 private static void CheckApplied(diff_match_patch googleDiff, string testFilePath, List <Patch> patches,
                                  string patched)
 {
     // check if applied by just seeing if all the inserts are present (we don't generate patches that insert and then delete the same thing)
     foreach (Patch patch in patches)
     {
         foreach (Diff chunk in patch.diffs)
         {
             if (chunk.operation == Operation.INSERT)
             {
                 if (!patched.Contains(chunk.text))
                 {
                     Debug.WriteLine(
                         "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
                     Debug.WriteLine(googleDiff.patch_toText(patches));
                     Debug.WriteLine(
                         "--------------------------------------------------------------------------------------");
                     Debug.WriteLine("missing text expected in patch result:");
                     Debug.WriteLine(chunk.text);
                     throw new Exception($"failed test case {testFilePath}");
                 }
             }
         }
     }
 }
Beispiel #34
0
 public void Edit(JObject editData)
 {
     var reader = new JsonSerializer();
     var jsonPatches = editData["Content"]["Patches"];
     var patches = jsonPatches.Select(p=> reader.Deserialize<Patch>(new JTokenReader(p))).ToList();
     var patcher = new diff_match_patch();
     _content = patcher.patch_apply(patches.ToList(), Content)[0] as string;
 }
 public void Ensure_When_We_Construct_A_Revision_And_Retreive_The_Current_Document_That_It_Contains_Changes_From_The_Latest_Revision()
 {
     var previousRevision = new TestRevision("Test");
     var patches = new diff_match_patch().patch_make("Test", "Test2");
     var revison = new BasicRevision(previousRevision,patches);
     var content = revison.GenerateEditedContent();
     Assert.That(content, Is.EqualTo("Test2"));
 }
Beispiel #36
0
        public void cargarDiff(byte[] a, byte[] b)
        {
            string TextoA = System.Text.Encoding.Default.GetString(a);
            string TextoB = System.Text.Encoding.Default.GetString(b);

            diff_match_patch dmp = new diff_match_patch();

            wbDiffViewer.DocumentText = dmp.diff_prettyHtml(dmp.diff_main(TextoA, TextoB));
        }
        public string GenerateEditedContent()
        {
            if(RevisionsConflict && RevisionChosenForResolution == null)
                throw  new ConflictException(_patchResult);

            if (RevisionChosenForResolution != null)
                return RevisionChosenForResolution.GenerateEditedContent();

            var dmp = new diff_match_patch { Match_Distance = 200, Match_Threshold = 0.2f };

            var patches = dmp.patch_make(PreviousRevisionAppliedTo.GenerateEditedContent(), RevisionsToMerge.ElementAt(0).GenerateEditedContent());

            var patchResult = dmp.patch_apply(patches, RevisionsToMerge.ElementAt(1).GenerateEditedContent());

            return patchResult[0] as string;
        }
        private static void updateContent(VisualDiffTextBlock textBlock)
        {
            textBlock.Inlines.Clear();

            if (textBlock.IsVisualDiffVisible)
            {
                var brushConverter = new BrushConverter();
                diff_match_patch dmp = new diff_match_patch();
                List<Diff> diffList = dmp.diff_main(
                    textBlock.PreviousText.Replace("\n", "\u00b6").Replace("\r", "").Replace(' ', '\u00B7'),
                    textBlock.CurrentText.Replace("\n", "\u00b6").Replace("\r", "").Replace(' ', '\u00B7'),
                    false);

                // Apply a clean up, the default value of this function is 4 chars.
                // To change the value, you'll need to do so inside the DiffMatchPatch.cs file.
                dmp.diff_cleanupEfficiency(diffList);

                foreach(Diff diffItem in diffList)
                {
                    switch(diffItem.operation)
                    {
                        case Operation.DELETE:
                            textBlock.Inlines.Add(new Run(diffItem.text) { Background = (Brush)brushConverter.ConvertFromString("#ff6a1010"), Foreground = (Brush)brushConverter.ConvertFromString("#ffdddddd"), TextDecorations = System.Windows.TextDecorations.Strikethrough });
                            break;
                        case Operation.EQUAL:
                            textBlock.Inlines.Add(new Run(diffItem.text.Replace("\u00b6", "\u00b6" + System.Environment.NewLine)));
                            break;
                        case Operation.INSERT:
                            textBlock.Inlines.Add(new Run(diffItem.text.Replace("\u00b6", "\u00b6" + System.Environment.NewLine)) { Background = (Brush)brushConverter.ConvertFromString("#ff005e41"), Foreground = (Brush)brushConverter.ConvertFromString("#ffdddddd") });
                            break;
                    }
                }
            }
            else
            {
                textBlock.Text = textBlock.CurrentText;
            }
        }
        // GET: Topics/ViewHistory/5
        /// <summary>
        /// Zeigt die Änderungen, die an dem Thema vorgenommen wurden.
        /// </summary>
        /// <param name="id">Die TopicID</param>
        public ActionResult ViewHistory(int id)
        {
            Topic topic = db.Topics.Find(id);
            var history = db.TopicHistory.Where(th => th.TopicID == topic.ID).OrderBy(th => th.ValidFrom).ToList();

            if (history.Count == 0)
                return RedirectToAction("Details", new {id});

            history.Add(TopicHistory.FromTopic(topic, 0));

            var vm = new TopicHistoryViewModel
            {
                Usernames = db.Users.Where(u => u.IsActive).ToDictionary(u => u.ID, u => u.ShortName),
                SessionTypes = db.SessionTypes.ToDictionary(s => s.ID, s => s.Name),
                Current = topic,
                Initial = history[0]
            };

            var diff = new diff_match_patch
            {
                Diff_Timeout = 0.4f
            };

            // Anonyme Funktion, um die Biliothek diff_match_patch handlich zu verpacken.
            Func<string, string, List<Diff>> textDiff = (a, b) =>
            {
                var list = diff.diff_main(a, b);
                diff.diff_cleanupSemantic(list);
                return list;
            };

            foreach (var p in history.Pairwise())
            {
                vm.Differences.Add(new TopicHistoryDiff
                {
                    // Ein Eintrag entspricht später einer Box auf der Seite. Wenn keine Änderung existiert, sollte hier null gespeichert werden. Bei einer Änderung wird der NEUE Wert (der in Item2 enthalten ist) genommen.
                    // SimpleDiff ist eine kleine Helferfunktion, da die Zeilen sonst arg lang werden würden. Hier wird kein Text vergleichen - entweder hat sich alles geändert, oder gar nichts. (Daher "simple")
                    // textDiff ist komplexer, hier wird der Text analysiert und auf ähnliche Abschnitte hin untersucht.
                    Modified = p.Item1.ValidUntil,
                    Editor = vm.Usernames[p.Item1.EditorID],
                    SessionType = SimpleDiff(p.Item1.SessionTypeID, p.Item2.SessionTypeID, vm.SessionTypes),
                    TargetSessionType = SimpleDiff(p.Item1.TargetSessionTypeID, p.Item2.TargetSessionTypeID, vm.SessionTypes, "(kein)"),
                    Owner = SimpleDiff(p.Item1.OwnerID, p.Item2.OwnerID, vm.Usernames),
                    Priority = p.Item1.Priority == p.Item2.Priority ? null : p.Item2.Priority.DisplayName(),
                    Title = textDiff(p.Item1.Title, p.Item2.Title),
                    Time = p.Item1.Time == p.Item2.Time ? null : p.Item2.Time,
                    Description = textDiff(p.Item1.Description, p.Item2.Description),
                    Proposal = textDiff(p.Item1.Proposal, p.Item2.Proposal)
                });
            }

            return View(vm);
        }
Beispiel #40
0
        /// <summary>
        /// Checks the application to see if there are updates.
        /// </summary>
        public bool Check()
        {
            diff_match_patch dmf = new diff_match_patch();
            WebClient client = new WebClient();
            string state = client.DownloadString(this.m_UpdateUri + "/initial");
            string[] lines = state.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
            int opers = 0;
            foreach (string line in lines)
            {
                Hash hash = Hash.FromString(line.Split(new char[] { ' ' }, 2)[0]);
                string file = line.Split(new char[] { ' ' }, 2)[1];

                // See if file already exists.
                if (File.Exists(Path.Combine(this.m_LocalPath, file)) || hash == Hash.Empty)
                {
                    if (hash == Hash.Empty)
                    {
                        // File needs to be deleted.
                        if (File.Exists(Path.Combine(this.m_LocalPath, file)))
                            opers++;
                    }
                    else
                    {
                        // Compare hashes, ignore if same.
                        Hash current = Hash.FromFile(Path.Combine(this.m_LocalPath, file));
                        if (current == hash)
                            continue;

                        // File needs to be patched.
                        opers++;
                    }
                }
                else
                {
                    // File needs to be downloaded.
                    opers++;
                }
            }

            return opers > 0;
        }
Beispiel #41
0
        /// <summary>
        /// Updates the application.
        /// </summary>
        public void Update(Action<UpdateStatus, object> callback)
        {
            callback(UpdateStatus.Starting, null);
            diff_match_patch dmf = new diff_match_patch();
            WebClient client = new WebClient();
            callback(UpdateStatus.RetrievingFileList, null);
            string state = client.DownloadString(this.m_UpdateUri + "/initial");
            string[] lines = state.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
            callback(UpdateStatus.RetrievedFileList, lines.Length);
            int opers = 0;
            foreach (string line in lines)
            {
                Hash hash = Hash.FromString(line.Split(new char[] { ' ' }, 2)[0]);
                string file = line.Split(new char[] { ' ' }, 2)[1];
                callback(UpdateStatus.DeterminingOperation, file);

                // See if file already exists.
                if (File.Exists(Path.Combine(this.m_LocalPath, file)) || hash == Hash.Empty)
                {
                    if (hash == Hash.Empty)
                    {
                        // Delete the local file if it exists.
                        if (File.Exists(Path.Combine(this.m_LocalPath, file)))
                        {
                            callback(UpdateStatus.DeletionStart, file);
                            File.Delete(Path.Combine(this.m_LocalPath, file));
                            callback(UpdateStatus.DeletionFinish, file);
                            opers++;
                        }
                    }
                    else
                    {
                        // Compare hashes, ignore if same.
                        Hash current = Hash.FromFile(Path.Combine(this.m_LocalPath, file));
                        if (current == hash)
                            continue;

                        // Download patch.
                        string patchstream;
                        try
                        {
                            patchstream = client.DownloadString(this.m_UpdateUri + "/patch/" + current + "/" + hash + "/" + file);
                            callback(UpdateStatus.PatchStart, file);
                            int a = 1;
                            using (StringReader reader = new StringReader(patchstream))
                            {
                                while (true)
                                {
                                    string header = reader.ReadLine();
                                    if (header == "--- END OF PATCHES ---")
                                        break;
                                    else if (header.StartsWith("--- NEXT PATCH ("))
                                    {
                                        int count = Convert.ToInt32(header.Substring("--- NEXT PATCH (".Length, header.Length - "--- NEXT PATCH () ---".Length));
                                        char[] data = new char[count];
                                        reader.ReadBlock(data, 0, count);
                                        List<Patch> patches = dmf.patch_fromText(new string(data));
                                        string newText;
                                        using (StreamReader stream = new StreamReader(Path.Combine(this.m_LocalPath, file)))
                                        {
                                            newText = (string)dmf.patch_apply(patches, stream.ReadToEnd())[0];
                                        }
                                        using (StreamWriter stream = new StreamWriter(Path.Combine(this.m_LocalPath, file)))
                                        {
                                            stream.Write(newText);
                                        }
                                        callback(UpdateStatus.PatchApplied, a);
                                        a++;
                                        // Read the empty terminator line.
                                        reader.ReadLine();
                                    }
                                    else
                                        throw new DataMisalignedException();
                                }
                            }
                            callback(UpdateStatus.PatchFinish, file);
                            opers++;
                        }
                        catch (WebException)
                        {
                            // There's no patch list for this file, redownload.
                            string[] coms = file.Split('/');
                            DirectoryInfo di = new DirectoryInfo(this.m_LocalPath);
                            for (int i = 0; i < coms.Length - 1; i++)
                            {
                                DirectoryInfo[] dis = di.GetDirectories(coms[i]);
                                if (dis.Length == 0)
                                    di = di.CreateSubdirectory(coms[i]);
                                else
                                    di = dis[0];
                            }
                            callback(UpdateStatus.DownloadFreshStart, file);
                            client.DownloadFile(this.m_UpdateUri + "/file/" + file, Path.Combine(this.m_LocalPath, file));
                            callback(UpdateStatus.DownloadFreshFinish, file);
                            opers++;
                        }
                    }
                }
                else
                {
                    // File does not exist, download fresh.
                    string[] coms = file.Split('/');
                    DirectoryInfo di = new DirectoryInfo(this.m_LocalPath);
                    for (int i = 0; i < coms.Length - 1; i++)
                    {
                        DirectoryInfo[] dis = di.GetDirectories(coms[i]);
                        if (dis.Length == 0)
                            di = di.CreateSubdirectory(coms[i]);
                        else
                            di = dis[0];
                    }
                    callback(UpdateStatus.DownloadNewStart, file);
                    client.DownloadFile(this.m_UpdateUri + "/file/" + file, Path.Combine(this.m_LocalPath, file));
                    callback(UpdateStatus.DownloadNewFinish, file);
                    opers++;
                }
            }
            callback(UpdateStatus.Complete, opers);

            return;
        }
 public void SetUp() {
     _diffMatchPatch = new diff_match_patch();
 }
        private void CheckForConflicts()
        {
            var dmp = new diff_match_patch {Match_Distance = 200, Match_Threshold = 0.2f};

            var patches = dmp.patch_make(RevisionsToMerge[0].PreviousRevisionAppliedTo.GenerateEditedContent(), RevisionsToMerge[0].GenerateEditedContent());

            _patchResult = dmp.patch_apply(patches, RevisionsToMerge.ElementAt(1).GenerateEditedContent());
            var patchSucessIndicators = (bool[])_patchResult[1];

            if (patchSucessIndicators.Any(sucess => !sucess))
                RevisionsConflict = true;
        }
Beispiel #44
0
        /// <summary>
        /// Merges the text editor content based on:
        /// - the content at the time of last sync between Google Docs (save or content download)
        /// - the current editor content
        /// - the content that's coming from Google Docs
        /// </summary>
        /// <param name="editorLastSync">Editor content at the time of last sync.</param>
        /// <param name="editorNow">Editor content now.</param>
        /// <param name="contentComingFromGoogleDocs">New content coming from Google Docs</param>
        /// <returns>Merged content.</returns>
        public static string MergeText(string editorLastSync, string editorNow, string contentComingFromGoogleDocs)
        {
            var dmp = new diff_match_patch
            {
                Match_Distance = 1000,
                Match_Threshold = 0.5f,
                Patch_DeleteThreshold = 0.5f
            };

            // let's create patches based on editorContent on last sync and the new text from Google Docs
            var patches = dmp.patch_make(editorLastSync, contentComingFromGoogleDocs);
            Debug.WriteLine("SyncContentUpdated > Patches: \t\t\t\t\t" + dmp.patch_toText(patches));

            // let's apply those patches to the current editor text
            var results = dmp.patch_apply(patches, editorNow);

            // and return results
            return results[0].ToString();
        }
Beispiel #45
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("must have at least 1 argument.");
                return;
            }

            switch (args[0])
            {
                case "create":
                    {
                        if (args.Length < 2)
                        {
                            Console.WriteLine("must have at least 2 arguments (create <appname>).");
                            return;
                        }

                        string appname = args[1];
                        Cache c = new Cache(false);

                        if (c.Exists("server/" + appname))
                        {
                            Console.WriteLine("this app is already created.");
                            return;
                        }

                        if (!File.Exists(".pvdeploy"))
                        {
                            Console.WriteLine("no .pvdeploy file found; please create one.");
                            return;
                        }

                        FileFilter filter = FileFilterParser.Parse(".pvdeploy", GetRecursiveFilesInCwd());
                        foreach (KeyValuePair<string, string> kv in filter)
                        {
                            // Key is original filename.
                            // Value is filename to store as.
                            Hash hash = Hash.FromFile(Path.Combine(Environment.CurrentDirectory, kv.Key));
                            Console.WriteLine(Hash.Empty.ToString() + " => " + hash.ToString() + " " + kv.Value);
                            c.Set<Hash>("server/" + appname + "/hashes/" + kv.Value, hash);
                            if (c.Exists("server/" + appname + "/store/" + kv.Value))
                                c.Delete("server/" + appname + "/store/" + kv.Value);
                            File.Copy(Path.Combine(Environment.CurrentDirectory, kv.Key), c.GetFilePath("server/" + appname + "/store/" + kv.Value));
                        }

                        return;
                    }
                case "test-pvdeploy":
                    {
                        if (args.Length < 1)
                        {
                            Console.WriteLine("must have at least 1 argument (test-pvdeploy).");
                            return;
                        }

                        if (!File.Exists(".pvdeploy"))
                        {
                            Console.WriteLine("no .pvdeploy file found; please create one.");
                            return;
                        }

                        FileFilter filter = FileFilterParser.Parse(".pvdeploy", GetRecursiveFilesInCwd());
                        foreach (KeyValuePair<string, string> kv in filter)
                        {
                            // Key is original filename.
                            // Value is filename to store as.
                            Console.WriteLine(kv.Key + " => " + kv.Value);
                        }

                        return;
                    }
                case "flash":
                    {
                        if (args.Length < 2)
                        {
                            Console.WriteLine("must have at least 2 arguments (flash <appname>).");
                            return;
                        }

                        string appname = args[1];
                        Cache c = new Cache(false);

                        if (!c.Exists("server/" + appname))
                        {
                            Console.WriteLine("use create to create this app first.");
                            return;
                        }

                        if (!File.Exists(".pvdeploy"))
                        {
                            Console.WriteLine("no .pvdeploy file found; please create one.");
                            return;
                        }

                        // Find all files in the current working directory.
                        diff_match_patch dmf = new diff_match_patch();
                        FileFilter filter = FileFilterParser.Parse(".pvdeploy", GetRecursiveFilesInCwd());
                        foreach (KeyValuePair<string, string> kv in filter)
                        {
                            if (c.Exists("server/" + appname + "/store/" + kv.Value))
                            {
                                // File is being updated, get a hash for the current version
                                // and for the stored version.
                                Hash oldHash = Hash.FromFile(c.GetFilePath("server/" + appname + "/store/" + kv.Value));
                                Hash newHash = Hash.FromFile(Path.Combine(Environment.CurrentDirectory, kv.Key));
                                if (oldHash != newHash)
                                {
                                    // Files are different, produce a diff.
                                    byte[] oldData = FileUtils.GetAllBytes(c.GetFilePath("server/" + appname + "/store/" + kv.Value));
                                    byte[] newData = FileUtils.GetAllBytes(Path.Combine(Environment.CurrentDirectory, kv.Key));
                                    List<Patch> patches = dmf.patch_make(Encoding.ASCII.GetString(oldData), Encoding.ASCII.GetString(newData));
                                    string result = dmf.patch_toText(patches);
                                    c.Set<string>("server/" + appname + "/patches/" + kv.Value + "/" + oldHash + "-" + newHash, result);
                                    c.Set<Hash>("server/" + appname + "/hashes/" + kv.Value, newHash);
                                    if (c.Exists("server/" + appname + "/store/" + kv.Value))
                                        c.Delete("server/" + appname + "/store/" + kv.Value);
                                    File.Copy(Path.Combine(Environment.CurrentDirectory, kv.Key), c.GetFilePath("server/" + appname + "/store/" + kv.Value));
                                    if (!c.Exists("server/" + appname + "/store/" + kv.Value))
                                        throw new InvalidOperationException("Unable to copy file to server store.");
                                    Console.WriteLine(oldHash + " => " + newHash + " " + kv.Value);
                                }
                            }
                            else
                            {
                                // A new file is being stored.
                                Hash newHash = Hash.FromFile(Path.Combine(Environment.CurrentDirectory, kv.Key));
                                byte[] newData = FileUtils.GetAllBytes(Path.Combine(Environment.CurrentDirectory, kv.Key));
                                List<Patch> patches = dmf.patch_make("", Encoding.ASCII.GetString(newData));
                                string result = dmf.patch_toText(patches);
                                c.Set<string>("server/" + appname + "/patches/" + kv.Value + "/" + Hash.Empty + "-" + newHash, result);
                                c.Set<Hash>("server/" + appname + "/hashes/" + kv.Value, newHash);
                                if (c.Exists("server/" + appname + "/store/" + kv.Value))
                                    c.Delete("server/" + appname + "/store/" + kv.Value);
                                File.Copy(Path.Combine(Environment.CurrentDirectory, kv.Key), c.GetFilePath("server/" + appname + "/store/" + kv.Value));
                                if (!c.Exists("server/" + appname + "/store/" + kv.Value))
                                    throw new InvalidOperationException("Unable to copy file to server store.");
                                Console.WriteLine(Hash.Empty + " => " + newHash + " " + kv.Value);
                            }
                        }
                        foreach (string s in c.ListRecursive("server/" + appname + "/store"))
                        {
                            if (filter.Count(v => v.Value == s) == 0)
                            {
                                // A file is being deleted.
                                Hash oldHash = Hash.FromFile(c.GetFilePath("server/" + appname + "/store/" + s));
                                byte[] oldData = FileUtils.GetAllBytes(c.GetFilePath("server/" + appname + "/store/" + s));
                                List<Patch> patches = dmf.patch_make(Encoding.ASCII.GetString(oldData), "");
                                string result = dmf.patch_toText(patches);
                                c.Set<string>("server/" + appname + "/patches/" + s + "/" + oldHash.ToString() + "-" + Hash.Empty.ToString(), result);
                                c.Set<Hash>("server/" + appname + "/hashes/" + s, Hash.Empty);
                                if (c.Exists("server/" + appname + "/store/" + s))
                                    c.Delete("server/" + appname + "/store/" + s);
                                if (c.Exists("server/" + appname + "/store/" + s))
                                    throw new InvalidOperationException("Unable to delete file from server store.");
                                Console.WriteLine(oldHash + " => " + Hash.Empty + " " + s);
                            }
                        }

                        Console.WriteLine("flash complete.");
                        return;
                    }
                case "state":
                    {
                        if (args.Length < 2)
                        {
                            Console.WriteLine("must have at least 2 arguments (state <appname>).");
                            return;
                        }

                        string appname = args[1];
                        Cache c = new Cache(false);

                        if (!c.Exists("server/" + appname))
                        {
                            Console.WriteLine("this app does not exist.");
                            return;
                        }

                        foreach (string s in c.ListRecursive("server/" + appname + "/hashes"))
                        {
                            Console.WriteLine(c.Get<Hash>("server/" + appname + "/hashes/" + s) + " " + s);
                        }

                        return;
                    }
                default:
                    Console.WriteLine("invalid command (must be 'flash', 'create', 'state' or 'test-pvdeploy').");
                    return;
            }
        }