Revision 9d2c0fc0 trunk/Pithos.Core/Agents/NetworkAgent.cs
b/trunk/Pithos.Core/Agents/NetworkAgent.cs | ||
---|---|---|
669 | 669 |
{ |
670 | 670 |
try |
671 | 671 |
{ |
672 |
|
|
672 | 673 |
var accountInfo = action.AccountInfo; |
673 | 674 |
|
674 | 675 |
var fileInfo = action.LocalFile; |
675 | 676 |
|
676 | 677 |
if (fileInfo.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase)) |
677 | 678 |
return; |
679 |
//Do not upload files in conflict |
|
680 |
if (action.FileState.FileStatus == FileStatus.Conflict ) |
|
681 |
{ |
|
682 |
Log.InfoFormat("Skipping file in conflict [{0}]",fileInfo.FullName); |
|
683 |
return; |
|
684 |
} |
|
685 |
if (action.FileState.FileStatus == FileStatus.Forbidden) |
|
686 |
{ |
|
687 |
Log.InfoFormat("Skipping forbidden file [{0}]",fileInfo.FullName); |
|
688 |
return; |
|
689 |
} |
|
678 | 690 |
|
679 | 691 |
var relativePath = fileInfo.AsRelativeTo(accountInfo.AccountPath); |
680 | 692 |
if (relativePath.StartsWith(FolderConstants.OthersFolder)) |
... | ... | |
707 | 719 |
|
708 | 720 |
var cloudFile = action.CloudFile; |
709 | 721 |
var account = cloudFile.Account ?? accountInfo.UserName; |
722 |
try |
|
723 |
{ |
|
710 | 724 |
|
711 | 725 |
var client = new CloudFilesClient(accountInfo); |
712 | 726 |
//Even if GetObjectInfo times out, we can proceed with the upload |
... | ... | |
717 | 731 |
return; |
718 | 732 |
|
719 | 733 |
//TODO: Check how a directory hash is calculated -> All dirs seem to have the same hash |
720 |
if (fileInfo is DirectoryInfo) |
|
721 |
{ |
|
722 |
//If the directory doesn't exist the Hash property will be empty |
|
723 |
if (String.IsNullOrWhiteSpace(info.Hash)) |
|
724 |
//Go on and create the directory |
|
725 |
await |
|
726 |
client.PutObject(account, cloudFile.Container, cloudFile.Name, fullFileName, |
|
727 |
String.Empty, "application/directory"); |
|
728 |
} |
|
729 |
else |
|
730 |
{ |
|
734 |
if (fileInfo is DirectoryInfo)
|
|
735 |
{
|
|
736 |
//If the directory doesn't exist the Hash property will be empty
|
|
737 |
if (String.IsNullOrWhiteSpace(info.Hash))
|
|
738 |
//Go on and create the directory
|
|
739 |
await
|
|
740 |
client.PutObject(account, cloudFile.Container, cloudFile.Name, fullFileName,
|
|
741 |
String.Empty, "application/directory");
|
|
742 |
}
|
|
743 |
else
|
|
744 |
{
|
|
731 | 745 |
|
732 |
var cloudHash = info.Hash.ToLower(); |
|
746 |
var cloudHash = info.Hash.ToLower();
|
|
733 | 747 |
|
734 |
var hash = action.LocalHash.Value; |
|
735 |
var topHash = action.TopHash.Value; |
|
748 |
var hash = action.LocalHash.Value;
|
|
749 |
var topHash = action.TopHash.Value;
|
|
736 | 750 |
|
737 |
//If the file hashes match, abort the upload |
|
738 |
if (hash == cloudHash || topHash == cloudHash) |
|
739 |
{ |
|
740 |
//but store any metadata changes |
|
741 |
StatusKeeper.StoreInfo(fullFileName, info); |
|
742 |
Log.InfoFormat("Skip upload of {0}, hashes match", fullFileName); |
|
743 |
return; |
|
744 |
} |
|
751 |
//If the file hashes match, abort the upload
|
|
752 |
if (hash == cloudHash || topHash == cloudHash)
|
|
753 |
{
|
|
754 |
//but store any metadata changes
|
|
755 |
StatusKeeper.StoreInfo(fullFileName, info);
|
|
756 |
Log.InfoFormat("Skip upload of {0}, hashes match", fullFileName);
|
|
757 |
return;
|
|
758 |
}
|
|
745 | 759 |
|
746 | 760 |
|
747 |
//Mark the file as modified while we upload it |
|
748 |
StatusKeeper.SetFileOverlayStatus(fullFileName, FileOverlayStatus.Modified); |
|
749 |
//And then upload it |
|
761 |
//Mark the file as modified while we upload it
|
|
762 |
StatusKeeper.SetFileOverlayStatus(fullFileName, FileOverlayStatus.Modified);
|
|
763 |
//And then upload it
|
|
750 | 764 |
|
751 |
//Upload even small files using the Hashmap. The server may already contain |
|
752 |
//the relevant block |
|
765 |
//Upload even small files using the Hashmap. The server may already contain
|
|
766 |
//the relevant block
|
|
753 | 767 |
|
754 |
//First, calculate the tree hash |
|
755 |
var treeHash = await Signature.CalculateTreeHashAsync(fullFileName, accountInfo.BlockSize, |
|
756 |
accountInfo.BlockHash, 2); |
|
768 |
//First, calculate the tree hash
|
|
769 |
var treeHash = await Signature.CalculateTreeHashAsync(fullFileName, accountInfo.BlockSize,
|
|
770 |
accountInfo.BlockHash, 2);
|
|
757 | 771 |
|
758 |
await |
|
759 |
UploadWithHashMap(accountInfo, cloudFile, fileInfo as FileInfo, cloudFile.Name, treeHash); |
|
772 |
//TODO: If the upload fails with a 403, abort it and mark conflict |
|
773 |
|
|
774 |
await |
|
775 |
UploadWithHashMap(accountInfo, cloudFile, fileInfo as FileInfo, cloudFile.Name, treeHash); |
|
776 |
} |
|
777 |
//If everything succeeds, change the file and overlay status to normal |
|
778 |
StatusKeeper.SetFileState(fullFileName, FileStatus.Unchanged, FileOverlayStatus.Normal); |
|
779 |
} |
|
780 |
catch (WebException exc) |
|
781 |
{ |
|
782 |
var response=(exc.Response as HttpWebResponse); |
|
783 |
if (response.StatusCode == HttpStatusCode.Forbidden) |
|
784 |
{ |
|
785 |
StatusKeeper.SetFileState(fileInfo.FullName,FileStatus.Forbidden, FileOverlayStatus.Conflict); |
|
786 |
} |
|
760 | 787 |
} |
761 |
//If everything succeeds, change the file and overlay status to normal |
|
762 |
StatusKeeper.SetFileState(fullFileName, FileStatus.Unchanged, FileOverlayStatus.Normal); |
|
763 | 788 |
} |
764 | 789 |
//Notify the Shell to update the overlays |
765 | 790 |
NativeMethods.RaiseChangeNotification(fullFileName); |
Also available in: Unified diff