private readonly PollAgent _pollAgent;
private readonly NetworkAgent _networkAgent;
+ [Import]
+ public Selectives Selectives { get; set; }
private MiniStatusViewModel _miniStatus;
MigrateFolders(account);
+ Selectives.SetIsSelectiveEnabled(account.AccountKey, account.SelectiveSyncEnabled);
+
if (Monitors.TryGetValue(account.AccountKey, out monitor))
{
//If the account is active
PithosMonitor monitor;
if (Monitors.TryGetValue(message.Account.AccountKey, out monitor))
{
- monitor.Selectives.SetIsSelectiveEnabled(message.Account.AccountKey, message.Enabled);
+ Selectives.SetIsSelectiveEnabled(message.Account.AccountKey, message.Enabled);
monitor.SetSelectivePaths(message.Uris, message.Added, message.Removed);
}
{
var comparer = new LocalFileComparer();
var account = new AccountInfo();
- var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"});
- var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" });
+ var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"},null);
+ var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" }, null);
Assert.That(comparer.Equals(x, y), Is.True);
}
{
var comparer = new LocalFileComparer();
var account = new AccountInfo();
- var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"});
- var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a" });
+ var x = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" }, null);
+ var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a" }, null);
Assert.That(comparer.Equals(x, y), Is.True);
}
[Test]
{
var comparer = new LocalFileComparer();
var account = new AccountInfo();
- var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a",Content_Type = "application/directory"});
- var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a", Content_Type = "application/directory" });
+ var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a",Content_Type = "application/directory"},null);
+ var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a", Content_Type = "application/directory" }, null);
Assert.That(comparer.Equals(x, y), Is.False);
}
public class CloudAction
{
+
+ public object Originator { get; set; }
public AccountInfo AccountInfo { get; set; }
public CloudActionType Action { get; set; }
public FileSystemInfo LocalFile { get; set; }
get { return CloudFile!=null && AccountInfo.UserName != CloudFile.Account; }
}
- protected CloudAction(AccountInfo accountInfo,CloudActionType action)
+ protected CloudAction(AccountInfo accountInfo,CloudActionType action,object originator)
{
if (accountInfo==null)
throw new ArgumentNullException("accountInfo");
Action = action;
AccountInfo = accountInfo;
+ Originator = originator;
}
- public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm)
- : this(accountInfo,action)
+ public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm,object originator)
+ : this(accountInfo,action,originator)
{
if(blockSize<=0)
throw new ArgumentOutOfRangeException("blockSize");
public class CloudDownloadAction:CloudAction
{
- public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile)
- :base(accountInfo,CloudActionType.DownloadUnconditional)
+ public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile,object originator)
+ :base(accountInfo,CloudActionType.DownloadUnconditional,originator)
{
if (String.IsNullOrWhiteSpace(cloudFile.Container))
throw new ArgumentException("CloudFile.Container","cloudFile");
}
public class CloudDeleteAction:CloudAction
{
- public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState)
- : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState)
+ public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState,object originator)
+ : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState,originator)
{
}
- public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState)
- : base(accountInfo,CloudActionType.DeleteCloud)
+ public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState,object originator)
+ : base(accountInfo,CloudActionType.DeleteCloud,originator)
{
CloudFile = cloudFile;
LocalFile = fileInfo;
}
public CloudDeleteAction(CloudAction action)
- : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState)
+ : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState,action)
{}
[ContractInvariantMethod]
public class CloudUploadAction:CloudAction
{
- public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm)
- : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm)
+ public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm,object originator)
+ : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm,originator)
{
}
public FileSystemInfo OldLocalFile { get; set; }
- public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile)
- :base(accountInfo,action)
+ public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile,object originator)
+ :base(accountInfo,action,originator)
{
LocalFile = newFile;
CloudFile = CreateObjectInfoFor(accountInfo, newFile);
if (!localHashes.ContainsKey(upHash))\r
{\r
StatusNotification.Notify(new CloudNotification { Data = cloudFile });\r
+ ReportDownloadProgress(Path.GetFileName(localPath), i, upHashes.Length, cloudFile.Bytes);\r
\r
if (blockUpdater.UseOrphan(i, upHash))\r
{\r
var localPath = FileInfoExtensions.GetProperFilePathCapitalization(filePath);\r
StatusNotification.SetPithosStatus(PithosStatus.LocalSyncing, String.Format("Downloading {0}", Path.GetFileName(localPath)));\r
StatusNotification.Notify(new CloudNotification { Data = cloudFile });\r
+ ReportDownloadProgress(Path.GetFileName(localPath), 1, 1, cloudFile.Bytes);\r
\r
var fileAgent = GetFileAgent(accountInfo);\r
//Calculate the relative file path for the new file\r
if (change.ChangeType == WatcherChangeTypes.Renamed)
{
var rename = (MovedEventArgs) change;
- _agent.Post(new WorkflowState
+ _agent.Post(new WorkflowState(change)
{
AccountInfo = AccountInfo,
OldPath = rename.OldFullPath,
});
}
else
- _agent.Post(new WorkflowState
+ _agent.Post(new WorkflowState(change)
{
AccountInfo = AccountInfo,
Path = change.FullPath,
\r
yield return new CloudAction(accountInfo, CloudActionType.MustSynch,\r
localFile, objectInfo, state, accountInfo.BlockSize,\r
- accountInfo.BlockHash);\r
+ accountInfo.BlockHash,"Poll Changes");\r
}\r
}\r
else\r
{\r
//Remote files should be downloaded\r
- yield return new CloudDownloadAction(accountInfo, objectInfo);\r
+ yield return new CloudDownloadAction(accountInfo, objectInfo,"Poll Changes");\r
}\r
}\r
}\r
//For each moved object we need to move both the local file and update \r
yield return new CloudAction(accountInfo, CloudActionType.RenameLocal,\r
previousFile, objectInfo, state, accountInfo.BlockSize,\r
- accountInfo.BlockHash);\r
+ accountInfo.BlockHash,"Poll Moves");\r
//For modified files, we need to download the changes as well\r
if (objectInfo.Hash!=objectInfo.PreviousHash)\r
- yield return new CloudDownloadAction(accountInfo,objectInfo);\r
+ yield return new CloudDownloadAction(accountInfo,objectInfo, "Poll Moves");\r
}\r
}\r
//If the previous file does not exist, we need to download it in the new location\r
else\r
{\r
//Remote files should be downloaded\r
- yield return new CloudDownloadAction(accountInfo, objectInfo);\r
+ yield return new CloudDownloadAction(accountInfo, objectInfo, "Poll Moves");\r
}\r
}\r
}\r
var state = StatusKeeper.GetStateByFilePath(localFile.WithProperCapitalization().FullName);\r
yield return new CloudAction(accountInfo, CloudActionType.MustSynch,\r
localFile, objectInfo, state, accountInfo.BlockSize,\r
- accountInfo.BlockHash); \r
+ accountInfo.BlockHash,"Poll Creates"); \r
}\r
else\r
{\r
//Remote files should be downloaded\r
- yield return new CloudDownloadAction(accountInfo, objectInfo);\r
+ yield return new CloudDownloadAction(accountInfo, objectInfo,"Poll Creates");\r
}\r
\r
}\r
using System.Linq;\r
using System.Net;\r
using System.Reflection;\r
+using System.Security.Cryptography;\r
using System.Threading;\r
using System.Threading.Tasks;\r
using Pithos.Interfaces;\r
topHash = treeHash.TopHash.ToHashString();\r
}\r
\r
+\r
+\r
//If the file hashes match, abort the upload\r
- if (cloudInfo != ObjectInfo.Empty && topHash == cloudHash)\r
+ if (cloudInfo != ObjectInfo.Empty && (topHash == cloudHash ))\r
{\r
//but store any metadata changes \r
StatusKeeper.StoreInfo(fullFileName, cloudInfo);\r
case FileStatus.Modified:
NetworkAgent.Post(new CloudUploadAction(accountInfo, info, fileState,
accountInfo.BlockSize,
- accountInfo.BlockHash));
+ accountInfo.BlockHash,state));
break;
case FileStatus.Deleted:
DeleteChildObjects(state, fileState);
- NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState));
+ NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState,state));
break;
case FileStatus.Renamed:
if (state.OldPath == null)
: new FileInfo(state.Path);
NetworkAgent.Post(new CloudMoveAction(accountInfo, CloudActionType.RenameCloud,
oldInfo,
- newInfo));
+ newInfo,state));
//TODO: Do I have to move children as well or will Pithos handle this?
//Need to find all children of the OLD filepath
//MoveChildObjects(state);
var childInfo = child.IsFolder
? (FileSystemInfo) new DirectoryInfo(child.FilePath)
: new FileInfo(child.FilePath);
- NetworkAgent.Post(new CloudDeleteAction(state.AccountInfo, childInfo, child));
+ NetworkAgent.Post(new CloudDeleteAction(state.AccountInfo, childInfo, child,state));
}
}
}
{
public class WorkflowState
{
+ public object Originator { get; set; }
public AccountInfo AccountInfo { get; set; }
public string Path { get; set; }
}
*/
- public WorkflowState()
+ public WorkflowState(object originator)
{
-
+ Originator = originator;
}
public WorkflowState(AccountInfo accountInfo, FileState state)
throw new ArgumentNullException("state");
Contract.EndContractBlock();
+ Originator = "Restart";
AccountInfo = accountInfo;
Path = state.FilePath.ToLower();
FileName = System.IO.Path.GetFileName(state.FilePath).ToLower();
{
private readonly List<string> _knownContainers= new List<string>{"trash"};
public string Name { get; set; }
-
-
+
+ public string ETag { get; set; }
+
public string Hash { get; set; }
public string X_Object_Hash { get { return Hash; } set { Hash = value; } }
Account = account,
Container = container,
Name = objectName,
- Hash = client.GetHeaderValue("ETag"),
+ ETag = client.GetHeaderValue("ETag"),
+ X_Object_Hash = client.GetHeaderValue("X-Object-Hash"),
Content_Type = client.GetHeaderValue("Content-Type"),
Bytes = Convert.ToInt64(client.GetHeaderValue("Content-Length",true)),
Tags = tags,
{
Bytes = length,
BlockSize = blockSize,
- Hashes = list
+ Hashes = list,
};
+ string fileHash;
+ var hasher = HashAlgorithm.Create("MD5");
+ stream.Position = 0;
+ treeHash.MD5= hasher.ComputeHash(stream).ToHashString();
+
return treeHash;
}
}
}
}
+ public string MD5 { get; set; }
+
//Saves the Json representation to a file
public async Task Save(string filePath)
{