/// <summary> /// Push data from source to destination /// </summary> /// <param name="factory">Storage Factory</param> private static void Push(StorageFactory factory) { Parallel.ForEach<IStorageItem>(factory.Source(), (from, state) => { Trace.WriteLine(string.Format("Processing file: '{0}'.", from)); var to = factory.To(from); var exists = to.Exists(); if (!exists) { Trace.WriteLine(string.Format("Synchronizing new file: '{0}'.", from)); } if (!exists || to.MD5 != from.MD5 || to.MD5 == null) { to.Save(from, exists); Trace.WriteLine(string.Format("Synchronizing file: '{0}'.", from)); } else { Trace.WriteLine(string.Format("File '{0}' already exists at '{1}', synchronization avoided.", from.Path, to.Path)); } to = null; from = null; }); }
/// <summary> /// Delete items from destination /// </summary> /// <param name="factory">Storage Factory</param> private static void Delete(StorageFactory factory) { var items = new HashSet<string>(); foreach (var item in factory.Source()) { items.Add(item.RelativePath); } Parallel.ForEach<IStorageItem>(factory.Destination(), (item, state) => { if (!items.Contains(item.RelativePath)) { item.Delete(); } }); }
/// <summary> /// Synchronize Contents /// </summary> /// <param name="factory">Storage Factory</param> private static void Synchronize(StorageFactory factory) { Program.Push(factory); var delete = false; bool.TryParse(ConfigurationManager.AppSettings["Synchronize"], out delete); if (delete) { Trace.Write("Deleting items which are not in source."); Program.Delete(factory); } }
/// <summary> /// Process Settings for Facotry /// </summary> /// <returns>Storage Factory</returns> public StorageFactory Process() { var factory = new StorageFactory(); var from = ConfigurationManager.AppSettings["From"]; var to = ConfigurationManager.AppSettings["To"]; if (null != arguments) { var appendingFrom = true; var toParse = string.Join(" ", arguments); foreach (var arg in arguments) { var val = arg.ToLowerInvariant(); if (val == "/from") { appendingFrom = true; } else if (val == "/to") { appendingFrom = false; } else if (appendingFrom) { from += string.Format("\"{0}\"", arg); } else { to += string.Format("\"{0}\"", arg); } } } if (string.IsNullOrWhiteSpace(from)) { throw new InvalidOperationException("Specify where the data is coming from '/From' in arguments, or in AppSettings."); } else if (string.IsNullOrWhiteSpace(to)) { throw new InvalidOperationException("Specify where the data is going to '/To' in arguments, or in AppSettings."); } else { var fromValues = Regex.Matches(from, valuesRegexStatement, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); switch (fromValues.Count) { case 1: var directory = fromValues[0].Groups["value"].Value; if (Directory.Exists(directory)) { Trace.WriteLine(string.Format("Synchronizing from folder: '{0}'", directory)); factory.AddDirectory(directory); } else { throw new InvalidOperationException("Directory does not exist."); } break; case 2: CloudStorageAccount account = null; var accountArgument = fromValues[0].Groups["value"].Value; var container = fromValues[1].Groups["value"].Value; if (CloudStorageAccount.TryParse(accountArgument, out account)) { if (!string.IsNullOrWhiteSpace(container)) { Trace.WriteLine(string.Format("Synchronizing container: '{0}'", container)); factory.AddContainer(account, container); } else { Trace.WriteLine("Storage Account Credentials must be coupled with container; please specify a container to synchronize to."); } } else { Trace.WriteLine("Storage Account Credentials is in invalid format."); } break; case 3: var accessKey = fromValues[0].Groups["value"].Value; var secretAccessKey = fromValues[1].Groups["value"].Value; var bucket = fromValues[2].Groups["value"].Value; var client = AWSClientFactory.CreateAmazonS3Client(accessKey, secretAccessKey); factory.AddBucket(client, bucket); break; default: throw new InvalidOperationException(string.Format("Unknown parameters: '{0}'", from)); } var toValues = Regex.Matches(to, valuesRegexStatement, RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); switch (toValues.Count) { case 1: if (Regex.IsMatch(toValues[0].Groups["value"].Value, directoryMatch)) { Trace.WriteLine(string.Format("Synchronizing folder: '{0}'", toValues[0].Groups["value"].Value)); factory.AddDirectory(toValues[0].Groups["value"].Value); } else { throw new InvalidOperationException("Directory is invalid."); } break; case 2: CloudStorageAccount account = null; var accountArgument = toValues[0].Groups["value"].Value; var container = toValues[1].Groups["value"].Value; if (CloudStorageAccount.TryParse(accountArgument, out account)) { if (!string.IsNullOrWhiteSpace(container)) { Trace.WriteLine(string.Format("Synchronizing container: '{0}'", container)); factory.AddContainer(account, container); } else { Trace.WriteLine("Storage Account Credentials must be coupled with container; please specify a container to synchronize to."); } } else { Trace.WriteLine("Storage Account Credentials is in invalid format."); } break; case 3: var accessKey = toValues[0].Groups["value"].Value; var secretAccessKey = toValues[1].Groups["value"].Value; var bucket = toValues[2].Groups["value"].Value; var client = AWSClientFactory.CreateAmazonS3Client(accessKey, secretAccessKey); factory.AddBucket(client, bucket); break; default: throw new InvalidOperationException(string.Format("Unknown parameters: '{0}'", to)); } } return factory; }