Skip to content

Commit

Permalink
1、增加FTP数据源。
Browse files Browse the repository at this point in the history
2、增加上传到FTP。
3、修改例子调用格式。
  • Loading branch information
sanjusss committed Dec 24, 2018
1 parent 7421c0d commit 74d2142
Show file tree
Hide file tree
Showing 7 changed files with 321 additions and 26 deletions.
11 changes: 11 additions & 0 deletions Backup2Cloud/Args/ExampleOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,16 @@ public class ExampleOptions
{
[Option('s', "save", Required = false, Default = null, HelpText = "示例配置文件保存地址。")]
public string Path { get; set; }

[Option('l', "list", Required = false, Default = null, HelpText = "获取datasource或uploader的名称。可以为 datasource 或 uploader")]

public string List { get; set; }

[Option('d', "datasource", Required = false, Default = null, HelpText = "获取datasource的格式,需填写名称。")]
public string DataSource { get; set; }


[Option('u', "uploader", Required = false, Default = null, HelpText = "获取uploader的格式,需填写名称。")]
public string Uploader { get; set; }
}
}
15 changes: 10 additions & 5 deletions Backup2Cloud/Backup2Cloud.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@

<ItemGroup>
<PackageReference Include="Aliyun.OSS.DotNetCore" Version="2.8.0" />
<PackageReference Include="AWSSDK.S3" Version="3.3.23.2" />
<PackageReference Include="AWSSDK.S3" Version="3.3.31.5" />
<PackageReference Include="BceSdkDotNetCore" Version="1.0.2.911" />
<PackageReference Include="CommandLineParser" Version="2.3.0" />
<PackageReference Include="Google.Cloud.Storage.V1" Version="2.2.0" />
<PackageReference Include="FluentFTP" Version="19.2.2" />
<PackageReference Include="Google.Cloud.Storage.V1" Version="2.2.1" />
<PackageReference Include="HuaweiCloud.SDK.OBS" Version="3.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="QCloudSDK.COS" Version="1.0.0" />
<PackageReference Include="Qiniu.Shared" Version="7.2.15" />
<PackageReference Include="Quartz" Version="3.0.6" />
<PackageReference Include="Quartz" Version="3.0.7" />
<PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="UCloudSDK.NetCore" Version="1.0.11" />
<PackageReference Include="WindowsAzure.Storage" Version="9.3.2" />
<PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />
</ItemGroup>

<ItemGroup>
<Folder Include="Common\" />
</ItemGroup>

</Project>
46 changes: 46 additions & 0 deletions Backup2Cloud/Conf/BaseFtpConf.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Backup2Cloud.Conf
{
/// <summary>
/// FTP基本配置。
/// </summary>
public abstract class BaseFtpConf
{
/// <summary>
/// 服务器主机名。
/// 默认为本机。
/// </summary>
public string host { get; set; } = "localhost";

/// <summary>
/// 服务器的FTP端口。
/// 默认为21。
/// </summary>
public int port { get; set; } = 21;

/// <summary>
/// 用户名。
/// 默认为anonymous。
/// </summary>
public string user { get; set; } = "anonymous";

/// <summary>
/// 密码。
/// </summary>
public string password { get; set; } = string.Empty;

/// <summary>
/// 是否使用匿名登陆。
/// 默认为false。
/// </summary>
public bool anonymous { get; set; } = false;

/// <summary>
/// 在ftp上的路径。
/// </summary>
public string path { get; set; } = "/";
}
}
106 changes: 86 additions & 20 deletions Backup2Cloud/Conf/ExamplePrinter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Backup2Cloud.Args;
using Backup2Cloud.DataSource;
using Backup2Cloud.Logging;
using Backup2Cloud.Uploader;
using Newtonsoft.Json;
Expand All @@ -21,38 +22,103 @@ public class ExamplePrinter
public static void Print(ExampleOptions options)
{
var uploaders = NamedInterfaceLoader.Load(typeof(IUploader));
List<SingleConfiguration> configurations = new List<SingleConfiguration>();
string[] crontab = { "0,30 * * * * ?" };
foreach (var i in uploaders)
var dataSources = NamedInterfaceLoader.Load(typeof(IDataSource));
string content = string.Empty;
if (string.IsNullOrEmpty(options.List) == false)
{
SingleConfiguration single = new SingleConfiguration()
if (options.List == "datasource")
{
uploader = (Activator.CreateInstance(i.Value) as IUploader).GetExample() as IUploader,
name = "上传到 " + i.Key,
path = "/data",
crontab = new HashSet<string>(crontab)
};

configurations.Add(single);
content = string.Join('\n', dataSources.Keys);
Console.WriteLine("已支持以下数据源:");
}
else if (options.List == "uploader")
{
content = string.Join('\n', uploaders.Keys);
Console.WriteLine("已支持以下上传类:");
}
else
{
Console.WriteLine("只能列出 datasource 或 uploader");
}
}

string json = JsonConvert.SerializeObject(configurations, Formatting.Indented, new NameConverter());
Log.Info("\n\n示例文件:\n");
Console.WriteLine(json);
if (string.IsNullOrEmpty(options.Path) == false)
else if (string.IsNullOrEmpty(options.Uploader) == false)
{
//保存到文件。
using (StreamWriter stream = new StreamWriter(options.Path, false, Encoding.UTF8))
if (uploaders.ContainsKey(options.Uploader))
{
stream.Write(json);
content = JsonConvert.SerializeObject((Activator.CreateInstance(uploaders[options.Uploader]) as IExampled).GetExample(),
Formatting.Indented,
new NameConverter());
}
else
{
Console.WriteLine($"不存在uploader类: { options.Uploader }");
}
}
else if (string.IsNullOrEmpty(options.DataSource) == false)
{
if (dataSources.ContainsKey(options.DataSource))
{
content = JsonConvert.SerializeObject((Activator.CreateInstance(dataSources[options.DataSource]) as IExampled).GetExample(),
Formatting.Indented,
new NameConverter());
}
else
{
Console.WriteLine($"不存在datasource类: { options.DataSource }");
}
}
else
{
content = GetExampleConfig(uploaders, dataSources);
}

Log.Info(string.Format("示例文件已经保存到\"{0}\"", options.Path));
if (string.IsNullOrEmpty(content) == false)
{
Console.WriteLine(content);
if (string.IsNullOrEmpty(options.Path) == false)
{
//保存到文件。
using (StreamWriter stream = new StreamWriter(options.Path, false, Encoding.UTF8))
{
stream.Write(content);
}

Console.WriteLine("\n\n");
Log.Info(string.Format("文件已经保存到\"{0}\"", options.Path));
}
}

#if !DEBUG
Environment.Exit(0);
#endif
}

private static string GetExampleConfig(Dictionary<string, Type> uploaders, Dictionary<string, Type> dataSources)
{
string[] crontab = { "0,30 * * * * ?" };
List<SingleConfiguration> configurations = new List<SingleConfiguration>();
SingleConfiguration single = new SingleConfiguration()
{
name = "上传到 ",
path = "/data",
crontab = new HashSet<string>(crontab)
};

if (uploaders.Count > 0)
{
var i = uploaders.GetEnumerator().Current;
single.uploader = (Activator.CreateInstance(i.Value) as IUploader).GetExample() as IUploader;
single.name += i.Key;
}

if (dataSources.Count > 0)
{
var i = dataSources.GetEnumerator().Current;
single.dataSource = (Activator.CreateInstance(i.Value) as IDataSource).GetExample() as IDataSource;
}

configurations.Add(single);
return JsonConvert.SerializeObject(configurations, Formatting.Indented, new NameConverter());
}
}
}
2 changes: 1 addition & 1 deletion Backup2Cloud/Conf/SingleConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Backup2Cloud.Conf
/// <summary>
/// 单条备份配置
/// </summary>
public struct SingleConfiguration : IConfigurable
public class SingleConfiguration : IConfigurable
{
/// <summary>
/// 任务名称
Expand Down
117 changes: 117 additions & 0 deletions Backup2Cloud/DataSource/FtpDataSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using Backup2Cloud.Conf;
using Backup2Cloud.Logging;
using FluentFTP;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;

namespace Backup2Cloud.DataSource
{
/// <summary>
/// FTP数据源。从远端FTP获取数据。
/// </summary>
[Name("ftp")]
public class FtpDataSource : BaseFtpConf, IDataSource
{
public string Tips
{
get
{
return string.Empty;
}
}

public object GetExample()
{
return new FtpDataSource();
}

public void SaveData(string des)
{
using (FtpClient client = new FtpClient(host))
{
client.Port = port;
client.Encoding = Encoding.UTF8;
if (anonymous == false)
{
client.Credentials = new NetworkCredential(user, password);
}

client.Connect();
if (client.DirectoryExists(path))
{
int result = DownloadDirectory(path, "/", des, client);
Log.Print($"从 ftp://{ host }:{ port }{ path } 成功下载 { result } 个文件到 { des }");
}
else
{
if (client.DownloadFile(des, path) == false)
{
throw new IOException($"下载 ftp://{ host }:{ port }{ path } 失败。");
}

Log.Print($"成功下载 ftp://{ host }:{ port }{ path }{ des }");
}

client.Disconnect();
}
}

private int DownloadDirectory(string baseSrc, string dir, string des, FtpClient client)
{
string target = FormatDirectoryName(des + dir);
if (Directory.Exists(target))
{
Directory.Delete(target, true);
}

Directory.CreateDirectory(target);
var list = client.GetListing(FormatDirectoryName(baseSrc + dir));
List<string> dirs = new List<string>();
int result = 0;
foreach (var i in list)
{
switch (i.Type)
{
case FtpFileSystemObjectType.File:
if (client.DownloadFile(target + i.Name, i.FullName))
{
++result;
}

break;

case FtpFileSystemObjectType.Directory:
dirs.Add(i.Name);
break;

case FtpFileSystemObjectType.Link:
break;

default:
break;
}
}

foreach (var i in dirs)
{
result += DownloadDirectory(baseSrc, dir + i + "/", des + i + "/", client);
}

return result;
}

private string FormatDirectoryName(string name)
{
name = name.Replace("\\", "/");
name = name.Replace("//", "/");
if (name.EndsWith("/") == false)
{
name += "/";
}

return name;
}
}
}
Loading

0 comments on commit 74d2142

Please sign in to comment.