Browse Source

Moved from .NET Framework

Piotr Czajkowski 5 years ago
commit
935d785a3b

+ 22 - 0
DOCX.sln

@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DOCX", "DOCX\DOCX.csproj", "{A274C14D-E456-410F-A3FB-8BFED869A392}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DOCXTests", "DOCXTests\DOCXTests.csproj", "{7A71A916-5DF5-4F4B-A10F-522EA4F1BDE3}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A274C14D-E456-410F-A3FB-8BFED869A392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A274C14D-E456-410F-A3FB-8BFED869A392}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A274C14D-E456-410F-A3FB-8BFED869A392}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A274C14D-E456-410F-A3FB-8BFED869A392}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7A71A916-5DF5-4F4B-A10F-522EA4F1BDE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7A71A916-5DF5-4F4B-A10F-522EA4F1BDE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7A71A916-5DF5-4F4B-A10F-522EA4F1BDE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7A71A916-5DF5-4F4B-A10F-522EA4F1BDE3}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+EndGlobal

+ 127 - 0
DOCX/DOCX.cs

@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Compression;
+using System.Xml;
+
+namespace DOCX
+{
+    public class Docx : IDisposable
+    {
+        private readonly ZipArchive _zip;
+        private readonly XmlNamespaceManager _ns = new XmlNamespaceManager(new NameTable());
+
+        private readonly Dictionary<string, string> _namespaces = new Dictionary<string, string>
+        {
+            {"w",  "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}
+        };
+
+        private void LoadNamespaces()
+        {
+            foreach (var item in _namespaces)
+            {
+                _ns.AddNamespace(item.Key, item.Value);
+            }
+        }
+
+        public Docx(string path)
+        {
+            _zip = ZipFile.Open(path, ZipArchiveMode.Update);
+            LoadNamespaces();
+        }
+
+        public Docx(ZipArchive zipArchive)
+        {
+            _zip = zipArchive;
+            LoadNamespaces();
+        }
+
+        private (XmlDocument doc, string message) GetXML(ZipArchiveEntry entry)
+        {
+            XmlDocument doc = new XmlDocument()
+            {
+                PreserveWhitespace = true // Disables auto-indent
+            };
+
+            try
+            {
+                using (StreamReader sr = new StreamReader(entry.Open()))
+                {
+                    doc.Load(sr);
+                }
+            }
+            catch (Exception e)
+            {
+                return (null, $"Error reading {entry.Name}!\n{e}");
+            }
+
+            return (doc, "OK");
+        }
+
+        private (bool status, string message) SaveXML(XmlDocument doc, ZipArchiveEntry entry)
+        {
+            try
+            {
+                using (StreamWriter sw = new StreamWriter(entry.Open()))
+                {
+                    doc.Save(sw);
+                }
+            }
+            catch (Exception e)
+            {
+                return (false, $"Error saving {entry.Name}!\n{e}");
+            }
+
+            return (true, "OK");
+        }
+
+        private (bool status, string message) AddTrackRevisions(ZipArchiveEntry settings)
+        {
+            var loadResult = GetXML(settings);
+            if (loadResult.doc == null)
+                return (false, loadResult.message);
+
+            XmlDocument doc = loadResult.doc;
+
+            if (doc.SelectSingleNode("//w:trackRevisions", _ns) != null) return (true, "No change needed.");
+
+            XmlElement trackRevisions = doc.CreateElement("w", "trackRevisions", _namespaces["w"]);
+            if (doc.DocumentElement == null)
+                return (false, "No root element in settings.xml!");
+
+            doc.DocumentElement.AppendChild(trackRevisions);
+
+            return SaveXML(doc, settings);
+        }
+
+        public (bool status, string message) EnableTrackedChanges()
+        {
+            ZipArchiveEntry settings = _zip.GetEntry(@"word/settings.xml");
+            if (settings == null)
+                return (false,
+            "Can't access settings.xml!");
+
+            var result = AddTrackRevisions(settings);
+            return !result.status ? (false, result.message) : (true, "OK");
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        ~Docx()
+        {
+            Dispose(false);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                _zip.Dispose();
+            }
+        }
+    }
+}

+ 7 - 0
DOCX/DOCX.csproj

@@ -0,0 +1,7 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>netcoreapp2.0</TargetFramework>
+    </PropertyGroup>
+
+</Project>

+ 85 - 0
DOCXTests/DOCXTests.cs

@@ -0,0 +1,85 @@
+using System.IO;
+using Xunit;
+
+namespace DOCXTests
+{
+    public class DocxTests
+    {
+        private bool FileCompare(string file1, string file2)
+        {
+            // Borrowed from https://stackoverflow.com/questions/7931304/comparing-two-files-in-c-sharp#7931353
+
+            int file1Byte;
+            int file2Byte;
+            FileStream fs1;
+            FileStream fs2;
+
+            // Determine if the same file was referenced two times.
+            if (file1 == file2)
+            {
+                // Return true to indicate that the files are the same.
+                return true;
+            }
+
+            // Open the two files.
+            fs1 = new FileStream(file1, FileMode.Open, FileAccess.Read);
+            fs2 = new FileStream(file2, FileMode.Open, FileAccess.Read);
+
+            // Check the file sizes. If they are not the same, the files 
+            // are not the same.
+            if (fs1.Length != fs2.Length)
+            {
+                // Close the file
+                fs1.Close();
+                fs2.Close();
+
+                // Return false to indicate files are different
+                return false;
+            }
+
+            // Read and compare a byte from each file until either a
+            // non-matching set of bytes is found or until the end of
+            // file1 is reached.
+            do
+            {
+                // Read one byte from each file.
+                file1Byte = fs1.ReadByte();
+                file2Byte = fs2.ReadByte();
+            }
+            while (file1Byte == file2Byte && file1Byte != -1);
+
+            // Close the files.
+            fs1.Close();
+            fs2.Close();
+
+            // Return the success of the comparison. "file1byte" is 
+            // equal to "file2byte" at this point only if the files are 
+            // the same.
+            return file1Byte - file2Byte == 0;
+        }
+
+        [Fact]
+        public void EnableTrackedChangesTest()
+        {
+            string testFile = @"testFiles/notTracked.docx";
+            string expectedFile = @"testFiles/tracked.docx";
+
+            using (var test = new DOCX.Docx(testFile))
+            {
+                var result = test.EnableTrackedChanges();
+                Assert.True(result.status);
+            }
+
+            Assert.True(FileCompare(expectedFile, testFile));
+
+            // Test for no duplication
+            using (var test = new DOCX.Docx(expectedFile))
+            {
+                var result = test.EnableTrackedChanges();
+                Assert.True(result.status);
+            }
+
+            Assert.True(FileCompare(expectedFile, testFile));
+        }
+    }
+}

+ 28 - 0
DOCXTests/DOCXTests.csproj

@@ -0,0 +1,28 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>netcoreapp2.0</TargetFramework>
+
+        <IsPackable>false</IsPackable>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
+        <PackageReference Include="xunit" Version="2.2.0" />
+        <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <ProjectReference Include="..\DOCX\DOCX.csproj" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <None Update="testFiles\notTracked.docx">
+        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+      </None>
+      <None Update="testFiles\tracked.docx">
+        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+      </None>
+    </ItemGroup>
+
+</Project>

BIN
DOCXTests/testFiles/notTracked.docx


BIN
DOCXTests/testFiles/tracked.docx