NSString *destinationPath = [directoryPath stringByAppendingPathComponent:fileName];
if (ifExists && [defaultManager fileExistsAtPath:destinationPath]) {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"File exists"];
+ [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"];
[defaultManager removeItemAtPath:directoryPath error:&error];
}
if (error) {
- NSLog(@"error: %@", error);
- // XXX do something on error, an alert maybe
+ 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];
return nil;
}
until:nil];
[containerRequest startSynchronous];
if ([containerRequest error]) {
- NSLog(@"error:%@", [containerRequest error]);
- // XXX do something on error
+ NSLog(@"HTTP Request Error: %@\nResponse String: %@", [containerRequest error], [containerRequest responseString]);
+ NSAlert *alert = [[[NSAlert alloc] init] autorelease];
+ [alert setMessageText:@"HTTP Request Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"HTTP Request Error: %@\nResponse String: %@",
+ [containerRequest error], [containerRequest responseString]]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
return nil;
}
NSArray *someObjects = [containerRequest objects];
NSError *error = nil;
if (!directoryExists) {
[defaultManager 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];
+ }
} else if (!directoryIsDirectory) {
- [defaultManager removeItemAtPath:directoryPath error:&error];
- }
- if (error) {
- NSLog(@"error: %@", error);
- // XXX do something on error, an alert maybe
+ [defaultManager 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];
+ }
}
} else {
NSString *fileName = [object.name lastPathComponent];
checkIfExists:(BOOL)ifExists
hashes:(NSArray **)hashes {
if (ifExists) {
+ NSString *responseString;
NSError *error;
- BOOL objectExists = [self objectExistsAtContainerName:containerName objectName:objectName error:&error];
+ BOOL isDirectory;
+ BOOL objectExists = [self objectExistsAtContainerName:containerName objectName:objectName
+ responseString:&responseString error:&error isDirectory:&isDirectory];
NSAlert *alert;
if (error) {
alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:@"HTTP Request Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"An error occured: %@", error]];
+ [alert setInformativeText:[NSString stringWithFormat:@"HTTP Request Error: %@", error]];
+ [alert setInformativeText:[NSString stringWithFormat:@"HTTP Request Error: %@\nResponse String: %@",
+ error, responseString]];
[alert addButtonWithTitle:@"OK"];
[alert runModal];
return nil;
} else if (objectExists) {
alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Object exists"];
- [alert setInformativeText:[NSString stringWithFormat:@"An object with path '%@' in the container '%@' already exists, do you want to replace it?", objectName, containerName]];
+ if (isDirectory) {
+ [alert setMessageText:@"Directory Exists"];
+ [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"];
+ [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];
if (choice == NSAlertSecondButtonReturn)
return nil;
- NSString *responseStatusMessage;
- int responseStatusCode = [self deleteObjectAtContainerName:containerName objectName:objectName
- responseStatusMessage:&responseStatusMessage error:&error];
- if (error) {
- alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"HTTP Request Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"An error occured: %@", error]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
- return nil;
- } else if (responseStatusCode != 204) {
- alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"Unexpected Response Status"];
- [alert setInformativeText:[NSString stringWithFormat:@"Unexpected response status %d - %@", responseStatusCode, responseStatusMessage]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
- return nil;
- }
}
}
blockSize:(NSUInteger)blockSize
forFile:(NSString *)filePath
hashes:(NSArray *)hashes
- missingHashesResponse:(NSString *)missingHashesResponse
- checkIfExists:(BOOL)ifExists {
- BOOL objectExists = YES;
- if (ifExists) {
- NSError *error;
- objectExists = [self objectExistsAtContainerName:containerName objectName:objectName error:&error];
- if (error) {
- NSAlert *alert = [[[NSAlert alloc] init] autorelease];
- [alert setMessageText:@"HTTP Request Error"];
- [alert setInformativeText:[NSString stringWithFormat:@"An error occured: %@", error]];
- [alert addButtonWithTitle:@"OK"];
- [alert runModal];
- return nil;
- }
- }
-
+ missingHashesResponse:(NSString *)missingHashesResponse {
NSArray *responseLines = [missingHashesResponse componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableIndexSet *missingBlocks = [NSMutableIndexSet indexSet];
for (NSString *line in responseLines) {
char *tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1);
strcpy(tempFileNameCString, tempFileTemplateCString);
int fileDescriptor = mkstemp(tempFileNameCString);
+ NSString *tempFilePath = [defaultManager stringWithFileSystemRepresentation:tempFileNameCString length:strlen(tempFileNameCString)];
if (fileDescriptor == -1) {
- NSLog(@"temp file creation failed");
- // XXX maybe alert?
+ 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];
return nil;
}
- NSString *tempFilePath = [defaultManager stringWithFileSystemRepresentation:tempFileNameCString length:strlen(tempFileNameCString)];
free(tempFileNameCString);
NSFileHandle *tempFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileDescriptor closeOnDealloc:YES];
}];
[tempFileHandle closeFile];
- if (objectExists) {
- return [ASIPithosObjectRequest updateObjectDataRequestWithContainerName:containerName
- objectName:objectName
- contentEncoding:nil
- contentDisposition:nil
- manifest:nil
- sharing:nil
- isPublic:ASIPithosObjectRequestPublicIgnore
- metadata:nil
- update:NO
- contentRange:@"bytes */*"
- bytes:[NSNumber numberWithUnsignedInteger:0]
- file:tempFilePath];
- } else {
- return [ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName
- objectName:objectName
- eTag:nil
- contentType:contentType
- contentEncoding:nil
- contentDisposition:nil
- manifest:nil
- sharing:nil
- isPublic:ASIPithosObjectRequestPublicIgnore
- metadata:nil
- file:tempFilePath];
+ return [ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName
+ objectName:objectName
+ eTag:nil
+ contentType:contentType
+ contentEncoding:nil
+ contentDisposition:nil
+ manifest:nil
+ sharing:nil
+ isPublic:ASIPithosObjectRequestPublicIgnore
+ metadata:nil
+ file:tempFilePath];
+}
+
++ (NSArray *)writeObjectDataRequestsWithContainerName:(NSString *)containerName
+ objectName:(NSString *)objectName
+ blockSize:(NSUInteger)blockSize
+ blockHash:(NSString *)blockHash
+ forDirectory:(NSString *)directoryPath
+ checkIfExists:(BOOL)ifExists
+ objectNames:(NSMutableArray **)objectNames
+ contentTypes:(NSMutableArray **)contentTypes
+ filePaths:(NSMutableArray **)filePaths
+ hashesArrays:(NSMutableArray **)hashesArrays {
+ if (ifExists) {
+ NSString *responseString;
+ NSError *error;
+ BOOL isDirectory;
+ BOOL objectExists = [self objectExistsAtContainerName:containerName objectName:objectName
+ responseString:&responseString error:&error isDirectory:&isDirectory];
+ NSAlert *alert;
+ if (error) {
+ alert = [[[NSAlert alloc] init] autorelease];
+ [alert setMessageText:@"HTTP Request Error"];
+ [alert setInformativeText:[NSString stringWithFormat:@"HTTP Request Error: %@\nResponse String: %@",
+ error, responseString]];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ return nil;
+ } else if (objectExists && !isDirectory) {
+ alert = [[[NSAlert alloc] init] autorelease];
+ [alert setMessageText:@"Object Exists"];
+ [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];
+ if (choice == NSAlertSecondButtonReturn)
+ return nil;
+ }
+ }
+
+ NSFileManager *defaultManager = [NSFileManager defaultManager];
+ NSError *error = nil;
+ NSArray *subPaths = [defaultManager 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];
+ return nil;
}
+ NSMutableArray *objectRequests = [NSMutableArray arrayWithCapacity:[subPaths count]];
+ *objectNames = [NSMutableArray arrayWithCapacity:[subPaths count]];
+ *contentTypes = [NSMutableArray arrayWithCapacity:[subPaths count]];
+ *filePaths = [NSMutableArray arrayWithCapacity:[subPaths count]];
+ *hashesArrays = [NSMutableArray arrayWithCapacity:[subPaths count]];
+ BOOL isDirectory;
+ NSString *subObjectName;
+ NSArray *hashes;
+ NSUInteger bytes;
+ NSString *contentType;
+ NSString *filePath;
+ for (NSString *objectNameSuffix in subPaths) {
+ filePath = [directoryPath stringByAppendingPathComponent:objectNameSuffix];
+ if ([defaultManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {
+ if (!isDirectory) {
+ hashes = [HashMapHash calculateObjectHashMap:filePath withBlockHash:blockHash andBlockSize:blockSize];
+ if (hashes) {
+ subObjectName = [objectName stringByAppendingPathComponent:objectNameSuffix];
+ bytes = [self bytesOfFile:filePath];
+ error = nil;
+ contentType = [self contentTypeOfFile:filePath error:&error];
+ if (contentType == nil)
+ contentType = @"application/binary";
+ if (error)
+ NSLog(@"contentType detection error: %@", error);
+ [objectRequests addObject:[ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName
+ objectName:subObjectName
+ contentType:contentType
+ contentEncoding:nil
+ contentDisposition:nil
+ manifest:nil
+ sharing:nil
+ isPublic:ASIPithosObjectRequestPublicIgnore
+ metadata:nil
+ blockSize:blockSize
+ blockHash:blockHash
+ hashes:hashes
+ bytes:bytes]];
+ [*objectNames addObject:subObjectName];
+ [*contentTypes addObject:contentType];
+ [*filePaths addObject:filePath];
+ [*hashesArrays addObject:hashes];
+ }
+
+ }//XXX else
+ }
+ }
+
+ return objectRequests;
}
#pragma mark -
return [[attributes objectForKey:NSFileSize] intValue];
}
-+ (BOOL)objectExistsAtContainerName:(NSString *)containerName objectName:(NSString *)objectName error:(NSError **)error {
++ (NSString *)contentTypeOfFile:(NSString *)filePath error:(NSError **)error {
+ NSURLResponse *response = nil;
+ [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]
+ cachePolicy:NSURLCacheStorageNotAllowed
+ timeoutInterval:.1]
+ returningResponse:&response
+ error:error];
+ return [response MIMEType];
+}
+
++ (BOOL)objectExistsAtContainerName:(NSString *)containerName objectName:(NSString *)objectName
+ responseString:(NSString **)responseString error:(NSError **)error isDirectory:(BOOL *)isDirectory {
ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectMetadataRequestWithContainerName:containerName
objectName:objectName];
[objectRequest startSynchronous];
+ *responseString = [objectRequest responseString];
*error = [objectRequest error];
if (*error) {
return NO;
} else if (objectRequest.responseStatusCode == 200) {
+ *isDirectory = [[objectRequest contentType] isEqualToString:@"application/directory"];
return YES;
}
return NO;
return objectRequest.responseStatusCode;
}
+#pragma mark -
+#pragma mark Alerts
+
++ (NSInteger)httpRequestErrorAlertWithRequest:(ASIPithosRequest *)request {
+ NSString *message = [NSString stringWithFormat:
+ @"HTTP request error: %@\n%@ URL: %@\nResponse String: %@",
+ [request error],
+ request.requestMethod,
+ request.url,
+ [request responseString]];
+ NSLog(@"%@", message);
+ NSAlert *alert = [[[NSAlert alloc] init] autorelease];
+ [alert setMessageText:@"HTTP Request Error"];
+ [alert setInformativeText:message];
+ [alert addButtonWithTitle:@"OK"];
+ return [alert runModal];
+}
+
++ (NSInteger)unexpectedResponseStatusAlertWithRequest:(ASIPithosRequest *)request {
+ NSString *message = [NSString stringWithFormat:
+ @"Unexpected response status %d: %@\n%@ URL: %@\nResponse String: %@",
+ request.responseStatusCode,
+ request.responseStatusMessage,
+ request.requestMethod,
+ request.url,
+ [request responseString]];
+ NSLog(@"%@", message);
+ NSAlert *alert = [[[NSAlert alloc] init] autorelease];
+ [alert setMessageText:@"Unexpected Response Status"];
+ [alert setInformativeText:message];
+ [alert addButtonWithTitle:@"OK"];
+ return [alert runModal];
+}
+
@end