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>2022-06-15 00:05:35 +0300
committerGitHub <noreply@github.com>2022-06-15 00:05:35 +0300
commit81cbb05a8ec5989152712172621694fa10657d59 (patch)
tree04d48d67b26bf11206fac6e52eddce794ff5d81d
parent1935e3f642e98fc2a08453b44cfde59a97a29626 (diff)
parent86e9aed31bd154cc915a96bfe473ae7ff756bd37 (diff)
Merge pull request #4726 from MuhammadAbrar1984/master
Added support for new backend IDrivee2(https://www.idrivee2.com)
-rw-r--r--Duplicati.sln14
-rw-r--r--Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj4
-rw-r--r--Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj6
-rw-r--r--Duplicati/CommandLine/Duplicati.CommandLine.csproj6
-rw-r--r--Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj6
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj6
-rw-r--r--Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config4
-rw-r--r--Duplicati/Library/Backend/Backblaze/Strings.cs6
-rw-r--r--Duplicati/Library/Backend/Dropbox/WebApi.cs2
-rw-r--r--Duplicati/Library/Backend/Idrivee2/Duplicati.Library.Backend.Idrivee2.csproj111
-rw-r--r--Duplicati/Library/Backend/Idrivee2/Duplicati.snkbin0 -> 596 bytes
-rw-r--r--Duplicati/Library/Backend/Idrivee2/Idrivee2Backend.cs249
-rw-r--r--Duplicati/Library/Backend/Idrivee2/Properties/AssemblyInfo.cs54
-rw-r--r--Duplicati/Library/Backend/Idrivee2/Strings.cs17
-rw-r--r--Duplicati/Library/Backend/Idrivee2/app.config6
-rw-r--r--Duplicati/Library/Backend/Idrivee2/packages.config9
-rw-r--r--Duplicati/Server/Duplicati.Server.csproj6
-rw-r--r--Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs6
-rw-r--r--Duplicati/Server/app.config4
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js78
-rw-r--r--Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js1
-rw-r--r--Duplicati/Server/webroot/ngax/templates/backends/e2.html18
-rw-r--r--Duplicati/Service/Runner.cs12
-rw-r--r--Duplicati/Service/app.config2
-rwxr-xr-xDuplicati/UnitTest/BackendToolTests.cs118
-rw-r--r--Duplicati/UnitTest/Duplicati.UnitTest.csproj4
-rw-r--r--Installer/Docker/README.md2
-rw-r--r--README.md2
28 files changed, 654 insertions, 99 deletions
diff --git a/Duplicati.sln b/Duplicati.sln
index 668a20ee0..d36769dc3 100644
--- a/Duplicati.sln
+++ b/Duplicati.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29102.190
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31919.166
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Utility", "Duplicati\Library\Utility\Duplicati.Library.Utility.csproj", "{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}"
EndProject
@@ -107,7 +107,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.T
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Tardigrade", "Duplicati\Library\Backend\Tardigrade\Duplicati.Library.Backend.Tardigrade.csproj", "{9A04CB37-DA72-4008-9703-3AC5191974E9}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.IDrive", "Duplicati\Library\Backend\IDrive\Duplicati.Library.Backend.IDrive.csproj", "{C16639F6-DACC-4DD9-86CD-8B937516B340}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.Idrivee2", "Duplicati\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj", "{6B594D23-B629-465C-B799-70EE9E56C218}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -323,10 +323,10 @@ Global
{9A04CB37-DA72-4008-9703-3AC5191974E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A04CB37-DA72-4008-9703-3AC5191974E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A04CB37-DA72-4008-9703-3AC5191974E9}.Release|Any CPU.Build.0 = Release|Any CPU
- {C16639F6-DACC-4DD9-86CD-8B937516B340}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C16639F6-DACC-4DD9-86CD-8B937516B340}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C16639F6-DACC-4DD9-86CD-8B937516B340}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C16639F6-DACC-4DD9-86CD-8B937516B340}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6B594D23-B629-465C-B799-70EE9E56C218}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6B594D23-B629-465C-B799-70EE9E56C218}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6B594D23-B629-465C-B799-70EE9E56C218}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6B594D23-B629-465C-B799-70EE9E56C218}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj b/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
index 69d035db8..a0fa7bbb8 100644
--- a/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
+++ b/Duplicati/CommandLine/BackendTester/Duplicati.CommandLine.BackendTester.csproj
@@ -70,6 +70,10 @@
<Project>{b20a7cee-9c5b-47b9-8b76-bc85adfe8493}</Project>
<Name>Duplicati.Library.Backend.Dropbox</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
+ <Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
+ <Name>Duplicati.Library.Backend.Idrivee2</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
<Name>Duplicati.Library.Backend.Jottacloud</Name>
diff --git a/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj b/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
index be7aa3971..1140e4b1f 100644
--- a/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
+++ b/Duplicati/CommandLine/BackendTool/Duplicati.CommandLine.BackendTool.csproj
@@ -64,9 +64,9 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
- <ProjectReference Include="..\..\Library\Backend\IDrive\Duplicati.Library.Backend.IDrive.csproj">
- <Project>{c16639f6-dacc-4dd9-86cd-8b937516b340}</Project>
- <Name>Duplicati.Library.Backend.IDrive</Name>
+ <ProjectReference Include="..\..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
+ <Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
+ <Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
diff --git a/Duplicati/CommandLine/Duplicati.CommandLine.csproj b/Duplicati/CommandLine/Duplicati.CommandLine.csproj
index efd5352ea..419dd61b4 100644
--- a/Duplicati/CommandLine/Duplicati.CommandLine.csproj
+++ b/Duplicati/CommandLine/Duplicati.CommandLine.csproj
@@ -95,9 +95,9 @@
<Project>{FC9B7611-836F-4127-8B44-A7C31F506807}</Project>
<Name>Duplicati.Library.Backend.File</Name>
</ProjectReference>
- <ProjectReference Include="..\Library\Backend\IDrive\Duplicati.Library.Backend.IDrive.csproj">
- <Project>{c16639f6-dacc-4dd9-86cd-8b937516b340}</Project>
- <Name>Duplicati.Library.Backend.IDrive</Name>
+ <ProjectReference Include="..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
+ <Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
+ <Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
diff --git a/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj b/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
index 204c9690a..ccd5c4d80 100644
--- a/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
+++ b/Duplicati/CommandLine/RecoveryTool/Duplicati.CommandLine.RecoveryTool.csproj
@@ -98,9 +98,9 @@
<Project>{D60AD540-0E7D-40CE-83AE-D26E01FFE9B8}</Project>
<Name>Duplicati.Library.Backend.HubiC</Name>
</ProjectReference>
- <ProjectReference Include="..\..\Library\Backend\IDrive\Duplicati.Library.Backend.IDrive.csproj">
- <Project>{c16639f6-dacc-4dd9-86cd-8b937516b340}</Project>
- <Name>Duplicati.Library.Backend.IDrive</Name>
+ <ProjectReference Include="..\..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
+ <Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
+ <Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
index 542d5e9d4..c0fb19547 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj
@@ -189,9 +189,9 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
- <ProjectReference Include="..\..\Library\Backend\IDrive\Duplicati.Library.Backend.IDrive.csproj">
- <Project>{c16639f6-dacc-4dd9-86cd-8b937516b340}</Project>
- <Name>Duplicati.Library.Backend.IDrive</Name>
+ <ProjectReference Include="..\..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
+ <Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
+ <Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config b/Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config
index 9eaab5dd7..7cfe686fd 100644
--- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config
+++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/app.config
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
- <startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" /></startup>
+ <startup useLegacyV2RuntimeActivationPolicy="true">
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
+ </startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
diff --git a/Duplicati/Library/Backend/Backblaze/Strings.cs b/Duplicati/Library/Backend/Backblaze/Strings.cs
index 168553757..b4d0b2429 100644
--- a/Duplicati/Library/Backend/Backblaze/Strings.cs
+++ b/Duplicati/Library/Backend/Backblaze/Strings.cs
@@ -14,9 +14,9 @@ namespace Duplicati.Library.Backend.Strings {
public static string NoB2UserIDError { get { return LC.L(@"No ""B2 Cloud Storage Account ID"" given"); } }
public static string Description { get { return LC.L(@"This backend can read and write data to the Backblaze B2 Cloud Storage. Allowed formats are: ""b2://bucketname/prefix"""); } }
public static string B2createbuckettypeDescriptionLong { get { return LC.L(@"By default, a private bucket is created. Use this option to set the bucket type. Refer to the B2 documentation for allowed types "); } }
- public static string B2createbuckettypeDescriptionShort { get { return LC.L(@"The bucket type used when creating a bucket"); } }
- public static string B2pagesizeDescriptionLong { get { return LC.L(@"Use this option to set the page size for listing contents of B2 buckets. A lower number means less data, but can increase the number of Class C transaction on B2. Suggested values are between 100 and 1000"); } }
- public static string B2pagesizeDescriptionShort { get { return LC.L(@"The size of file-listing pages"); } }
+ public static string B2createbuckettypeDescriptionShort { get { return LC.L(@"The bucket type used when creating a bucket"); } }
+ public static string B2pagesizeDescriptionLong { get { return LC.L(@"Use this option to set the page size for listing contents of B2 buckets. A lower number means less data, but can increase the number of Class C transaction on B2. Suggested values are between 100 and 1000"); } }
+ public static string B2pagesizeDescriptionShort { get { return LC.L(@"The size of file-listing pages"); } }
public static string B2downloadurlDescriptionLong { get { return LC.L(@"Change this if you want to use your custom domain to download files, and uploading will not be affected. The default download url depends on your account and looks like ""https://f00X.backblazeb2.com"""); } }
public static string B2downloadurlDescriptionShort { get { return LC.L(@"The base URL to use for downloading files"); } }
public static string InvalidPageSizeError(string argname, string value) { return LC.L(@"The setting ""{0}"" is invalid for ""{1}"", it must be an integer larger than zero", value, argname); }
diff --git a/Duplicati/Library/Backend/Dropbox/WebApi.cs b/Duplicati/Library/Backend/Dropbox/WebApi.cs
index 1d0f2af86..376dd4ec9 100644
--- a/Duplicati/Library/Backend/Dropbox/WebApi.cs
+++ b/Duplicati/Library/Backend/Dropbox/WebApi.cs
@@ -41,7 +41,7 @@ namespace Duplicati.Library.Backend.WebApi
return Uri.UriBuilder(Url.API, Path.DeleteFolder);
}
- public static string UploadSessionStartUrl()
+ public static string UploadSessionStartUrl()
{
return Uri.UriBuilder(Url.CONTENT_API_URL, Path.UploadSessionStart);
}
diff --git a/Duplicati/Library/Backend/Idrivee2/Duplicati.Library.Backend.Idrivee2.csproj b/Duplicati/Library/Backend/Idrivee2/Duplicati.Library.Backend.Idrivee2.csproj
new file mode 100644
index 000000000..1447efbf7
--- /dev/null
+++ b/Duplicati/Library/Backend/Idrivee2/Duplicati.Library.Backend.Idrivee2.csproj
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{6B594D23-B629-465C-B799-70EE9E56C218}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Duplicati.Library.Backend</RootNamespace>
+ <AssemblyName>Duplicati.Library.Backend.idrivee2</AssemblyName>
+ <AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
+ <TargetFrameworkProfile />
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <UseMSBuildEngine>false</UseMSBuildEngine>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>false</SignAssembly>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL">
+ <HintPath>..\..\..\..\packages\AWSSDK.Core.3.3.103.37\lib\net45\AWSSDK.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="AWSSDK.S3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL">
+ <HintPath>..\..\..\..\packages\AWSSDK.S3.3.3.104.25\lib\net45\AWSSDK.S3.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="RestSharp, Version=106.3.1.0, Culture=neutral, PublicKeyToken=598062e77f915f75">
+ <HintPath>..\..\..\..\packages\RestSharp.106.3.1\lib\net452\RestSharp.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Reactive, Version=4.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263">
+ <HintPath>..\..\..\..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Reactive.Linq, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263">
+ <HintPath>..\..\..\..\packages\System.Reactive.Linq.4.0.0\lib\net46\System.Reactive.Linq.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Web" />
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="WindowsBase" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Idrivee2Backend.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Strings.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Utility\Duplicati.Library.Utility.csproj">
+ <Project>{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}</Project>
+ <Name>Duplicati.Library.Utility</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
+ <Project>{C5899F45-B0FF-483C-9D38-24A9FCAAB237}</Project>
+ <Name>Duplicati.Library.Interface</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Localization\Duplicati.Library.Localization.csproj">
+ <Project>{B68F2214-951F-4F78-8488-66E1ED3F50BF}</Project>
+ <Name>Duplicati.Library.Localization</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Logging\Duplicati.Library.Logging.csproj">
+ <Project>{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}</Project>
+ <Name>Duplicati.Library.Logging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Common\Duplicati.Library.Common.csproj">
+ <Project>{D63E53E4-A458-4C2F-914D-92F715F58ACF}</Project>
+ <Name>Duplicati.Library.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\S3\Duplicati.Library.Backend.S3.csproj">
+ <Project>{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}</Project>
+ <Name>Duplicati.Library.Backend.S3</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="Duplicati.snk" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/Duplicati/Library/Backend/Idrivee2/Duplicati.snk b/Duplicati/Library/Backend/Idrivee2/Duplicati.snk
new file mode 100644
index 000000000..e0c1e2dd8
--- /dev/null
+++ b/Duplicati/Library/Backend/Idrivee2/Duplicati.snk
Binary files differ
diff --git a/Duplicati/Library/Backend/Idrivee2/Idrivee2Backend.cs b/Duplicati/Library/Backend/Idrivee2/Idrivee2Backend.cs
new file mode 100644
index 000000000..aef41259b
--- /dev/null
+++ b/Duplicati/Library/Backend/Idrivee2/Idrivee2Backend.cs
@@ -0,0 +1,249 @@
+#region Disclaimer / License
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using Duplicati.Library.Common.IO;
+using Duplicati.Library.Interface;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Duplicati.Library.Backend
+{
+ public class Idrivee2Backend : IBackend, IStreamingBackend
+ {
+ private static readonly string LOGTAG = Logging.Log.LogTagFromType<Idrivee2Backend>();
+
+ static Idrivee2Backend()
+ {
+
+ }
+
+ private readonly string m_prefix;
+ private readonly string m_bucket;
+
+ private IS3Client m_s3Client;
+
+ public Idrivee2Backend()
+ {
+ }
+
+ public Idrivee2Backend(string url, Dictionary<string, string> options)
+ {
+ var uri = new Utility.Uri(url);
+ m_bucket = uri.Host;
+ m_prefix = uri.Path;
+ m_prefix = m_prefix.Trim();
+ if (m_prefix.Length != 0)
+ {
+ m_prefix = Util.AppendDirSeparator(m_prefix, "/");
+ }
+ string accessKeyId = null;
+ string accessKeySecret = null;
+
+ if (options.ContainsKey("auth-username"))
+ accessKeyId = options["auth-username"];
+ if (options.ContainsKey("auth-password"))
+ accessKeySecret = options["auth-password"];
+
+ if (options.ContainsKey("access_key_id"))
+ accessKeyId = options["access_key_id"];
+ if (options.ContainsKey("secret_access_key"))
+ accessKeySecret = options["secret_access_key"];
+
+ if (string.IsNullOrEmpty(accessKeyId))
+ throw new UserInformationException(Strings.Idrivee2Backend.NoKeyIdError, "Idrivee2NoKeyId");
+ if (string.IsNullOrEmpty(accessKeySecret))
+ throw new UserInformationException(Strings.Idrivee2Backend.NoKeySecretError, "Idrivee2NoKeySecret");
+ string host= GetRegionEndpoint("https://api.idrivee2.com/api/service/get_region_end_point/" + accessKeyId);
+
+
+ m_s3Client = new S3AwsClient(accessKeyId, accessKeySecret, null, host, null, true, options);
+
+ }
+
+ public string GetRegionEndpoint(string url)
+ {
+ try
+ {
+ System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
+ req.Method = System.Net.WebRequestMethods.Http.Get;
+
+ Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req);
+
+ using (System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)areq.GetResponse())
+ {
+ int code = (int)resp.StatusCode;
+ if (code < 200 || code >= 300) //For some reason Mono does not throw this automatically
+ throw new Exception("Failed to fetch region endpoint");
+ using (var s = areq.GetResponseStream())
+ {
+ using (var reader = new StreamReader(s))
+ {
+ string endpoint = reader.ReadToEnd();
+ return endpoint;
+ }
+ }
+ }
+ }
+ catch (System.Net.WebException wex)
+ {
+ //Convert to better exception
+ throw new Exception("Failed to fetch region endpoint");
+ }
+ }
+
+ #region IBackend Members
+
+ public string DisplayName
+ {
+ get { return Strings.Idrivee2Backend.DisplayName; }
+ }
+
+ public string ProtocolKey => "e2";
+
+ public bool SupportsStreaming => true;
+
+
+ public IEnumerable<IFileEntry> List()
+ {
+ foreach (IFileEntry file in Connection.ListBucket(m_bucket, m_prefix))
+ {
+ ((FileEntry)file).Name = file.Name.Substring(m_prefix.Length);
+ if (file.Name.StartsWith("/", StringComparison.Ordinal) && !m_prefix.StartsWith("/", StringComparison.Ordinal))
+ ((FileEntry)file).Name = file.Name.Substring(1);
+
+ yield return file;
+ }
+ }
+
+ public async Task PutAsync(string remotename, string localname, CancellationToken cancelToken)
+ {
+ using (FileStream fs = File.Open(localname, FileMode.Open, FileAccess.Read, FileShare.Read))
+ await PutAsync(remotename, fs, cancelToken);
+ }
+
+ public async Task PutAsync(string remotename, Stream input, CancellationToken cancelToken)
+ {
+ await Connection.AddFileStreamAsync(m_bucket, GetFullKey(remotename), input, cancelToken);
+ }
+
+ public void Get(string remotename, string localname)
+ {
+ using (var fs = File.Open(localname, FileMode.Create, FileAccess.Write, FileShare.None))
+ Get(remotename, fs);
+ }
+
+ public void Get(string remotename, Stream output)
+ {
+ Connection.GetFileStream(m_bucket, GetFullKey(remotename), output);
+ }
+
+ public void Delete(string remotename)
+ {
+ Connection.DeleteObject(m_bucket, GetFullKey(remotename));
+ }
+
+ public IList<ICommandLineArgument> SupportedCommands
+ {
+ get
+ {
+
+ var defaults = new Amazon.S3.AmazonS3Config();
+
+ var exts =
+ typeof(Amazon.S3.AmazonS3Config).GetProperties().Where(x => x.CanRead && x.CanWrite && (x.PropertyType == typeof(string) || x.PropertyType == typeof(bool) || x.PropertyType == typeof(int) || x.PropertyType == typeof(long) || x.PropertyType.IsEnum))
+ .Select(x => (ICommandLineArgument)new CommandLineArgument(
+ "s3-ext-" + x.Name.ToLowerInvariant(),
+ x.PropertyType == typeof(bool) ? CommandLineArgument.ArgumentType.Boolean : x.PropertyType.IsEnum ? CommandLineArgument.ArgumentType.Enumeration : CommandLineArgument.ArgumentType.String,
+ x.Name,
+ string.Format("Extended option {0}", x.Name),
+ string.Format("{0}", x.GetValue(defaults)),
+ null,
+ x.PropertyType.IsEnum ? Enum.GetNames(x.PropertyType) : null));
+
+
+ var normal = new ICommandLineArgument[] {
+
+ new CommandLineArgument("access_key_secret", CommandLineArgument.ArgumentType.Password, Strings.Idrivee2Backend.KeySecretDescriptionShort, Strings.Idrivee2Backend.KeySecretDescriptionLong, null, new[]{"auth-password"}, null),
+ new CommandLineArgument("access_key_id", CommandLineArgument.ArgumentType.String, Strings.Idrivee2Backend.KeyIDDescriptionShort, Strings.Idrivee2Backend.KeyIDDescriptionLong,null, new[]{"auth-username"}, null)
+
+ };
+
+ return normal.Union(exts).ToList();
+
+ }
+ }
+
+ public string Description
+ {
+ get
+ {
+ return Strings.Idrivee2Backend.Description;
+ }
+ }
+
+ public void Test()
+ {
+ this.TestList();
+ }
+
+ public void CreateFolder()
+ {
+ //S3 does not complain if the bucket already exists
+ Connection.AddBucket(m_bucket);
+ }
+
+ #endregion
+
+ #region IRenameEnabledBackend Members
+
+ public void Rename(string source, string target)
+ {
+ Connection.RenameFile(m_bucket, GetFullKey(source), GetFullKey(target));
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ m_s3Client?.Dispose();
+ m_s3Client = null;
+ }
+
+ #endregion
+
+ private IS3Client Connection => m_s3Client;
+
+ public string[] DNSName
+ {
+ get { return new[] { m_s3Client.GetDnsHost() }; }
+ }
+
+ private string GetFullKey(string name)
+ {
+ //AWS SDK encodes the filenames correctly
+ return m_prefix + name;
+ }
+ }
+}
diff --git a/Duplicati/Library/Backend/Idrivee2/Properties/AssemblyInfo.cs b/Duplicati/Library/Backend/Idrivee2/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..e169e70d0
--- /dev/null
+++ b/Duplicati/Library/Backend/Idrivee2/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+#region Disclaimer / License
+// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("S3")]
+[assembly: AssemblyDescription("An S3-compatible backend for Duplicati")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Duplicati Team")]
+[assembly: AssemblyProduct("Duplicati.Backend.S3")]
+[assembly: AssemblyCopyright("LGPL, Copyright © Duplicati Team 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("afa68988-4d82-490e-8044-acbc7d52ef4f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.0.0.7")]
+[assembly: AssemblyFileVersion("2.0.0.7")]
diff --git a/Duplicati/Library/Backend/Idrivee2/Strings.cs b/Duplicati/Library/Backend/Idrivee2/Strings.cs
new file mode 100644
index 000000000..f80a5f159
--- /dev/null
+++ b/Duplicati/Library/Backend/Idrivee2/Strings.cs
@@ -0,0 +1,17 @@
+using Duplicati.Library.Localization.Short;
+namespace Duplicati.Library.Backend.Strings {
+ internal static class Idrivee2Backend {
+ public static string KeySecretDescriptionLong { get { return LC.L(@"The ""Access Key Secret "" can be obtained after logging into your IDrive e2 account, this can also be supplied through the ""auth-password"" property."); } }
+ public static string KeySecretDescriptionShort { get { return LC.L(@"The ""Access Key Secret"""); } }
+ public static string KeyIDDescriptionLong { get { return LC.L(@"The ""Access Key ID"" can be obtained after logging into your IDrive e2 account., this can also be supplied through the ""auth-username"" property."); } }
+ public static string KeyIDDescriptionShort { get { return LC.L(@"The ""Access Key ID"""); } }
+
+ public static string BucketNameOrPathDescriptionLong { get { return LC.L(@"The ""Bucket Name or Complete Path"" is name of target bucket or complete of a folder inside the bucket."); } }
+ public static string BucketNameOrPathDescriptionShort { get { return LC.L(@"The ""Bucket Name or Complete Path"""); } }
+
+ public static string DisplayName { get { return LC.L(@"IDrive e2"); } }
+ public static string NoKeySecretError { get { return LC.L(@"No Access key secret given"); } }
+ public static string NoKeyIdError { get { return LC.L(@"No Access key Id given"); } }
+ public static string Description { get; set; }
+ }
+}
diff --git a/Duplicati/Library/Backend/Idrivee2/app.config b/Duplicati/Library/Backend/Idrivee2/app.config
new file mode 100644
index 000000000..ba98fc967
--- /dev/null
+++ b/Duplicati/Library/Backend/Idrivee2/app.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <startup>
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/>
+ </startup>
+</configuration>
diff --git a/Duplicati/Library/Backend/Idrivee2/packages.config b/Duplicati/Library/Backend/Idrivee2/packages.config
new file mode 100644
index 000000000..52f490cda
--- /dev/null
+++ b/Duplicati/Library/Backend/Idrivee2/packages.config
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="AWSSDK.Core" version="3.3.103.37" targetFramework="net471" />
+ <package id="AWSSDK.S3" version="3.3.104.25" targetFramework="net471" />
+ <package id="Minio" version="3.1.7" targetFramework="net471" />
+ <package id="RestSharp" version="106.3.1" targetFramework="net471" />
+ <package id="System.Reactive" version="4.0.0" targetFramework="net471" />
+ <package id="System.Reactive.Linq" version="4.0.0" targetFramework="net471" />
+</packages> \ No newline at end of file
diff --git a/Duplicati/Server/Duplicati.Server.csproj b/Duplicati/Server/Duplicati.Server.csproj
index 2daf6db29..f661556c9 100644
--- a/Duplicati/Server/Duplicati.Server.csproj
+++ b/Duplicati/Server/Duplicati.Server.csproj
@@ -168,9 +168,9 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
- <ProjectReference Include="..\Library\Backend\IDrive\Duplicati.Library.Backend.IDrive.csproj">
- <Project>{c16639f6-dacc-4dd9-86cd-8b937516b340}</Project>
- <Name>Duplicati.Library.Backend.IDrive</Name>
+ <ProjectReference Include="..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
+ <Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
+ <Name>Duplicati.Library.Backend.Idrivee2</Name>
</ProjectReference>
<ProjectReference Include="..\Library\Backend\Jottacloud\Duplicati.Library.Backend.Jottacloud.csproj">
<Project>{2cd5dbc3-3da6-432d-ba97-f0b8d24501c2}</Project>
diff --git a/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs b/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs
index 1df9d13cf..cb09037d8 100644
--- a/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs
+++ b/Duplicati/Server/WebServer/RESTMethods/ServerSettings.cs
@@ -75,10 +75,10 @@ namespace Duplicati.Server.WebServer.RESTMethods
var serversettings = data.Where(x => !string.IsNullOrWhiteSpace(x.Key)).ToDictionary(x => x.Key, x => x.Key.StartsWith("--", StringComparison.Ordinal) ? null : x.Value);
var globalsettings = data.Where(x => !string.IsNullOrWhiteSpace(x.Key) && x.Key.StartsWith("--", StringComparison.Ordinal));
- serversettings.Remove("server-ssl-certificate");
- serversettings.Remove("ServerSSLCertificate");
+ serversettings.Remove("server-ssl-certificate");
+ serversettings.Remove("ServerSSLCertificate");
- if (serversettings.Any())
+ if (serversettings.Any())
Program.DataConnection.ApplicationSettings.UpdateSettings(serversettings, false);
if (globalsettings.Any())
diff --git a/Duplicati/Server/app.config b/Duplicati/Server/app.config
index 9eaab5dd7..7cfe686fd 100644
--- a/Duplicati/Server/app.config
+++ b/Duplicati/Server/app.config
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
- <startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" /></startup>
+ <startup useLegacyV2RuntimeActivationPolicy="true">
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
+ </startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js
index c9abb3ebf..7ec3a522c 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js
@@ -32,8 +32,9 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
EditUriBackendConfig.templates['sia'] = 'templates/backends/sia.html';
EditUriBackendConfig.templates['storj'] = 'templates/backends/storj.html';
EditUriBackendConfig.templates['tardigrade'] = 'templates/backends/tardigrade.html';
- EditUriBackendConfig.templates['rclone'] = 'templates/backends/rclone.html';
- EditUriBackendConfig.templates['cos'] = 'templates/backends/cos.html';
+ EditUriBackendConfig.templates['rclone'] = 'templates/backends/rclone.html';
+ EditUriBackendConfig.templates['cos'] = 'templates/backends/cos.html';
+ EditUriBackendConfig.templates['e2'] = 'templates/backends/e2.html';
EditUriBackendConfig.testers['s3'] = function(scope, callback) {
@@ -481,6 +482,17 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
delete options[nukeopts[x]];
};
+ EditUriBackendConfig.parsers['e2'] = function (scope, module, server, port, path, options) {
+ if (options['--access-key-id'])
+ scope.Username = options['--access-key-id'];
+ if (options['--access-key-secret'])
+ scope.Password = options['--access-key-secret'];
+
+ var nukeopts = ['--access-key-id', '--access-key-secret'];
+ for (var x in nukeopts)
+ delete options[nukeopts[x]];
+ };
+
EditUriBackendConfig.parsers['mega'] = function (scope, module, server, port, path, options) {
EditUriBackendConfig.mergeServerAndPath(scope);
};
@@ -759,6 +771,24 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
return url;
};
+ EditUriBackendConfig.builders['e2'] = function (scope) {
+ var opts = {};
+
+ EditUriBackendConfig.merge_in_advanced_options(scope, opts);
+
+ // Slightly better error message
+ scope.Folder = scope.Server;
+
+ var url = AppUtils.format('{0}://{1}/{2}{3}',
+ scope.Backend.Key,
+ scope.Server || '',
+ scope.Path || '',
+ AppUtils.encodeDictAsUrl(opts)
+ );
+
+ return url;
+ };
+
EditUriBackendConfig.builders['mega'] = function (scope) {
var opts = {};
@@ -1246,4 +1276,48 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo,
if (res)
continuation();
};
+
+ EditUriBackendConfig.validaters['e2'] = function (scope, continuation) {
+ var res =
+ EditUriBackendConfig.require_field(scope, 'Username', gettextCatalog.getString('Idrivee2 Access Key Id')) &&
+ EditUriBackendConfig.require_field(scope, 'Password', gettextCatalog.getString('Idrivee2 Access Key Secret')) &&
+ EditUriBackendConfig.require_field(scope, 'Server', gettextCatalog.getString('Bucket Name'));
+
+ if (res) {
+ var re = new RegExp('[^A-Za-z0-9-]');
+ var bucketname = scope['Server'] || '';
+ var ix = bucketname.search(/[^A-Za-z0-9-]/g);
+
+ if (ix >= 0) {
+ EditUriBackendConfig.show_error_dialog(gettextCatalog.getString('The \'{{fieldname}}\' field contains an invalid character: {{character}} (value: {{value}}, index: {{pos}})', {
+ value: bucketname[ix].charCodeAt(),
+ pos: ix,
+ character: bucketname[ix],
+ fieldname: gettextCatalog.getString('Bucket Name')
+ }));
+ res = false;
+ }
+ }
+
+ if (res) {
+ var pathname = scope['Path'] || '';
+ for (var i = pathname.length - 1; i >= 0; i--) {
+ var char = pathname.charCodeAt(i);
+
+ if (char == '\\'.charCodeAt(0) || char == 127 || char < 32) {
+ EditUriBackendConfig.show_error_dialog(gettextCatalog.getString('The \'{{fieldname}}\' field contains an invalid character: {{character}} (value: {{value}}, index: {{pos}})', {
+ value: char,
+ pos: i,
+ character: pathname[i],
+ fieldname: gettextCatalog.getString('Path')
+ }));
+ res = false;
+ break;
+ }
+ }
+ }
+
+ if (res)
+ continuation();
+ };
});
diff --git a/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js b/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js
index a05af144a..deef0c821 100644
--- a/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js
+++ b/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js
@@ -53,6 +53,7 @@ backupApp.service('SystemInfo', function($rootScope, $timeout, $cookies, AppServ
},
local: {'file': null},
prop: {
+ 'e2':null,
's3': null,
'azure': null,
'googledrive': null,
diff --git a/Duplicati/Server/webroot/ngax/templates/backends/e2.html b/Duplicati/Server/webroot/ngax/templates/backends/e2.html
new file mode 100644
index 000000000..86af8a762
--- /dev/null
+++ b/Duplicati/Server/webroot/ngax/templates/backends/e2.html
@@ -0,0 +1,18 @@
+<div class="input text">
+ <label for="e2_access_key" translate>Access Key Id</label>
+ <input type="text" name="e2_access_key" id="e2_access_key" ng-model="$parent.Username" placeholder="{{'Idrivee2 Access Id' | translate}}" />
+</div>
+<div class="input password">
+ <label for="e2_access_secret" translate>Access Key Secret</label>
+ <input autocomplete="new-password" type="password" name="e2_access_secret" id="e2_access_secret" ng-model="$parent.Password" placeholder="{{'Idrivee2 Access Secret' | translate}}" />
+</div>
+
+<div class="input text">
+ <label for="e2_bucket" translate>Bucket name</label>
+ <input type="text" id="b2_bucket" ng-model="$parent.Server" placeholder="{{'Bucket name' | translate}}" />
+</div>
+
+<div class="input text">
+ <label for="e2_path" translate>Folder path</label>
+ <input type="text" name="e2_path" id="e2_path" ng-model="$parent.Path" placeholder="{{'Path or subfolder in the bucket' | translate}}" />
+</div>
diff --git a/Duplicati/Service/Runner.cs b/Duplicati/Service/Runner.cs
index 4f2ae0f76..3922f7910 100644
--- a/Duplicati/Service/Runner.cs
+++ b/Duplicati/Service/Runner.cs
@@ -79,13 +79,13 @@ namespace Duplicati.Service
m_reportMessage(string.Format("Starting process {0} with cmd args {1}", exec, cmdargs), false);
- var pr = new System.Diagnostics.ProcessStartInfo(exec, cmdargs)
- {
- UseShellExecute = false,
- RedirectStandardInput = true,
+ var pr = new System.Diagnostics.ProcessStartInfo(exec, cmdargs)
+ {
+ UseShellExecute = false,
+ RedirectStandardInput = true,
RedirectStandardOutput = true,
- RedirectStandardError = false,
- WorkingDirectory = path
+ RedirectStandardError = false,
+ WorkingDirectory = path
};
if (!m_terminate)
diff --git a/Duplicati/Service/app.config b/Duplicati/Service/app.config
index f8e90b9d2..29826702b 100644
--- a/Duplicati/Service/app.config
+++ b/Duplicati/Service/app.config
@@ -20,4 +20,4 @@
</dependentAssembly>
</assemblyBinding>
</runtime>
-</configuration>
+</configuration> \ No newline at end of file
diff --git a/Duplicati/UnitTest/BackendToolTests.cs b/Duplicati/UnitTest/BackendToolTests.cs
index 6c4b17122..e12b4b484 100755
--- a/Duplicati/UnitTest/BackendToolTests.cs
+++ b/Duplicati/UnitTest/BackendToolTests.cs
@@ -1,58 +1,62 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Duplicati.Library.Interface;
-using Duplicati.Library.Main;
-using NUnit.Framework;
-
-namespace Duplicati.UnitTest
-{
- [TestFixture]
- public class BackendToolTests : BasicSetupHelper
- {
- [Test]
- [Category("BackendTool")]
- public void Get()
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Duplicati.Library.Interface;
+using Duplicati.Library.Main;
+using NUnit.Framework;
+
+namespace Duplicati.UnitTest
+{
+ [TestFixture]
+ public class BackendToolTests : BasicSetupHelper
+ {
+ [Test]
+ [Category("BackendTool")]
+ public void Get()
{
- // Files to create in MB.
- int[] fileSizes = {10, 20, 30};
- foreach (int size in fileSizes)
- {
- var data = new byte[size * 1024 * 1024];
- var rng = new Random();
- rng.NextBytes(data);
- File.WriteAllBytes(Path.Combine(DATAFOLDER, size + "MB"), data);
- }
-
- // Run a backup.
- var options = new Dictionary<string, string>(TestOptions);
- var backendURL = "file://" + this.TARGETFOLDER;
- using (Controller c = new Controller(backendURL, options, null))
- {
- var backupResults = c.Backup(new[] {DATAFOLDER});
- Assert.AreEqual(0, backupResults.Errors.Count());
- Assert.AreEqual(0, backupResults.Warnings.Count());
- }
-
- // Get the backend files using absolute paths
- var absoluteDownloadFolder = Path.Combine(RESTOREFOLDER, "target-files-absolute");
- Directory.CreateDirectory(absoluteDownloadFolder);
- foreach (var targetFile in Directory.GetFiles(TARGETFOLDER))
- {
- // Absolute path
+ // Files to create in MB.
+ int[] fileSizes = {10, 20, 30};
+ foreach (int size in fileSizes)
+ {
+ var data = new byte[size * 1024 * 1024];
+ var rng = new Random();
+ rng.NextBytes(data);
+ File.WriteAllBytes(Path.Combine(DATAFOLDER, size + "MB"), data);
+ }
+
+ // Run a backup.
+ var options = new Dictionary<string, string>(TestOptions);
+ var backendURL = "file://" + this.TARGETFOLDER;
+ using (Controller c = new Controller(backendURL, options, null))
+ {
+ var backupResults = c.Backup(new[] {DATAFOLDER});
+ foreach (var backupResultsWarning in backupResults.Warnings)
+ {
+ TestContext.WriteLine("Backend result warning:" + backupResultsWarning);
+ }
+ Assert.AreEqual(0, backupResults.Errors.Count());
+ Assert.AreEqual(0, backupResults.Warnings.Count());
+ }
+
+ // Get the backend files using absolute paths
+ var absoluteDownloadFolder = Path.Combine(RESTOREFOLDER, "target-files-absolute");
+ Directory.CreateDirectory(absoluteDownloadFolder);
+ foreach (var targetFile in Directory.GetFiles(TARGETFOLDER))
+ {
+ // Absolute path
var downloadFileName = Path.Combine(absoluteDownloadFolder, Path.GetFileName(targetFile));
var status = CommandLine.BackendTool.Program.RealMain(new[] { "GET", $"{backendURL}", $"{downloadFileName}" });
- Assert.AreEqual(0, status);
- Assert.IsTrue(File.Exists(downloadFileName));
- TestUtils.AssertFilesAreEqual(targetFile, downloadFileName, false, downloadFileName);
- }
-
- // Get the backend files using relative paths
- var relativeDownloadFolder = Path.Combine(RESTOREFOLDER, "target-files-relative");
- Directory.CreateDirectory(relativeDownloadFolder);
- var originalCurrentDirectory = Directory.GetCurrentDirectory();
- Directory.SetCurrentDirectory(relativeDownloadFolder);
+ Assert.AreEqual(0, status);
+ Assert.IsTrue(File.Exists(downloadFileName));
+ TestUtils.AssertFilesAreEqual(targetFile, downloadFileName, false, downloadFileName);
+ }
+
+ // Get the backend files using relative paths
+ var relativeDownloadFolder = Path.Combine(RESTOREFOLDER, "target-files-relative");
+ Directory.CreateDirectory(relativeDownloadFolder);
+ var originalCurrentDirectory = Directory.GetCurrentDirectory();
+ Directory.SetCurrentDirectory(relativeDownloadFolder);
try
{
foreach (var targetFile in Directory.GetFiles(TARGETFOLDER))
@@ -63,12 +67,12 @@ namespace Duplicati.UnitTest
Assert.AreEqual(0, status);
Assert.IsTrue(File.Exists(downloadFileName));
TestUtils.AssertFilesAreEqual(targetFile, downloadFileName, false, downloadFileName);
- }
- }
- finally
+ }
+ }
+ finally
{
- Directory.SetCurrentDirectory(originalCurrentDirectory);
- }
+ Directory.SetCurrentDirectory(originalCurrentDirectory);
+ }
}
}
} \ No newline at end of file
diff --git a/Duplicati/UnitTest/Duplicati.UnitTest.csproj b/Duplicati/UnitTest/Duplicati.UnitTest.csproj
index e0459ce24..995e4471e 100644
--- a/Duplicati/UnitTest/Duplicati.UnitTest.csproj
+++ b/Duplicati/UnitTest/Duplicati.UnitTest.csproj
@@ -118,6 +118,10 @@
<Project>{F61679A9-E5DE-468A-B5A4-05F92D0143D2}</Project>
<Name>Duplicati.Library.Backend.FTP</Name>
</ProjectReference>
+ <ProjectReference Include="..\Library\Backend\Idrivee2\Duplicati.Library.Backend.Idrivee2.csproj">
+ <Project>{6b594d23-b629-465c-b799-70ee9e56c218}</Project>
+ <Name>Duplicati.Library.Backend.Idrivee2</Name>
+ </ProjectReference>
<ProjectReference Include="..\Library\Backend\OneDrive\Duplicati.Library.Backend.OneDrive.csproj">
<Project>{CCD76347-7DC7-4B42-B7E1-E500E624CAC3}</Project>
<Name>Duplicati.Library.Backend.OneDrive</Name>
diff --git a/Installer/Docker/README.md b/Installer/Docker/README.md
index 3928c17d5..e905ed620 100644
--- a/Installer/Docker/README.md
+++ b/Installer/Docker/README.md
@@ -1,7 +1,7 @@
# [Duplicati](https://www.duplicati.com)
Duplicati is a free, open source, backup client that securely stores encrypted, incremental, compressed backups on cloud storage services and remote file servers. It works with:
-*Amazon S3, OneDrive, Google Drive, Rackspace Cloud Files, HubiC, Backblaze (B2), Swift / OpenStack, WebDAV, SSH (SFTP), FTP, and more!*
+*Amazon S3, IDrive e2, OneDrive, Google Drive, Rackspace Cloud Files, HubiC, Backblaze (B2), Swift / OpenStack, WebDAV, SSH (SFTP), FTP, and more!*
Duplicati is licensed under LGPL and available for Windows, OSX and Linux (.NET 4.7.1+ or Mono 4.8.0+ required).
diff --git a/README.md b/README.md
index 4200e63b8..a0eec245a 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ Removed Gitter
Duplicati is a free, open source, backup client that securely stores encrypted, incremental, compressed backups on cloud storage services and remote file servers. It works with:
-&nbsp;&nbsp; *Amazon S3, [Backblaze (B2)](https://www.backblaze.com/blog/duplicati-backups-cloud-storage/ "Duplicati with Backblaze B2 Cloud Storage"), Box, Dropbox, FTP, Google Cloud and Drive, HubiC, MEGA, Microsoft Azure and OneDrive, Rackspace Cloud Files, OpenStack Storage (Swift), Sia, Storj DCS, SSH (SFTP), WebDAV, Tencent Cloud Object Storage (COS), [and more!](https://duplicati.readthedocs.io/en/latest/01-introduction/#supported-backends)*
+&nbsp;&nbsp; *Amazon S3, [IDrive e2](https://www.idrive.com/e2/duplicati "Using Duplicati with IDrive e2"), [Backblaze (B2)](https://www.backblaze.com/blog/duplicati-backups-cloud-storage/ "Duplicati with Backblaze B2 Cloud Storage"), Box, Dropbox, FTP, Google Cloud and Drive, HubiC, MEGA, Microsoft Azure and OneDrive, Rackspace Cloud Files, OpenStack Storage (Swift), Sia, Storj DCS, SSH (SFTP), WebDAV, Tencent Cloud Object Storage (COS), [and more!](https://duplicati.readthedocs.io/en/latest/01-introduction/#supported-backends)*
Duplicati is licensed under LGPL and available for Windows, OSX and Linux (.NET 4.7.1+ or Mono 5.10.0+ required).