Rewrote the logic for reporting JSON to avoid reporting JSON inside a text blob, but instead use an extra tag in the JSON.

The logic is currently that the template is scanned for potential values, and those that are found are reported in the extra tag for the JSON.
A bit clumsy, but allows the user to choose specific fields to include in the reported data.
This commit is contained in:
Kenneth Skovhede
2018-04-12 11:46:54 +02:00
parent 4e5f4a12bf
commit de84650eae
6 changed files with 67 additions and 27 deletions
@@ -294,29 +294,61 @@ namespace Duplicati.Library.Modules.Builtin
/// <param name="result">The result object.</param>
/// <param name="subjectline">If set to <c>true</c>, the result is intended for a subject or title line.</param>
protected virtual string ReplaceTemplate(string input, object result, bool subjectline)
{
input = Regex.Replace(input, "\\%OPERATIONNAME\\%", m_operationname ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%REMOTEURL\\%", m_remoteurl ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%LOCALPATH\\%", m_localpath == null ? "" : string.Join(System.IO.Path.PathSeparator.ToString(), m_localpath), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%PARSEDRESULT\\%", m_parsedresultlevel ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
if (subjectline)
{
input = Regex.Replace(input, "\\%RESULT\\%", m_parsedresultlevel ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}
else
{
// For JSON, ignore the template and just use the contents
if (ExportFormat == ResultExportFormat.Json)
{
if (input.IndexOf("%RESULT%", StringComparison.OrdinalIgnoreCase) >= 0)
input = Regex.Replace(input, "\\%RESULT\\%", m_resultFormatSerializer.Serialize(result, LogLines), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
var extra = new Dictionary<string, string>();
if (input.IndexOf("%OPERATIONNAME%", StringComparison.OrdinalIgnoreCase) >= 0)
extra["OperationName"] = m_operationname;
if (input.IndexOf("%REMOTEURL%", StringComparison.OrdinalIgnoreCase) >= 0)
extra["RemoteUrl"] = m_remoteurl;
if (input.IndexOf("%LOCALPATH%", StringComparison.OrdinalIgnoreCase) >= 0 && m_localpath != null)
extra["LocalPath"] = string.Join(System.IO.Path.PathSeparator.ToString(), m_localpath);
if (input.IndexOf("%PARSEDRESULT%", StringComparison.OrdinalIgnoreCase) >= 0)
extra["ParsedResult"] = m_parsedresultlevel;
if (input.IndexOf("%backup-name%", StringComparison.OrdinalIgnoreCase) >= 0)
{
if (m_options.ContainsKey("backup-name"))
extra["backup-name"] = m_options["backup-name"];
else
extra["backup-name"] = System.IO.Path.GetFileNameWithoutExtension(Duplicati.Library.Utility.Utility.getEntryAssembly().Location);
}
foreach (KeyValuePair<string, string> kv in m_options)
if (input.IndexOf($"%{kv.Key}%", StringComparison.OrdinalIgnoreCase) >= 0)
extra[kv.Key] = kv.Value;
return m_resultFormatSerializer.Serialize(result, LogLines, extra);
}
else
{
input = Regex.Replace(input, "\\%OPERATIONNAME\\%", m_operationname ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%REMOTEURL\\%", m_remoteurl ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%LOCALPATH\\%", m_localpath == null ? "" : string.Join(System.IO.Path.PathSeparator.ToString(), m_localpath), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%PARSEDRESULT\\%", m_parsedresultlevel ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
if (subjectline)
{
input = Regex.Replace(input, "\\%RESULT\\%", m_parsedresultlevel ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}
else
{
if (input.IndexOf("%RESULT%", StringComparison.OrdinalIgnoreCase) >= 0)
input = Regex.Replace(input, "\\%RESULT\\%", m_resultFormatSerializer.Serialize(result, LogLines, null), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
}
foreach (KeyValuePair<string, string> kv in m_options)
input = Regex.Replace(input, "\\%" + kv.Key + "\\%", kv.Value ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
if (!m_options.ContainsKey("backup-name"))
input = Regex.Replace(input, "\\%backup-name\\%", System.IO.Path.GetFileNameWithoutExtension(Duplicati.Library.Utility.Utility.getEntryAssembly().Location) ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%[^\\%]+\\%", "");
return input;
}
foreach (KeyValuePair<string, string> kv in m_options)
input = Regex.Replace(input, "\\%" + kv.Key + "\\%", kv.Value ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
if (!m_options.ContainsKey("backup-name"))
input = Regex.Replace(input, "\\%backup-name\\%", System.IO.Path.GetFileNameWithoutExtension(Duplicati.Library.Utility.Utility.getEntryAssembly().Location) ?? "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
input = Regex.Replace(input, "\\%[^\\%]+\\%", "");
return input;
}
/// <summary>
@@ -17,7 +17,8 @@ namespace Duplicati.Library.Modules.Builtin.ResultSerialization
/// <returns>The serialized result string.</returns>
/// <param name="result">The result to serialize.</param>
/// <param name="loglines">The log lines to serialize.</param>
public string Serialize(object result, IEnumerable<string> loglines)
/// <param name="additional">Additional parameters to include</param>
public string Serialize(object result, IEnumerable<string> loglines, Dictionary<string, string> additional)
{
StringBuilder sb = new StringBuilder();
@@ -88,6 +89,9 @@ namespace Duplicati.Library.Modules.Builtin.ResultSerialization
Utility.Utility.PrintSerializeObject(result, sb);
}
if (additional != null && additional.Count > 0)
sb.AppendLine(Serialize(additional, null, null));
if (loglines != null && loglines.Any())
{
sb.AppendLine();
@@ -13,7 +13,8 @@ namespace Duplicati.Library.Modules.Builtin
/// <returns>The serialized result string.</returns>
/// <param name="result">The result to serialize.</param>
/// <param name="loglines">The log lines to serialize.</param>
string Serialize(object result, IEnumerable<string> loglines);
/// <param name="additional">Additional parameters to include</param>
string Serialize(object result, IEnumerable<string> loglines, Dictionary<string, string> additional);
/// <summary>
/// Returns the format that the serializer represents
@@ -53,12 +53,14 @@ namespace Duplicati.Library.Modules.Builtin.ResultSerialization
/// <returns>The serialized result string.</returns>
/// <param name="result">The result to serialize.</param>
/// <param name="loglines">The log lines to serialize.</param>
public string Serialize(object result, IEnumerable<string> loglines)
{
/// <param name="additional">Additional parameters to include</param>
public string Serialize(object result, IEnumerable<string> loglines, Dictionary<string, string> additional)
{
return JsonConvert.SerializeObject(
new
{
Data = result,
Data = result,
Extra = additional,
LogLines = loglines
},
@@ -188,7 +188,7 @@ namespace Duplicati.Library.Modules.Builtin
using (TempFile tmpfile = new TempFile())
{
using (var streamWriter = new StreamWriter(tmpfile))
streamWriter.Write(resultFormatSerializer.Serialize(result, m_logstorage));
streamWriter.Write(resultFormatSerializer.Serialize(result, m_logstorage, null));
Execute(m_finishScript, "AFTER", m_operationName, ref m_remoteurl, ref m_localpath, m_timeout, false, m_options, tmpfile, level);
}
@@ -191,6 +191,7 @@ namespace Duplicati.Library.Modules.Builtin {
// No need to do the expansion as we throw away the result
if (subjectline)
return string.Empty;
return base.ReplaceTemplate(input, result, subjectline);
}