Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/duplicati/duplicati.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Skovhede <kenneth@hexad.dk>2018-09-05 12:21:08 +0300
committerKenneth Skovhede <kenneth@hexad.dk>2018-09-05 12:21:08 +0300
commite0eaf3351430cf939ce0ac5b61f7af9b6147816d (patch)
treef5eba2e51841662c0030643b9486deb8c1072ae9
parentd395c3af82ee9440b06d24c50e2402a54ddc6bb0 (diff)
parent72fc8e4134aaf15bfb107bcb4e9a119971ef745d (diff)
Merge branch 'master' of github.com:duplicati/duplicati
-rw-r--r--Duplicati/Library/Main/Operation/Backup/FileEnumerationProcess.cs16
-rw-r--r--Duplicati/Library/Main/Operation/Backup/FilePreFilterProcess.cs2
-rw-r--r--Duplicati/Library/Main/Operation/Backup/MetadataGenerator.cs2
-rw-r--r--Duplicati/Library/Main/Operation/Backup/MetadataPreProcess.cs4
-rw-r--r--Duplicati/Library/Main/Operation/Common/BackendHandler.cs15
-rw-r--r--Duplicati/Library/Main/default_compressed_extensions.txt5
-rw-r--r--Duplicati/Library/Utility/Utility.cs4
-rw-r--r--Duplicati/Server/webroot/login.html2
-rw-r--r--Duplicati/Server/webroot/ngax/templates/pause.html17
-rw-r--r--Duplicati/UnitTest/UtilityTests.cs42
10 files changed, 83 insertions, 26 deletions
diff --git a/Duplicati/Library/Main/Operation/Backup/FileEnumerationProcess.cs b/Duplicati/Library/Main/Operation/Backup/FileEnumerationProcess.cs
index 745adccb2..6799c716f 100644
--- a/Duplicati/Library/Main/Operation/Backup/FileEnumerationProcess.cs
+++ b/Duplicati/Library/Main/Operation/Backup/FileEnumerationProcess.cs
@@ -38,7 +38,7 @@ namespace Duplicati.Library.Main.Operation.Backup
/// </summary>
private static readonly string FILTER_LOGTAG = Logging.Log.LogTagFromType(typeof(FileEnumerationProcess));
- public static Task Run(IEnumerable<string> sources, Snapshots.ISnapshotService snapshot, UsnJournalService journalService, FileAttributes attributeFilter, Duplicati.Library.Utility.IFilter sourcefilter, Duplicati.Library.Utility.IFilter emitfilter, Options.SymlinkStrategy symlinkPolicy, Options.HardlinkStrategy hardlinkPolicy, bool excludeemptyfolders, string[] ignorenames, string[] changedfilelist, ITaskReader taskreader)
+ public static Task Run(IEnumerable<string> sources, Snapshots.ISnapshotService snapshot, UsnJournalService journalService, FileAttributes fileAttributes, Duplicati.Library.Utility.IFilter sourcefilter, Duplicati.Library.Utility.IFilter emitfilter, Options.SymlinkStrategy symlinkPolicy, Options.HardlinkStrategy hardlinkPolicy, bool excludeemptyfolders, string[] ignorenames, string[] changedfilelist, ITaskReader taskreader)
{
return AutomationExtensions.RunTask(
new
@@ -77,21 +77,21 @@ namespace Duplicati.Library.Main.Operation.Backup
{
}
- return AttributeFilterAsync(null, x, fa, snapshot, sourcefilter, hardlinkPolicy, symlinkPolicy, hardlinkmap, attributeFilter, enumeratefilter, ignorenames, mixinqueue).WaitForTask().Result;
+ return AttributeFilter(null, x, fa, snapshot, sourcefilter, hardlinkPolicy, symlinkPolicy, hardlinkmap, fileAttributes, enumeratefilter, ignorenames, mixinqueue);
});
}
else
{
- Library.Utility.Utility.EnumerationFilterDelegate AttributeFilter = (root, path, attr) =>
- AttributeFilterAsync(root, path, attr, snapshot, sourcefilter, hardlinkPolicy, symlinkPolicy, hardlinkmap, attributeFilter, enumeratefilter, ignorenames, mixinqueue).WaitForTask().Result;
+ Library.Utility.Utility.EnumerationFilterDelegate attributeFilter = (root, path, attr) =>
+ AttributeFilter(root, path, attr, snapshot, sourcefilter, hardlinkPolicy, symlinkPolicy, hardlinkmap, fileAttributes, enumeratefilter, ignorenames, mixinqueue);
if (journalService != null)
{
// filter sources using USN journal, to obtain a sub-set of files / folders that may have been modified
- sources = journalService.GetModifiedSources(AttributeFilter);
+ sources = journalService.GetModifiedSources(attributeFilter);
}
- worklist = snapshot.EnumerateFilesAndFolders(sources, AttributeFilter, (rootpath, errorpath, ex) =>
+ worklist = snapshot.EnumerateFilesAndFolders(sources, attributeFilter, (rootpath, errorpath, ex) =>
{
Logging.Log.WriteWarningMessage(FILTER_LOGTAG, "FileAccessError", ex, "Error reported while accessing file: {0}", errorpath);
});
@@ -222,7 +222,7 @@ namespace Duplicati.Library.Main.Operation.Backup
/// <param name="rootpath">The root path that initiated this enumeration.</param>
/// <param name="path">The current path.</param>
/// <param name="attributes">The file or folder attributes.</param>
- private static async Task<bool> AttributeFilterAsync(string rootpath, string path, FileAttributes attributes, Snapshots.ISnapshotService snapshot, Library.Utility.IFilter sourcefilter, Options.HardlinkStrategy hardlinkPolicy, Options.SymlinkStrategy symlinkPolicy, Dictionary<string, string> hardlinkmap, FileAttributes attributeFilter, Duplicati.Library.Utility.IFilter enumeratefilter, string[] ignorenames, Queue<string> mixinqueue)
+ private static bool AttributeFilter(string rootpath, string path, FileAttributes attributes, Snapshots.ISnapshotService snapshot, Library.Utility.IFilter sourcefilter, Options.HardlinkStrategy hardlinkPolicy, Options.SymlinkStrategy symlinkPolicy, Dictionary<string, string> hardlinkmap, FileAttributes fileAttributes, Duplicati.Library.Utility.IFilter enumeratefilter, string[] ignorenames, Queue<string> mixinqueue)
{
// Step 1, exclude block devices
try
@@ -304,7 +304,7 @@ namespace Duplicati.Library.Main.Operation.Backup
}
// If we exclude files based on attributes, filter that
- if ((attributeFilter & attributes) != 0)
+ if ((fileAttributes & attributes) != 0)
{
Logging.Log.WriteVerboseMessage(FILTER_LOGTAG, "ExcludingPathFromAttributes", "Excluding path due to attribute filter: {0}", path);
return false;
diff --git a/Duplicati/Library/Main/Operation/Backup/FilePreFilterProcess.cs b/Duplicati/Library/Main/Operation/Backup/FilePreFilterProcess.cs
index 34b458d8a..304b0c859 100644
--- a/Duplicati/Library/Main/Operation/Backup/FilePreFilterProcess.cs
+++ b/Duplicati/Library/Main/Operation/Backup/FilePreFilterProcess.cs
@@ -124,7 +124,7 @@ namespace Duplicati.Library.Main.Operation.Backup
}
// Compute current metadata
- e.MetaHashAndSize = SKIPMETADATA ? EMPTY_METADATA : Utility.WrapMetadata(await MetadataGenerator.GenerateMetadataAsync(e.Path, e.Attributes, options, snapshot), options);
+ e.MetaHashAndSize = SKIPMETADATA ? EMPTY_METADATA : Utility.WrapMetadata(MetadataGenerator.GenerateMetadata(e.Path, e.Attributes, options, snapshot), options);
e.MetadataChanged = !SKIPMETADATA && (e.MetaHashAndSize.Blob.Length != e.OldMetaSize || e.MetaHashAndSize.FileHash != e.OldMetaHash);
// Check if the file is new, or something indicates a change
diff --git a/Duplicati/Library/Main/Operation/Backup/MetadataGenerator.cs b/Duplicati/Library/Main/Operation/Backup/MetadataGenerator.cs
index bd982751c..a6b5a16fc 100644
--- a/Duplicati/Library/Main/Operation/Backup/MetadataGenerator.cs
+++ b/Duplicati/Library/Main/Operation/Backup/MetadataGenerator.cs
@@ -30,7 +30,7 @@ namespace Duplicati.Library.Main.Operation.Backup
{
private static readonly string METALOGTAG = Logging.Log.LogTagFromType(typeof(MetadataGenerator)) + ".Metadata";
- public static async Task<Dictionary<string, string>> GenerateMetadataAsync(string path, System.IO.FileAttributes attributes, Options options, Snapshots.ISnapshotService snapshot)
+ public static Dictionary<string, string> GenerateMetadata(string path, System.IO.FileAttributes attributes, Options options, Snapshots.ISnapshotService snapshot)
{
try
{
diff --git a/Duplicati/Library/Main/Operation/Backup/MetadataPreProcess.cs b/Duplicati/Library/Main/Operation/Backup/MetadataPreProcess.cs
index 335a1996c..53e09905c 100644
--- a/Duplicati/Library/Main/Operation/Backup/MetadataPreProcess.cs
+++ b/Duplicati/Library/Main/Operation/Backup/MetadataPreProcess.cs
@@ -162,7 +162,7 @@ namespace Duplicati.Library.Main.Operation.Backup
if (options.SymlinkPolicy == Options.SymlinkStrategy.Store)
{
- var metadata = await MetadataGenerator.GenerateMetadataAsync(path, attributes, options, snapshot);
+ var metadata = MetadataGenerator.GenerateMetadata(path, attributes, options, snapshot);
if (!metadata.ContainsKey("CoreSymlinkTarget"))
metadata["CoreSymlinkTarget"] = symlinkTarget;
@@ -187,7 +187,7 @@ namespace Duplicati.Library.Main.Operation.Backup
if (!options.SkipMetadata)
{
- metahash = Utility.WrapMetadata(await MetadataGenerator.GenerateMetadataAsync(path, attributes, options, snapshot), options);
+ metahash = Utility.WrapMetadata(MetadataGenerator.GenerateMetadata(path, attributes, options, snapshot), options);
}
else
{
diff --git a/Duplicati/Library/Main/Operation/Common/BackendHandler.cs b/Duplicati/Library/Main/Operation/Common/BackendHandler.cs
index b028c5e1c..88dae4cce 100644
--- a/Duplicati/Library/Main/Operation/Common/BackendHandler.cs
+++ b/Duplicati/Library/Main/Operation/Common/BackendHandler.cs
@@ -109,7 +109,7 @@ namespace Duplicati.Library.Main.Operation.Common
this.LocalTempfile.Protected = true;
}
- public async Task Encrypt(Options options)
+ public void Encrypt(Options options)
{
if (!this.Encrypted && !options.NoEncryption)
{
@@ -221,9 +221,9 @@ namespace Duplicati.Library.Main.Operation.Common
var tcs = new TaskCompletionSource<bool>();
- var backgroundhashAndEncrypt = Task.Run(async () =>
+ var backgroundhashAndEncrypt = Task.Run(() =>
{
- await fe.Encrypt(m_options).ConfigureAwait(false);
+ fe.Encrypt(m_options);
return fe.UpdateHashAndSize(m_options);
});
@@ -331,7 +331,7 @@ namespace Duplicati.Library.Main.Operation.Common
return RunRetryOnMain(fe, () => DoGet(fe));
}
- private async Task ResetBackendAsync(Exception ex)
+ private void ResetBackend(Exception ex)
{
try
{
@@ -343,7 +343,6 @@ namespace Duplicati.Library.Main.Operation.Common
Logging.Log.WriteWarningMessage(LOGTAG, "BackendDisposeError", dex, "Failed to dispose backend instance: {0}", ex.Message);
}
m_backend = null;
-
}
private async Task<T> DoWithRetry<T>(FileEntryItem item, Func<Task<T>> method)
@@ -405,12 +404,12 @@ namespace Duplicati.Library.Main.Operation.Common
}
if (!recovered)
- await ResetBackendAsync(ex).ConfigureAwait(false);
+ ResetBackend(ex);
}
finally
{
if (m_options.NoConnectionReuse)
- await ResetBackendAsync(null).ConfigureAwait(false);
+ ResetBackend(null);
}
}
@@ -435,7 +434,7 @@ namespace Duplicati.Library.Main.Operation.Common
private async Task<bool> DoPut(FileEntryItem item, bool updatedHash = false)
{
// If this is not already encrypted, do it now
- await item.Encrypt(m_options).ConfigureAwait(false);
+ item.Encrypt(m_options);
updatedHash |= item.UpdateHashAndSize(m_options);
diff --git a/Duplicati/Library/Main/default_compressed_extensions.txt b/Duplicati/Library/Main/default_compressed_extensions.txt
index 7b189bf7a..87c9e3c5d 100644
--- a/Duplicati/Library/Main/default_compressed_extensions.txt
+++ b/Duplicati/Library/Main/default_compressed_extensions.txt
@@ -97,8 +97,11 @@
.pspimage #PaintShopPro Image
.tif #TIFF image
.dng #Adobe Digital Negative
-.cr2 #Canon RAW Image Format
+.cr2 #Canon RAW Image Format (already compressed despite being "RAW")
.webp #WebP Image
+.nef #Nikon RAW format
+.arw #Sony RAW format
+.heic #High Efficiency Image File Format
# Compressed Font files
diff --git a/Duplicati/Library/Utility/Utility.cs b/Duplicati/Library/Utility/Utility.cs
index 70d5ff23c..6626ce6a7 100644
--- a/Duplicati/Library/Utility/Utility.cs
+++ b/Duplicati/Library/Utility/Utility.cs
@@ -1054,12 +1054,12 @@ namespace Duplicati.Library.Utility
/// <summary>
/// Gets a string comparer that matches the client filesystems case sensitivity
/// </summary>
- public static StringComparer ClientFilenameStringComparer => IsFSCaseSensitive ? StringComparer.CurrentCulture : StringComparer.CurrentCultureIgnoreCase;
+ public static StringComparer ClientFilenameStringComparer => IsFSCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
/// <summary>
/// Gets the string comparision that matches the client filesystems case sensitivity
/// </summary>
- public static StringComparison ClientFilenameStringComparison => IsFSCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase;
+ public static StringComparison ClientFilenameStringComparison => IsFSCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
/// <summary>
/// The path to the users home directory
diff --git a/Duplicati/Server/webroot/login.html b/Duplicati/Server/webroot/login.html
index 0ad4b6887..42e3d1c42 100644
--- a/Duplicati/Server/webroot/login.html
+++ b/Duplicati/Server/webroot/login.html
@@ -22,7 +22,7 @@
<fieldset>
<p><label for="login-password">Password</label></p>
- <p><input type="password" id="login-password" value="password" onBlur="if(this.value=='')this.value='password'" onFocus="if(this.value=='password')this.value=''"></p> <!-- JS because of IE support; better: placeholder="password" -->
+ <p><input type="password" id="login-password" value="password" onBlur="if(this.value=='')this.value='password'" onFocus="if(this.value=='password')this.value=''" autofocus></p> <!-- JS because of IE support; better: placeholder="password" -->
<p><input type="submit" id="login-button" value="Sign In"></p>
diff --git a/Duplicati/Server/webroot/ngax/templates/pause.html b/Duplicati/Server/webroot/ngax/templates/pause.html
index c709054dc..7ff6abdf7 100644
--- a/Duplicati/Server/webroot/ngax/templates/pause.html
+++ b/Duplicati/Server/webroot/ngax/templates/pause.html
@@ -26,6 +26,21 @@
<label for="onehour" class="pause-60" translate translate-params-number="1">{{number}} Hour</label>
</li>
+ <li class="input" ng-click="selection.time = '4h'">
+ <input type="radio" name="fourhour" id="fourhour" ng-model="selection.time" value="4h">
+ <label for="fourhour" class="pause-240" translate translate-params-number="4">{{number}} Hours</label>
+ </li>
+
+ <li class="input" ng-click="selection.time = '8h'">
+ <input type="radio" name="eighthour" id="eighthour" ng-model="selection.time" value="8h">
+ <label for="eighthour" class="pause-480" translate translate-params-number="8">{{number}} Hours</label>
+ </li>
+
+ <li class="input" ng-click="selection.time = '24h'">
+ <input type="radio" name="twentyfourhour" id="twentyfourhour" ng-model="selection.time" value="24h">
+ <label for="twentyfourhour" class="pause-1440" translate translate-params-number="24">{{number}} Hours</label>
+ </li>
+
<li class="input" ng-click="selection.time = 'infinite'">
<input type="radio" name="infinite" id="infinite" ng-model="selection.time" value="infinite">
<label for="infinite" class="pause-x" translate>Until resumed</label>
@@ -33,4 +48,4 @@
</ul>
</form>
-</div> \ No newline at end of file
+</div>
diff --git a/Duplicati/UnitTest/UtilityTests.cs b/Duplicati/UnitTest/UtilityTests.cs
index 28c0a7991..f5ce20035 100644
--- a/Duplicati/UnitTest/UtilityTests.cs
+++ b/Duplicati/UnitTest/UtilityTests.cs
@@ -26,6 +26,46 @@ namespace Duplicati.UnitTest
{
[Test]
[Category("Utility")]
+ [TestCase("da-DK")]
+ [TestCase("en-US")]
+ [TestCase("hu-HU")]
+ [TestCase("tr-TR")]
+ public static void FilenameStringComparison(string cultureName)
+ {
+ Action<string, string> checkStringComparison = (x, y) => Assert.IsFalse(String.Equals(x, y, Utility.ClientFilenameStringComparison));
+ Action<string, string> checkStringComparer = (x, y) => Assert.IsFalse(new HashSet<string>(new[] { x }).Contains(y, Utility.ClientFilenameStringComparer));
+
+ System.Globalization.CultureInfo originalCulture = System.Globalization.CultureInfo.CurrentCulture;
+ try
+ {
+ System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName, false);
+
+ // These are equivalent with respect to hu-HU, but different with respect to en-US.
+ string ddzs = "ddzs";
+ string dzsdzs = "dzsdzs";
+ checkStringComparison(ddzs, dzsdzs);
+ checkStringComparer(ddzs, dzsdzs);
+
+ // Many cultures treat the following as equivalent.
+ string eAcuteOneCharacter = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(new byte[] { 233 }); // 'é' as one character (ALT+0233).
+ string eAcuteTwoCharacters = "\u0065\u0301"; // 'e', combined with an acute accent (U+301).
+ checkStringComparison(eAcuteOneCharacter, eAcuteTwoCharacters);
+ checkStringComparer(eAcuteOneCharacter, eAcuteTwoCharacters);
+
+ // These are equivalent with respect to en-US, but different with respect to da-DK.
+ string aDiaeresisOneCharacter = "\u00C4"; // 'A' with a diaeresis.
+ string aDiaeresisTwoCharacters = "\u0041\u0308"; // 'A', combined with a diaeresis.
+ checkStringComparison(aDiaeresisOneCharacter, aDiaeresisTwoCharacters);
+ checkStringComparer(aDiaeresisOneCharacter, aDiaeresisTwoCharacters);
+ }
+ finally
+ {
+ System.Threading.Thread.CurrentThread.CurrentCulture = originalCulture;
+ }
+ }
+
+ [Test]
+ [Category("Utility")]
public static void ForceStreamRead()
{
byte[] source = { 0x10, 0x20, 0x30, 0x40, 0x50 };
@@ -82,7 +122,7 @@ namespace Duplicati.UnitTest
// Test with custom comparer.
IEqualityComparer<string> comparer = StringComparer.OrdinalIgnoreCase;
- uniqueItems = new string[] {"a", "b", "c"};
+ uniqueItems = new string[] { "a", "b", "c" };
duplicateItems = new string[] { "a", "c" };
actualDuplicateItems = null;