private static void CreateLog(string file, RSMFValidatorResult result) { //Create a log to capture the warnings and errors //Errors and warnings should be addressed before attempting to ingest an RSMF file into Relativity try { using (StreamWriter w = File.AppendText("rsmf.validation.log.txt")) { w.WriteLine($"{DateTime.Now.ToLongTimeString()} {DateTime.Now.ToLongDateString()}"); w.WriteLine(file); //Use the IValidatorError object to check the ErrorMessage property for specific information about the error //Use this information to correct the problem in the RSMF file and repeat the verification process //Capture the errors foreach (IValidatorError err in result.Errors) { w.WriteLine($"*{err.Error.ToString()}*"); if (err.LineNumber != null) { w.WriteLine($"Line number: {err.LineNumber}"); w.WriteLine($"Line position: {err.LinePosition}"); } w.WriteLine($"*{err.ErrorMessage}*"); } //Capture the warnings foreach (IValidatorError war in result.Warnings) { w.WriteLine($"*{war.Error.ToString()}*"); if (war.LineNumber != null) { w.WriteLine($"Line number: {war.LineNumber}"); w.WriteLine($"Line position: {war.LinePosition}"); } w.WriteLine($"*{war.ErrorMessage}*"); } w.WriteLine($"--------{Environment.NewLine}"); } } catch (Exception ex) { Console.Error.WriteLine($"Unable to create log:{Environment.NewLine}{ex.Message}"); } }
/* * Convert the contents of the supplied directory into an RSMF file that can be ingested into Relativity via * Relativity processing. The inputDirectory must contain a file named rsmf_manifest.json. Any other files * in the directory will also be included in the RSMF regardless of if they are referenced by the * manifest files or not. The outputFile will be where the RSMF file is written to. */ public void GenerateRSMF(DirectoryInfo inputDirectory, FileInfo outputFile) { FileInfo manifest = null; if (!inputDirectory.Exists) { throw new Exception($"The input directory {inputDirectory.FullName} doesn't exist."); } if (!File.Exists(Path.Combine(inputDirectory.FullName, "rsmf_manifest.json"))) { throw new Exception($"The file rsmf_manifest.json does not exist in {inputDirectory.FullName}."); } manifest = inputDirectory.GetFiles("rsmf_manifest.json", SearchOption.TopDirectoryOnly)?[0]; /* * Create a stream to a zip that contains the rsmf_manifest.json file and any other files that exist in its * directory. */ using (Stream rsmf_zip = CreateRSMFZip(inputDirectory)) { /* * Validating the zip stream validates that the JSON in the rsmf_manifest.json file is compliant with the * RSMF specification. It also verifies that the attachment references in rsmf_manifest.json have equivalent * files in the Zip. */ if (ValidateZip) { IValidator zipValidator = RSMFValidatorFactory.GetRSMFZipValidator(); RSMFValidatorResult results = zipValidator.PerformTests(rsmf_zip); /* * This code only reports errors, not warnings. Warnings from the validator are * contained in the results.Warnings list. */ if (results.Result == ResultTypes.Failed) { StringBuilder errorString = new StringBuilder(); foreach (IValidatorError error in results.Errors) { errorString.AppendLine(); errorString.AppendLine(error.ErrorMessage); } throw new Exception("Validation of the generated ZIP failed: " + errorString.ToString()); } } /* Leverage MimeKit to create the representation of the RSMF file.*/ MimeMessage rsmf = CreateRSMF(manifest); /* MimePart defaults to application/octet-stream, which is exactly what is necessary.*/ MimePart attachment = new MimePart(); attachment.Content = new MimeContent(rsmf_zip); attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Attachment); /* The RSMF specification requires that the name of the attachment be rsmf.zip */ attachment.FileName = "rsmf.zip"; /* * This is a trick to make it easier to add the zip attachment to the RSMF. It is known that the Body property * of RSMF returned by CreateRSMF is a Multipart object, so this cast is safe. */ ((Multipart)rsmf.Body).Add(attachment); /* * Prepare the final EML before writing it out. This accomplishes various things like making sure the body * text is encoded correctly. For RSMF files, the encoding constraint is 7-bit. */ rsmf.Prepare(EncodingConstraint.SevenBit); /* Finally, write the object to the provided file. */ rsmf.WriteTo(outputFile.FullName); } }