Revision cfc17d33 pithos-macos/PithosBrowserController.m
b/pithos-macos/PithosBrowserController.m | ||
---|---|---|
806 | 806 |
- (NSArray *)browser:(NSBrowser *)aBrowser namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination |
807 | 807 |
forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column { |
808 | 808 |
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[draggedNodes count]]; |
809 |
for (PithosNode *node in draggedNodes) { |
|
809 |
for (PithosNode *node in draggedNodes) { |
|
810 |
[names addObject:node.displayName]; |
|
810 | 811 |
// If the node is a subdir ask if the whole tree should be downloaded |
811 | 812 |
if ([node class] == [PithosSubdirNode class]) { |
812 | 813 |
NSAlert *alert = [[[NSAlert alloc] init] autorelease]; |
... | ... | |
815 | 816 |
[alert addButtonWithTitle:@"OK"]; |
816 | 817 |
[alert addButtonWithTitle:@"Cancel"]; |
817 | 818 |
NSInteger choice = [alert runModal]; |
818 |
if (choice == NSAlertFirstButtonReturn) { |
|
819 |
// Operation: Download a subdir node and its descendants |
|
820 |
// The resulting ASIPithosObjectRequests are chained through dependencies |
|
821 |
__block NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ |
|
822 |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
|
823 |
if (operation.isCancelled) { |
|
824 |
[pool drain]; |
|
825 |
return; |
|
826 |
} |
|
827 |
NSArray *objectRequests = [PithosUtilities objectDataRequestsForSubdirWithPithos:pithos |
|
828 |
containerName:node.pithosContainer.name |
|
829 |
objectName:node.pithosObject.name |
|
830 |
toDirectory:[dropDestination path] |
|
831 |
checkIfExists:YES |
|
832 |
sharingAccount:node.sharingAccount]; |
|
833 |
if (!operation.isCancelled && objectRequests) { |
|
834 |
ASIPithosObjectRequest *previousObjectRequest = nil; |
|
835 |
for (__block ASIPithosObjectRequest *objectRequest in objectRequests) { |
|
836 |
if (operation.isCancelled) { |
|
837 |
[pool drain]; |
|
838 |
return; |
|
839 |
} |
|
840 |
[names addObject:[objectRequest.userInfo objectForKey:@"fileName"]]; |
|
841 |
objectRequest.delegate = self; |
|
842 |
objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
|
843 |
objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
|
844 |
NSString *messagePrefix = [NSString stringWithFormat:@"Downloading '%@'", [objectRequest.userInfo objectForKey:@"fileName"]]; |
|
845 |
PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload |
|
846 |
message:[messagePrefix stringByAppendingString:@" (0%)"] |
|
847 |
totalBytes:[[objectRequest.userInfo objectForKey:@"bytes"] unsignedIntegerValue] |
|
848 |
currentBytes:0]; |
|
849 |
dispatch_async(dispatch_get_main_queue(), ^{ |
|
850 |
[activityFacility updateActivity:activity withMessage:activity.message]; |
|
851 |
}); |
|
852 |
[(NSMutableDictionary *)objectRequest.userInfo addEntriesFromDictionary: |
|
853 |
[NSDictionary dictionaryWithObjectsAndKeys: |
|
854 |
activity, @"activity", |
|
855 |
[messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", |
|
856 |
[messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", |
|
857 |
[messagePrefix stringByAppendingString:@" (100%)"], @"finishedActivityMessage", |
|
858 |
[NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", |
|
859 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
|
860 |
NSStringFromSelector(@selector(downloadObjectFinished:)), @"didFinishSelector", |
|
861 |
NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", |
|
862 |
downloadNetworkQueue, @"networkQueue", |
|
863 |
@"download", @"operationType", |
|
864 |
nil]]; |
|
865 |
[objectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){ |
|
866 |
[activityFacility updateActivity:activity |
|
867 |
withMessage:[messagePrefix stringByAppendingFormat:@" (%.0f%%)", (activity.totalBytes ? (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0)) : 100)] |
|
868 |
totalBytes:activity.totalBytes |
|
869 |
currentBytes:(activity.currentBytes + size)]; |
|
870 |
}]; |
|
871 |
if (previousObjectRequest) |
|
872 |
[objectRequest addDependency:previousObjectRequest]; |
|
873 |
previousObjectRequest = objectRequest; |
|
874 |
[downloadNetworkQueue addOperation:[PithosUtilities prepareRequest:objectRequest]]; |
|
875 |
} |
|
876 |
} |
|
877 |
[pool drain]; |
|
878 |
}]; |
|
879 |
[downloadQueue addOperation:operation]; |
|
880 |
} |
|
819 |
if (choice == NSAlertFirstButtonReturn) |
|
820 |
[self downloadNode:node toDirectory:[dropDestination path] withNewFileName:nil version:nil]; |
|
881 | 821 |
} else { |
882 |
// Operation: Download an object node |
|
883 |
__block NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ |
|
884 |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
|
885 |
if (operation.isCancelled) { |
|
886 |
[pool drain]; |
|
887 |
return; |
|
888 |
} |
|
889 |
__block ASIPithosObjectRequest *objectRequest = [PithosUtilities objectDataRequestWithPithos:pithos |
|
890 |
containerName:node.pithosContainer.name |
|
891 |
objectName:node.pithosObject.name |
|
892 |
toDirectory:[dropDestination path] |
|
893 |
checkIfExists:YES |
|
894 |
sharingAccount:node.sharingAccount]; |
|
895 |
if (!operation.isCancelled && objectRequest) { |
|
896 |
[names addObject:[objectRequest.userInfo objectForKey:@"fileName"]]; |
|
897 |
objectRequest.delegate = self; |
|
898 |
objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
|
899 |
objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
|
900 |
NSString *messagePrefix = [NSString stringWithFormat:@"Downloading '%@'", [objectRequest.userInfo objectForKey:@"fileName"]]; |
|
901 |
PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload |
|
902 |
message:[messagePrefix stringByAppendingString:@" (0%)"] |
|
903 |
totalBytes:node.pithosObject.bytes |
|
904 |
currentBytes:0]; |
|
905 |
dispatch_async(dispatch_get_main_queue(), ^{ |
|
906 |
[activityFacility updateActivity:activity withMessage:activity.message]; |
|
907 |
}); |
|
908 |
[(NSMutableDictionary *)objectRequest.userInfo addEntriesFromDictionary: |
|
909 |
[NSDictionary dictionaryWithObjectsAndKeys: |
|
910 |
activity, @"activity", |
|
911 |
[messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", |
|
912 |
[messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", |
|
913 |
[messagePrefix stringByAppendingString:@" (100%)"], @"finishedActivityMessage", |
|
914 |
[NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", |
|
915 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
|
916 |
NSStringFromSelector(@selector(downloadObjectFinished:)), @"didFinishSelector", |
|
917 |
NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", |
|
918 |
downloadNetworkQueue, @"networkQueue", |
|
919 |
@"download", @"operationType", |
|
920 |
nil]]; |
|
921 |
[objectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){ |
|
922 |
[activityFacility updateActivity:activity |
|
923 |
withMessage:[messagePrefix stringByAppendingFormat:@" (%.0f%%)", (activity.totalBytes ? (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0)) : 100)] |
|
924 |
totalBytes:activity.totalBytes |
|
925 |
currentBytes:(activity.currentBytes + size)]; |
|
926 |
}]; |
|
927 |
[downloadNetworkQueue addOperation:[PithosUtilities prepareRequest:objectRequest]]; |
|
928 |
[pool drain]; |
|
929 |
} |
|
930 |
}]; |
|
931 |
[downloadQueue addOperation:operation]; |
|
822 |
[self downloadNode:node toDirectory:[dropDestination path] withNewFileName:nil version:nil]; |
|
932 | 823 |
} |
933 | 824 |
} |
934 | 825 |
return names; |
... | ... | |
1045 | 936 |
#pragma mark - |
1046 | 937 |
#pragma mark Drag and Drop methods |
1047 | 938 |
|
939 |
- (void)downloadNode:(PithosNode *)node |
|
940 |
toDirectory:(NSString *)dirPath |
|
941 |
withNewFileName:(NSString *)newFileName |
|
942 |
version:(NSString *)version { |
|
943 |
if ([node class] == [PithosSubdirNode class]) { |
|
944 |
// XXX newFilename and version are ignored in the case of a subdir node for now |
|
945 |
// Operation: Download a subdir node and its descendants |
|
946 |
// The resulting ASIPithosObjectRequests are chained through dependencies |
|
947 |
__block NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ |
|
948 |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
|
949 |
if (operation.isCancelled) { |
|
950 |
[pool drain]; |
|
951 |
return; |
|
952 |
} |
|
953 |
NSArray *objectRequests = [PithosUtilities objectDataRequestsForSubdirWithPithos:pithos |
|
954 |
containerName:node.pithosContainer.name |
|
955 |
objectName:node.pithosObject.name |
|
956 |
toDirectory:dirPath |
|
957 |
checkIfExists:YES |
|
958 |
sharingAccount:node.sharingAccount]; |
|
959 |
if (!operation.isCancelled && objectRequests) { |
|
960 |
ASIPithosObjectRequest *previousObjectRequest = nil; |
|
961 |
for (__block ASIPithosObjectRequest *objectRequest in objectRequests) { |
|
962 |
if (operation.isCancelled) { |
|
963 |
[pool drain]; |
|
964 |
return; |
|
965 |
} |
|
966 |
objectRequest.delegate = self; |
|
967 |
objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
|
968 |
objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
|
969 |
NSString *messagePrefix = [NSString stringWithFormat:@"Downloading '%@'", [objectRequest.userInfo objectForKey:@"fileName"]]; |
|
970 |
PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload |
|
971 |
message:[messagePrefix stringByAppendingString:@" (0%)"] |
|
972 |
totalBytes:[[objectRequest.userInfo objectForKey:@"bytes"] unsignedIntegerValue] |
|
973 |
currentBytes:0]; |
|
974 |
dispatch_async(dispatch_get_main_queue(), ^{ |
|
975 |
[activityFacility updateActivity:activity withMessage:activity.message]; |
|
976 |
}); |
|
977 |
[(NSMutableDictionary *)objectRequest.userInfo addEntriesFromDictionary: |
|
978 |
[NSDictionary dictionaryWithObjectsAndKeys: |
|
979 |
activity, @"activity", |
|
980 |
[messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", |
|
981 |
[messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", |
|
982 |
[messagePrefix stringByAppendingString:@" (100%)"], @"finishedActivityMessage", |
|
983 |
[NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", |
|
984 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
|
985 |
NSStringFromSelector(@selector(downloadObjectFinished:)), @"didFinishSelector", |
|
986 |
NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", |
|
987 |
downloadNetworkQueue, @"networkQueue", |
|
988 |
@"download", @"operationType", |
|
989 |
nil]]; |
|
990 |
[objectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){ |
|
991 |
[activityFacility updateActivity:activity |
|
992 |
withMessage:[messagePrefix stringByAppendingFormat:@" (%.0f%%)", (activity.totalBytes ? (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0)) : 100)] |
|
993 |
totalBytes:activity.totalBytes |
|
994 |
currentBytes:(activity.currentBytes + size)]; |
|
995 |
}]; |
|
996 |
if (previousObjectRequest) |
|
997 |
[objectRequest addDependency:previousObjectRequest]; |
|
998 |
previousObjectRequest = objectRequest; |
|
999 |
[downloadNetworkQueue addOperation:[PithosUtilities prepareRequest:objectRequest]]; |
|
1000 |
} |
|
1001 |
} |
|
1002 |
[pool drain]; |
|
1003 |
}]; |
|
1004 |
[downloadQueue addOperation:operation]; |
|
1005 |
} else if ([node class] == [PithosObjectNode class]) { |
|
1006 |
// Operation: Download an object node |
|
1007 |
__block NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ |
|
1008 |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
|
1009 |
if (operation.isCancelled) { |
|
1010 |
[pool drain]; |
|
1011 |
return; |
|
1012 |
} |
|
1013 |
__block ASIPithosObjectRequest *objectRequest = [PithosUtilities objectDataRequestWithPithos:pithos |
|
1014 |
containerName:node.pithosContainer.name |
|
1015 |
objectName:node.pithosObject.name |
|
1016 |
version:version |
|
1017 |
toDirectory:dirPath |
|
1018 |
withNewFileName:newFileName |
|
1019 |
checkIfExists:(version ? NO : YES) |
|
1020 |
sharingAccount:node.sharingAccount]; |
|
1021 |
if (!operation.isCancelled && objectRequest) { |
|
1022 |
objectRequest.delegate = self; |
|
1023 |
objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:); |
|
1024 |
objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:); |
|
1025 |
NSString *messagePrefix = [NSString stringWithFormat:@"Downloading '%@'", [objectRequest.userInfo objectForKey:@"fileName"]]; |
|
1026 |
PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload |
|
1027 |
message:[messagePrefix stringByAppendingString:@" (0%)"] |
|
1028 |
totalBytes:node.pithosObject.bytes |
|
1029 |
currentBytes:0]; |
|
1030 |
dispatch_async(dispatch_get_main_queue(), ^{ |
|
1031 |
[activityFacility updateActivity:activity withMessage:activity.message]; |
|
1032 |
}); |
|
1033 |
[(NSMutableDictionary *)objectRequest.userInfo addEntriesFromDictionary: |
|
1034 |
[NSDictionary dictionaryWithObjectsAndKeys: |
|
1035 |
activity, @"activity", |
|
1036 |
[messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", |
|
1037 |
[messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", |
|
1038 |
[messagePrefix stringByAppendingString:@" (100%)"], @"finishedActivityMessage", |
|
1039 |
[NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", |
|
1040 |
[NSNumber numberWithUnsignedInteger:10], @"retries", |
|
1041 |
NSStringFromSelector(@selector(downloadObjectFinished:)), @"didFinishSelector", |
|
1042 |
NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", |
|
1043 |
downloadNetworkQueue, @"networkQueue", |
|
1044 |
@"download", @"operationType", |
|
1045 |
nil]]; |
|
1046 |
[objectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){ |
|
1047 |
[activityFacility updateActivity:activity |
|
1048 |
withMessage:[messagePrefix stringByAppendingFormat:@" (%.0f%%)", (activity.totalBytes ? (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0)) : 100)] |
|
1049 |
totalBytes:activity.totalBytes |
|
1050 |
currentBytes:(activity.currentBytes + size)]; |
|
1051 |
}]; |
|
1052 |
[downloadNetworkQueue addOperation:[PithosUtilities prepareRequest:objectRequest]]; |
|
1053 |
[pool drain]; |
|
1054 |
} |
|
1055 |
}]; |
|
1056 |
[downloadQueue addOperation:operation]; |
|
1057 |
} |
|
1058 |
} |
|
1059 |
|
|
1048 | 1060 |
- (BOOL)uploadFiles:(NSArray *)filenames toNode:(PithosNode *)destinationNode { |
1049 | 1061 |
if (([destinationNode class] != [PithosSubdirNode class]) && ([destinationNode class] != [PithosContainerNode class])) |
1050 | 1062 |
return NO; |
... | ... | |
1677 | 1689 |
NSUInteger totalBytes = activity.totalBytes; |
1678 | 1690 |
|
1679 | 1691 |
// XXX change contentLength to objectContentLength if it is fixed in the server |
1680 |
if (([objectRequest contentLength] == 0) && ![PithosUtilities isContentTypeDirectory:[objectRequest contentType]]) { |
|
1692 |
if ([objectRequest contentLength] == 0) { |
|
1693 |
// The check above was: |
|
1694 |
// if (([objectRequest contentLength] == 0) && ![PithosUtilities isContentTypeDirectory:[objectRequest contentType]]) { |
|
1695 |
// I checked for directory content types in order not to create a file in place of a directory, |
|
1696 |
// but this callback method is not called in the case of a directory download. |
|
1697 |
// It maybe the case though, when downloading an old version of an object, is of a directory content type. |
|
1698 |
// In this case, a file should be created. This is actually a feature that allows you to hide data in a directory object. |
|
1681 | 1699 |
NSLog(@"Downloaded 0 bytes"); |
1682 | 1700 |
NSFileManager *fileManager = [NSFileManager defaultManager]; |
1683 | 1701 |
if (![fileManager fileExistsAtPath:filePath]) { |
Also available in: Unified diff