NSString *destinationPath = [directoryPath stringByAppendingPathComponent:fileName];
if (ifExists && [fileManager fileExistsAtPath:destinationPath]) {
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"File Exists"];
- [alert setInformativeText:[NSString stringWithFormat:@"A file or directory named '%@' already exists, do you want to replace it?", fileName]];
- [alert addButtonWithTitle:@"OK"];
- [alert addButtonWithTitle:@"Cancel"];
- NSInteger choice = [alert runModal];
+ __block NSInteger choice;
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"File Exists"];
+ [alert setInformativeText:[NSString stringWithFormat:@"A file or directory named '%@' already exists, do you want to replace it?", fileName]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert addButtonWithTitle:@"Cancel"];
+ choice = [alert runModal];
+ });
if (choice == NSAlertSecondButtonReturn)
return nil;
}
[fileManager removeItemAtPath:directoryPath error:&error];
}
if (error) {
- NSLog(@"Cannot remove existing file '%@': %@", fileName, error);
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Removal Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"Cannot remove existing file '%@': %@", fileName, error]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
+ DLog(@"Cannot remove existing file '%@': %@", fileName, error);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Removal Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"Cannot remove existing file '%@': %@",
+ fileName, [error localizedDescription]]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ });
return nil;
}
NSString *subdirName = [objectName lastPathComponent];
NSString *destinationPath = [directoryPath stringByAppendingPathComponent:subdirName];
if (ifExists && [[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"File exists"];
- [alert setInformativeText:[NSString stringWithFormat:@"A file or directory named '%@' already exists, do you want to replace it?", subdirName]];
- [alert addButtonWithTitle:@"OK"];
- [alert addButtonWithTitle:@"Cancel"];
- NSInteger choice = [alert runModal];
+ __block NSInteger choice;
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"File exists"];
+ [alert setInformativeText:[NSString stringWithFormat:@"A file or directory named '%@' already exists, do you want to replace it?", subdirName]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert addButtonWithTitle:@"Cancel"];
+ choice = [alert runModal];
+ });
if (choice == NSAlertSecondButtonReturn)
return nil;
}
NSError *error = nil;
[fileManager createDirectoryAtPath:[directoryPath stringByAppendingPathComponent:subdirName] withIntermediateDirectories:YES attributes:nil error:&error];
if (error) {
- NSLog(@"Cannot create directory at '%@': %@", directoryPath, error);
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Create Directory Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"Cannot create directory at '%@': %@",
- directoryPath, error]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
+ DLog(@"Cannot create directory at '%@': %@", directoryPath, error);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Create Directory Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"Cannot create directory at '%@': %@",
+ directoryPath, [error localizedDescription]]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ });
}
for (ASIPithosObject *object in objects) {
if (!directoryExists) {
[fileManager createDirectoryAtPath:subdirDirectoryPath withIntermediateDirectories:YES attributes:nil error:&error];
if (error) {
- NSLog(@"Cannot create directory at '%@': %@", subdirDirectoryPath, error);
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Create Directory Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"Cannot create directory at '%@': %@",
- subdirDirectoryPath, error]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
+ DLog(@"Cannot create directory at '%@': %@", subdirDirectoryPath, error);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Create Directory Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"Cannot create directory at '%@': %@",
+ subdirDirectoryPath, [error localizedDescription]]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ });
}
} else if (!directoryIsDirectory) {
[fileManager removeItemAtPath:subdirDirectoryPath error:&error];
if (error) {
- NSLog(@"Cannot remove existing file at '%@': %@", subdirDirectoryPath, error);
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Remove File Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"Cannot remove existing file at '%@': %@",
- subdirDirectoryPath, error]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
+ DLog(@"Cannot remove existing file at '%@': %@", subdirDirectoryPath, error);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Remove File Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"Cannot remove existing file at '%@': %@",
+ subdirDirectoryPath, [error localizedDescription]]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ });
}
}
} else {
strcpy(tempFileNameCString, tempFileTemplateCString);
int fileDescriptor = mkstemp(tempFileNameCString);
NSString *tempFilePath = [fileManager stringWithFileSystemRepresentation:tempFileNameCString length:strlen(tempFileNameCString)];
+ free(tempFileNameCString);
if (fileDescriptor == -1) {
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Create Temporary File Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"Cannot create temporary file at '%@'", tempFilePath]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Create Temporary File Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"Cannot create temporary file at '%@'", tempFilePath]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ });
return nil;
}
- free(tempFileNameCString);
NSFileHandle *tempFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileDescriptor closeOnDealloc:YES];
[missingBlocks enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop){
NSError *error = nil;
NSArray *subPaths = [fileManager subpathsOfDirectoryAtPath:directoryPath error:&error];
if (error) {
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Directory Read Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"Cannot read contents of directory '%@': %@",
- [directoryPath lastPathComponent], error]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Directory Read Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"Cannot read contents of directory '%@': %@",
+ [directoryPath lastPathComponent], [error localizedDescription]]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ });
return nil;
}
if (!isDirectory) {
hashes = [HashMapHash objectHashMapStrings:filePath withBlockHash:blockHash andBlockSize:blockSize];
if (hashes) {
- subObjectName = [objectName stringByAppendingPathComponent:objectNameSuffix];
+ subObjectName = [[objectName stringByAppendingPathComponent:objectNameSuffix] precomposedStringWithCanonicalMapping];
fileName = [filePath lastPathComponent];
if ([filePath hasSuffix:@"/"])
fileName = [fileName stringByAppendingString:@"/"];
contentType = [self contentTypeOfFile:filePath error:&error];
if (contentType == nil)
contentType = @"application/octet-stream";
+ #if DEBUG_PITHOS
if (error)
- NSLog(@"contentType detection error: %@", error);
+ DLog(@"contentType detection error: %@", error);
+ #endif
objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos
containerName:containerName
objectName:subObjectName
}
} else {
- subObjectName = [objectName stringByAppendingPathComponent:objectNameSuffix];
+ subObjectName = [[objectName stringByAppendingPathComponent:objectNameSuffix] precomposedStringWithCanonicalMapping];
fileName = [filePath lastPathComponent];
objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos
containerName:containerName
#pragma mark -
#pragma mark Copy
-+ (ASIPithosObjectRequest *)copyObjectRequestWithPithos:(ASIPithos *)pithos
++ (ASIPithosObjectRequest *)cpyObjectRequestWithPithos:(ASIPithos *)pithos
containerName:(NSString *)containerName
objectName:(NSString *)objectName
destinationContainerName:(NSString *)destinationContainerName
sharingAccount:nil])
return nil;
- ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos
+ ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest cpyObjectDataRequestWithPithos:pithos
containerName:containerName
objectName:objectName
contentType:nil
return objectRequest;
}
-+ (NSArray *)copyObjectRequestsForSubdirWithPithos:(ASIPithos *)pithos
++ (NSArray *)cpyObjectRequestsForSubdirWithPithos:(ASIPithos *)pithos
containerName:(NSString *)containerName
objectName:(NSString *)objectName
destinationContainerName:(NSString *)destinationContainerName
ASIPithosObjectRequest *objectRequest;
if ([objectName isEqualToString:destinationObjectName]) {
if (![objectName hasSuffix:@"/"]) {
- objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos
+ objectRequest = [ASIPithosObjectRequest cpyObjectDataRequestWithPithos:pithos
containerName:containerName
objectName:objectName
contentType:nil
[objectRequests addObject:objectRequest];
}
for (ASIPithosObject *object in objects) {
- objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos
+ objectRequest = [ASIPithosObjectRequest cpyObjectDataRequestWithPithos:pithos
containerName:containerName
objectName:object.name
contentType:nil
}
} else {
if (![objectName hasSuffix:@"/"]) {
- objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos
+ objectRequest = [ASIPithosObjectRequest cpyObjectDataRequestWithPithos:pithos
containerName:containerName
objectName:objectName
contentType:nil
withString:destinationObjectName
options:NSAnchoredSearch
range:prefixRange];
- objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos
+ objectRequest = [ASIPithosObjectRequest cpyObjectDataRequestWithPithos:pithos
containerName:containerName
objectName:object.name
contentType:nil
if (uti != NULL) {
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType);
CFRelease(uti);
- return (NSString *)MIMEType;
+ CFRelease(url);
+ return (__bridge_transfer NSString *)MIMEType;
}
}
+ CFRelease(url);
return nil;
}
return YES;
}
-// Removes contents of a directory
-+ (void)removeContentsAtPath:(NSString *)dirPath {
+// Removes contents of a directory and the directory itself if selected
++ (void)removeContentsAtPath:(NSString *)dirPath andDirectory:(BOOL)removeDirectory {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
BOOL isDirectory;
}
error = nil;
}
+ if (removeDirectory && (![fileManager removeItemAtPath:dirPath error:&error] || error)) {
+ [self fileActionFailedAlertWithTitle:@"Remove Directory Error"
+ message:[NSString stringWithFormat:@"Cannot remove directory at '%@'", dirPath]
+ error:error];
+ }
} else if (![fileManager removeItemAtPath:dirPath error:&error] || error) {
[self fileActionFailedAlertWithTitle:@"Remove File Error"
message:[NSString stringWithFormat:@"Cannot remove file at '%@'", dirPath]
}
}
+// Removes contents of a directory
++ (void)removeContentsAtPath:(NSString *)dirPath {
+ [self removeContentsAtPath:dirPath andDirectory:NO];
+}
+
// Returns if an object is a directory based on its content type
+ (BOOL)isContentTypeDirectory:(NSString *)contentType {
return ([contentType isEqualToString:@"application/directory"] ||
objectName:objectName];
if (sharingAccount)
[objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
- ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
- [networkQueue go];
- [networkQueue addOperations:[NSArray arrayWithObject:[self prepareRequest:objectRequest]] waitUntilFinished:YES];
- *error = [objectRequest error];
- if (*error) {
- [self httpRequestErrorAlertWithRequest:objectRequest];
- return NO;
- } else if (objectRequest.responseStatusCode == 200) {
- *isDirectory = [self isContentTypeDirectory:[objectRequest contentType]];
- return YES;
+ [self startAndWaitForRequest:objectRequest];
+ if (error != NULL) {
+ *error = [objectRequest error];
+ if (*error) {
+ [self httpRequestErrorAlertWithRequest:objectRequest];
+ return NO;
+ } else if (objectRequest.responseStatusCode == 200) {
+ *isDirectory = [self isContentTypeDirectory:[objectRequest contentType]];
+ return YES;
+ }
}
return NO;
}
if (error) {
return NO;
} else if (objectExists) {
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- if (isDirectory) {
- [alert setMessageText:@"Directory Exists"];
- if (sharingAccount)
- [alert setInformativeText:[NSString stringWithFormat:@"A directory with path '%@' in the container '%@' of user '%@' already exists, do you want to replace it?", objectName, containerName, sharingAccount]];
- else
- [alert setInformativeText:[NSString stringWithFormat:@"A directory with path '%@' in the container '%@' already exists, do you want to replace it?", objectName, containerName]];
- } else {
- [alert setMessageText:@"Object Exists"];
- if (sharingAccount)
- [alert setInformativeText:[NSString stringWithFormat:@"An object with path '%@' in the container '%@' of user '%@' already exists, do you want to replace it?", objectName, containerName, sharingAccount]];
- else
- [alert setInformativeText:[NSString stringWithFormat:@"An object with path '%@' in the container '%@' already exists, do you want to replace it?", objectName, containerName]];
- }
- [alert addButtonWithTitle:@"OK"];
- [alert addButtonWithTitle:@"Cancel"];
- NSInteger choice = [alert runModal];
+ __block NSInteger choice;
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ NSAlert *alert = [[NSAlert alloc] init];
+ if (isDirectory) {
+ [alert setMessageText:@"Directory Exists"];
+ if (sharingAccount)
+ [alert setInformativeText:[NSString stringWithFormat:@"A directory with path '%@' in the container '%@' of user '%@' already exists, do you want to replace it?", objectName, containerName, sharingAccount]];
+ else
+ [alert setInformativeText:[NSString stringWithFormat:@"A directory with path '%@' in the container '%@' already exists, do you want to replace it?", objectName, containerName]];
+ } else {
+ [alert setMessageText:@"Object Exists"];
+ if (sharingAccount)
+ [alert setInformativeText:[NSString stringWithFormat:@"An object with path '%@' in the container '%@' of user '%@' already exists, do you want to replace it?", objectName, containerName, sharingAccount]];
+ else
+ [alert setInformativeText:[NSString stringWithFormat:@"An object with path '%@' in the container '%@' already exists, do you want to replace it?", objectName, containerName]];
+ }
+ [alert addButtonWithTitle:@"OK"];
+ [alert addButtonWithTitle:@"Cancel"];
+ choice = [alert runModal];
+ });
if (choice == NSAlertSecondButtonReturn)
return NO;
}
until:nil];
if (sharingAccount)
[containerRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
- ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
- [networkQueue go];
- [networkQueue addOperations:[NSArray arrayWithObject:[self prepareRequest:containerRequest]] waitUntilFinished:YES];
+ [self startAndWaitForRequest:containerRequest];
if ([containerRequest error]) {
[self httpRequestErrorAlertWithRequest:containerRequest];
return nil;
objectNameExtraSuffix = [objectName substringFromIndex:lastDotRange.location];
} else if ([objectName hasSuffix:@"/"]) {
objectNamePrefix = [objectName substringToIndex:([objectName length] - 1)];
- objectNameExtraSuffix = [NSString stringWithString:@"/"];
+ objectNameExtraSuffix = @"/";
} else {
objectNamePrefix = [NSString stringWithString:objectName];
objectNameExtraSuffix = [NSString string];
NSString *subdirNameExtraSuffix;
if ([subdirName hasSuffix:@"/"]) {
subdirNamePrefix = [subdirName substringToIndex:([subdirName length] - 1)];
- subdirNameExtraSuffix = [NSString stringWithString:@"/"];
+ subdirNameExtraSuffix = @"/";
} else {
subdirNamePrefix = [NSString stringWithString:subdirName];
subdirNameExtraSuffix = [NSString string];
#pragma mark -
#pragma mark Alerts
-+ (NSInteger)httpRequestErrorAlertWithRequest:(ASIPithosRequest *)request {
++ (void)httpRequestErrorAlertWithRequest:(ASIPithosRequest *)request {
+ if (request.responseStatusCode == 401) {
+ [self httpAuthenticationError];
+ return;
+ }
NSString *message = [NSString stringWithFormat:
@"HTTP request error: %@\n%@ URL: %@\nRequest Headers: %@\nResponse Headers: %@\nResponse String: %@",
- [request error],
+ [[request error] localizedDescription],
request.requestMethod,
request.url,
[request requestHeaders],
[request responseHeaders],
[request responseString]];
- NSLog(@"%@", message);
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"HTTP Request Error"];
- [alert setInformativeText:message];
- [alert addButtonWithTitle:@"OK"];
- return [alert runModal];
+ DLog(@"%@", message);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ @autoreleasepool {
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"HTTP Request Error"];
+ [alert setInformativeText:message];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ }
+ });
}
-+ (NSInteger)unexpectedResponseStatusAlertWithRequest:(ASIPithosRequest *)request {
++ (void)unexpectedResponseStatusAlertWithRequest:(ASIPithosRequest *)request {
+ if (request.responseStatusCode == 401) {
+ [self httpAuthenticationError];
+ return;
+ }
NSString *message = [NSString stringWithFormat:
@"Unexpected response status %d: %@\n%@ URL: %@\nRequest Headers: %@\nResponse Headers: %@\nResponse String: %@",
request.responseStatusCode,
[request requestHeaders],
[request responseHeaders],
[request responseString]];
- NSLog(@"%@", message);
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Unexpected Response Status"];
- [alert setInformativeText:message];
- [alert addButtonWithTitle:@"OK"];
- return [alert runModal];
+ DLog(@"%@", message);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ @autoreleasepool {
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Unexpected Response Status"];
+ [alert setInformativeText:message];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ }
+ });
}
-+ (NSInteger)fileActionFailedAlertWithTitle:(NSString *)title message:(NSString *)message error:(NSError *)error {
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:title];
- if (error)
- [alert setInformativeText:[NSString stringWithFormat:@"%@: %@", message, error]];
- else
- [alert setInformativeText:message];
- [alert addButtonWithTitle:@"OK"];
- return [alert runModal];
++ (void)httpAuthenticationError {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ @autoreleasepool {
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Authentication Error"];
+ [alert setInformativeText:@"Authentication error, please check your token or login again"];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ }
+ });
+}
+
++ (void)fileActionFailedAlertWithTitle:(NSString *)title message:(NSString *)message error:(NSError *)error {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ @autoreleasepool {
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:title];
+ if (error)
+ [alert setInformativeText:[NSString stringWithFormat:@"%@: %@", message, [error localizedDescription]]];
+ else
+ [alert setInformativeText:message];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ }
+ });
}
#pragma mark -
}
+ (ASIPithosRequest *)copyRequest:(ASIPithosRequest *)request {
- NSMutableDictionary *userInfo = (NSMutableDictionary *)[[request.userInfo retain] autorelease];
+ NSMutableDictionary *userInfo = (NSMutableDictionary *)request.userInfo;
request.userInfo = nil;
ASIPithosRequest *newRequest = [request copy];
newRequest.userInfo = userInfo;
return newRequest;
}
++ (void)startAndWaitForRequest:(ASIPithosRequest *)request {
+ ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
+ [networkQueue go];
+ [networkQueue addOperations:[NSArray arrayWithObject:[self prepareRequest:request]] waitUntilFinished:YES];
+}
+
@end