Browse Source

Able to anonymize comments

Piotr Czajkowski 5 years ago
parent
commit
092fd33547
4 changed files with 65 additions and 2 deletions
  1. 50 2
      DOCX/DOCX.cs
  2. 12 0
      DOCXTests/DOCXTests.cs
  3. 3 0
      DOCXTests/DOCXTests.csproj
  4. BIN
      DOCXTests/testFiles/testComments.docx

+ 50 - 2
DOCX/DOCX.cs

@@ -62,9 +62,13 @@ namespace DOCX
         {
             try
             {
-                using (StreamWriter sw = new StreamWriter(entry.Open()))
+                using (var sr = entry.Open())
                 {
-                    doc.Save(sw);
+                    sr.SetLength(doc.OuterXml.Length);
+                    using (StreamWriter sw = new StreamWriter(sr))
+                    {
+                        doc.Save(sw);
+                    }
                 }
             }
             catch (Exception e)
@@ -105,6 +109,50 @@ namespace DOCX
             return !result.status ? (false, result.message) : (true, "OK");
         }
 
+        private Dictionary<string, string> _authors = new Dictionary<string, string>();
+
+        private string AnonymizeName(string name)
+        {
+            if (_authors.TryGetValue(name, out var anonymousName))
+                return anonymousName;
+
+            anonymousName = $"Author{_authors.Count + 1}";
+            _authors.Add(name, anonymousName);
+            return anonymousName;
+        }
+        
+        private (bool status, string message) AnonymizeAuthors(ZipArchiveEntry comments)
+        {
+            var loadResult = GetXML(comments);
+            if (loadResult.doc == null)
+                return (false, loadResult.message);
+
+            XmlDocument doc = loadResult.doc;
+
+            var commentNodes = doc.SelectNodes("//w:comment", _ns);
+            if (commentNodes == null)
+                return (false, "There are no comments!");
+
+            foreach (XmlNode node in commentNodes)
+            {
+                var author = node.Attributes["w:author"];
+                author.Value = AnonymizeName(author.Value);
+            }
+
+            return SaveXML(doc, comments);
+        }
+        
+        public (bool status, string message) AnonymizeComments()
+        {
+            ZipArchiveEntry comments = _zip.GetEntry(@"word/comments.xml");
+            if (comments == null)
+                return (false,
+                    "Can't access comments.xml!");
+
+            var result = AnonymizeAuthors(comments);
+            return !result.status ? (false, result.message) : (true, "OK");
+        }
+
         public void Dispose()
         {
             Dispose(true);

+ 12 - 0
DOCXTests/DOCXTests.cs

@@ -79,5 +79,17 @@ namespace DOCXTests
 
             Assert.True(FileCompare(expectedFile, testFile));
         }
+
+        [Fact]
+        public void AnonymizeAuthorsTest()
+        {
+            const string testFile = @"testFiles/testComments.docx";
+
+            using (var test = new DOCX.Docx(testFile))
+            {
+                var result = test.AnonymizeComments();
+                Assert.True(result.status);
+            }
+        }
     }
 }

+ 3 - 0
DOCXTests/DOCXTests.csproj

@@ -23,6 +23,9 @@
       <None Update="testFiles\tracked.docx">
         <CopyToOutputDirectory>Always</CopyToOutputDirectory>
       </None>
+      <None Update="testFiles\testComments.docx">
+        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+      </None>
     </ItemGroup>
 
 </Project>

BIN
DOCXTests/testFiles/testComments.docx