fixed #150: Amazon S3 custom domain support, Moved URL methods to URLHelpers class

This commit is contained in:
Jaex 2014-05-30 12:09:13 +03:00
parent fade5485e3
commit d3fcedf677
18 changed files with 339 additions and 297 deletions

View file

@ -287,4 +287,10 @@ public enum ProxyMethod
Manual,
Automatic
}
public enum SlashType
{
Prefix,
Suffix
}
}

View file

@ -845,18 +845,5 @@ public static Size MeasureText(string text, Font font, int width)
return g.MeasureString(text, font, width).ToSize();
}
}
public static string GetURLFilename(string url)
{
Uri uri = new Uri(url);
try
{
return Path.GetFileName(uri.LocalPath);
}
catch { }
return null;
}
}
}

View file

@ -0,0 +1,135 @@
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright (C) 2007-2014 ShareX Developers
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
using HelpersLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace HelpersLib
{
public static class URLHelpers
{
public static string AddSlash(string url, SlashType slashType)
{
return AddSlash(url, slashType, 1);
}
public static string AddSlash(string url, SlashType slashType, int count)
{
if (slashType == SlashType.Prefix)
{
if (url.StartsWith("/"))
{
url = url.Remove(0, 1);
}
for (int i = 0; i < count; i++)
{
url = "/" + url;
}
}
else
{
if (url.EndsWith("/"))
{
url = url.Substring(0, url.Length - 1);
}
for (int i = 0; i < count; i++)
{
url += "/";
}
}
return url;
}
public static string GetFileName(string path, bool checkExtension = false)
{
if (path.Contains("/"))
{
path = path.Remove(0, path.LastIndexOf('/') + 1);
}
if (checkExtension && !Path.HasExtension(path))
{
return null;
}
return path;
}
public static string GetDirectoryPath(string path)
{
if (path.Contains("/"))
{
path = path.Substring(0, path.LastIndexOf('/'));
}
return path;
}
public static List<string> GetPaths(string path)
{
List<string> result = new List<string>();
string temp = string.Empty;
string[] dirs = path.Split('/');
foreach (string dir in dirs)
{
if (!string.IsNullOrEmpty(dir))
{
temp += "/" + dir;
result.Add(temp);
}
}
return result;
}
private static readonly string[] URLPrefixes = new string[] { "http://", "https://", "ftp://", "ftps://", "file://" };
public static bool HasPrefix(string url)
{
return URLPrefixes.Any(x => url.StartsWith(x, StringComparison.InvariantCultureIgnoreCase));
}
public static string RemovePrefixes(string url)
{
foreach (string prefix in URLPrefixes)
{
if (url.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
{
url = url.Remove(0, prefix.Length);
break;
}
}
return url;
}
}
}

View file

@ -97,6 +97,7 @@
<Compile Include="Forms\QRCodeForm.Designer.cs">
<DependentUpon>QRCodeForm.cs</DependentUpon>
</Compile>
<Compile Include="Helpers\URLHelpers.cs" />
<Compile Include="Helpers\MathHelpers.cs" />
<Compile Include="ListViewColumnSorter.cs" />
<Compile Include="MimeTypes.cs" />

View file

@ -178,7 +178,7 @@ public static void ClipboardUpload(TaskSettings taskSettings = null)
{
if (taskSettings.UploadSettings.ClipboardUploadURLContents)
{
string filename = Helpers.GetURLFilename(url);
string filename = URLHelpers.GetFileName(url, true);
if (!string.IsNullOrEmpty(filename))
{

View file

@ -90,7 +90,7 @@ private void RefreshDirectory()
private void FillDirectories(string path)
{
List<string> paths = FTPHelpers.GetPaths(path);
List<string> paths = URLHelpers.GetPaths(path);
paths.Insert(0, "/");
cbDirectoryList.Items.Clear();
@ -441,11 +441,11 @@ private void lvFTPList_DragDrop(object sender, DragEventArgs e)
{
if (file.Name == ".")
{
movePath = FTPHelpers.AddSlash(filename, FTPHelpers.SlashType.Prefix, 2);
movePath = URLHelpers.AddSlash(filename, SlashType.Prefix, 2);
}
else if (file.Name == "..")
{
movePath = FTPHelpers.AddSlash(filename, FTPHelpers.SlashType.Prefix);
movePath = URLHelpers.AddSlash(filename, SlashType.Prefix);
}
}
else

View file

@ -83,14 +83,14 @@ private string GetEndpoint()
// http://codeonaboat.wordpress.com/2011/04/22/uploading-a-file-to-amazon-s3-using-an-asp-net-mvc-application-directly-from-the-users-browser/
private string CreateSignature(string secretKey, byte[] policyBytes)
{
var encoding = new ASCIIEncoding();
var base64Policy = Convert.ToBase64String(policyBytes);
var secretKeyBytes = encoding.GetBytes(secretKey);
ASCIIEncoding encoding = new ASCIIEncoding();
string base64Policy = Convert.ToBase64String(policyBytes);
byte[] secretKeyBytes = encoding.GetBytes(secretKey);
byte[] signatureBytes;
using (var hmacsha1 = new HMACSHA1(secretKeyBytes))
using (HMACSHA1 hmacsha1 = new HMACSHA1(secretKeyBytes))
{
var base64PolicyBytes = encoding.GetBytes(base64Policy);
byte[] base64PolicyBytes = encoding.GetBytes(base64Policy);
signatureBytes = hmacsha1.ComputeHash(base64PolicyBytes);
}
@ -109,14 +109,30 @@ private string GetObjectURL(string objectName)
objectName = objectName.Trim('/');
objectName = Helpers.URLPathEncode(objectName);
string url = string.Empty;
if (S3Settings.UseCustomCNAME)
{
return "http://" + Helpers.CombineURL(S3Settings.Bucket, objectName);
if (!string.IsNullOrEmpty(S3Settings.CustomDomain))
{
url = Helpers.CombineURL(S3Settings.CustomDomain, objectName);
}
else
{
url = Helpers.CombineURL(S3Settings.Bucket, objectName);
}
}
else
{
return Helpers.CombineURL(GetEndpoint(), objectName);
url = Helpers.CombineURL(GetEndpoint(), objectName);
}
if (!URLHelpers.HasPrefix(url))
{
url = "http://" + url;
}
return url;
}
public string GetURL(string fileName)
@ -126,11 +142,11 @@ public string GetURL(string fileName)
private Dictionary<string, string> GetParameters(string fileName, string objectKey)
{
var policyDocument = GetPolicyDocument(fileName, objectKey);
var policyBytes = Encoding.ASCII.GetBytes(policyDocument);
var signature = CreateSignature(S3Settings.SecretAccessKey, policyBytes);
string policyDocument = GetPolicyDocument(fileName, objectKey);
byte[] policyBytes = Encoding.ASCII.GetBytes(policyDocument);
string signature = CreateSignature(S3Settings.SecretAccessKey, policyBytes);
var parameters = new Dictionary<string, string>();
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("key", objectKey);
parameters.Add("acl", "public-read");
parameters.Add("content-type", Helpers.GetMimeType(fileName));
@ -148,9 +164,9 @@ public override UploadResult Upload(Stream stream, string fileName)
if (string.IsNullOrEmpty(S3Settings.Endpoint)) throw new Exception("'Endpoint' must not be emoty.");
if (string.IsNullOrEmpty(S3Settings.Bucket)) throw new Exception("'Bucket' must not be empty.");
var objectKey = GetObjectKey(fileName);
string objectKey = GetObjectKey(fileName);
var uploadResult = UploadData(stream, GetEndpoint(), fileName, arguments: GetParameters(fileName, objectKey), responseType: ResponseType.Headers);
UploadResult uploadResult = UploadData(stream, GetEndpoint(), fileName, arguments: GetParameters(fileName, objectKey), responseType: ResponseType.Headers);
if (uploadResult.IsSuccess)
{
@ -165,10 +181,11 @@ public class AmazonS3Settings
{
public string AccessKeyID { get; set; }
public string SecretAccessKey { get; set; }
public bool UseReducedRedundancyStorage { get; set; }
public bool UseCustomCNAME { get; set; }
public string ObjectPrefix { get; set; }
public string Bucket { get; set; }
public string Endpoint { get; set; }
public string Bucket { get; set; }
public string ObjectPrefix { get; set; }
public bool UseCustomCNAME { get; set; }
public string CustomDomain { get; set; }
public bool UseReducedRedundancyStorage { get; set; }
}
}

View file

@ -163,7 +163,7 @@ public bool UploadData(Stream localStream, string remotePath)
// Probably directory not exist, try creating it
if (e.CompletionCode == "553")
{
MakeMultiDirectory(FTPHelpers.GetDirectoryName(remotePath));
MakeMultiDirectory(URLHelpers.GetDirectoryPath(remotePath));
using (Stream remoteStream = client.OpenWrite(remotePath))
{
@ -291,7 +291,7 @@ public bool ChangeDirectory(string remotePath, bool autoCreateDirectory = false)
{
if (Connect())
{
remotePath = FTPHelpers.AddSlash(remotePath, FTPHelpers.SlashType.Prefix);
remotePath = URLHelpers.AddSlash(remotePath, SlashType.Prefix);
try
{
@ -335,7 +335,7 @@ public bool MakeDirectory(string remotePath)
public void MakeMultiDirectory(string remotePath)
{
List<string> paths = FTPHelpers.GetPaths(remotePath);
List<string> paths = URLHelpers.GetPaths(remotePath);
foreach (string path in paths)
{
@ -384,7 +384,7 @@ public void DeleteDirectory(string remotePath)
{
if (Connect())
{
string filename = FTPHelpers.GetFileName(remotePath);
string filename = URLHelpers.GetFileName(remotePath);
if (filename == "." || filename == "..")
{
return;

View file

@ -154,7 +154,7 @@ public string GetHttpHomePath()
HttpHomePathAutoAddSubFolderPath = false;
}
HttpHomePath = FTPHelpers.RemovePrefixes(HttpHomePath);
HttpHomePath = URLHelpers.RemovePrefixes(HttpHomePath);
NameParser nameParser = new NameParser(NameParserType.URL);
return nameParser.Parse(HttpHomePath.Replace("%host", Host));

View file

@ -30,6 +30,7 @@
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using UploadersLib.HelperClasses;
namespace UploadersLib
@ -242,7 +243,7 @@ public bool DownloadFile(string url, string savePath)
public void DeleteFile(string url)
{
string filename = FTPHelpers.GetFileName(url);
string filename = URLHelpers.GetFileName(url);
if (filename == "." || filename == "..") return;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
@ -258,11 +259,11 @@ public void DeleteFile(string url)
public void RemoveDirectory(string url)
{
string filename = FTPHelpers.GetFileName(url);
string filename = URLHelpers.GetFileName(url);
if (filename == "." || filename == "..") return;
List<FTPLineResult> files = ListDirectoryDetails(url);
string path = FTPHelpers.GetDirectoryName(url);
string path = URLHelpers.GetDirectoryPath(url);
foreach (FTPLineResult file in files)
{
@ -321,7 +322,7 @@ public string[] ListDirectory(string url)
{
List<string> result = new List<string>();
url = FTPHelpers.AddSlash(url, FTPHelpers.SlashType.Suffix);
url = URLHelpers.AddSlash(url, SlashType.Suffix);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Proxy = Options.ProxySettings;
@ -416,4 +417,95 @@ public void WriteOutput(string text)
}
}
}
public static class FTPLineParser
{
private static Regex unixStyle = new Regex(@"^(?<Permissions>(?<Directory>[-dl])(?<OwnerPerm>[-r][-w][-x])(?<GroupPerm>[-r][-w][-x])(?<EveryonePerm>[-r][-w][-x]))\s+(?<FileType>\d+)\s+(?<Owner>\w+)\s+(?<Group>\w+)\s+(?<Size>\d+)\s+(?<Month>\w+)\s+(?<Day>\d{1,2})\s+(?<Year>(?<Hour>\d{1,2}):*(?<Minutes>\d{1,2}))\s+(?<Name>.*)$");
private static Regex winStyle = new Regex(@"^(?<Month>\d{1,2})-(?<Day>\d{1,2})-(?<Year>\d{1,2})\s+(?<Hour>\d{1,2}):(?<Minutes>\d{1,2})(?<ampm>am|pm)\s+(?<Dir>[<]dir[>])?\s+(?<Size>\d+)?\s+(?<Name>.*)$");
public static FTPLineResult Parse(string line)
{
Match match = unixStyle.Match(line);
if (match.Success)
{
return ParseMatch(match.Groups, ListStyle.Unix);
}
throw new Exception("Only support Unix ftp servers.");
/*
match = winStyle.Match(line);
if (match.Success)
{
return ParseMatch(match.Groups, ListStyle.Windows);
}
throw new Exception("Invalid line format");
*/
}
private static FTPLineResult ParseMatch(GroupCollection matchGroups, ListStyle style)
{
FTPLineResult result = new FTPLineResult();
result.Style = style;
string dirMatch = style == ListStyle.Unix ? "d" : "<dir>";
result.IsDirectory = matchGroups["Directory"].Value.Equals(dirMatch, StringComparison.InvariantCultureIgnoreCase);
result.Permissions = matchGroups["Permissions"].Value;
result.Name = matchGroups["Name"].Value;
if (!result.IsDirectory)
{
result.SetSize(matchGroups["Size"].Value);
}
result.Owner = matchGroups["Owner"].Value;
result.Group = matchGroups["Group"].Value;
result.SetDateTime(matchGroups["Year"].Value, matchGroups["Month"].Value, matchGroups["Day"].Value);
return result;
}
}
public enum ListStyle
{
Unix,
Windows
}
public class FTPLineResult
{
public ListStyle Style;
public string Name;
public string Permissions;
public DateTime DateTime;
public bool TimeInfo;
public bool IsDirectory;
public long Size;
public string SizeString;
public string Owner;
public string Group;
public bool IsSpecial;
public void SetSize(string size)
{
Size = long.Parse(size);
SizeString = Size.ToString("N0");
}
public void SetDateTime(string year, string month, string day)
{
string time = string.Empty;
if (year.Contains(":"))
{
time = year;
year = FastDateTime.Now.Year.ToString();
TimeInfo = true;
}
DateTime = DateTime.Parse(string.Format("{0}/{1}/{2} {3}", year, month, day, time));
DateTime = DateTime.ToLocalTime();
}
}
}

View file

@ -1,220 +0,0 @@
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright (C) 2007-2014 ShareX Developers
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
using HelpersLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace UploadersLib
{
public static class FTPHelpers
{
public enum SlashType
{
Prefix,
Suffix
}
public static string AddSlash(string url, SlashType slashType)
{
return AddSlash(url, slashType, 1);
}
public static string AddSlash(string url, SlashType slashType, int count)
{
if (slashType == SlashType.Prefix)
{
if (url.StartsWith("/"))
{
url = url.Remove(0, 1);
}
for (int i = 0; i < count; i++)
{
url = "/" + url;
}
}
else
{
if (url.EndsWith("/"))
{
url = url.Substring(0, url.Length - 1);
}
for (int i = 0; i < count; i++)
{
url += "/";
}
}
return url;
}
public static string GetFileName(string path)
{
if (path.Contains('/'))
{
path = path.Remove(0, path.LastIndexOf('/') + 1);
}
return path;
}
public static string GetDirectoryName(string path)
{
if (path.Contains('/'))
{
path = path.Substring(0, path.LastIndexOf('/'));
}
return path;
}
public static List<string> GetPaths(string path)
{
List<string> result = new List<string>();
string temp = string.Empty;
string[] dirs = path.Split('/');
foreach (string dir in dirs)
{
if (!string.IsNullOrEmpty(dir))
{
temp += "/" + dir;
result.Add(temp);
}
}
return result;
}
public static string RemovePrefixes(string host)
{
string[] prefixes = new string[] { "http://", "https://" };
foreach (string prefix in prefixes)
{
if (host.StartsWith(prefix))
{
host = host.Remove(0, prefix.Length);
}
}
return host;
}
}
public static class FTPLineParser
{
private static Regex unixStyle = new Regex(@"^(?<Permissions>(?<Directory>[-dl])(?<OwnerPerm>[-r][-w][-x])(?<GroupPerm>[-r][-w][-x])(?<EveryonePerm>[-r][-w][-x]))\s+(?<FileType>\d+)\s+(?<Owner>\w+)\s+(?<Group>\w+)\s+(?<Size>\d+)\s+(?<Month>\w+)\s+(?<Day>\d{1,2})\s+(?<Year>(?<Hour>\d{1,2}):*(?<Minutes>\d{1,2}))\s+(?<Name>.*)$");
private static Regex winStyle = new Regex(@"^(?<Month>\d{1,2})-(?<Day>\d{1,2})-(?<Year>\d{1,2})\s+(?<Hour>\d{1,2}):(?<Minutes>\d{1,2})(?<ampm>am|pm)\s+(?<Dir>[<]dir[>])?\s+(?<Size>\d+)?\s+(?<Name>.*)$");
public static FTPLineResult Parse(string line)
{
Match match = unixStyle.Match(line);
if (match.Success)
{
return ParseMatch(match.Groups, ListStyle.Unix);
}
throw new Exception("Only support Unix ftp servers.");
/*
match = winStyle.Match(line);
if (match.Success)
{
return ParseMatch(match.Groups, ListStyle.Windows);
}
throw new Exception("Invalid line format");
*/
}
private static FTPLineResult ParseMatch(GroupCollection matchGroups, ListStyle style)
{
FTPLineResult result = new FTPLineResult();
result.Style = style;
string dirMatch = style == ListStyle.Unix ? "d" : "<dir>";
result.IsDirectory = matchGroups["Directory"].Value.Equals(dirMatch, StringComparison.InvariantCultureIgnoreCase);
result.Permissions = matchGroups["Permissions"].Value;
result.Name = matchGroups["Name"].Value;
if (!result.IsDirectory)
{
result.SetSize(matchGroups["Size"].Value);
}
result.Owner = matchGroups["Owner"].Value;
result.Group = matchGroups["Group"].Value;
result.SetDateTime(matchGroups["Year"].Value, matchGroups["Month"].Value, matchGroups["Day"].Value);
return result;
}
}
public enum ListStyle
{
Unix,
Windows
}
public class FTPLineResult
{
public ListStyle Style;
public string Name;
public string Permissions;
public DateTime DateTime;
public bool TimeInfo;
public bool IsDirectory;
public long Size;
public string SizeString;
public string Owner;
public string Group;
public bool IsSpecial;
public void SetSize(string size)
{
Size = long.Parse(size);
SizeString = Size.ToString("N0");
}
public void SetDateTime(string year, string month, string day)
{
string time = string.Empty;
if (year.Contains(':'))
{
time = year;
year = FastDateTime.Now.Year.ToString();
TimeInfo = true;
}
DateTime = DateTime.Parse(string.Format("{0}/{1}/{2} {3}", year, month, day, time));
DateTime = DateTime.ToLocalTime();
}
}
}

View file

@ -125,7 +125,7 @@ public string GetHttpHomePath()
HttpHomePathAutoAddSubFolderPath = false;
}
HttpHomePath = FTPHelpers.RemovePrefixes(HttpHomePath);
HttpHomePath = URLHelpers.RemovePrefixes(HttpHomePath);
NameParser parser = new NameParser(NameParserType.URL);
return parser.Parse(HttpHomePath.Replace("%host", LocalhostRoot));

View file

@ -164,7 +164,7 @@ public List<string> CreateMultiDirectory(string path)
{
List<string> directoryList = new List<string>();
IEnumerable<string> paths = FTPHelpers.GetPaths(path).Select(x => x.TrimStart('/'));
IEnumerable<string> paths = URLHelpers.GetPaths(path).Select(x => x.TrimStart('/'));
foreach (string directory in paths)
{

View file

@ -165,6 +165,7 @@ private void InitializeComponent()
this.btnMegaLogin = new System.Windows.Forms.Button();
this.lblMegaStatusTitle = new System.Windows.Forms.Label();
this.tpAmazonS3 = new System.Windows.Forms.TabPage();
this.txtAmazonS3CustomDomain = new System.Windows.Forms.TextBox();
this.lblAmazonS3PathPreviewLabel = new System.Windows.Forms.Label();
this.lblAmazonS3PathPreview = new System.Windows.Forms.Label();
this.btnAmazonS3BucketNameOpen = new System.Windows.Forms.Button();
@ -1846,6 +1847,7 @@ private void InitializeComponent()
//
// tpAmazonS3
//
this.tpAmazonS3.Controls.Add(this.txtAmazonS3CustomDomain);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3PathPreviewLabel);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3PathPreview);
this.tpAmazonS3.Controls.Add(this.btnAmazonS3BucketNameOpen);
@ -1870,10 +1872,18 @@ private void InitializeComponent()
this.tpAmazonS3.Text = "Amazon S3";
this.tpAmazonS3.UseVisualStyleBackColor = true;
//
// txtAmazonS3CustomDomain
//
this.txtAmazonS3CustomDomain.Location = new System.Drawing.Point(152, 144);
this.txtAmazonS3CustomDomain.Name = "txtAmazonS3CustomDomain";
this.txtAmazonS3CustomDomain.Size = new System.Drawing.Size(304, 20);
this.txtAmazonS3CustomDomain.TabIndex = 16;
this.txtAmazonS3CustomDomain.TextChanged += new System.EventHandler(this.txtAmazonS3CustomDomain_TextChanged);
//
// lblAmazonS3PathPreviewLabel
//
this.lblAmazonS3PathPreviewLabel.AutoSize = true;
this.lblAmazonS3PathPreviewLabel.Location = new System.Drawing.Point(24, 144);
this.lblAmazonS3PathPreviewLabel.Location = new System.Drawing.Point(24, 192);
this.lblAmazonS3PathPreviewLabel.Name = "lblAmazonS3PathPreviewLabel";
this.lblAmazonS3PathPreviewLabel.Size = new System.Drawing.Size(72, 13);
this.lblAmazonS3PathPreviewLabel.TabIndex = 12;
@ -1882,7 +1892,7 @@ private void InitializeComponent()
// lblAmazonS3PathPreview
//
this.lblAmazonS3PathPreview.AutoSize = true;
this.lblAmazonS3PathPreview.Location = new System.Drawing.Point(102, 144);
this.lblAmazonS3PathPreview.Location = new System.Drawing.Point(102, 192);
this.lblAmazonS3PathPreview.Name = "lblAmazonS3PathPreview";
this.lblAmazonS3PathPreview.Size = new System.Drawing.Size(45, 13);
this.lblAmazonS3PathPreview.TabIndex = 13;
@ -1890,11 +1900,11 @@ private void InitializeComponent()
//
// btnAmazonS3BucketNameOpen
//
this.btnAmazonS3BucketNameOpen.Location = new System.Drawing.Point(464, 114);
this.btnAmazonS3BucketNameOpen.Location = new System.Drawing.Point(464, 90);
this.btnAmazonS3BucketNameOpen.Name = "btnAmazonS3BucketNameOpen";
this.btnAmazonS3BucketNameOpen.Size = new System.Drawing.Size(24, 24);
this.btnAmazonS3BucketNameOpen.TabIndex = 11;
this.btnAmazonS3BucketNameOpen.Text = "?";
this.btnAmazonS3BucketNameOpen.Text = "...";
this.btnAmazonS3BucketNameOpen.UseVisualStyleBackColor = true;
this.btnAmazonS3BucketNameOpen.Click += new System.EventHandler(this.btnAmazonS3BucketNameOpen_Click);
//
@ -1904,21 +1914,19 @@ private void InitializeComponent()
this.btnAmazonS3AccessKeyOpen.Name = "btnAmazonS3AccessKeyOpen";
this.btnAmazonS3AccessKeyOpen.Size = new System.Drawing.Size(24, 24);
this.btnAmazonS3AccessKeyOpen.TabIndex = 2;
this.btnAmazonS3AccessKeyOpen.Text = "?";
this.btnAmazonS3AccessKeyOpen.Text = "...";
this.btnAmazonS3AccessKeyOpen.UseVisualStyleBackColor = true;
this.btnAmazonS3AccessKeyOpen.Click += new System.EventHandler(this.btnAmazonS3AccessKeyOpen_Click);
//
// cbAmazonS3CustomCNAME
//
this.cbAmazonS3CustomCNAME.AutoSize = true;
this.cbAmazonS3CustomCNAME.Location = new System.Drawing.Point(104, 192);
this.cbAmazonS3CustomCNAME.Location = new System.Drawing.Point(27, 144);
this.cbAmazonS3CustomCNAME.Name = "cbAmazonS3CustomCNAME";
this.cbAmazonS3CustomCNAME.Size = new System.Drawing.Size(163, 17);
this.cbAmazonS3CustomCNAME.Size = new System.Drawing.Size(122, 17);
this.cbAmazonS3CustomCNAME.TabIndex = 15;
this.cbAmazonS3CustomCNAME.Text = "Bucket uses custom CNAME";
this.ttHelpTip.SetToolTip(this.cbAmazonS3CustomCNAME, "Use this option if you have a bucket set up with a custom CNAME.\r\nFor example, if" +
" your bucket is called bucket.example.com, and is accessible\r\nfrom http://bucket" +
".example.com/.");
this.cbAmazonS3CustomCNAME.Text = "Use custom domain:";
this.ttHelpTip.SetToolTip(this.cbAmazonS3CustomCNAME, resources.GetString("cbAmazonS3CustomCNAME.ToolTip"));
this.cbAmazonS3CustomCNAME.UseVisualStyleBackColor = true;
this.cbAmazonS3CustomCNAME.CheckedChanged += new System.EventHandler(this.cbAmazonS3CustomCNAME_CheckedChanged);
//
@ -1988,7 +1996,7 @@ private void InitializeComponent()
// cbAmazonS3UseRRS
//
this.cbAmazonS3UseRRS.AutoSize = true;
this.cbAmazonS3UseRRS.Location = new System.Drawing.Point(104, 168);
this.cbAmazonS3UseRRS.Location = new System.Drawing.Point(27, 168);
this.cbAmazonS3UseRRS.Name = "cbAmazonS3UseRRS";
this.cbAmazonS3UseRRS.Size = new System.Drawing.Size(184, 17);
this.cbAmazonS3UseRRS.TabIndex = 14;
@ -4310,5 +4318,6 @@ private void InitializeComponent()
private System.Windows.Forms.ComboBox cbDropboxURLType;
private System.Windows.Forms.Label lblAmazonS3PathPreview;
private System.Windows.Forms.Label lblAmazonS3PathPreviewLabel;
private System.Windows.Forms.TextBox txtAmazonS3CustomDomain;
}
}

View file

@ -1011,14 +1011,22 @@ private void txtAmazonS3ObjectPrefix_TextChanged(object sender, EventArgs e)
UpdateAmazonS3Status();
}
private void cbAmazonS3UseRRS_CheckedChanged(object sender, EventArgs e)
{
Config.AmazonS3Settings.UseReducedRedundancyStorage = cbAmazonS3UseRRS.Checked;
}
private void cbAmazonS3CustomCNAME_CheckedChanged(object sender, EventArgs e)
{
Config.AmazonS3Settings.UseCustomCNAME = cbAmazonS3CustomCNAME.Checked;
txtAmazonS3CustomDomain.Enabled = Config.AmazonS3Settings.UseCustomCNAME;
UpdateAmazonS3Status();
}
private void txtAmazonS3CustomDomain_TextChanged(object sender, EventArgs e)
{
Config.AmazonS3Settings.CustomDomain = txtAmazonS3CustomDomain.Text;
UpdateAmazonS3Status();
}
private void cbAmazonS3UseRRS_CheckedChanged(object sender, EventArgs e)
{
Config.AmazonS3Settings.UseReducedRedundancyStorage = cbAmazonS3UseRRS.Checked;
UpdateAmazonS3Status();
}

View file

@ -112,12 +112,25 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<metadata name="ttHelpTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="cbAmazonS3CustomCNAME.ToolTip" xml:space="preserve">
<value>Use this option if you have a bucket set up with a custom domain.
If text field is empty then bucket name will be used for URL.
For example, if your bucket is called bucket.example.com then URL will be http://bucket.example.com/...</value>
</data>
<data name="cbAmazonS3UseRRS.ToolTip" xml:space="preserve">
<value>Use a lower-redundancy storage class for stored objects.
With this option, objects are cheaper to store, but have 99.99% durability, instead of 99.999999999%.
This means that they may be lost from Amazon S3 at some point.</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pbDropboxLogo.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAOcAAAA8CAYAAACdDa3MAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
@ -234,15 +247,7 @@
cEDOIz9clMt26LAWUUxcLUy92z9hAUk7h0+HDimqY/4fT5V6IeBXOg8AAAAASUVORK5CYII=
</value>
</data>
<metadata name="ttHelpTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="cbAmazonS3UseRRS.ToolTip" xml:space="preserve">
<value>Use a lower-redundancy storage class for stored objects.
With this option, objects are cheaper to store, but have 99.99% durability, instead of 99.999999999%.
This means that they may be lost from Amazon S3 at some point.</value>
</data>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>72</value>
</metadata>
</root>

View file

@ -428,11 +428,14 @@ public void LoadSettings(UploadersConfig uploadersConfig)
txtAmazonS3AccessKey.Text = Config.AmazonS3Settings.AccessKeyID;
txtAmazonS3SecretKey.Text = Config.AmazonS3Settings.SecretAccessKey;
cbAmazonS3UseRRS.Checked = Config.AmazonS3Settings.UseReducedRedundancyStorage;
cbAmazonS3Endpoint.Text = Config.AmazonS3Settings.Endpoint;
cbAmazonS3CustomCNAME.Checked = Config.AmazonS3Settings.UseCustomCNAME;
txtAmazonS3BucketName.Text = Config.AmazonS3Settings.Bucket;
txtAmazonS3ObjectPrefix.Text = Config.AmazonS3Settings.ObjectPrefix;
cbAmazonS3CustomCNAME.Checked = Config.AmazonS3Settings.UseCustomCNAME;
txtAmazonS3CustomDomain.Enabled = Config.AmazonS3Settings.UseCustomCNAME;
txtAmazonS3CustomDomain.Text = Config.AmazonS3Settings.CustomDomain;
cbAmazonS3UseRRS.Checked = Config.AmazonS3Settings.UseReducedRedundancyStorage;
UpdateAmazonS3Status();
#endregion File uploaders

View file

@ -212,7 +212,6 @@
<Compile Include="FileUploaders\FTP\FTPAccount.cs" />
<Compile Include="FileUploaders\FTP\FTPAccountManager.cs" />
<Compile Include="FileUploaders\FTP\FTPAdapter.cs" />
<Compile Include="FileUploaders\FTP\FTPHelpers.cs" />
<Compile Include="FileUploaders\FTP.cs" />
<Compile Include="FileUploaders\RapidShare.cs" />
<Compile Include="FileUploaders\SendSpace.cs" />