diff --git a/Duplicati/Library/Modules/Builtin/ReportHelper.cs b/Duplicati/Library/Modules/Builtin/ReportHelper.cs
index b83c81d3f..4f5f145c3 100644
--- a/Duplicati/Library/Modules/Builtin/ReportHelper.cs
+++ b/Duplicati/Library/Modules/Builtin/ReportHelper.cs
@@ -294,29 +294,61 @@ namespace Duplicati.Library.Modules.Builtin
/// The result object.
/// If set to true, the result is intended for a subject or title line.
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();
+
+ 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 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 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 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;
}
///
diff --git a/Duplicati/Library/Modules/Builtin/ResultSerialization/DuplicatiFormatSerializer.cs b/Duplicati/Library/Modules/Builtin/ResultSerialization/DuplicatiFormatSerializer.cs
index a066e370f..a88cf21d6 100644
--- a/Duplicati/Library/Modules/Builtin/ResultSerialization/DuplicatiFormatSerializer.cs
+++ b/Duplicati/Library/Modules/Builtin/ResultSerialization/DuplicatiFormatSerializer.cs
@@ -17,7 +17,8 @@ namespace Duplicati.Library.Modules.Builtin.ResultSerialization
/// The serialized result string.
/// The result to serialize.
/// The log lines to serialize.
- public string Serialize(object result, IEnumerable loglines)
+ /// Additional parameters to include
+ public string Serialize(object result, IEnumerable loglines, Dictionary 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();
diff --git a/Duplicati/Library/Modules/Builtin/ResultSerialization/IResultFormatSerializer.cs b/Duplicati/Library/Modules/Builtin/ResultSerialization/IResultFormatSerializer.cs
index 4fbfdf3fb..2df6776dc 100644
--- a/Duplicati/Library/Modules/Builtin/ResultSerialization/IResultFormatSerializer.cs
+++ b/Duplicati/Library/Modules/Builtin/ResultSerialization/IResultFormatSerializer.cs
@@ -13,7 +13,8 @@ namespace Duplicati.Library.Modules.Builtin
/// The serialized result string.
/// The result to serialize.
/// The log lines to serialize.
- string Serialize(object result, IEnumerable loglines);
+ /// Additional parameters to include
+ string Serialize(object result, IEnumerable loglines, Dictionary additional);
///
/// Returns the format that the serializer represents
diff --git a/Duplicati/Library/Modules/Builtin/ResultSerialization/JsonFormatSerializer.cs b/Duplicati/Library/Modules/Builtin/ResultSerialization/JsonFormatSerializer.cs
index 1d1bdee49..f15516fca 100644
--- a/Duplicati/Library/Modules/Builtin/ResultSerialization/JsonFormatSerializer.cs
+++ b/Duplicati/Library/Modules/Builtin/ResultSerialization/JsonFormatSerializer.cs
@@ -53,12 +53,14 @@ namespace Duplicati.Library.Modules.Builtin.ResultSerialization
/// The serialized result string.
/// The result to serialize.
/// The log lines to serialize.
- public string Serialize(object result, IEnumerable loglines)
- {
+ /// Additional parameters to include
+ public string Serialize(object result, IEnumerable loglines, Dictionary additional)
+ {
return JsonConvert.SerializeObject(
new
{
- Data = result,
+ Data = result,
+ Extra = additional,
LogLines = loglines
},
diff --git a/Duplicati/Library/Modules/Builtin/RunScript.cs b/Duplicati/Library/Modules/Builtin/RunScript.cs
index 4c33a44a1..25db9a530 100644
--- a/Duplicati/Library/Modules/Builtin/RunScript.cs
+++ b/Duplicati/Library/Modules/Builtin/RunScript.cs
@@ -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);
}
diff --git a/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs b/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
index e0dc9fdb8..ec1363c1f 100644
--- a/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
+++ b/Duplicati/Library/Modules/Builtin/SendHttpMessage.cs
@@ -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);
}