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