mirror of
https://github.com/ShareX/ShareX.git
synced 2024-10-01 09:47:22 +13:00
fixed #150: Amazon S3 custom domain support, Moved URL methods to URLHelpers class
This commit is contained in:
parent
fade5485e3
commit
d3fcedf677
18 changed files with 339 additions and 297 deletions
|
@ -287,4 +287,10 @@ public enum ProxyMethod
|
|||
Manual,
|
||||
Automatic
|
||||
}
|
||||
|
||||
public enum SlashType
|
||||
{
|
||||
Prefix,
|
||||
Suffix
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
135
HelpersLib/Helpers/URLHelpers.cs
Normal file
135
HelpersLib/Helpers/URLHelpers.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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" />
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,15 +109,31 @@ 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
|
||||
{
|
||||
return Helpers.CombineURL(GetEndpoint(), objectName);
|
||||
url = Helpers.CombineURL(S3Settings.Bucket, objectName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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; }
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -30,6 +30,7 @@ You should have received a copy of the GNU General Public License
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
33
UploadersLib/GUI/UploadersConfigForm.Designer.cs
generated
33
UploadersLib/GUI/UploadersConfigForm.Designer.cs
generated
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
|
Loading…
Reference in a new issue