Initial commit of my iPhoto2Ansel export plugin.
authorMichael J. Rubinsky <mrubinsk@horde.org>
Sun, 23 Nov 2008 20:34:29 +0000 (15:34 -0500)
committerMichael J. Rubinsky <mrubinsk@horde.org>
Sun, 23 Nov 2008 20:34:29 +0000 (15:34 -0500)
Very rough code, but it provides basic functionality at this point.

At this point, I believe it is iPhoto 7+ / OSX 10.5+ only. (I don't
have access to any other versions to test/class dump etc..)

Be gentle, this is my first "real" Cocoa/Objective C proect, but am
always happy to receive constructive feedback...

If you want to run this in the debugger, you need to add a
"Custom Executable" to the xcode project. This setting is stored in the
user specific project file, which is ignored in git since it changes just
about everytime you open the project.

61 files changed:
iPhoto2Ansel/.gitignore [new file with mode: 0644]
iPhoto2Ansel/AnselExportController.h [new file with mode: 0644]
iPhoto2Ansel/AnselExportController.m [new file with mode: 0644]
iPhoto2Ansel/AnselExportPluginBox.h [new file with mode: 0644]
iPhoto2Ansel/AnselExportPluginBox.m [new file with mode: 0644]
iPhoto2Ansel/English.lproj/InfoPlist.strings [new file with mode: 0755]
iPhoto2Ansel/English.lproj/Panel.nib/classes.nib [new file with mode: 0644]
iPhoto2Ansel/English.lproj/Panel.nib/info.nib [new file with mode: 0644]
iPhoto2Ansel/English.lproj/Panel.nib/keyedobjects.nib [new file with mode: 0644]
iPhoto2Ansel/ExportImageProtocol.h [new file with mode: 0755]
iPhoto2Ansel/ExportPluginBoxProtocol.h [new file with mode: 0755]
iPhoto2Ansel/ExportPluginProtocol.h [new file with mode: 0755]
iPhoto2Ansel/FBProgressController.h [new file with mode: 0644]
iPhoto2Ansel/FBProgressController.m [new file with mode: 0644]
iPhoto2Ansel/Info.plist [new file with mode: 0644]
iPhoto2Ansel/InterThreadMessaging.h [new file with mode: 0644]
iPhoto2Ansel/InterThreadMessaging.m [new file with mode: 0644]
iPhoto2Ansel/ProgressSheet.nib/classes.nib [new file with mode: 0644]
iPhoto2Ansel/ProgressSheet.nib/info.nib [new file with mode: 0644]
iPhoto2Ansel/ProgressSheet.nib/keyedobjects.nib [new file with mode: 0644]
iPhoto2Ansel/TURAnsel.h [new file with mode: 0644]
iPhoto2Ansel/TURAnsel.m [new file with mode: 0644]
iPhoto2Ansel/TURAnselGallery.h [new file with mode: 0644]
iPhoto2Ansel/TURAnselGallery.m [new file with mode: 0644]
iPhoto2Ansel/TURXMLConnection.h [new file with mode: 0644]
iPhoto2Ansel/TURXMLConnection.m [new file with mode: 0644]
iPhoto2Ansel/XMLRPC-Info.plist [new file with mode: 0644]
iPhoto2Ansel/XMLRPC.framework/Headers [new symlink]
iPhoto2Ansel/XMLRPC.framework/Resources [new symlink]
iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPC.h [new file with mode: 0644]
iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCConnection.h [new file with mode: 0644]
iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCRequest.h [new file with mode: 0644]
iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCResponse.h [new file with mode: 0644]
iPhoto2Ansel/XMLRPC.framework/Versions/A/Resources/English.lproj/Localizable.strings [new file with mode: 0644]
iPhoto2Ansel/XMLRPC.framework/Versions/A/Resources/Info.plist [new file with mode: 0644]
iPhoto2Ansel/XMLRPC.framework/Versions/A/XMLRPC [new file with mode: 0755]
iPhoto2Ansel/XMLRPC.framework/Versions/Current [new symlink]
iPhoto2Ansel/XMLRPC.framework/XMLRPC [new symlink]
iPhoto2Ansel/iPhoto2Ansel.xcodeproj/mrubinsk.mode1v3 [new file with mode: 0644]
iPhoto2Ansel/iPhoto2Ansel.xcodeproj/project.pbxproj [new file with mode: 0644]
iPhoto2Ansel/iPhoto2Ansel_Prefix.pch [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSDataAdditions.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSDataAdditions.m [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSStringAdditions.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSStringAdditions.m [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/Info.plist [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/LICENSE [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/Languages/English.lproj/Localizable.strings [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/README [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPC.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPC.pch [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCConnection.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCConnection.m [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCDecoder.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCDecoder.m [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCEncoder.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCEncoder.m [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCRequest.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCRequest.m [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCResponse.h [new file with mode: 0644]
iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCResponse.m [new file with mode: 0644]

diff --git a/iPhoto2Ansel/.gitignore b/iPhoto2Ansel/.gitignore
new file mode 100644 (file)
index 0000000..62f6022
--- /dev/null
@@ -0,0 +1,4 @@
+build/
+*.pbxuser
+*.perspectivev3
+*.pbxproject
diff --git a/iPhoto2Ansel/AnselExportController.h b/iPhoto2Ansel/AnselExportController.h
new file mode 100644 (file)
index 0000000..85df06e
--- /dev/null
@@ -0,0 +1,67 @@
+//
+//  AnselExportController.h
+//  iPhoto2Ansel
+//
+//  Created by Michael Rubinsky on 10/23/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "ExportPluginProtocol.h"
+
+@class TURAnsel, TURAnselGallery;
+@class FBProgressController;
+
+@interface AnselExportController : NSObject <ExportPluginProtocol> {
+
+    // Export manager passed in from iPhoto
+    id <ExportImageProtocol> mExportMgr;
+    
+    // iPhoto asks for these
+    IBOutlet NSBox <ExportPluginBoxProtocol> *mSettingsBox;
+    IBOutlet NSControl *firstView;
+    
+    //Outlets   
+    IBOutlet NSPopUpButton *mSizePopUp;
+    IBOutlet NSPopUpButton *mQualityPopUp;
+    IBOutlet NSTextField *anselHostURL;
+    IBOutlet NSTextField *username;
+    IBOutlet NSSecureTextField *password;
+    IBOutlet NSComboBox *galleryCombo;
+    IBOutlet NSTextField *connectedLabel;
+    IBOutlet NSTextField *newGalleryName;
+    IBOutlet NSButton *beginButton;
+    IBOutlet NSButton *newGalleryButton;
+    IBOutlet NSProgressIndicator *spinner;
+    // User choosen settings
+    int size;
+    int quality;
+    
+    // Progress struct (This one is part of the protocol, but we don't use it)
+    ExportPluginProgress progress;
+    
+    // This is our real progress controller (stolen from Facebook exporter).
+    FBProgressController *progressController;
+    
+    // Mutex lock (required for the protocol, but not used)
+    NSRecursiveLock *progressLock;
+
+    BOOL cancelExport;
+
+    TURAnsel *anselController;
+    TURAnselGallery *currentGallery;
+    int currentImageCount;
+}
+@property (readwrite, retain) TURAnselGallery *currentGallery;
+@property (readwrite) int size;
+@property (readwrite) int quality;
+
+- (NSWindow *)window;
+- (IBAction) doConnect: (id)sender;
+- (IBAction) doNewGallery: (id)sender;
+
+// overrides
+- (void)awakeFromNib;
+- (void)dealloc;
+
+@end
diff --git a/iPhoto2Ansel/AnselExportController.m b/iPhoto2Ansel/AnselExportController.m
new file mode 100644 (file)
index 0000000..3074460
--- /dev/null
@@ -0,0 +1,394 @@
+//
+//  AnselExportController.m
+//  iPhoto2Ansel
+//
+//  Created by Michael Rubinsky on 10/23/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+#import <QuickTime/QuickTime.h>
+#import "TURAnsel.h"
+#import "TURAnselGallery.h"
+#import "AnselExportController.h"
+#import "FBProgressController.h";
+
+@interface AnselExportController (PrivateAPI)
+- (void)connect;
+- (void)postProgressStatus:(NSString *)status;
+- (void)privatePerformExport;
+- (void)runExport;
+- (void)canExport;
+- (void)newGallery;
+@end
+
+@implementation AnselExportController
+
+@synthesize size;
+@synthesize quality;
+@synthesize currentGallery;
+
+#pragma mark Overrides
+/**
+ * Set up UI defaults
+ */
+- (void)awakeFromNib
+{
+    // UI Defaults
+    [mSizePopUp selectItemWithTag:2];
+    [mQualityPopUp selectItemWithTag:2];
+    [connectedLabel setStringValue:@"Not Connected"];
+    [connectedLabel setTextColor: [NSColor redColor]];
+    [spinner stopAnimation:self];
+}
+-(void)dealloc
+{
+    //anselController is released from the AnselController delegate method.
+    [progressController release];
+    [super dealloc];
+}
+
+#pragma mark Getter Setters
+- (NSWindow *)window {
+    return [mExportMgr window];
+}
+
+#pragma mark Actions
+// Start the connection process.
+-(void)doConnect: (id)sender
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSDictionary *p = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:[anselHostURL stringValue],
+                                                             [username stringValue],
+                                                             [password stringValue], nil]
+                                                    forKeys:[NSArray arrayWithObjects:@"endpoint", @"username", @"password", nil]];
+    // Create our controller
+    anselController = [[TURAnsel alloc] initWithConnectionParameters:p];
+    [anselController setDelegate:self];
+    
+    // Set up the galleryCombo
+    [galleryCombo setUsesDataSource:YES];
+    [galleryCombo setDataSource:anselController];
+    [galleryCombo setDelegate:self];
+    [spinner startAnimation:self];
+    // Detach to a new thread and do the actual login/retrieval of gallery list
+    [NSApplication detachDrawingThread: @selector(connect) toTarget: self withObject: nil];
+    [p release];
+    [pool release];
+}
+
+
+//TODO
+-(void)doNewGallery: (id)sender
+{
+    // Make sure we're not doing this for nothing
+    if ([anselController state] == TURAnselStateConnected &&
+        [[newGalleryName stringValue] length] > 0) {
+        [NSApplication detachDrawingThread:@selector(newGallery:)
+                                  toTarget:self 
+                                withObject:[newGalleryName stringValue]];
+    }
+}
+
+#pragma mark ExportPluginProtocol
+
+// Initialize
+- (id)initWithExportImageObj:(id <ExportImageProtocol>)obj
+{
+    if(self = [super init])
+    {
+        mExportMgr = obj;
+    }
+    
+    [mExportMgr disableControls];
+    return self;
+}
+
+- (NSView <ExportPluginBoxProtocol> *)settingsView
+{
+    return mSettingsBox;
+}
+- (NSView *)firstView
+{
+    return firstView;
+}
+
+// These seem to be called when the plugin panel is actived/deactivated while
+// export screen is open, not when the plugin is finished.
+- (void)viewWillBeActivated
+{
+    [self canExport];
+}
+- (void)viewWillBeDeactivated
+{
+}
+
+// These are all pretty much moot for saving across the network, but are part
+// of the protocol, so we must implement them.
+- (NSString *)requiredFileType
+{
+    return @"";
+}
+- (BOOL)wantsDestinationPrompt
+{
+    return NO;
+}
+- (NSString*)getDestinationPath
+{
+    return @"";
+}
+- (NSString *)defaultFileName
+{
+    return @"";
+}
+- (NSString *)defaultDirectory
+{
+    return @"";
+}
+- (BOOL)treatSingleSelectionDifferently
+{
+    return NO;
+}
+- (BOOL)validateUserCreatedPath:(NSString*)path
+{
+    return NO;
+}
+
+// No movies allowed, at least for now ;)
+- (BOOL)handlesMovieFiles
+{
+    return NO;
+}
+
+// Export was clicked in the UI
+- (void)clickExport
+{
+}
+
+
+// Do any preperations/validations and call our own privatePerformExport
+// (We don't want the iPhoto progress controller).
+- (void)startExport:(NSString *)path
+{
+    [self privatePerformExport];
+}
+
+// We use our own class for this so we don't use iPhoto's progress controller.
+- (void)performExport: (NSString *)path
+{
+}
+
+#pragma mark Progress (We don't use these)
+- (ExportPluginProgress *)progress
+{
+    return &progress;
+}
+- (void)lockProgress
+{
+    [progressLock lock];
+}
+- (void)unlockProgress
+{
+    [progressLock unlock];
+}
+- (void)cancelExport
+{
+    cancelExport = YES;
+}
+
+// Return the name of our plugin.
+- (NSString *)name
+{
+    return @"iPhoto2Ansel Export Plugin v1.0";
+}
+
+#pragma mark PrivateAPI
+
+// See if we have everything we need to export...
+- (void)canExport
+{
+    if ([anselController state] == TURAnselStateConnected &&
+        currentGallery != nil) {
+        [mExportMgr enableControls];
+    } else {
+        [mExportMgr disableControls];        
+    }
+}
+// Runs in a new thread.
+- (void)connect
+{
+    [anselController connect];
+}
+
+// Update our progress controller. Always update on the main thread.
+- (void)postProgressStatus:(NSString *)status {
+    [progressController performSelectorOnMainThread: @selector(setStatus:) withObject: status waitUntilDone: NO];
+}
+
+// This gets called when the ExportManager is sent the startExport message
+- (void)privatePerformExport
+{
+    cancelExport = NO;
+    
+    // Init our own progress controller.
+    if (progressController == nil) {
+        progressController = [[FBProgressController alloc] initWithFBExport: self];
+    }
+    [progressController startProgress];
+    [progressController setStatus: @"Starting export"];    
+    
+    // Detach to a new thread for the export.
+    [NSApplication detachDrawingThread: @selector(runExport) toTarget: self withObject: nil];
+}
+
+// Create a new gallery on the Horde server
+// TODO
+- (void)newGallery: (NSString *)galleryName
+{    
+    NSDictionary *results = [[anselController createNewGallery: [NSDictionary dictionaryWithObjectsAndKeys: galleryName, @"name", nil]] retain];
+    
+    if ([anselController state] != TURAnselStateError) {
+        NSLog(@"Added %@", results);
+        [galleryCombo reloadData];
+    }
+    [results release];
+}
+        
+// Runs the actual export (This is run in it's own thread)
+- (void) runExport
+{   
+    // Init the progress bar and image counts.
+    int count = [mExportMgr imageCount];
+    currentImageCount = 0;   
+    int i = 0;
+    while (i < count) {
+        // Don't hog memory...
+        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+        
+        // Check for cancel?
+        
+        // use 99% max so the last photo upload doesn't make the progress bar look finished
+        // (Thanks to Facebook exporter for this tip and code)
+        double progressPercent = (double) 99. * (i+1) / count;
+        [self postProgressStatus: [NSString stringWithFormat: @"Uploading photo %d out of %d", (i+1), count]];
+        [progressController performSelectorOnMainThread: @selector(setPercent:) withObject: [NSNumber numberWithDouble: progressPercent] waitUntilDone: NO];
+        
+        // Prepare the image data
+        NSData *theImage = [[NSData alloc] initWithContentsOfFile: [mExportMgr imagePathAtIndex:i]];
+        NSString *base64ImageData = [NSString base64StringFromData:theImage 
+                                                            length:[theImage length]];
+        
+        // Get the filename/path for this image. This returns either the most
+        // recent version of the image, the original, or (if RAW) the jpeg 
+        // version of the original. Still need to figure out how to modify
+        // the image size/quality etc... when not doing a file export.
+        NSString *filename = [mExportMgr imageFileNameAtIndex:i];
+        NSString *imageDescription = [mExportMgr imageTitleAtIndex:i];
+        
+        NSArray *keys = [[NSArray alloc] initWithObjects:
+                         @"filename", @"description", @"data", @"type", nil];
+        
+        NSString *fileType = NSFileTypeForHFSTypeCode([mExportMgr imageFormatAtIndex:i]);
+        NSArray *values = [[NSArray alloc] initWithObjects:
+                           filename,
+                           imageDescription,
+                           base64ImageData,
+                           fileType,
+                           nil];
+        
+        NSDictionary *imageData = [[NSDictionary alloc] initWithObjects:values
+                                                                forKeys:keys];
+        NSDictionary *params = [[NSDictionary alloc] initWithObjectsAndKeys:
+                                imageData, @"data", 
+                                [NSNumber numberWithBool:NO], @"default",
+                                nil];
+        
+        //Start upload with current gallery.
+        [currentGallery uploadImageObject: params];
+        [keys release];
+        [values release];
+        [imageData release];
+        [params release];
+        [pool release];
+        i++;
+    }
+    
+    // We are done - kill the progress controller and close the export window.
+    // TODO: Put up some kind of alert, maybe add growl support, offer to open
+    // the browser window??
+    [progressController performSelectorOnMainThread: @selector(setPercent:)
+                                         withObject: nil 
+                                      waitUntilDone: NO];
+    
+    [progressController performSelectorOnMainThread: @selector(stopProgress) 
+                                         withObject: nil 
+                                      waitUntilDone: YES];
+    
+    // Need to do this ourselves since we aren't using iPhoto's progress bar.
+    // Not really cancelling the export, but all this method does is close
+    // the export interface and notify iPhoto that we are done.
+    [mExportMgr cancelExportBeforeBeginning];
+}
+
+#pragma mark TURAnselDelegate
+
+// The ansel controller is initialized, populate the gallery data
+// and update the UI.
+- (void)TURAnselDidInitialize
+{   
+    [galleryCombo reloadData];
+    [connectedLabel setStringValue:@"Connected"];
+    [connectedLabel setTextColor:[NSColor greenColor]];
+    [self canExport];
+    [spinner stopAnimation: self];
+}
+
+- (void)TURAnselHadError: (NSError *)error
+{
+    NSAlert *alert;
+    
+    // For some reason, this method doesn't pick up our userInfo dictionary...
+    if ([[error userInfo] valueForKey:@"NSLocalizedDescriptionKey"] == nil) {
+        alert = [[NSAlert alertWithError: error] retain];
+        [mExportMgr disableControls];
+    } else {
+        alert = [[NSAlert alloc] init];
+        [alert setAlertStyle:NSWarningAlertStyle];
+        [alert setMessageText:[[error userInfo] valueForKey:@"NSLocalizedDescriptionKey"]];
+        if ([[error userInfo] valueForKey: @"NSLocalizedRecoverySuggestionErrorKey"] != nil) {
+            [alert setInformativeText: [[error userInfo] valueForKey: @"NSLocalizedRecoverySuggestionErrorKey"]];
+        }
+    }
+    
+    [alert beginSheetModalForWindow:[self window]
+                      modalDelegate:nil
+                     didEndSelector:nil
+                        contextInfo:nil];
+    [mExportMgr disableControls];
+    [alert release];
+}
+
+#pragma mark TURAnselGalleryDelegate
+- (void)TURAnselGalleryDidUploadImage: (TURAnselGallery *)gallery {
+    NSLog(@"TURAnselGalleryDidUploadImage in thread: %@", [NSThread currentThread]);
+    if (++currentImageCount < [mExportMgr imageCount] && cancelExport == NO) {
+
+    } else {
+        [currentGallery setDelegate:nil];
+        [currentGallery release];
+        [anselController setDelegate:nil];
+        [anselController release];
+        [galleryCombo setDelegate:nil];
+    }
+}
+
+#pragma mark comboBoxDelegate
+- (void)comboBoxSelectionDidChange:(NSNotification *)notification
+{
+    int row = [galleryCombo indexOfSelectedItem];
+    [currentGallery setDelegate:nil];
+    [currentGallery autorelease];
+    currentGallery = [[anselController getGalleryByIndex:row] retain];
+    NSLog(@"THe selected gallery: %@", currentGallery);
+    [currentGallery setDelegate: self];
+    [self canExport];
+}
+@end
\ No newline at end of file
diff --git a/iPhoto2Ansel/AnselExportPluginBox.h b/iPhoto2Ansel/AnselExportPluginBox.h
new file mode 100644 (file)
index 0000000..9bf027a
--- /dev/null
@@ -0,0 +1,19 @@
+//
+//  AnselExportPluginBox.h
+//  iPhoto2Ansel
+//
+//  Created by Michael Rubinsky on 10/23/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "ExportPluginProtocol.h"
+#import "ExportPluginBoxProtocol.h"
+
+@interface AnselExportPluginBox : NSBox <ExportPluginBoxProtocol> {
+    IBOutlet id <ExportPluginProtocol> mPlugin;
+}
+
+- (BOOL)performKeyEquivalent: (NSEvent *)anEvent;
+
+@end
diff --git a/iPhoto2Ansel/AnselExportPluginBox.m b/iPhoto2Ansel/AnselExportPluginBox.m
new file mode 100644 (file)
index 0000000..ef325f8
--- /dev/null
@@ -0,0 +1,38 @@
+//
+//  AnselExportPluginBox.m
+//  iPhoto2Ansel
+//
+//  Generic PluginBox handles Enter key presses to initiate the
+//  export.
+//
+//  Created by Michael Rubinsky on 10/23/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+
+#import "AnselExportPluginBox.h"
+
+@implementation AnselExportPluginBox
+
+
+-(BOOL)performKeyEquivalent:(NSEvent *)anEvent
+{
+    NSString *keyString = [anEvent charactersIgnoringModifiers];
+    unichar keyChar = [keyString characterAtIndex:0];
+    
+    switch (keyChar)
+    {
+        case NSFormFeedCharacter:
+        case NSNewlineCharacter:
+        case NSCarriageReturnCharacter:
+        case NSEnterCharacter:
+        {
+            [mPlugin clickExport];
+            return(YES);
+        }
+        default:
+            break;
+    }
+    
+    return([super performKeyEquivalent:anEvent]);
+}
+@end
diff --git a/iPhoto2Ansel/English.lproj/InfoPlist.strings b/iPhoto2Ansel/English.lproj/InfoPlist.strings
new file mode 100755 (executable)
index 0000000..26bf880
Binary files /dev/null and b/iPhoto2Ansel/English.lproj/InfoPlist.strings differ
diff --git a/iPhoto2Ansel/English.lproj/Panel.nib/classes.nib b/iPhoto2Ansel/English.lproj/Panel.nib/classes.nib
new file mode 100644 (file)
index 0000000..624a92e
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IBClasses</key>
+       <array>
+               <dict>
+                       <key>CLASS</key>
+                       <string>AnselExportPluginBox</string>
+                       <key>LANGUAGE</key>
+                       <string>ObjC</string>
+                       <key>OUTLETS</key>
+                       <dict>
+                               <key>mPlugin</key>
+                               <string>id</string>
+                       </dict>
+                       <key>SUPERCLASS</key>
+                       <string>NSBox</string>
+               </dict>
+               <dict>
+                       <key>ACTIONS</key>
+                       <dict>
+                               <key>doConnect</key>
+                               <string>id</string>
+                               <key>doNewGallery</key>
+                               <string>id</string>
+                       </dict>
+                       <key>CLASS</key>
+                       <string>AnselExportController</string>
+                       <key>LANGUAGE</key>
+                       <string>ObjC</string>
+                       <key>OUTLETS</key>
+                       <dict>
+                               <key>anselHostURL</key>
+                               <string>NSTextField</string>
+                               <key>beginButton</key>
+                               <string>NSButton</string>
+                               <key>connectedLabel</key>
+                               <string>NSTextField</string>
+                               <key>firstView</key>
+                               <string>NSControl</string>
+                               <key>galleryCombo</key>
+                               <string>NSComboBox</string>
+                               <key>galleryTableView</key>
+                               <string>NSTableView</string>
+                               <key>mExportMgr</key>
+                               <string>id</string>
+                               <key>mQualityPopUp</key>
+                               <string>NSPopUpButton</string>
+                               <key>mSettingsBox</key>
+                               <string>NSBox</string>
+                               <key>mSizePopUp</key>
+                               <string>NSPopUpButton</string>
+                               <key>newGalleryButton</key>
+                               <string>NSButton</string>
+                               <key>newGalleryName</key>
+                               <string>NSTextField</string>
+                               <key>password</key>
+                               <string>NSSecureTextField</string>
+                               <key>spinner</key>
+                               <string>NSProgressIndicator</string>
+                               <key>username</key>
+                               <string>NSTextField</string>
+                       </dict>
+                       <key>SUPERCLASS</key>
+                       <string>NSObject</string>
+               </dict>
+               <dict>
+                       <key>CLASS</key>
+                       <string>FirstResponder</string>
+                       <key>LANGUAGE</key>
+                       <string>ObjC</string>
+                       <key>SUPERCLASS</key>
+                       <string>NSObject</string>
+               </dict>
+               <dict>
+                       <key>CLASS</key>
+                       <string>NSObject</string>
+                       <key>LANGUAGE</key>
+                       <string>ObjC</string>
+               </dict>
+       </array>
+       <key>IBVersion</key>
+       <string>1</string>
+</dict>
+</plist>
diff --git a/iPhoto2Ansel/English.lproj/Panel.nib/info.nib b/iPhoto2Ansel/English.lproj/Panel.nib/info.nib
new file mode 100644 (file)
index 0000000..d55a332
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IBFramework Version</key>
+       <string>672</string>
+       <key>IBLastKnownRelativeProjectPath</key>
+       <string>../iPhoto2Ansel.xcodeproj</string>
+       <key>IBOldestOS</key>
+       <integer>5</integer>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>6</integer>
+       </array>
+       <key>IBSystem Version</key>
+       <string>9F33</string>
+       <key>targetFramework</key>
+       <string>IBCocoaFramework</string>
+</dict>
+</plist>
diff --git a/iPhoto2Ansel/English.lproj/Panel.nib/keyedobjects.nib b/iPhoto2Ansel/English.lproj/Panel.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..85eed58
Binary files /dev/null and b/iPhoto2Ansel/English.lproj/Panel.nib/keyedobjects.nib differ
diff --git a/iPhoto2Ansel/ExportImageProtocol.h b/iPhoto2Ansel/ExportImageProtocol.h
new file mode 100755 (executable)
index 0000000..d9334f6
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+     File:       ExportImageProtocol.h
+     Contains:   iPhoto Plug-ins interfaces: Protocol for image exporting
+     Version:    Technology: iPhoto
+                 Release:    1.0
+     Copyright:  © 2002-2007 by Apple Inc. All rights reserved.
+     Bugs?:      For bug reports, consult the following page on
+                 the World Wide Web:
+                     http://developer.apple.com/bugreporter/
+*/
+
+typedef enum
+{
+       EQualityLow,
+       EQualityMed,
+       EQualityHigh,
+       EQualityMax
+} ExportQuality;
+
+typedef enum
+{
+       EMNone, // 0000
+       EMEXIF, // 0001
+       EMIPTC, // 0010
+       EMBoth  // 0011
+} ExportMetadata;
+
+typedef struct
+{
+       OSType                  format;
+       ExportQuality   quality;
+       float                   rotation;
+       unsigned                width;
+       unsigned                height;
+       ExportMetadata  metadata;
+} ImageExportOptions;
+
+//exif metadata access keys
+#define kIPExifDateDigitized @"DateDigitized"
+#define kIPExifCameraModel @"CameraModel"
+#define kIPExifShutter @"Shutter"
+#define kIPExifAperture @"Aperture"
+#define kIPExifMaxAperture @"MaxAperture"
+#define kIPExifExposureBias @"ExposureBias"
+#define kIPExifExposure @"Exposure"
+#define kIPExifExposureIndex @"ExposureIndex"
+#define kIPExifFocalLength @"FocalLength"
+#define kIPExifDistance @"Distance"
+#define kIPExifSensing @"Sensing"
+#define kIPExifLightSource @"LightSource"
+#define kIPExifFlash @"Flash"
+#define kIPExifMetering @"Metering"
+#define kIPExifBrightness @"Brightness"
+#define kIPExifISOSpeed @"ISOSpeed"
+
+//tiff metadata access keys
+#define kIPTiffImageWidth @"ImageWidth"
+#define kIPTiffImageHeight @"ImageHeight"
+#define kIPTiffOriginalDate @"OriginalDate"
+#define kIPTiffDigitizedDate @"DigitizedDate"
+#define kIPTiffFileName @"FileName"
+#define kIPTiffFileSize @"FileSize"
+#define kIPTiffModifiedDate @"ModifiedDate"
+#define kIPTiffImportedDate @"ImportedDate"
+#define kIPTiffCameraMaker @"CameraMaker"
+#define kIPTiffCameraModel @"CameraModel"
+#define kIPTiffSoftware @"Software"
+
+@protocol ExportImageProtocol
+
+//------------------------------------------------------------------------------
+// Access to images
+//------------------------------------------------------------------------------
+- (unsigned)imageCount;
+- (NSSize)imageSizeAtIndex:(unsigned)index;
+- (OSType)imageFormatAtIndex:(unsigned)index;
+- (OSType)originalImageFormatAtIndex:(unsigned)index;
+- (BOOL)originalIsRawAtIndex:(unsigned)index;
+- (BOOL)originalIsMovieAtIndex:(unsigned)index;
+- (NSString *)imageTitleAtIndex:(unsigned)index;
+- (NSString *)imageCommentsAtIndex:(unsigned)index;
+- (float)imageRotationAtIndex:(unsigned)index;
+- (NSString *)imagePathAtIndex:(unsigned)index;
+- (NSString *)sourcePathAtIndex:(unsigned)index;
+- (NSString *)thumbnailPathAtIndex:(unsigned)index;
+- (NSString *)imageFileNameAtIndex:(unsigned)index;
+- (BOOL)imageIsEditedAtIndex:(unsigned)index;
+- (BOOL)imageIsPortraitAtIndex:(unsigned)index;
+- (float)imageAspectRatioAtIndex:(unsigned)index;
+- (unsigned long long)imageFileSizeAtIndex:(unsigned)index;
+- (NSDate *)imageDateAtIndex:(unsigned)index;
+- (int)imageRatingAtIndex:(unsigned)index;
+- (NSDictionary *)imageTiffPropertiesAtIndex:(unsigned)index;
+- (NSDictionary *)imageExifPropertiesAtIndex:(unsigned)index;
+- (NSArray *)imageKeywordsAtIndex:(unsigned)index;
+- (NSArray *)albumsOfImageAtIndex:(unsigned)index;
+
+- (NSString *)getExtensionForImageFormat:(OSType)format;
+- (OSType)getImageFormatForExtension:(NSString *)extension;
+
+       //------------------------------------------------------------------------------
+       // Access to albums
+       //------------------------------------------------------------------------------
+- (unsigned)albumCount; //total number of albums
+- (NSString *)albumNameAtIndex:(unsigned)index; //name of album at index
+- (NSString *)albumMusicPathAtIndex:(unsigned)index;
+- (NSString *)albumCommentsAtIndex:(unsigned)index;
+- (unsigned)positionOfImageAtIndex:(unsigned)index inAlbum:(unsigned)album;
+
+       //------------------------------------------------------------------------------
+       // Access to export controller's GUI
+       //------------------------------------------------------------------------------
+- (id)window;
+- (void)enableControls;
+- (void)disableControls;
+
+- (void)clickExport;
+- (void)startExport;
+- (void)cancelExportBeforeBeginning;
+
+- (NSString *)directoryPath;
+- (unsigned)sessionID;
+
+- (BOOL)exportImageAtIndex:(unsigned)index dest:(NSString *)dest options:(ImageExportOptions *)options;
+- (NSSize)lastExportedImageSize;
+
+       //------------------------------------------------------------------------------
+@end
diff --git a/iPhoto2Ansel/ExportPluginBoxProtocol.h b/iPhoto2Ansel/ExportPluginBoxProtocol.h
new file mode 100755 (executable)
index 0000000..cf9f9ac
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+     File:       ExportPluginBoxProtocol.h
+     Contains:   iPhoto Plug-ins interfaces: Export plugin box expected format and methods
+     Version:    Technology: iPhoto
+                 Release:    1.0
+     Copyright:  © 2002-2007 by Apple Inc. All rights reserved.
+     Bugs?:      For bug reports, consult the following page on
+                 the World Wide Web:
+                     http://developer.apple.com/bugreporter/
+*/
+
+#import <Cocoa/Cocoa.h>
+
+//------------------------------------------------------------------------------
+@protocol ExportPluginBoxProtocol
+
+//------------------------------------------------------------------------------
+// Public methods
+//------------------------------------------------------------------------------
+
+// Used to respond to the enter key
+- (BOOL)performKeyEquivalent:(NSEvent *)anEvent;
+
+//------------------------------------------------------------------------------
+@end
diff --git a/iPhoto2Ansel/ExportPluginProtocol.h b/iPhoto2Ansel/ExportPluginProtocol.h
new file mode 100755 (executable)
index 0000000..96bdbff
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+     File:       ExportPluginProtocol.h
+     Contains:   iPhoto Plug-ins interfaces: Export plugin expected format and methods
+     Version:    Technology: iPhoto
+                 Release:    1.0
+     Copyright:  © 2002-2007 by Apple Inc. All rights reserved.
+     Bugs?:      For bug reports, consult the following page on
+                 the World Wide Web:
+                     http://developer.apple.com/bugreporter/
+*/
+
+#import <Cocoa/Cocoa.h>
+
+#import "ExportImageProtocol.h"
+#import "ExportPluginBoxProtocol.h"
+
+@class NSView;
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+typedef struct
+{
+       unsigned long   currentItem;
+       unsigned long   totalItems;
+       NSString                *message;
+       BOOL                    indeterminateProgress;  // YES, if use indeterminate progress bar
+       BOOL                    shouldCancel;                   // Can be set by the progressSelector
+       BOOL                    shouldStop;
+} ExportPluginProgress;
+
+//------------------------------------------------------------------------------
+@protocol ExportPluginProtocol
+
+//------------------------------------------------------------------------------
+// Public methods
+//------------------------------------------------------------------------------
+// Initialize with an image exporter
+- (id)initWithExportImageObj:(id <ExportImageProtocol>)obj;
+
+       // Return the view that you want displayed
+- (NSView<ExportPluginBoxProtocol> *)settingsView;
+- (NSView *)firstView; // First focus item
+//- (NSControl *)lastView;     // Last focus item
+
+       // Gain/Lose focus
+- (void)viewWillBeActivated;
+- (void)viewWillBeDeactivated;
+
+       // Required file type for saving
+- (NSString *)requiredFileType;
+
+       // If the plugin wants to handle prompting for a desitnation,
+       // return NO to wantsDestinationPrompt and provide a path
+       // in getDestinationPath. If getDestinationPath returns nil,
+       // then the export should be canceled.
+- (BOOL)wantsDestinationPrompt;
+- (NSString*)getDestinationPath;
+
+       // Defaults for save prompt
+- (NSString *)defaultFileName;
+- (NSString *)defaultDirectory;
+
+       // Some plugins (currently just the File Exporter) need to be able
+       // to tell the controller to work a little differently if the
+       // user is exporting just one image.
+- (BOOL)treatSingleSelectionDifferently;
+
+       // ask if the plugin can handle movies
+- (BOOL)handlesMovieFiles;
+
+       // let each plugin decide what to do if the user types a path into the export dialog
+- (BOOL)validateUserCreatedPath:(NSString*)path;
+
+       // If the user hits Enter/Return, pass this action back to the
+       // controller as a click on the Export button.
+- (void)clickExport;
+
+       // This selector may be called from within a separate NSThread.
+       // Prepare to export with the current settings to <path>.
+       // Must call ExportController's startExport to begin
+- (void)startExport:(NSString *)path;
+
+       // This selector may be called from within a separate NSThread.
+       // Perform the export with the current settings to <path>.
+       // It will periodically send the <callback> selector a 
+       // progress message in the form of a pointer to a ExportPluginProgress structure.
+- (void)performExport:(NSString *)path;
+
+// Updating progress information: lockProgress before changing values in ExportPluginProgress
+- (ExportPluginProgress *)progress;
+- (void)lockProgress;
+- (void)unlockProgress;
+
+       // Called when the user cancels
+- (void)cancelExport;
+
+- (NSString *)name;
+
+       //------------------------------------------------------------------------------
+@end
diff --git a/iPhoto2Ansel/FBProgressController.h b/iPhoto2Ansel/FBProgressController.h
new file mode 100644 (file)
index 0000000..e348771
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Facebook Exporter for iPhoto Software License
+ * Copyright (c) 2007, Facebook, Inc.
+ * All rights reserved.
+ * Permission is hereby granted, free of charge, to any person or organization 
+ * obtaining a copy of the software and accompanying documentation covered by 
+ * this license (which, together with any graphical images included with such 
+ * software, are collectively referred to below as the “Software”) to (a) use, 
+ * reproduce, display, distribute, execute, and transmit the Software, (b) 
+ * prepare derivative works of the Software (excluding any graphical images 
+ * included with the Software, which may not be modified or altered), and (c) 
+ * permit third-parties to whom the Software is furnished to do so, all 
+ * subject to the following:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice, 
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Facebook, Inc. nor the names of its contributors may 
+ *   be used to endorse or promote products derived from this software without 
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+//
+//  FBProgressController.h
+//  FacebookExport
+//
+//  Created by Josh Wiseman on 1/28/07.
+//
+
+#import <Cocoa/Cocoa.h>
+
+//@class FBExport;
+@class AnselExportController;
+
+extern NSString* const CompleteStatus;
+
+@interface FBProgressController : NSObject {
+    //FBExport *fbExport;
+    AnselExportController *fbExport;
+    IBOutlet NSPanel *progressPanel;
+    IBOutlet NSProgressIndicator *progressIndicator;
+    IBOutlet NSTextField *statusField;
+}
+
+- (id)initWithFBExport:(AnselExportController *)fbe;
+- (void)startProgress;
+- (void)stopProgress;
+- (void)setStatus:(NSString *)status;
+- (void)setPercent:(NSNumber *)percent;
+
+- (IBAction)cancel:(id)sender;
+
+@end
diff --git a/iPhoto2Ansel/FBProgressController.m b/iPhoto2Ansel/FBProgressController.m
new file mode 100644 (file)
index 0000000..d52f6ff
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Facebook Exporter for iPhoto Software License
+ * Copyright (c) 2007, Facebook, Inc.
+ * All rights reserved.
+ * Permission is hereby granted, free of charge, to any person or organization 
+ * obtaining a copy of the software and accompanying documentation covered by 
+ * this license (which, together with any graphical images included with such 
+ * software, are collectively referred to below as the “Software”) to (a) use, 
+ * reproduce, display, distribute, execute, and transmit the Software, (b) 
+ * prepare derivative works of the Software (excluding any graphical images 
+ * included with the Software, which may not be modified or altered), and (c) 
+ * permit third-parties to whom the Software is furnished to do so, all 
+ * subject to the following:
+ *
+ * - Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice, 
+ *   this list of conditions and the following disclaimer in the documentation 
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of Facebook, Inc. nor the names of its contributors may 
+ *   be used to endorse or promote products derived from this software without 
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+//
+//  FBProgressController.m
+//  FacebookExport
+//
+//  Created by Josh Wiseman on 1/28/07.
+//
+
+#import "FBProgressController.h"
+
+#import "AnselExportController.h"
+
+NSString* const CompleteStatus = @"Export completed!";
+
+@implementation FBProgressController
+
+- (id)initWithFBExport:(AnselExportController *)fbe {
+    if ((self = [super init])) {
+        fbExport = fbe;
+        [NSBundle loadNibNamed: @"ProgressSheet" owner: self];
+    }
+    return self;
+}
+
+- (void)dealloc {
+    [super dealloc];
+}
+
+- (void)awakeFromNib {
+    [progressIndicator setUsesThreadedAnimation: YES];
+}
+
+- (IBAction)cancel:(id)sender {
+    [self setStatus: @"Cancelling"];
+    [progressIndicator setIndeterminate: YES];
+    [progressIndicator startAnimation: nil];
+    [fbExport cancelExport];
+}
+
+- (void)startProgress {
+    [progressIndicator setDoubleValue: 0.0];
+    [progressIndicator setIndeterminate: YES];
+    [progressIndicator startAnimation: nil];
+    [self setStatus: @"Started export"];
+    
+    [NSApp beginSheet: progressPanel modalForWindow: [fbExport window] modalDelegate: nil didEndSelector: nil contextInfo: nil];
+}
+
+- (void)stopProgress {
+    [progressIndicator stopAnimation: nil];
+    [NSApp endSheet: progressPanel];
+    [progressPanel orderOut: nil];
+}
+
+- (void)setStatus:(NSString *)status {
+    [statusField setStringValue: status];
+    [statusField display];
+}
+
+- (void)setPercent:(NSNumber *)percent {
+    if (percent == nil)
+        [progressIndicator setIndeterminate: YES];
+    else {
+        if ([progressIndicator isIndeterminate])
+            [progressIndicator setIndeterminate: NO];
+        [progressIndicator setDoubleValue: [percent doubleValue]];
+    }
+    [progressIndicator display];
+}
+
+@end
diff --git a/iPhoto2Ansel/Info.plist b/iPhoto2Ansel/Info.plist
new file mode 100644 (file)
index 0000000..cc62ba9
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.theupstairsroom.iphoto2ansel</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+       <key>NSMainNibFile</key>
+       <string>Panel</string>
+       <key>NSPrincipalClass</key>
+       <string>AnselExportController</string>
+</dict>
+</plist>
diff --git a/iPhoto2Ansel/InterThreadMessaging.h b/iPhoto2Ansel/InterThreadMessaging.h
new file mode 100644 (file)
index 0000000..76a50bd
--- /dev/null
@@ -0,0 +1,147 @@
+/*-*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4  -*-*/
+/*
+ * InterThreadMessaging -- InterThreadMessaging.h
+ * Created by toby on Tue Jun 19 2001.
+ *
+ * A low-cost-but-not-quite-as-general alternative to D.O.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+
+@interface NSThread (InterThreadMessaging)
+
+/* The inter-thread messaging category methods use NSPorts to deliver messages
+   between threads.  In order to receive an inter-thread message, the receiver
+   must both (1) be running a run loop; and (2) be monitoring this port in its
+   run loop.  You must call this method from the context of the thread you wish
+   to prepare for inter-thread messages (which is why these are class methods).
+
+   Before a thread can receive any inter-thread messages, it must invoke one
+   of the following methods to prepare the thread and its run loop to receive
+   these messages.  In order to process a message from another thread, the
+   receiving thread must, of course, be running its run loop. */
+
++ (void) prepareForInterThreadMessages; // in NSDefaultRunLoopMode
+
+@end
+
+
+
+/* Invoke in the specified thread a method on an object.  The target
+   thread must have been readied for inter-thread messages by invoking
+   +prepareForInterThreadMessages.  It must be running its run loop in
+   order to receive the messages.
+
+   In some situations, a sender may be able to blast messages to an object
+   faster than they can be processed in the target thread.  To prevent things
+   from spiraling out of control, the underlying NSPorts implement a throtling
+   mechanism in the form of a fixed queue size.  When this queue is filled, all
+   further messages are rejected until until a message has been pulled off the
+   queue.  The sender may specify a limit date; if the queue is full, the
+   sender will block until this limit date expires or until space is made in
+   the queue.  An NSPortTimeoutException exception is thrown if the limit date
+   expires (or if no limit date is specified) before the message can be
+   delivered.
+
+   There is one very important point to watch out for: to prevent heinously
+   difficult to debug memory smashers, the receing object and all of its
+   arguments are retained in the context of the sending thread.  When the
+   message has been delivered in the target thread, these objects are auto-
+   released IN THE CONTEXT OF THE TARGET THREAD.  Thus, it is possible for
+   the objects to be deallocated in a thread different from the one they were
+   allocated in.  (In general, you don't need to worry about simple/immutable
+   objects, such as NSString, NSData, etc.) */
+
+@interface NSObject (InterThreadMessaging)
+
+- (void) performSelector:(SEL)selector
+         inThread:(NSThread *)thread;  // before date [NSDate distantFuture]
+
+- (void) performSelector:(SEL)selector
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate;
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object
+         inThread:(NSThread *)thread;  // before date [NSDate distantFuture]
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate;
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object1
+         withObject:(id)object2
+         inThread:(NSThread *)thread;  // before date [NSDate distantFuture]
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object1
+         withObject:(id)object2
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate;
+
+@end
+
+
+
+
+/* Post a notification in the specified thread.  The target thread must
+   have been readied for inter-thread messages by sending itself the
+   +prepareForInterThreadMessages.  It must be running its run loop in
+   order to receive the messages.
+
+   In some situations, a sender may be able to blast messages to an object
+   faster than they can be processed in the target thread.  To prevent things
+   from spiraling out of control, the underlying NSPorts implement a throtling
+   mechanism in the form of a fixed queue size.  When this queue is filled, all
+   further messages are rejected until until a message has been pulled off the
+   queue.  The sender may specify a limit date; if the queue is full, the
+   sender will block until this limit date expires or until space is made in
+   the queue.  An NSPortTimeoutException exception is thrown if the limit date
+   expires (or if no limit date is specified) before the message can be
+   delivered.
+
+   There is one very important point to watch out for: to prevent heinously
+   difficult to debug memory smashers, the notification object (and
+   consequently the userInfo dictionary) are retained in the context of
+   the sending thread.  When the message has been delivered in the target
+   thread, the notification object is auto-released IN THE CONTEXT OF THE
+   TARGET THREAD.  Thus, it is possible for objects to be deallocated in a
+   thread different from the one they were allocated in.  (In general, you
+   don't need to worry about simple/immutable objects, such as NSString,
+   NSData, etc.) */
+
+@interface NSNotificationCenter (InterThreadMessaging)
+
+- (void) postNotification:(NSNotification *)notification
+         inThread:(NSThread *)thread;  // before date [NSDate distantFuture]
+
+- (void) postNotification:(NSNotification *)notification
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate;
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         inThread:(NSThread *)thread;  // before date [NSDate distantFuture]
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate;
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         userInfo:(NSDictionary *)userInfo
+         inThread:(NSThread *)thread;  // before date [NSDate distantFuture]
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         userInfo:(NSDictionary *)userInfo
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate;
+
+@end
+
diff --git a/iPhoto2Ansel/InterThreadMessaging.m b/iPhoto2Ansel/InterThreadMessaging.m
new file mode 100644 (file)
index 0000000..a17d569
--- /dev/null
@@ -0,0 +1,445 @@
+/*-*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4  -*-*/
+/*
+ * InterThreadMessaging -- InterThreadMessaging.m
+ * Created by toby on Tue Jun 19 2001.
+ *
+ * NOTE: this is a modified InterThreadMessaging that schedules on the run loop for the modal mode along with default
+ *
+ */
+
+#import <pthread.h>
+#import "InterThreadMessaging.h"
+
+/* There are four types of messages that can be posted between threads: a
+   notification to be posted to the default notification centre and selectors
+   to be performed with a varying number of arguments.  (I was tempted to
+   implement all three in terms of performSelector:withObject:withObject:
+   and passing in nil for the empty arguments, but then it occurred to me
+   that perhaps the receiver has overridden performSelector: and
+   performSelector:withObject:.  So I think I must disambiguate between
+   them all.) */
+
+typedef enum InterThreadMessageType InterThreadMessageType;
+enum InterThreadMessageType
+{
+    kITMPostNotification = 1,
+    kITMPerformSelector0Args,
+    kITMPerformSelector1Args,
+    kITMPerformSelector2Args
+};
+
+
+/* The message contents are carried between threads in this struct.  The
+   struct is allocated in the sending thread and freed in the receiving thread.
+   It is carried between the threads in an NSPortMessage - the NSPortMessage
+   contains a single NSData argument, which is a wrapper around the pointer to
+   this struct. */
+
+typedef struct InterThreadMessage InterThreadMessage;
+struct InterThreadMessage
+{
+    InterThreadMessageType type;
+    union {
+        NSNotification *notification;
+        struct {
+            SEL selector;
+            id receiver;
+            id arg1;
+            id arg2;
+        } sel;
+    } data;
+};
+
+
+
+/* Each thread is associated with an NSPort.  This port is used to deliver
+   messages to the target thread. */
+
+static NSMapTable *pThreadMessagePorts = NULL;
+static pthread_mutex_t pGate = { 0 };
+
+@interface InterThreadManager : NSObject
++ (void) threadDied:(NSNotification *)notification;
++ (void) handlePortMessage:(NSPortMessage *)msg;
+@end
+
+static void
+createMessagePortForThread (NSThread *thread, NSRunLoop *runLoop)
+{
+    NSPort *port;
+
+    assert(nil != thread);
+    assert(nil != runLoop);
+    assert(NULL != pThreadMessagePorts);
+
+    pthread_mutex_lock(&pGate);
+
+    port = NSMapGet(pThreadMessagePorts, thread);
+    if (nil == port) {
+        port = [[NSPort allocWithZone:NULL] init];
+        [port setDelegate:[InterThreadManager class]];
+        [port scheduleInRunLoop:runLoop forMode:NSModalPanelRunLoopMode];  // MJR: I need this for iPhotoToAnsel usage
+        [port scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
+        NSMapInsertKnownAbsent(pThreadMessagePorts, thread, port);
+
+        /* Transfer ownership of this port to the map table. */
+        [port release];
+    }
+
+    pthread_mutex_unlock(&pGate);
+}
+
+static NSPort *
+messagePortForThread (NSThread *thread)
+{
+    NSPort *port;
+
+    assert(nil != thread);
+    assert(NULL != pThreadMessagePorts);
+
+    pthread_mutex_lock(&pGate);
+    port = NSMapGet(pThreadMessagePorts, thread);
+    pthread_mutex_unlock(&pGate);
+
+    if (nil == port) {
+        [NSException raise:NSInvalidArgumentException
+                     format:@"Thread %@ is not prepared to receive "
+                            @"inter-thread messages.  You must invoke "
+                            @"+prepareForInterThreadMessages first.", thread];
+    }
+
+    return port;
+}
+
+static void
+removeMessagePortForThread (NSThread *thread, NSRunLoop *runLoop)
+{
+    NSPort *port;
+
+    assert(nil != thread);
+    assert(NULL != pThreadMessagePorts);
+
+    pthread_mutex_lock(&pGate);
+    
+    port = (NSPort *) NSMapGet(pThreadMessagePorts, thread);
+    if (nil != port) {
+        [port removeFromRunLoop:runLoop forMode:NSModalPanelRunLoopMode];    // ZWw: I added it, so I need to remove it
+        [port removeFromRunLoop:runLoop forMode:NSDefaultRunLoopMode];
+        NSMapRemove(pThreadMessagePorts, thread);
+    }
+
+    pthread_mutex_unlock(&pGate);
+}
+
+
+
+
+@implementation NSThread (InterThreadMessaging)
+
++ (void) prepareForInterThreadMessages
+{
+    /* Force the class initialization. */
+    [InterThreadManager class];
+
+    createMessagePortForThread([NSThread currentThread],
+                               [NSRunLoop currentRunLoop]);
+}
+
+@end
+
+
+
+
+@interface NSThread (SecretStuff)
+- (NSRunLoop *) runLoop;
+@end
+
+@implementation InterThreadManager
+
++ (void) initialize
+{
+    /* Create the mutex - this should be invoked by the Objective-C runtime
+       (in a thread-safe manner) before any one can use this module, so I
+       don't think I need to worry about race conditions here. */
+    if (nil == pThreadMessagePorts) {
+        pthread_mutex_init(&pGate, NULL);
+
+        pThreadMessagePorts =
+            NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks,
+                             NSObjectMapValueCallBacks, 0);
+
+        [[NSNotificationCenter defaultCenter]
+            addObserver:[self class]
+            selector:@selector(threadDied:)
+            name:NSThreadWillExitNotification
+            object:nil];
+    }
+}
+
++ (void) threadDied:(NSNotification *)notification
+{
+    NSThread *thread;
+    NSRunLoop *runLoop;
+
+    thread = [notification object];
+    runLoop = [thread runLoop];
+    if (nil != runLoop) {
+        removeMessagePortForThread(thread, [thread runLoop]);
+    }
+}
+
++ (void) handlePortMessage:(NSPortMessage *)portMessage
+{
+    InterThreadMessage *msg;
+    NSArray *components;
+    NSData *data;
+
+    components = [portMessage components];
+    assert(1 == [components count]);
+
+    data = [components objectAtIndex:0];
+    msg = *((InterThreadMessage **) [data bytes]);
+    
+    switch (msg->type)
+    {
+        case kITMPostNotification:
+            [[NSNotificationCenter defaultCenter]
+                postNotification:msg->data.notification];
+            [msg->data.notification release];
+            break;
+
+        case kITMPerformSelector0Args:
+            [msg->data.sel.receiver performSelector:msg->data.sel.selector];
+            [msg->data.sel.receiver release];
+            break;
+
+        case kITMPerformSelector1Args:
+            [msg->data.sel.receiver performSelector:msg->data.sel.selector
+                                    withObject:msg->data.sel.arg1];
+            [msg->data.sel.receiver release];
+            [msg->data.sel.arg1 release];
+            break;
+
+        case kITMPerformSelector2Args:
+            [msg->data.sel.receiver performSelector:msg->data.sel.selector
+                                    withObject:msg->data.sel.arg1
+                                    withObject:msg->data.sel.arg2];
+            [msg->data.sel.receiver release];
+            [msg->data.sel.arg1 release];
+            [msg->data.sel.arg2 release];
+            break;
+
+        default:
+            assert(0);
+    }
+
+    free(msg);
+}
+
+@end
+
+
+
+
+
+static void
+postMessage (InterThreadMessage *message, NSThread *thread, NSDate *limitDate)
+{
+    NSPortMessage *portMessage;
+    NSMutableArray *components;
+    NSPort *port;
+    NSData *data;
+    BOOL retval;
+
+    if (nil == thread) { thread = [NSThread currentThread]; }
+    port = messagePortForThread(thread);
+    assert(nil != port);
+
+    data = [[NSData alloc] initWithBytes:&message length:sizeof(void *)];
+    components = [[NSMutableArray alloc] initWithObjects:&data count:1];
+    portMessage = [[NSPortMessage alloc] initWithSendPort:port
+                                         receivePort:nil
+                                         components:components];
+
+    if (nil == limitDate) { limitDate = [NSDate distantFuture]; }
+    retval = [portMessage sendBeforeDate:limitDate];
+    [portMessage release];
+    [components release];
+    [data release];
+
+    if (!retval) {
+        [NSException raise:NSPortTimeoutException
+                     format:@"Can't send message to thread %@: timeout "
+                            @"before date %@", thread, limitDate];
+    }
+}
+
+static void
+performSelector (InterThreadMessageType type, SEL selector, id receiver,
+                 id object1, id object2, NSThread *thread, NSDate *limitDate)
+{
+    InterThreadMessage *msg;
+
+    assert(NULL != selector);
+    
+    if (nil != receiver) {
+        msg = (InterThreadMessage *) malloc(sizeof(struct InterThreadMessage));
+        bzero(msg, sizeof(struct InterThreadMessage));
+        msg->type = type;
+        msg->data.sel.selector = selector;
+        msg->data.sel.receiver = [receiver retain];
+        msg->data.sel.arg1 = [object1 retain];
+        msg->data.sel.arg2 = [object2 retain];
+
+        postMessage(msg, thread, limitDate);
+    }
+}
+
+static void
+postNotification (NSNotification *notification, NSThread *thread,
+                  NSDate *limitDate)
+{
+    InterThreadMessage *msg;
+
+    assert(nil != notification);
+    
+    msg = (InterThreadMessage *) malloc(sizeof(struct InterThreadMessage));
+    bzero(msg, sizeof(struct InterThreadMessage));
+    msg->type = kITMPostNotification;
+    msg->data.notification = [notification retain];
+
+    postMessage(msg, thread, limitDate);
+}
+
+
+
+
+
+
+@implementation NSObject (InterThreadMessaging)
+
+- (void) performSelector:(SEL)selector
+         inThread:(NSThread *)thread
+{
+    performSelector(kITMPerformSelector0Args, selector, self, nil, nil,
+                    thread, nil);
+}
+
+- (void) performSelector:(SEL)selector
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate
+{
+    performSelector(kITMPerformSelector0Args, selector, self, nil, nil,
+                    thread, limitDate);
+}
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object
+         inThread:(NSThread *)thread
+{
+    performSelector(kITMPerformSelector1Args, selector, self, object, nil,
+                    thread, nil);
+}
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate
+{
+    performSelector(kITMPerformSelector1Args, selector, self, object, nil,
+                    thread, limitDate);
+}
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object1
+         withObject:(id)object2
+         inThread:(NSThread *)thread
+{
+    performSelector(kITMPerformSelector2Args, selector, self, object1, object2,
+                    thread, nil);
+}
+
+- (void) performSelector:(SEL)selector
+         withObject:(id)object1
+         withObject:(id)object2
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate
+{
+    performSelector(kITMPerformSelector2Args, selector, self, object1, object2,
+                    thread, limitDate);
+}
+
+@end
+
+
+
+@implementation NSNotificationCenter (InterThreadMessaging)
+
+- (void) postNotification:(NSNotification *)notification
+         inThread:(NSThread *)thread
+{
+    postNotification(notification, thread, nil);
+}
+
+- (void) postNotification:(NSNotification *)notification
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate
+{
+    postNotification(notification, thread, limitDate);
+}
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         inThread:(NSThread *)thread
+{
+    NSNotification *notification;
+    
+    notification = [NSNotification notificationWithName:name
+                                   object:object
+                                   userInfo:nil];
+    postNotification(notification, thread, nil);
+}
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate
+{
+    NSNotification *notification;
+    
+    notification = [NSNotification notificationWithName:name
+                                   object:object
+                                   userInfo:nil];
+    postNotification(notification, thread, limitDate);
+}
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         userInfo:(NSDictionary *)userInfo
+         inThread:(NSThread *)thread
+{
+    NSNotification *notification;
+    
+    notification = [NSNotification notificationWithName:name
+                                   object:object
+                                   userInfo:userInfo];
+    postNotification(notification, thread, nil);
+}
+
+- (void) postNotificationName:(NSString *)name
+         object:(id)object
+         userInfo:(NSDictionary *)userInfo
+         inThread:(NSThread *)thread
+         beforeDate:(NSDate *)limitDate
+{
+    NSNotification *notification;
+    
+    notification = [NSNotification notificationWithName:name
+                                   object:object
+                                   userInfo:userInfo];
+    postNotification(notification, thread, limitDate);
+}
+
+@end
+
+
diff --git a/iPhoto2Ansel/ProgressSheet.nib/classes.nib b/iPhoto2Ansel/ProgressSheet.nib/classes.nib
new file mode 100644 (file)
index 0000000..fbf4da3
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {cancel = id; }; 
+            CLASS = FBProgressController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {progressIndicator = id; progressPanel = id; statusField = id; }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
diff --git a/iPhoto2Ansel/ProgressSheet.nib/info.nib b/iPhoto2Ansel/ProgressSheet.nib/info.nib
new file mode 100644 (file)
index 0000000..a92d71d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IBDocumentLocation</key>
+       <string>750 59 356 240 0 0 1440 878 </string>
+       <key>IBFramework Version</key>
+       <string>443.0</string>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>5</integer>
+       </array>
+       <key>IBSystem Version</key>
+       <string>8P2137</string>
+</dict>
+</plist>
diff --git a/iPhoto2Ansel/ProgressSheet.nib/keyedobjects.nib b/iPhoto2Ansel/ProgressSheet.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..e70ba65
Binary files /dev/null and b/iPhoto2Ansel/ProgressSheet.nib/keyedobjects.nib differ
diff --git a/iPhoto2Ansel/TURAnsel.h b/iPhoto2Ansel/TURAnsel.h
new file mode 100644 (file)
index 0000000..5f47f9f
--- /dev/null
@@ -0,0 +1,57 @@
+//
+//  TURAnsel.h
+//  myXMLTest
+//
+//  Created by Michael Rubinsky on 10/31/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+#import <Cocoa/Cocoa.h>
+@class TURAnselGallery, XMLRPCResponse;
+
+typedef enum {
+    PERMS_SHOW = 2,
+    PERMS_READ = 4,
+    PERMS_EDIT = 8,
+    PERMS_DELETE = 16
+} HORDE_PERMS;
+
+typedef enum {
+    TURAnselStateDisconnected = 0,
+    TURAnselStateConnected,
+    TURAnselStateError
+} TURAnselState;
+
+
+@interface NSObject (TURAnselDelegate)
+- (void)TURAnselDidInitialize;
+- (void)TURAnselHadError: (NSError *)error;
+@end
+
+@interface TURAnsel : NSObject {
+    NSString *userAgent;
+    NSString *rpcEndPoint;
+    NSString *username;
+    NSString *password;
+    NSMutableArray *galleryList;
+    TURAnselState state;
+    id delegate;
+    NSLock *lock;
+}
+
+@property (readwrite, retain) NSString *rpcEndPoint;
+@property (readwrite, retain) NSString *username;
+@property (readwrite, retain) NSString *password;
+
+- (id)initWithConnectionParameters: (NSDictionary *)params;
+- (void)connect;
+- (TURAnselGallery *)getGalleryById: (NSString *)galleryId;
+- (TURAnselGallery *)getGalleryByIndex: (NSInteger)index;
+- (XMLRPCResponse *)callRPCMethod: (NSString *)methodName withParams: (NSArray *)params;
+- (NSDictionary *)createNewGallery: (NSDictionary *)params;
+
+// Getters/setters
+- (void) setState: (TURAnselState)state;
+- (TURAnselState)state;
+- (id)delegate;
+- (void)setDelegate:(id)newDelegate;
+@end
diff --git a/iPhoto2Ansel/TURAnsel.m b/iPhoto2Ansel/TURAnsel.m
new file mode 100644 (file)
index 0000000..04d663c
--- /dev/null
@@ -0,0 +1,259 @@
+//
+//  TURAnsel.m
+//  AnselCocoaToolkit
+//
+//  Created by Michael Rubinsky on 10/31/08.
+//  Copyright 2008 Michael Rubinsky <mrubinsk@horde.org>
+//
+
+#import <Foundation/Foundation.h>
+#import <XMLRPC/XMLRPC.h>
+#import "TURXMLConnection.h"
+#import "TURAnsel.h"
+#import "TURAnselGallery.h"
+
+@interface TURAnsel (PrivateAPI)
+- (void)doLogin;
+@end
+
+@implementation TURAnsel
+@synthesize rpcEndPoint;
+@synthesize username;
+@synthesize password;
+
+#pragma mark init
+- (id)initWithConnectionParameters: (NSDictionary *)params
+{
+    [super init];
+    galleryList = [[NSMutableArray alloc] init];
+    
+    // Initialize the connection properties, KVC style
+    [self setValue:[params objectForKey:@"endpoint"] 
+            forKey: @"rpcEndPoint"];
+    [self setValue: [params objectForKey:@"username"]
+            forKey: @"username"];
+    [self setValue: [params objectForKey:@"password"]
+            forKey: @"password"];
+    [self setValue: @"The Ansel Cocoa XML-RPC Client"
+            forKey: @"userAgent"];
+    return self;
+}
+
+#pragma mark Instance Methods
+/**
+ * Initial connection to the Ansel server
+ * Authenticate and fill our cache with the available galleries for uploading to
+ */
+- (void)connect 
+{
+    [self doLogin];
+    if (state == TURAnselStateConnected) {
+        if ([delegate respondsToSelector:@selector(TURAnselDidInitialize)]) {
+            [delegate performSelectorOnMainThread:@selector(TURAnselDidInitialize)
+                                       withObject:self
+                                    waitUntilDone: NO];
+        }
+    }
+}
+
+// Fetch a gallery by id
+- (TURAnselGallery *)getGalleryById: (NSString *)galleryId
+{
+    TURAnselGallery *g;
+    for (g in galleryList) {
+        if ([galleryId isEqualTo: [NSNumber numberWithInt: [g galleryId]]]) {
+            return g;
+        }
+    }
+    
+    return nil;
+}
+
+// Return the gallery at the specified position in the internal storage array.
+// Needed for when we are using this class as a datasource for a UI element.
+- (TURAnselGallery *)getGalleryByIndex: (NSInteger)index
+{
+    TURAnselGallery *g = [galleryList objectAtIndex:index];
+    return g;
+}
+
+// Creates a new gallery
+// For now, only takes a gallery name, but no reason it can't take descriiption
+// and default perms etc...
+- (NSDictionary *)createNewGallery: (NSDictionary *)params
+{
+    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
+                                [params valueForKey:@"name"], @"name", nil];
+    NSArray *apiparams = [NSArray arrayWithObjects:
+                             @"ansel", attributes, nil]; 
+    XMLRPCResponse *response = [self callRPCMethod:@"images.createGallery"
+                                        withParams:apiparams];
+    if (state != TURAnselStateError) {
+        NSDictionary *results = [NSDictionary dictionaryWithObjectsAndKeys:
+                                    response, @"share_id",
+                                    [params valueForKey:@"name"], @"attribute_name",
+                                    @"", @"attribute_desc",
+                                    [NSNumber numberWithInt:0], @"attribute_images",
+                                    [NSNumber numberWithInt:0], @"attribute_default", nil];
+        TURAnselGallery *newGallery = [[TURAnselGallery alloc] initWithObject:results];
+        [galleryList addObject:newGallery];
+        return results;
+    }
+    
+    // If we have an error, tell the world
+    // *really* need to give these errors real numbers.....
+    if ([delegate respondsToSelector:@selector(TURAnselHadError:)]) {
+        NSError *error = [NSError errorWithDomain:@"TURAnsel"
+                                             code:3
+                                         userInfo:[NSDictionary dictionaryWithObjectsAndKeys: @"Could not create gallery.", @"message", nil]];
+        [delegate TURAnselHadError:error];
+    }
+
+    return nil;
+}
+
+
+// Call an arbitrary RPC method on the Horde server.
+- (XMLRPCResponse *)callRPCMethod: (NSString *)methodName
+                       withParams: (NSArray *)params
+{
+    NSLog(@"Initiating connection for %@", methodName);
+    
+    // Get a URL object
+    NSURL *url = [NSURL URLWithString: [self valueForKey: @"rpcEndPoint"]];
+    XMLRPCRequest *request = [[XMLRPCRequest alloc]initWithHost: url];
+    [request setUserAgent: [self valueForKey:@"userAgent"]];
+    [request setMethod: methodName
+        withParameters: params];
+    
+    NSDictionary *credentials = [[NSDictionary alloc] initWithObjectsAndKeys: 
+                                 [self valueForKey:@"username"], @"username",
+                                 [self valueForKey:@"password"], @"password", nil];
+    
+    TURXMLConnection *connection = [[TURXMLConnection alloc]
+                                    initWithXMLRPCRequest: request 
+                                    withCredentials:credentials];
+
+    // Don't move on until we have a response - this blocks the thread until
+    // that happens.  We should have some kind of timeout here...
+    while ([connection isRunning]) {
+        NSDate *loopDate = [[NSDate alloc] initWithTimeIntervalSinceNow:0.1];
+        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
+                                 beforeDate:loopDate];
+        [loopDate release];
+    }
+    
+    if ([connection hasError] == NO) {
+        XMLRPCResponse *response = [[connection response] autorelease];
+        [credentials release];
+        [connection release];
+        return response;
+    } else {
+        state = TURAnselStateError;
+        NSError *error = [[connection error] retain];
+        if ([delegate respondsToSelector:@selector(TURAnselHadError:)]) {
+            [delegate TURAnselHadError:error];
+        }
+        [error autorelease];
+        [connection release];
+        return nil;
+    }
+
+}
+
+#pragma mark TableView datasource ----------------------------------------------
+- (int)numberOfRowsInTableView: (NSTableView *)tv
+{
+    return [galleryList count];
+}
+
+- (id)tableView: (NSTableView *)tv
+objectValueForTableColumn:(NSTableColumn *)tc
+            row: (int)rowIndex
+{
+    NSString *identifier = [tc identifier]; 
+    TURAnselGallery *g = [galleryList objectAtIndex:rowIndex];
+    NSString *stringValue = [g valueForKey: identifier];
+    return stringValue;
+}
+
+#pragma mark ComboBox Datasource
+
+- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox
+{
+    return [galleryList count];
+}
+
+- (id)comboBox:(NSComboBox *)aComboBox
+  objectValueForItemAtIndex:(NSInteger)index
+{
+    TURAnselGallery *g = [galleryList objectAtIndex:index];
+    NSString *stringValue = [g valueForKey:@"galleryName"];
+    return stringValue;
+}
+
+#pragma mark Getter/Setters----------------------------------------------------
+- (TURAnselState) state
+{
+    return state;
+}
+-(void) setState: (TURAnselState)newstate
+{
+    state = newstate;
+}
+
+- (id)delegate {
+    return delegate;    
+}
+
+- (void)setDelegate:(id)newDelegate {
+    delegate = newDelegate;
+}
+
+-(void) dealloc
+{
+    NSLog(@"TURAnsel dealloc");   
+    [galleryList release];
+    galleryList = nil;
+    [rpcEndPoint release];
+    [username release];
+    [password release];
+    [userAgent release];
+    [super dealloc];
+}
+
+#pragma mark PrivateAPI
+- (void)doLogin
+{
+    NSLog(@"Initiating the connection in [TURAnsel doLogin] in thread: %@", [NSThread currentThread]);
+    
+    // Start out by building an array of parameters to pass to the api call.
+    // We start by asking for a list of available galleries with PERMS_EDIT.
+    // This has the side effect of authenticating for the session.
+    NSArray *params = [[NSArray alloc] initWithObjects:
+                       @"ansel",                                 // Scope 
+                       [NSNumber numberWithInt: PERMS_EDIT],     // Perms
+                       @"",                                      // No parent
+                       [NSNumber numberWithBool:YES],            // allLevels
+                       [NSNumber numberWithInt: 0],              // Offset
+                       [NSNumber numberWithInt: 0],              // Count
+                       [self valueForKey:@"username"], nil];     // Restrict to user (This should be an option eventually).do
+    
+
+    id galleries = [self callRPCMethod:@"images.listGalleries"
+                            withParams:params];
+    
+    if (state != TURAnselStateError) {
+        state = TURAnselStateConnected;
+        for (NSString *gal in galleries) {
+            TURAnselGallery *theGallery = [[TURAnselGallery alloc] initWithObject:gal];
+            [theGallery setAnselController: self];
+            [galleryList addObject: theGallery];
+            [theGallery release];
+            theGallery = nil;
+        }
+    }
+    [params release];
+}
+
+@end
diff --git a/iPhoto2Ansel/TURAnselGallery.h b/iPhoto2Ansel/TURAnselGallery.h
new file mode 100644 (file)
index 0000000..c39891c
--- /dev/null
@@ -0,0 +1,57 @@
+//
+//  TURAnselGallery.h
+//  
+// Class to wrap Ansel Gallery.
+//
+//  Created by Michael Rubinsky on 10/21/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+@class TURAnsel, NSURL, XMLRPCResponse;
+
+typedef enum {
+    TURAnselGalleryStateReady = 0,
+    TURAnselGalleryStateBusy
+} TURAnselGalleryState; 
+
+@interface NSObject (TURAnselGalleryDelegate)
+- (void)TURAnselGalleryDidReceiveRPCResponse: (XMLRPCResponse *)response;
+- (void)TURAnselGalleryDidUploadImage: (TURAnselGallery *)gallery;
+- (void)TURAnselGalleryDidReceiveDefaultURL: (TURAnselGallery *)gallery;
+@end
+
+@interface TURAnselGallery : NSObject {
+    int galleryId;
+    int galleryImageCount;
+    int galleryDefaultImage;
+    NSURL *galleryDefaultImageURL;
+    NSString *galleryName;
+    NSString *galleryDescription;
+    TURAnsel *anselController;
+    TURAnselGalleryState state;
+    id delegate;
+}
+@property (readonly) NSString *galleryName;
+@property (readonly) NSString *galleryDescription;
+@property (readonly) int galleryImageCount;
+@property (readwrite) int galleryDefaultImage;
+@property (readonly, retain) NSURL *galleryDefaultImageURL;
+
+- (id)initWithObject:(id)galleryData;
+- (int)galleryId;
+- (void)requestDefaultImageURL;
+- (void)parseImageUrlRequest:(XMLRPCResponse *)response;
+- (void)uploadImageObject: (NSDictionary *)imageParameters;
+- (void)setDelegate: (id)newDelegate;
+- (id)delegate;
+- (TURAnselGalleryState) state;
+- (void)setState: (TURAnselGalleryState)theState;
+- (bool)isBusy;
+- (void)setAnselController:(TURAnsel *)newController;
+@end
+
+@interface TURAnselGallery (PrivateAPI)
+- (void)uploadThread:(NSDictionary *)threadDispatchInfo;
+- (void)doUplod: (NSDictionary *)imageParams;
+@end
\ No newline at end of file
diff --git a/iPhoto2Ansel/TURAnselGallery.m b/iPhoto2Ansel/TURAnselGallery.m
new file mode 100644 (file)
index 0000000..a72e5cf
--- /dev/null
@@ -0,0 +1,205 @@
+//
+//  TURAnselGallery.m
+// Class wraps an Ansel Gallery
+//
+//  Created by Michael Rubinsky on 10/21/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+#import <Foundation/Foundation.h>
+#import "XMLRPC/XMLRPC.h"
+#import "TURXMLConnection.h"
+#import "TURAnsel.h"
+#import "TURAnselGallery.h"
+
+@implementation TURAnselGallery
+
+@synthesize galleryDescription;
+@synthesize galleryName;
+@synthesize galleryImageCount;
+@synthesize galleryDefaultImage;
+@synthesize galleryDefaultImageURL;
+
+#pragma mark Instance Methods --------------------------------------------------
+
+/**
+ * Init a gallery object
+ */
+- (id)initWithObject: (id)galleryData
+{
+    [super init];
+    // KVC automatically type coerces
+    [self setValue: [galleryData valueForKey:@"share_id"]
+            forKey: @"galleryId"];
+    [self setValue:[galleryData valueForKey:@"attribute_desc"]
+            forKey:@"galleryDescription"];
+    [self setValue:[galleryData valueForKey:@"attribute_name"]
+            forKey:@"galleryName"];
+    [self setValue: [galleryData valueForKey:@"attribute_images"]
+            forKey:@"galleryImageCount"];    
+    [self setValue: [galleryData valueForKey:@"attribute_default"]
+            forKey:@"galleryDefaultImage"];
+
+    return self;
+}
+
+/**
+ * Requests the gallery's default image url to be fetched from the server
+ * (This information is not present in the gallery definition array returned
+ *  from the images.listGalleries call). 
+ *  
+ * This tells the anselController to send the request and sets this object up
+ * as the delegate to receive the results. 
+ */
+- (void)requestDefaultImageURL
+{
+
+//    NSArray *params = [[NSArray alloc] initWithObjects:
+//                       @"ansel",                                         // Scope
+//                       [NSNumber numberWithInt: galleryDefaultImage],    // Image Id
+//                       @"thumb",                                         // Thumbnail type
+//                       [NSNumber numberWithBool:YES],                    // Full path
+//                       nil];
+//    [self setState:TURAnselGalleryStateBusy];
+//    [anselController callRPCMethod:@"images.getImageUrl"
+//                        withParams: params
+//                      withDelegate: self];
+    
+}
+
+/**
+ * Forks off a new thread for the upload
+ */
+- (void)uploadImageObject: (NSDictionary *)imageParameters
+{
+    //[NSThread prepareForInterThreadMessages];
+    NSDictionary *threadDispatchInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+                                        [NSThread currentThread], @"CallingThread",
+                                        nil];
+    NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
+                               imageParameters, @"imageParameters",
+                               threadDispatchInfo, @"threadDispatchInfo",
+                               nil];
+    
+    
+    [self uploadThread: arguments];
+}
+
+- (bool) isBusy
+{
+    if (state == TURAnselGalleryStateReady) {
+        return NO;
+    } else {
+        return YES;
+    }
+}
+
+#pragma mark Response parsers called from the delegate method ------------------
+/**
+ * Called by the XMLRPCConnection delegate to parse the resposne
+ */
+- (void)parseImageUrlRequest: (XMLRPCResponse *)response
+{
+    [self setState:TURAnselGalleryStateReady];
+    NSLog(@"Image URL For Gallery Preview: %@",[response responseObject]);
+    NSString *url = [NSString stringWithFormat:@"%@", [response responseObject]];
+    NSURL *imageURL = [NSURL URLWithString:url];
+    galleryDefaultImageURL = [imageURL retain]; 
+    
+    if ([delegate respondsToSelector:@selector(TURAnselGalleryDidReceiveDefaultURL:)]) {
+        [delegate TURAnselGalleryDidReceiveDefaultURL: self];
+    }
+    
+}
+
+#pragma mark Getter/Setter------------------------------------------------------
+- (int)galleryId
+{
+    return galleryId;
+}
+- (void)setGalleryId:(int)id
+{
+    galleryId = id;
+}
+
+- (id)delegate
+{
+    return delegate;
+}
+- (void)setDelegate: (id)newDelegate
+{
+    delegate = newDelegate;
+}
+
+- (TURAnselGalleryState)state
+{
+    return state;
+}
+- (void)setState: (TURAnselGalleryState)theState 
+{
+    state = theState;
+}
+
+- (void)setAnselController: (TURAnsel *)newController
+{
+    [anselController autorelease];
+    anselController = [newController retain];
+}
+
+- (TURAnsel *)anselController
+{
+    return anselController;
+}
+
+#pragma mark Overrides----------------------------------------------------------
+- (void)dealloc
+{
+    NSLog(@"TURAnselGallery dealloc called");
+    [galleryDescription release];
+    [anselController release];
+    [galleryDefaultImageURL release];
+    [galleryDescription release];
+    [super dealloc];
+}
+
+- (id)init
+{
+    [super init];
+    [self setState:TURAnselGalleryStateReady];
+    return self;
+}
+
+- (id)description 
+{
+    NSString *text = [NSString stringWithFormat:@"Description: %@ Id: %d has: %d images", galleryDescription, galleryId, galleryImageCount];
+    return text;
+}
+
+#pragma mark PrivateAPI
+- (void)uploadThread:(NSDictionary *)parameters
+{
+        //For now, assume success stil need to do error checking/handling
+        [self doUplod:[[parameters objectForKey:@"imageParameters"] retain]];
+        if ([delegate respondsToSelector:@selector(TURAnselGalleryDidUploadImage:)]) {
+            [delegate performSelectorOnMainThread:@selector(TURAnselGalleryDidUploadImage:)
+                                       withObject:self 
+                                    waitUntilDone:NO];
+        }
+}
+- (void)doUplod:(NSDictionary *)imageParameters
+{
+        // Need to build the XMLRPC params array now.
+        NSArray *params = [[NSArray alloc] initWithObjects:
+                           @"ansel",                                 // app
+                           [NSNumber numberWithInt: galleryId],      // gallery_id
+                           [imageParameters valueForKey: @"data"],   // image data array   
+                           [imageParameters valueForKey:@"default"], // set as default?
+                           @"",                                      // Additional gallery data to set?      
+                           @"base64",                                // Image data encoding      
+                           nil];
+        
+        // Send the request up to the controller
+         [anselController callRPCMethod:@"images.saveImage"
+                           withParams: params];
+        [params release];
+}
+@end
diff --git a/iPhoto2Ansel/TURXMLConnection.h b/iPhoto2Ansel/TURXMLConnection.h
new file mode 100644 (file)
index 0000000..3ac5457
--- /dev/null
@@ -0,0 +1,38 @@
+//
+//  TURXMLConnection.h
+//
+// This is a thin wrapper around XMLRPCRequests to allow them to more easily
+// be run in a seperate thread then the reciever that needs to know about it's
+// progress.  Done to deal with modal threads blocking the NSURLConnection
+// responses in iPhoto plugins.
+//
+//  Created by Michael Rubinsky on 11/5/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "XMLRPC/XMLRPCConnection.h"
+@class XMLRPCRequest;
+
+// Local error codes
+#define TURXML_ERR_BADAUTH  1  // Login failed
+#define TURXML_ERR_PARSE    2  // Could not parse XML
+
+@interface TURXMLConnection : XMLRPCConnection {
+    NSString *username;
+    NSString *password;
+    XMLRPCResponse *response;
+    XMLRPCConnection *connection;
+    BOOL hasError;
+    NSError *error;
+    BOOL running;
+}
+
+- (TURXMLConnection *)initWithXMLRPCRequest: (XMLRPCRequest *)request 
+                            withCredentials:(NSDictionary *)credentials;
+
+- (id)response;
+- (BOOL)hasError;
+- (BOOL)isRunning;
+- (NSError *)error;
+@end
diff --git a/iPhoto2Ansel/TURXMLConnection.m b/iPhoto2Ansel/TURXMLConnection.m
new file mode 100644 (file)
index 0000000..cf39814
--- /dev/null
@@ -0,0 +1,129 @@
+//
+//  TURXMLConnection.m
+//  iPhoto2Ansel
+//
+//  Created by Michael Rubinsky on 11/5/08.
+//  Copyright 2008 __MyCompanyName__. All rights reserved.
+//
+#import <Foundation/Foundation.h>
+#import <XMLRPC/XMLRPC.h>
+#import "TURXMLConnection.h"
+
+@implementation TURXMLConnection
+
+static NSString *ERR_DOMAIN = @"com.theupstairsroom.XMLConnection";
+
+- (TURXMLConnection *)initWithXMLRPCRequest: (XMLRPCRequest *)request 
+                            withCredentials:(NSDictionary *)credentials
+{
+    username = [[credentials objectForKey:@"username"] retain];
+    password = [[credentials objectForKey:@"password"] retain];
+    running = YES;
+    connection = [[XMLRPCConnection alloc] initWithXMLRPCRequest:request
+                                                        delegate:self];
+    return self;
+}
+
+- (BOOL)isRunning
+{
+    return running;
+}
+
+- (id)response
+{
+    return response;
+}
+
+- (void)dealloc
+{
+    NSLog(@"TURXMLConnection dealloc called");
+    [username release];
+    [password release];
+    [super dealloc];
+}
+
+- (BOOL)hasError
+{
+    return hasError;
+}
+
+// Return the error object, but get rid of it.
+- (NSError *)error
+{
+    return [error autorelease];
+}
+
+#pragma mark XMLRPCConnection Delegate
+- (void)connection: (XMLRPCConnection *)xconnection 
+didReceiveResponse: (XMLRPCResponse *)theResponse 
+         forMethod: (NSString *)method
+{    
+    NSLog(@"Received response for %@", method);
+    if (theResponse != nil) {
+        if ([theResponse isFault]) {
+            NSLog(@"Fault code: %@", [theResponse faultCode]);
+            NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+                                      [theResponse faultString], @"NSLocalizedDescriptionKey", nil];
+            error = [[NSError alloc] initWithDomain: ERR_DOMAIN
+                                               code: [[theResponse faultCode] intValue]
+                                           userInfo: userInfo];
+            hasError = YES;
+            [theResponse release];
+            [xconnection cancel];
+        }
+    } else {
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+                                  @"Unable to parse XML in XMLRPCDelegate method", @"NSLocalizedDescriptionKey", nil];
+        error = [[NSError alloc] initWithDomain: ERR_DOMAIN
+                                           code: TURXML_ERR_PARSE
+                                       userInfo: userInfo];
+        hasError = YES;
+        [theResponse release];
+        [xconnection cancel];
+    }
+    
+    response = [[theResponse responseObject] retain];
+    [theResponse release];
+    [xconnection release];
+    running = NO;
+}
+
+- (void)connection: (XMLRPCConnection *)xconnection 
+didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
+                        forMethod: (NSString *)method
+{
+    NSLog(@"Credentials requested in method: %@", method);
+    if ([challenge previousFailureCount] == 0) {
+        NSURLCredential *newCredential;
+        newCredential = [NSURLCredential credentialWithUser: [self valueForKey: @"username"]
+                                                   password: [self valueForKey: @"password"]
+                                                persistence: NSURLCredentialPersistenceForSession];
+        
+        [[challenge sender] useCredential: newCredential
+               forAuthenticationChallenge: challenge];
+        NSLog(@"Credentials sent");
+    } else {
+        [[challenge sender] cancelAuthenticationChallenge: challenge];
+        NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+                                  @"Authentication Failed", @"NSLocalizedDescriptionKey",
+                                  @"Check your username and password and try again.", @"NSLocalizedRecoverySuggestionErrorKey", nil];
+
+        error = [[NSError alloc] initWithDomain: ERR_DOMAIN
+                                           code: TURXML_ERR_BADAUTH
+                                       userInfo: userInfo];
+        running = NO;
+        hasError = YES;
+    }
+}
+
+- (void)connection: (XMLRPCConnection *)xconnection
+  didFailWithError: (NSError *)xerror
+         forMethod: (NSString *)method
+{
+    error = [xerror retain];
+    hasError = YES;
+    running = NO;
+}
+
+
+@end
diff --git a/iPhoto2Ansel/XMLRPC-Info.plist b/iPhoto2Ansel/XMLRPC-Info.plist
new file mode 100644 (file)
index 0000000..3e59a1a
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.yourcompany.XMLRPC</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+</dict>
+</plist>
diff --git a/iPhoto2Ansel/XMLRPC.framework/Headers b/iPhoto2Ansel/XMLRPC.framework/Headers
new file mode 120000 (symlink)
index 0000000..a177d2a
--- /dev/null
@@ -0,0 +1 @@
+Versions/Current/Headers
\ No newline at end of file
diff --git a/iPhoto2Ansel/XMLRPC.framework/Resources b/iPhoto2Ansel/XMLRPC.framework/Resources
new file mode 120000 (symlink)
index 0000000..953ee36
--- /dev/null
@@ -0,0 +1 @@
+Versions/Current/Resources
\ No newline at end of file
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPC.h b/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPC.h
new file mode 100644 (file)
index 0000000..09de627
--- /dev/null
@@ -0,0 +1,33 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPC.h
+// 
+// Created by Eric Czarny on Wednesday, February 10, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <XMLRPC/XMLRPCConnection.h>
+#import <XMLRPC/XMLRPCRequest.h>
+#import <XMLRPC/XMLRPCResponse.h>
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCConnection.h b/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCConnection.h
new file mode 100644 (file)
index 0000000..9c6b94a
--- /dev/null
@@ -0,0 +1,73 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCConnection.h
+// 
+// Created by Eric Czarny on Thursday, January 15, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+#import <Foundation/Foundation.h>
+
+@class XMLRPCRequest, XMLRPCResponse;
+
+/* XML-RPC Connection Notifications */
+extern NSString *XMLRPCSentRequestNotification;
+extern NSString *XMLRPCRequestFailedNotification;
+extern NSString *XMLRPCReceivedAuthenticationChallengeNotification;
+extern NSString *XMLRPCCancelledAuthenticationChallengeNotification;
+extern NSString *XMLRPCReceivedResponseNotification;
+
+@interface XMLRPCConnection : NSObject {
+       NSURLConnection *currentConnection;
+       NSString *currentXMLRPCMethod;
+       NSMutableData *incomingXMLData;
+       id applicationDelegate;
+}
+
+- (id)initWithXMLRPCRequest: (XMLRPCRequest *)request delegate: (id)delegate;
+
+#pragma mark -
+
++ (XMLRPCResponse *)sendSynchronousXMLRPCRequest: (XMLRPCRequest *)request;
+
+#pragma mark -
+
+- (void)cancel;
+
+@end
+
+#pragma mark -
+
+@interface NSObject (XMLRPCConnectionDelegate)
+
+- (void)connection: (XMLRPCConnection *)connection didReceiveResponse: (XMLRPCResponse *)response forMethod: (NSString *)method;
+
+- (void)connection: (XMLRPCConnection *)connection didFailWithError: (NSError *)error forMethod: (NSString *)method;
+
+- (void)connection: (XMLRPCConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge forMethod: (NSString *)method;
+
+- (void)connection: (XMLRPCConnection *)connection didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge forMethod: (NSString *)method;
+
+@end
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCRequest.h b/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCRequest.h
new file mode 100644 (file)
index 0000000..1db012e
--- /dev/null
@@ -0,0 +1,73 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCRequest.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/Foundation.h>
+
+@class XMLRPCEncoder;
+
+@interface XMLRPCRequest : NSObject {
+       NSMutableURLRequest *mutableRequest;
+       XMLRPCEncoder *requestXMLEncoder;
+}
+
+- (id)initWithHost: (NSURL *)host;
+
+#pragma mark -
+
+- (void)setHost: (NSURL *)host;
+- (NSURL *)host;
+
+#pragma mark -
+
+- (void)setUserAgent: (NSString *)userAgent;
+- (NSString *)userAgent;
+
+#pragma mark -
+
+- (void)setMethod: (NSString *)method;
+
+- (void)setMethod: (NSString *)method withParameter: (id)parameter;
+
+- (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters;
+
+#pragma mark -
+
+- (NSString *)method;
+- (NSArray *)parameters;
+
+#pragma mark -
+
+- (NSString *)requestSourceXML;
+
+#pragma mark -
+
+- (NSURLRequest *)request;
+
+@end
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCResponse.h b/iPhoto2Ansel/XMLRPC.framework/Versions/A/Headers/XMLRPCResponse.h
new file mode 100644 (file)
index 0000000..fe645a6
--- /dev/null
@@ -0,0 +1,60 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCResponse.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/Foundation.h>
+
+@class XMLRPCDecoder;
+
+@interface XMLRPCResponse : NSObject {
+       NSData *responseXMLData;
+       NSString *responseSourceXML;
+       id responseObject;
+       BOOL isFault;
+}
+
+- (id)initWithData: (NSData *)data;
+
+#pragma mark -
+
+- (BOOL)isFault;
+
+- (NSNumber *)faultCode;
+
+- (NSString *)faultString;
+
+#pragma mark -
+
+- (id)responseObject;
+
+#pragma mark -
+
+- (NSString *)responseSourceXML;
+
+@end
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/A/Resources/English.lproj/Localizable.strings b/iPhoto2Ansel/XMLRPC.framework/Versions/A/Resources/English.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..afec4bd
--- /dev/null
@@ -0,0 +1,3 @@
+/* ENGLISH */
+
+NSHumanReadableCopyright = "Cocoa XML-RPC Framework © 2008 Divisible by Zero";
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/A/Resources/Info.plist b/iPhoto2Ansel/XMLRPC.framework/Versions/A/Resources/Info.plist
new file mode 100644 (file)
index 0000000..9ab427f
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>XMLRPC</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.divisiblebyzero.XMLRPC</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>XMLRPC</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleSignature</key>
+       <string>ZERO</string>
+       <key>CFBundleVersion</key>
+       <string>1.5.1</string>
+</dict>
+</plist>
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/A/XMLRPC b/iPhoto2Ansel/XMLRPC.framework/Versions/A/XMLRPC
new file mode 100755 (executable)
index 0000000..f15c5d0
Binary files /dev/null and b/iPhoto2Ansel/XMLRPC.framework/Versions/A/XMLRPC differ
diff --git a/iPhoto2Ansel/XMLRPC.framework/Versions/Current b/iPhoto2Ansel/XMLRPC.framework/Versions/Current
new file mode 120000 (symlink)
index 0000000..8c7e5a6
--- /dev/null
@@ -0,0 +1 @@
+A
\ No newline at end of file
diff --git a/iPhoto2Ansel/XMLRPC.framework/XMLRPC b/iPhoto2Ansel/XMLRPC.framework/XMLRPC
new file mode 120000 (symlink)
index 0000000..0a7400a
--- /dev/null
@@ -0,0 +1 @@
+Versions/Current/XMLRPC
\ No newline at end of file
diff --git a/iPhoto2Ansel/iPhoto2Ansel.xcodeproj/mrubinsk.mode1v3 b/iPhoto2Ansel/iPhoto2Ansel.xcodeproj/mrubinsk.mode1v3
new file mode 100644 (file)
index 0000000..5070cce
--- /dev/null
@@ -0,0 +1,1374 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>ActivePerspectiveName</key>
+       <string>Project</string>
+       <key>AllowedModules</key>
+       <array>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXSmartGroupTreeModule</string>
+                       <key>Name</key>
+                       <string>Groups and Files Outline View</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXNavigatorGroup</string>
+                       <key>Name</key>
+                       <string>Editor</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCTaskListModule</string>
+                       <key>Name</key>
+                       <string>Task List</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDetailModule</string>
+                       <key>Name</key>
+                       <string>File and Smart Group Detail Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXBuildResultsModule</string>
+                       <key>Name</key>
+                       <string>Detailed Build Results Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXProjectFindModule</string>
+                       <key>Name</key>
+                       <string>Project Batch Find Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCProjectFormatConflictsModule</string>
+                       <key>Name</key>
+                       <string>Project Format Conflicts List</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXBookmarksModule</string>
+                       <key>Name</key>
+                       <string>Bookmarks Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXClassBrowserModule</string>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXCVSModule</string>
+                       <key>Name</key>
+                       <string>Source Code Control Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXDebugBreakpointsModule</string>
+                       <key>Name</key>
+                       <string>Debug Breakpoints Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDockableInspector</string>
+                       <key>Name</key>
+                       <string>Inspector</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXOpenQuicklyModule</string>
+                       <key>Name</key>
+                       <string>Open Quickly Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugSessionModule</string>
+                       <key>Name</key>
+                       <string>Debugger</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugCLIModule</string>
+                       <key>Name</key>
+                       <string>Debug Console</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCSnapshotModule</string>
+                       <key>Name</key>
+                       <string>Snapshots Tool</string>
+               </dict>
+       </array>
+       <key>BundlePath</key>
+       <string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources</string>
+       <key>Description</key>
+       <string>DefaultDescriptionKey</string>
+       <key>DockingSystemVisible</key>
+       <false/>
+       <key>Extension</key>
+       <string>mode1v3</string>
+       <key>FavBarConfig</key>
+       <dict>
+               <key>PBXProjectModuleGUID</key>
+               <string>B0C8882C0ED8579D000E19FB</string>
+               <key>XCBarModuleItemNames</key>
+               <dict/>
+               <key>XCBarModuleItems</key>
+               <array/>
+       </dict>
+       <key>FirstTimeWindowDisplayed</key>
+       <false/>
+       <key>Identifier</key>
+       <string>com.apple.perspectives.project.mode1v3</string>
+       <key>MajorVersion</key>
+       <integer>33</integer>
+       <key>MinorVersion</key>
+       <integer>0</integer>
+       <key>Name</key>
+       <string>Default</string>
+       <key>Notifications</key>
+       <array>
+               <dict>
+                       <key>XCObserverAutoDisconnectKey</key>
+                       <true/>
+                       <key>XCObserverDefintionKey</key>
+                       <dict/>
+                       <key>XCObserverFactoryKey</key>
+                       <string>XCPerspectivesSpecificationIdentifier</string>
+                       <key>XCObserverGUIDKey</key>
+                       <string>XCObserverProjectIdentifier</string>
+                       <key>XCObserverNotificationKey</key>
+                       <string>PBXStatusBuildStateMessageNotification</string>
+                       <key>XCObserverTargetKey</key>
+                       <string>XCMainBuildResultsModuleGUID</string>
+                       <key>XCObserverTriggerKey</key>
+                       <string>awakenModuleWithObserver:</string>
+                       <key>XCObserverValidationKey</key>
+                       <dict/>
+               </dict>
+       </array>
+       <key>OpenEditors</key>
+       <array/>
+       <key>PerspectiveWidths</key>
+       <array>
+               <integer>-1</integer>
+               <integer>-1</integer>
+       </array>
+       <key>Perspectives</key>
+       <array>
+               <dict>
+                       <key>ChosenToolbarItems</key>
+                       <array>
+                               <string>active-target-popup</string>
+                               <string>active-buildstyle-popup</string>
+                               <string>action</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>buildOrClean</string>
+                               <string>build-and-goOrGo</string>
+                               <string>com.apple.ide.PBXToolbarStopButton</string>
+                               <string>get-info</string>
+                               <string>toggle-editor</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>com.apple.pbx.toolbar.searchfield</string>
+                       </array>
+                       <key>ControllerClassBaseName</key>
+                       <string></string>
+                       <key>IconName</key>
+                       <string>WindowOfProjectWithEditor</string>
+                       <key>Identifier</key>
+                       <string>perspective.project</string>
+                       <key>IsVertical</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>ContentConfiguration</key>
+                                       <dict>
+                                               <key>PBXBottomSmartGroupGIDs</key>
+                                               <array>
+                                                       <string>1C37FBAC04509CD000000102</string>
+                                                       <string>1C37FAAC04509CD000000102</string>
+                                                       <string>1C08E77C0454961000C914BD</string>
+                                                       <string>1C37FABC05509CD000000102</string>
+                                                       <string>1C37FABC05539CD112110102</string>
+                                                       <string>E2644B35053B69B200211256</string>
+                                                       <string>1C37FABC04509CD000100104</string>
+                                                       <string>1CC0EA4004350EF90044410B</string>
+                                                       <string>1CC0EA4004350EF90041110B</string>
+                                               </array>
+                                               <key>PBXProjectModuleGUID</key>
+                                               <string>1CE0B1FE06471DED0097A5F4</string>
+                                               <key>PBXProjectModuleLabel</key>
+                                               <string>Files</string>
+                                               <key>PBXProjectStructureProvided</key>
+                                               <string>yes</string>
+                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                       <array>
+                                                               <real>186</real>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                       <array>
+                                                               <string>MainColumn</string>
+                                                       </array>
+                                               </dict>
+                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                       <array>
+                                                               <string>089C166AFE841209C02AAC07</string>
+                                                               <string>B00076DE0EBA573900A95FC0</string>
+                                                               <string>1C37FABC05509CD000000102</string>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                       <array>
+                                                               <array>
+                                                                       <integer>3</integer>
+                                                                       <integer>1</integer>
+                                                                       <integer>0</integer>
+                                                               </array>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                       <string>{{0, 0}, {186, 630}}</string>
+                                               </dict>
+                                               <key>PBXTopSmartGroupGIDs</key>
+                                               <array/>
+                                               <key>XCIncludePerspectivesSwitch</key>
+                                               <true/>
+                                               <key>XCSharingToken</key>
+                                               <string>com.apple.Xcode.GFSharingToken</string>
+                                       </dict>
+                                       <key>GeometryConfiguration</key>
+                                       <dict>
+                                               <key>Frame</key>
+                                               <string>{{0, 0}, {203, 648}}</string>
+                                               <key>GroupTreeTableConfiguration</key>
+                                               <array>
+                                                       <string>MainColumn</string>
+                                                       <real>186</real>
+                                               </array>
+                                               <key>RubberWindowFrame</key>
+                                               <string>64 480 614 689 0 0 1920 1178 </string>
+                                       </dict>
+                                       <key>Module</key>
+                                       <string>PBXSmartGroupTreeModule</string>
+                                       <key>Proportion</key>
+                                       <string>203pt</string>
+                               </dict>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20306471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>MyNewFile14.java</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CE0B20406471E060097A5F4</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>MyNewFile14.java</string>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {406, 470}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>64 480 614 689 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>470pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20506471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Detail</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 475}, {406, 173}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>64 480 614 689 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCDetailModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>173pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>406pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCModuleDock</string>
+                               <string>PBXSmartGroupTreeModule</string>
+                               <string>XCModuleDock</string>
+                               <string>PBXNavigatorGroup</string>
+                               <string>XCDetailModule</string>
+                       </array>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>B0C8882A0ED8579D000E19FB</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>B0C8882B0ED8579D000E19FB</string>
+                               <string>1CE0B20306471E060097A5F4</string>
+                               <string>1CE0B20506471E060097A5F4</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.defaultV3</string>
+               </dict>
+               <dict>
+                       <key>ControllerClassBaseName</key>
+                       <string></string>
+                       <key>IconName</key>
+                       <string>WindowOfProject</string>
+                       <key>Identifier</key>
+                       <string>perspective.morph</string>
+                       <key>IsVertical</key>
+                       <integer>0</integer>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>BecomeActive</key>
+                                       <integer>1</integer>
+                                       <key>ContentConfiguration</key>
+                                       <dict>
+                                               <key>PBXBottomSmartGroupGIDs</key>
+                                               <array>
+                                                       <string>1C37FBAC04509CD000000102</string>
+                                                       <string>1C37FAAC04509CD000000102</string>
+                                                       <string>1C08E77C0454961000C914BD</string>
+                                                       <string>1C37FABC05509CD000000102</string>
+                                                       <string>1C37FABC05539CD112110102</string>
+                                                       <string>E2644B35053B69B200211256</string>
+                                                       <string>1C37FABC04509CD000100104</string>
+                                                       <string>1CC0EA4004350EF90044410B</string>
+                                                       <string>1CC0EA4004350EF90041110B</string>
+                                               </array>
+                                               <key>PBXProjectModuleGUID</key>
+                                               <string>11E0B1FE06471DED0097A5F4</string>
+                                               <key>PBXProjectModuleLabel</key>
+                                               <string>Files</string>
+                                               <key>PBXProjectStructureProvided</key>
+                                               <string>yes</string>
+                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                       <array>
+                                                               <real>186</real>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                       <array>
+                                                               <string>MainColumn</string>
+                                                       </array>
+                                               </dict>
+                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                       <array>
+                                                               <string>29B97314FDCFA39411CA2CEA</string>
+                                                               <string>1C37FABC05509CD000000102</string>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                       <array>
+                                                               <array>
+                                                                       <integer>0</integer>
+                                                               </array>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                       <string>{{0, 0}, {186, 337}}</string>
+                                               </dict>
+                                               <key>PBXTopSmartGroupGIDs</key>
+                                               <array/>
+                                               <key>XCIncludePerspectivesSwitch</key>
+                                               <integer>1</integer>
+                                               <key>XCSharingToken</key>
+                                               <string>com.apple.Xcode.GFSharingToken</string>
+                                       </dict>
+                                       <key>GeometryConfiguration</key>
+                                       <dict>
+                                               <key>Frame</key>
+                                               <string>{{0, 0}, {203, 355}}</string>
+                                               <key>GroupTreeTableConfiguration</key>
+                                               <array>
+                                                       <string>MainColumn</string>
+                                                       <real>186</real>
+                                               </array>
+                                               <key>RubberWindowFrame</key>
+                                               <string>373 269 690 397 0 0 1440 878 </string>
+                                       </dict>
+                                       <key>Module</key>
+                                       <string>PBXSmartGroupTreeModule</string>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Morph</string>
+                       <key>PreferredWidth</key>
+                       <integer>300</integer>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCModuleDock</string>
+                               <string>PBXSmartGroupTreeModule</string>
+                       </array>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>11E0B1FE06471DED0097A5F4</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.default.shortV3</string>
+               </dict>
+       </array>
+       <key>PerspectivesBarVisible</key>
+       <false/>
+       <key>ShelfIsVisible</key>
+       <false/>
+       <key>SourceDescription</key>
+       <string>file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+       <key>StatusbarIsVisible</key>
+       <true/>
+       <key>TimeStamp</key>
+       <real>249059197.57768601</real>
+       <key>ToolbarDisplayMode</key>
+       <integer>1</integer>
+       <key>ToolbarIsVisible</key>
+       <true/>
+       <key>ToolbarSizeMode</key>
+       <integer>1</integer>
+       <key>Type</key>
+       <string>Perspectives</string>
+       <key>UpdateMessage</key>
+       <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature).  You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature.  Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+       <key>WindowJustification</key>
+       <integer>5</integer>
+       <key>WindowOrderList</key>
+       <array>
+               <string>B0C888290ED85791000E19FB</string>
+               <string>/Users/mrubinsk/cocoa_projects/iPhoto2Ansel2/iPhoto2Ansel.xcodeproj</string>
+       </array>
+       <key>WindowString</key>
+       <string>64 480 614 689 0 0 1920 1178 </string>
+       <key>WindowToolsV3</key>
+       <array>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.build</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528F0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>&lt;No Editor&gt;</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CD052900623707200166675</string>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <integer>1</integer>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {500, 215}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>192 257 500 500 0 0 1280 1002 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>218pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <integer>1</integer>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>XCMainBuildResultsModuleGUID</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Build</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 222}, {500, 236}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>192 257 500 500 0 0 1280 1002 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBuildResultsModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>236pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>458pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Build Results</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBuildResultsModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>1</integer>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C78EAA5065D492600B07095</string>
+                               <string>1C78EAA6065D492600B07095</string>
+                               <string>1CD0528F0623707200166675</string>
+                               <string>XCMainBuildResultsModuleGUID</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.buildV3</string>
+                       <key>WindowString</key>
+                       <string>192 257 500 500 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.debugger</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>Debugger</key>
+                                                               <dict>
+                                                                       <key>HorizontalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {317, 164}}</string>
+                                                                                       <string>{{317, 0}, {377, 164}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>VerticalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {694, 164}}</string>
+                                                                                       <string>{{0, 164}, {694, 216}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                               </dict>
+                                                               <key>LauncherConfigVersion</key>
+                                                               <string>8</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C162984064C10D400B95A72</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debug - GLUTExamples (Underwater)</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>DebugConsoleDrawerSize</key>
+                                                               <string>{100, 120}</string>
+                                                               <key>DebugConsoleVisible</key>
+                                                               <string>None</string>
+                                                               <key>DebugConsoleWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>DebugSTDIOWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {694, 380}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>321 238 694 422 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugSessionModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugSessionModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>1</integer>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1CD10A99069EF8BA00B06720</string>
+                               <string>1C0AD2AB069F1E9B00FABCE6</string>
+                               <string>1C162984064C10D400B95A72</string>
+                               <string>1C0AD2AC069F1E9B00FABCE6</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.debugV3</string>
+                       <key>WindowString</key>
+                       <string>321 238 694 422 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1CD10A99069EF8BA00B06720</string>
+                       <key>WindowToolIsVisible</key>
+                       <integer>0</integer>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.find</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Dock</key>
+                                                       <array>
+                                                               <dict>
+                                                                       <key>ContentConfiguration</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CDD528C0622207200134675</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>&lt;No Editor&gt;</string>
+                                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                                               <dict>
+                                                                                       <key>Split0</key>
+                                                                                       <dict>
+                                                                                               <key>PBXProjectModuleGUID</key>
+                                                                                               <string>1CD0528D0623707200166675</string>
+                                                                                       </dict>
+                                                                                       <key>SplitCount</key>
+                                                                                       <string>1</string>
+                                                                               </dict>
+                                                                               <key>StatusBarVisibility</key>
+                                                                               <integer>1</integer>
+                                                                       </dict>
+                                                                       <key>GeometryConfiguration</key>
+                                                                       <dict>
+                                                                               <key>Frame</key>
+                                                                               <string>{{0, 0}, {781, 167}}</string>
+                                                                               <key>RubberWindowFrame</key>
+                                                                               <string>62 385 781 470 0 0 1440 878 </string>
+                                                                       </dict>
+                                                                       <key>Module</key>
+                                                                       <string>PBXNavigatorGroup</string>
+                                                                       <key>Proportion</key>
+                                                                       <string>781pt</string>
+                                                               </dict>
+                                                       </array>
+                                                       <key>Proportion</key>
+                                                       <string>50%</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <integer>1</integer>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528E0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Project Find</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{8, 0}, {773, 254}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>62 385 781 470 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXProjectFindModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>50%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>428pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project Find</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXProjectFindModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>1</integer>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C530D57069F1CE1000CFCEE</string>
+                               <string>1C530D58069F1CE1000CFCEE</string>
+                               <string>1C530D59069F1CE1000CFCEE</string>
+                               <string>1CDD528C0622207200134675</string>
+                               <string>1C530D5A069F1CE1000CFCEE</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>1CD0528E0623707200166675</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>62 385 781 470 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C530D57069F1CE1000CFCEE</string>
+                       <key>WindowToolIsVisible</key>
+                       <integer>0</integer>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>MENUSEPARATOR</string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.debuggerConsole</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <integer>1</integer>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAAC065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debugger Console</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {650, 250}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>516 632 650 250 0 0 1680 1027 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugCLIModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>209pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>209pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger Console</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugCLIModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>1</integer>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C78EAAD065D492600B07095</string>
+                               <string>1C78EAAE065D492600B07095</string>
+                               <string>1C78EAAC065D492600B07095</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.consoleV3</string>
+                       <key>WindowString</key>
+                       <string>650 41 650 250 0 0 1280 1002 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C78EAAD065D492600B07095</string>
+                       <key>WindowToolIsVisible</key>
+                       <integer>0</integer>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.snapshots</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>XCSnapshotModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Snapshots</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCSnapshotModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <string>Yes</string>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.snapshots</string>
+                       <key>WindowString</key>
+                       <string>315 824 300 550 0 0 1440 878 </string>
+                       <key>WindowToolIsVisible</key>
+                       <string>Yes</string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.scm</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAB2065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>&lt;No Editor&gt;</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1C78EAB3065D492600B07095</string>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <integer>1</integer>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {452, 0}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>743 379 452 308 0 0 1280 1002 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>0pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <integer>1</integer>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD052920623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>SCM</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>ConsoleFrame</key>
+                                                               <string>{{0, 259}, {452, 0}}</string>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 7}, {452, 259}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>743 379 452 308 0 0 1280 1002 </string>
+                                                               <key>TableConfiguration</key>
+                                                               <array>
+                                                                       <string>Status</string>
+                                                                       <real>30</real>
+                                                                       <string>FileName</string>
+                                                                       <real>199</real>
+                                                                       <string>Path</string>
+                                                                       <real>197.0950012207031</real>
+                                                               </array>
+                                                               <key>TableFrame</key>
+                                                               <string>{{0, 0}, {452, 250}}</string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXCVSModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>262pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>266pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>SCM</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXCVSModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>1</integer>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C78EAB4065D492600B07095</string>
+                               <string>1C78EAB5065D492600B07095</string>
+                               <string>1C78EAB2065D492600B07095</string>
+                               <string>1CD052920623707200166675</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.scm</string>
+                       <key>WindowString</key>
+                       <string>743 379 452 308 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.breakpoints</string>
+                       <key>IsVertical</key>
+                       <integer>0</integer>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <integer>1</integer>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXBottomSmartGroupGIDs</key>
+                                                               <array>
+                                                                       <string>1C77FABC04509CD000000102</string>
+                                                               </array>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B1FE06471DED0097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Files</string>
+                                                               <key>PBXProjectStructureProvided</key>
+                                                               <string>no</string>
+                                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                                               <dict>
+                                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                                       <array>
+                                                                               <real>168</real>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                                       <array>
+                                                                               <string>MainColumn</string>
+                                                                       </array>
+                                                               </dict>
+                                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                                               <dict>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                                       <array>
+                                                                               <string>1C77FABC04509CD000000102</string>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                                       <array>
+                                                                               <array>
+                                                                                       <integer>0</integer>
+                                                                               </array>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                                       <string>{{0, 0}, {168, 350}}</string>
+                                                               </dict>
+                                                               <key>PBXTopSmartGroupGIDs</key>
+                                                               <array/>
+                                                               <key>XCIncludePerspectivesSwitch</key>
+                                                               <integer>0</integer>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {185, 368}}</string>
+                                                               <key>GroupTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>MainColumn</string>
+                                                                       <real>168</real>
+                                                               </array>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>315 424 744 409 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXSmartGroupTreeModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>185pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CA1AED706398EBD00589147</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Detail</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{190, 0}, {554, 368}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>315 424 744 409 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCDetailModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>554pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>368pt</string>
+                               </dict>
+                       </array>
+                       <key>MajorVersion</key>
+                       <integer>3</integer>
+                       <key>MinorVersion</key>
+                       <integer>0</integer>
+                       <key>Name</key>
+                       <string>Breakpoints</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXSmartGroupTreeModule</string>
+                               <string>XCDetailModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>1</integer>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1CDDB66807F98D9800BB5817</string>
+                               <string>1CDDB66907F98D9800BB5817</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>1CA1AED706398EBD00589147</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.breakpointsV3</string>
+                       <key>WindowString</key>
+                       <string>315 424 744 409 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1CDDB66807F98D9800BB5817</string>
+                       <key>WindowToolIsVisible</key>
+                       <integer>1</integer>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.debugAnimator</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debug Visualizer</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXNavigatorGroup</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>1</integer>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.debugAnimatorV3</string>
+                       <key>WindowString</key>
+                       <string>100 100 700 500 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.bookmarks</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBookmarksModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Bookmarks</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBookmarksModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>0</integer>
+                       <key>WindowString</key>
+                       <string>538 42 401 187 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.projectFormatConflicts</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>XCProjectFormatConflictsModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project Format Conflicts</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCProjectFormatConflictsModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>0</integer>
+                       <key>WindowContentMinSize</key>
+                       <string>450 300</string>
+                       <key>WindowString</key>
+                       <string>50 850 472 307 0 0 1440 877</string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.classBrowser</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <integer>1</integer>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>OptionsSetName</key>
+                                                               <string>Hierarchy, all classes</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CA6456E063B45B4001379D8</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Class Browser - NSObject</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>ClassesFrame</key>
+                                                               <string>{{0, 0}, {374, 96}}</string>
+                                                               <key>ClassesTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXClassNameColumnIdentifier</string>
+                                                                       <real>208</real>
+                                                                       <string>PBXClassBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {630, 331}}</string>
+                                                               <key>MembersFrame</key>
+                                                               <string>{{0, 105}, {374, 395}}</string>
+                                                               <key>MembersTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXMemberTypeIconColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                                       <string>PBXMemberNameColumnIdentifier</string>
+                                                                       <real>216</real>
+                                                                       <string>PBXMemberTypeColumnIdentifier</string>
+                                                                       <real>97</real>
+                                                                       <string>PBXMemberBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>PBXModuleWindowStatusBarHidden2</key>
+                                                               <integer>1</integer>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>385 179 630 352 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXClassBrowserModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>332pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>332pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXClassBrowserModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>0</integer>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C0AD2AF069F1E9B00FABCE6</string>
+                               <string>1C0AD2B0069F1E9B00FABCE6</string>
+                               <string>1CA6456E063B45B4001379D8</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.classbrowser</string>
+                       <key>WindowString</key>
+                       <string>385 179 630 352 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C0AD2AF069F1E9B00FABCE6</string>
+                       <key>WindowToolIsVisible</key>
+                       <integer>0</integer>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.refactoring</string>
+                       <key>IncludeInToolsMenu</key>
+                       <integer>0</integer>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <integer>1</integer>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{0, 0}, {500, 335}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>{0, 0}, {500, 335}</string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCRefactoringModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Refactoring</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCRefactoringModule</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>200 200 500 356 0 0 1920 1200 </string>
+               </dict>
+       </array>
+</dict>
+</plist>
diff --git a/iPhoto2Ansel/iPhoto2Ansel.xcodeproj/project.pbxproj b/iPhoto2Ansel/iPhoto2Ansel.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..05661f8
--- /dev/null
@@ -0,0 +1,610 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 44;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
+               8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+               B06C1E030EB1644600BFAFCB /* AnselExportPluginBox.m in Sources */ = {isa = PBXBuildFile; fileRef = B06C1E020EB1644600BFAFCB /* AnselExportPluginBox.m */; };
+               B06C1E060EB164D900BFAFCB /* AnselExportController.m in Sources */ = {isa = PBXBuildFile; fileRef = B06C1E050EB164D900BFAFCB /* AnselExportController.m */; };
+               B06C1E3D0EB17E3700BFAFCB /* Panel.nib in Resources */ = {isa = PBXBuildFile; fileRef = B06C1E3C0EB17E3700BFAFCB /* Panel.nib */; };
+               B07D42700EC230B100B59765 /* TURAnsel.m in Sources */ = {isa = PBXBuildFile; fileRef = B07D426D0EC230B100B59765 /* TURAnsel.m */; };
+               B07D42710EC230B100B59765 /* TURAnselGallery.m in Sources */ = {isa = PBXBuildFile; fileRef = B07D426F0EC230B100B59765 /* TURAnselGallery.m */; };
+               B07D44F70EC2AEC700B59765 /* TURXMLConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = B07D44F60EC2AEC700B59765 /* TURXMLConnection.m */; };
+               B0BFBC780ED5B2AB006581A5 /* XMLRPC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0BFBC700ED5B221006581A5 /* XMLRPC.framework */; };
+               B0BFBC7B0ED5B2B2006581A5 /* XMLRPC.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = B0BFBC700ED5B221006581A5 /* XMLRPC.framework */; };
+               B0BFBC970ED5B32B006581A5 /* NSDataAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC810ED5B32B006581A5 /* NSDataAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBC980ED5B32B006581A5 /* NSDataAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC820ED5B32B006581A5 /* NSDataAdditions.m */; };
+               B0BFBC990ED5B32B006581A5 /* NSStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC830ED5B32B006581A5 /* NSStringAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBC9A0ED5B32B006581A5 /* NSStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC840ED5B32B006581A5 /* NSStringAdditions.m */; };
+               B0BFBC9C0ED5B32B006581A5 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B0BFBC870ED5B32B006581A5 /* Localizable.strings */; };
+               B0BFBC9D0ED5B32B006581A5 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = B0BFBC890ED5B32B006581A5 /* LICENSE */; };
+               B0BFBC9E0ED5B32B006581A5 /* README in Resources */ = {isa = PBXBuildFile; fileRef = B0BFBC8A0ED5B32B006581A5 /* README */; };
+               B0BFBC9F0ED5B32B006581A5 /* XMLRPC.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC8B0ED5B32B006581A5 /* XMLRPC.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBCA00ED5B32B006581A5 /* XMLRPC.pch in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC8C0ED5B32B006581A5 /* XMLRPC.pch */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBCA10ED5B32B006581A5 /* XMLRPCConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC8D0ED5B32B006581A5 /* XMLRPCConnection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBCA20ED5B32B006581A5 /* XMLRPCConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC8E0ED5B32B006581A5 /* XMLRPCConnection.m */; };
+               B0BFBCA30ED5B32B006581A5 /* XMLRPCDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC8F0ED5B32B006581A5 /* XMLRPCDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBCA40ED5B32B006581A5 /* XMLRPCDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC900ED5B32B006581A5 /* XMLRPCDecoder.m */; };
+               B0BFBCA50ED5B32B006581A5 /* XMLRPCEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC910ED5B32B006581A5 /* XMLRPCEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBCA60ED5B32B006581A5 /* XMLRPCEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC920ED5B32B006581A5 /* XMLRPCEncoder.m */; };
+               B0BFBCA70ED5B32B006581A5 /* XMLRPCRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC930ED5B32B006581A5 /* XMLRPCRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBCA80ED5B32B006581A5 /* XMLRPCRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC940ED5B32B006581A5 /* XMLRPCRequest.m */; };
+               B0BFBCA90ED5B32B006581A5 /* XMLRPCResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = B0BFBC950ED5B32B006581A5 /* XMLRPCResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               B0BFBCAA0ED5B32B006581A5 /* XMLRPCResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC960ED5B32B006581A5 /* XMLRPCResponse.m */; };
+               B0C888490ED85DEA000E19FB /* ProgressSheet.nib in Resources */ = {isa = PBXBuildFile; fileRef = B0C888480ED85DEA000E19FB /* ProgressSheet.nib */; };
+               B0C8884E0ED85E02000E19FB /* FBProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C8884D0ED85E02000E19FB /* FBProgressController.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+               B0BFBCBF0ED5B440006581A5 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = B0BFBC6F0ED5B221006581A5;
+                       remoteInfo = XMLRPC;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+               B0BFBC7E0ED5B2D3006581A5 /* CopyFiles */ = {
+                       isa = PBXCopyFilesBuildPhase;
+                       buildActionMask = 2147483647;
+                       dstPath = "";
+                       dstSubfolderSpec = 10;
+                       files = (
+                               B0BFBC7B0ED5B2B2006581A5 /* XMLRPC.framework in CopyFiles */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+               089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+               089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+               1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+               32DBCF630370AF2F00C91783 /* iPhoto2Ansel_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoto2Ansel_Prefix.pch; sourceTree = "<group>"; };
+               8D5B49B6048680CD000E48DA /* iPhoto2Ansel.iPhotoExporter */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iPhoto2Ansel.iPhotoExporter; sourceTree = BUILT_PRODUCTS_DIR; };
+               8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+               B03D3B590ED5BB3800CF5B92 /* XMLRPC-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "XMLRPC-Info.plist"; sourceTree = SOURCE_ROOT; };
+               B06C1E010EB1644600BFAFCB /* AnselExportPluginBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnselExportPluginBox.h; sourceTree = "<group>"; };
+               B06C1E020EB1644600BFAFCB /* AnselExportPluginBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnselExportPluginBox.m; sourceTree = "<group>"; };
+               B06C1E040EB164D900BFAFCB /* AnselExportController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnselExportController.h; sourceTree = "<group>"; };
+               B06C1E050EB164D900BFAFCB /* AnselExportController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnselExportController.m; sourceTree = "<group>"; };
+               B06C1E070EB1652100BFAFCB /* ExportPluginProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExportPluginProtocol.h; sourceTree = "<group>"; };
+               B06C1E080EB1652100BFAFCB /* ExportPluginBoxProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExportPluginBoxProtocol.h; sourceTree = "<group>"; };
+               B06C1E090EB1652100BFAFCB /* ExportImageProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExportImageProtocol.h; sourceTree = "<group>"; };
+               B06C1E3C0EB17E3700BFAFCB /* Panel.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = Panel.nib; path = English.lproj/Panel.nib; sourceTree = "<group>"; };
+               B07D426C0EC230B100B59765 /* TURAnsel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TURAnsel.h; sourceTree = "<group>"; };
+               B07D426D0EC230B100B59765 /* TURAnsel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TURAnsel.m; sourceTree = "<group>"; };
+               B07D426E0EC230B100B59765 /* TURAnselGallery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TURAnselGallery.h; sourceTree = "<group>"; };
+               B07D426F0EC230B100B59765 /* TURAnselGallery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TURAnselGallery.m; sourceTree = "<group>"; };
+               B07D44F50EC2AEC700B59765 /* TURXMLConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TURXMLConnection.h; sourceTree = "<group>"; };
+               B07D44F60EC2AEC700B59765 /* TURXMLConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TURXMLConnection.m; sourceTree = "<group>"; };
+               B0BFBC700ED5B221006581A5 /* XMLRPC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XMLRPC.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               B0BFBC810ED5B32B006581A5 /* NSDataAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSDataAdditions.h; sourceTree = "<group>"; };
+               B0BFBC820ED5B32B006581A5 /* NSDataAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDataAdditions.m; sourceTree = "<group>"; };
+               B0BFBC830ED5B32B006581A5 /* NSStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSStringAdditions.h; sourceTree = "<group>"; };
+               B0BFBC840ED5B32B006581A5 /* NSStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSStringAdditions.m; sourceTree = "<group>"; };
+               B0BFBC880ED5B32B006581A5 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = "<group>"; };
+               B0BFBC890ED5B32B006581A5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
+               B0BFBC8A0ED5B32B006581A5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+               B0BFBC8B0ED5B32B006581A5 /* XMLRPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPC.h; sourceTree = "<group>"; };
+               B0BFBC8C0ED5B32B006581A5 /* XMLRPC.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPC.pch; sourceTree = "<group>"; };
+               B0BFBC8D0ED5B32B006581A5 /* XMLRPCConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCConnection.h; sourceTree = "<group>"; };
+               B0BFBC8E0ED5B32B006581A5 /* XMLRPCConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCConnection.m; sourceTree = "<group>"; };
+               B0BFBC8F0ED5B32B006581A5 /* XMLRPCDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCDecoder.h; sourceTree = "<group>"; };
+               B0BFBC900ED5B32B006581A5 /* XMLRPCDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCDecoder.m; sourceTree = "<group>"; };
+               B0BFBC910ED5B32B006581A5 /* XMLRPCEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCEncoder.h; sourceTree = "<group>"; };
+               B0BFBC920ED5B32B006581A5 /* XMLRPCEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCEncoder.m; sourceTree = "<group>"; };
+               B0BFBC930ED5B32B006581A5 /* XMLRPCRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCRequest.h; sourceTree = "<group>"; };
+               B0BFBC940ED5B32B006581A5 /* XMLRPCRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCRequest.m; sourceTree = "<group>"; };
+               B0BFBC950ED5B32B006581A5 /* XMLRPCResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLRPCResponse.h; sourceTree = "<group>"; };
+               B0BFBC960ED5B32B006581A5 /* XMLRPCResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLRPCResponse.m; sourceTree = "<group>"; };
+               B0C888480ED85DEA000E19FB /* ProgressSheet.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = ProgressSheet.nib; sourceTree = "<group>"; };
+               B0C8884C0ED85E02000E19FB /* FBProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBProgressController.h; sourceTree = "<group>"; };
+               B0C8884D0ED85E02000E19FB /* FBProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBProgressController.m; sourceTree = "<group>"; };
+               D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               8D5B49B3048680CD000E48DA /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               B0BFBC780ED5B2AB006581A5 /* XMLRPC.framework in Frameworks */,
+                               8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               B0BFBC6E0ED5B221006581A5 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               089C166AFE841209C02AAC07 /* iPhoto2Ansel */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B00076DE0EBA573900A95FC0 /* AnselToolkit */,
+                               B00076D20EBA568800A95FC0 /* SDK Headers */,
+                               08FB77AFFE84173DC02AAC07 /* ExportPlugin */,
+                               32C88E010371C26100C91783 /* Other Sources */,
+                               089C167CFE841241C02AAC07 /* Resources */,
+                               089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
+                               19C28FB8FE9D52D311CA2CBB /* Products */,
+                       );
+                       name = iPhoto2Ansel;
+                       sourceTree = "<group>";
+               };
+               089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B0BFBC7F0ED5B32B006581A5 /* xmlrpc-1.5.1 */,
+                               1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
+                               1058C7AEFEA557BF11CA2CBB /* Other Frameworks */,
+                       );
+                       name = "Frameworks and Libraries";
+                       sourceTree = "<group>";
+               };
+               089C167CFE841241C02AAC07 /* Resources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B0C888480ED85DEA000E19FB /* ProgressSheet.nib */,
+                               B06C1E3C0EB17E3700BFAFCB /* Panel.nib */,
+                               8D5B49B7048680CD000E48DA /* Info.plist */,
+                               089C167DFE841241C02AAC07 /* InfoPlist.strings */,
+                       );
+                       name = Resources;
+                       sourceTree = "<group>";
+               };
+               08FB77AFFE84173DC02AAC07 /* ExportPlugin */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B06C1E020EB1644600BFAFCB /* AnselExportPluginBox.m */,
+                               B06C1E010EB1644600BFAFCB /* AnselExportPluginBox.h */,
+                               B06C1E040EB164D900BFAFCB /* AnselExportController.h */,
+                               B06C1E050EB164D900BFAFCB /* AnselExportController.m */,
+                       );
+                       name = ExportPlugin;
+                       sourceTree = "<group>";
+               };
+               1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
+                       );
+                       name = "Linked Frameworks";
+                       sourceTree = "<group>";
+               };
+               1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               089C167FFE841241C02AAC07 /* AppKit.framework */,
+                               D2F7E65807B2D6F200F64583 /* CoreData.framework */,
+                               089C1672FE841209C02AAC07 /* Foundation.framework */,
+                       );
+                       name = "Other Frameworks";
+                       sourceTree = "<group>";
+               };
+               19C28FB8FE9D52D311CA2CBB /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               8D5B49B6048680CD000E48DA /* iPhoto2Ansel.iPhotoExporter */,
+                               B0BFBC700ED5B221006581A5 /* XMLRPC.framework */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               32C88E010371C26100C91783 /* Other Sources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B0C8884D0ED85E02000E19FB /* FBProgressController.m */,
+                               B0C8884C0ED85E02000E19FB /* FBProgressController.h */,
+                               B07D44F50EC2AEC700B59765 /* TURXMLConnection.h */,
+                               B07D44F60EC2AEC700B59765 /* TURXMLConnection.m */,
+                               32DBCF630370AF2F00C91783 /* iPhoto2Ansel_Prefix.pch */,
+                       );
+                       name = "Other Sources";
+                       sourceTree = "<group>";
+               };
+               B00076D20EBA568800A95FC0 /* SDK Headers */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B06C1E070EB1652100BFAFCB /* ExportPluginProtocol.h */,
+                               B06C1E080EB1652100BFAFCB /* ExportPluginBoxProtocol.h */,
+                               B06C1E090EB1652100BFAFCB /* ExportImageProtocol.h */,
+                       );
+                       name = "SDK Headers";
+                       sourceTree = "<group>";
+               };
+               B00076DE0EBA573900A95FC0 /* AnselToolkit */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B07D426C0EC230B100B59765 /* TURAnsel.h */,
+                               B07D426D0EC230B100B59765 /* TURAnsel.m */,
+                               B07D426E0EC230B100B59765 /* TURAnselGallery.h */,
+                               B07D426F0EC230B100B59765 /* TURAnselGallery.m */,
+                       );
+                       name = AnselToolkit;
+                       sourceTree = "<group>";
+               };
+               B0BFBC7F0ED5B32B006581A5 /* xmlrpc-1.5.1 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B03D3B590ED5BB3800CF5B92 /* XMLRPC-Info.plist */,
+                               B0BFBC800ED5B32B006581A5 /* Additions */,
+                               B0BFBC860ED5B32B006581A5 /* Languages */,
+                               B0BFBC890ED5B32B006581A5 /* LICENSE */,
+                               B0BFBC8A0ED5B32B006581A5 /* README */,
+                               B0BFBC8B0ED5B32B006581A5 /* XMLRPC.h */,
+                               B0BFBC8C0ED5B32B006581A5 /* XMLRPC.pch */,
+                               B0BFBC8D0ED5B32B006581A5 /* XMLRPCConnection.h */,
+                               B0BFBC8E0ED5B32B006581A5 /* XMLRPCConnection.m */,
+                               B0BFBC8F0ED5B32B006581A5 /* XMLRPCDecoder.h */,
+                               B0BFBC900ED5B32B006581A5 /* XMLRPCDecoder.m */,
+                               B0BFBC910ED5B32B006581A5 /* XMLRPCEncoder.h */,
+                               B0BFBC920ED5B32B006581A5 /* XMLRPCEncoder.m */,
+                               B0BFBC930ED5B32B006581A5 /* XMLRPCRequest.h */,
+                               B0BFBC940ED5B32B006581A5 /* XMLRPCRequest.m */,
+                               B0BFBC950ED5B32B006581A5 /* XMLRPCResponse.h */,
+                               B0BFBC960ED5B32B006581A5 /* XMLRPCResponse.m */,
+                       );
+                       path = "xmlrpc-1.5.1";
+                       sourceTree = "<group>";
+               };
+               B0BFBC800ED5B32B006581A5 /* Additions */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B0BFBC810ED5B32B006581A5 /* NSDataAdditions.h */,
+                               B0BFBC820ED5B32B006581A5 /* NSDataAdditions.m */,
+                               B0BFBC830ED5B32B006581A5 /* NSStringAdditions.h */,
+                               B0BFBC840ED5B32B006581A5 /* NSStringAdditions.m */,
+                       );
+                       path = Additions;
+                       sourceTree = "<group>";
+               };
+               B0BFBC860ED5B32B006581A5 /* Languages */ = {
+                       isa = PBXGroup;
+                       children = (
+                               B0BFBC870ED5B32B006581A5 /* Localizable.strings */,
+                       );
+                       path = Languages;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               B0BFBC6B0ED5B221006581A5 /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               B0BFBC970ED5B32B006581A5 /* NSDataAdditions.h in Headers */,
+                               B0BFBC990ED5B32B006581A5 /* NSStringAdditions.h in Headers */,
+                               B0BFBC9F0ED5B32B006581A5 /* XMLRPC.h in Headers */,
+                               B0BFBCA00ED5B32B006581A5 /* XMLRPC.pch in Headers */,
+                               B0BFBCA10ED5B32B006581A5 /* XMLRPCConnection.h in Headers */,
+                               B0BFBCA30ED5B32B006581A5 /* XMLRPCDecoder.h in Headers */,
+                               B0BFBCA50ED5B32B006581A5 /* XMLRPCEncoder.h in Headers */,
+                               B0BFBCA70ED5B32B006581A5 /* XMLRPCRequest.h in Headers */,
+                               B0BFBCA90ED5B32B006581A5 /* XMLRPCResponse.h in Headers */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               8D5B49AC048680CD000E48DA /* iPhoto2Ansel */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "iPhoto2Ansel" */;
+                       buildPhases = (
+                               8D5B49AF048680CD000E48DA /* Resources */,
+                               8D5B49B1048680CD000E48DA /* Sources */,
+                               8D5B49B3048680CD000E48DA /* Frameworks */,
+                               B0BFBC7E0ED5B2D3006581A5 /* CopyFiles */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               B0BFBCC00ED5B440006581A5 /* PBXTargetDependency */,
+                       );
+                       name = iPhoto2Ansel;
+                       productInstallPath = "$(HOME)/Library/Bundles";
+                       productName = iPhoto2Ansel;
+                       productReference = 8D5B49B6048680CD000E48DA /* iPhoto2Ansel.iPhotoExporter */;
+                       productType = "com.apple.product-type.bundle";
+               };
+               B0BFBC6F0ED5B221006581A5 /* XMLRPC */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = B0BFBC750ED5B221006581A5 /* Build configuration list for PBXNativeTarget "XMLRPC" */;
+                       buildPhases = (
+                               B0BFBC6B0ED5B221006581A5 /* Headers */,
+                               B0BFBC6C0ED5B221006581A5 /* Resources */,
+                               B0BFBC6D0ED5B221006581A5 /* Sources */,
+                               B0BFBC6E0ED5B221006581A5 /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = XMLRPC;
+                       productName = XMLRPC;
+                       productReference = B0BFBC700ED5B221006581A5 /* XMLRPC.framework */;
+                       productType = "com.apple.product-type.framework";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               089C1669FE841209C02AAC07 /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "iPhoto2Ansel" */;
+                       compatibilityVersion = "Xcode 3.0";
+                       hasScannedForEncodings = 1;
+                       mainGroup = 089C166AFE841209C02AAC07 /* iPhoto2Ansel */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               8D5B49AC048680CD000E48DA /* iPhoto2Ansel */,
+                               B0BFBC6F0ED5B221006581A5 /* XMLRPC */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+               8D5B49AF048680CD000E48DA /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
+                               B06C1E3D0EB17E3700BFAFCB /* Panel.nib in Resources */,
+                               B0C888490ED85DEA000E19FB /* ProgressSheet.nib in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               B0BFBC6C0ED5B221006581A5 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               B0BFBC9C0ED5B32B006581A5 /* Localizable.strings in Resources */,
+                               B0BFBC9D0ED5B32B006581A5 /* LICENSE in Resources */,
+                               B0BFBC9E0ED5B32B006581A5 /* README in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               8D5B49B1048680CD000E48DA /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               B06C1E030EB1644600BFAFCB /* AnselExportPluginBox.m in Sources */,
+                               B06C1E060EB164D900BFAFCB /* AnselExportController.m in Sources */,
+                               B07D42700EC230B100B59765 /* TURAnsel.m in Sources */,
+                               B07D42710EC230B100B59765 /* TURAnselGallery.m in Sources */,
+                               B07D44F70EC2AEC700B59765 /* TURXMLConnection.m in Sources */,
+                               B0C8884E0ED85E02000E19FB /* FBProgressController.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               B0BFBC6D0ED5B221006581A5 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               B0BFBC980ED5B32B006581A5 /* NSDataAdditions.m in Sources */,
+                               B0BFBC9A0ED5B32B006581A5 /* NSStringAdditions.m in Sources */,
+                               B0BFBCA20ED5B32B006581A5 /* XMLRPCConnection.m in Sources */,
+                               B0BFBCA40ED5B32B006581A5 /* XMLRPCDecoder.m in Sources */,
+                               B0BFBCA60ED5B32B006581A5 /* XMLRPCEncoder.m in Sources */,
+                               B0BFBCA80ED5B32B006581A5 /* XMLRPCRequest.m in Sources */,
+                               B0BFBCAA0ED5B32B006581A5 /* XMLRPCResponse.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               B0BFBCC00ED5B440006581A5 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = B0BFBC6F0ED5B221006581A5 /* XMLRPC */;
+                       targetProxy = B0BFBCBF0ED5B440006581A5 /* PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+               089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               089C167EFE841241C02AAC07 /* English */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+               B0BFBC870ED5B32B006581A5 /* Localizable.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               B0BFBC880ED5B32B006581A5 /* English */,
+                       );
+                       name = Localizable.strings;
+                       sourceTree = "<group>";
+               };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+               1DEB913B08733D840010E9CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               DEPLOYMENT_LOCATION = YES;
+                               DSTROOT = /;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "$(inherited)",
+                                       "\"$(SRCROOT)\"",
+                                       "$(INSTALL_PATH)/$(PRODUCT_NAME).iPhotoExporter",
+                               );
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = iPhoto2Ansel_Prefix.pch;
+                               INFOPLIST_FILE = Info.plist;
+                               INSTALL_PATH = "$(HOME)/Library/Application Support/iPhoto/Plugins";
+                               PRODUCT_NAME = iPhoto2Ansel;
+                               WRAPPER_EXTENSION = iPhotoExporter;
+                               ZERO_LINK = YES;
+                       };
+                       name = Debug;
+               };
+               1DEB913C08733D840010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               DEPLOYMENT_LOCATION = YES;
+                               FRAMEWORK_SEARCH_PATHS = (
+                                       "\"$(SRCROOT)/XMLRPC\"",
+                                       "$(inherited)",
+                                       "\"$(SRCROOT)\"",
+                               );
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = iPhoto2Ansel_Prefix.pch;
+                               INFOPLIST_FILE = Info.plist;
+                               INSTALL_PATH = "$(HOME)/Library/Application Support/iPhoto/Plugins";
+                               PRODUCT_NAME = iPhoto2Ansel;
+                               WRAPPER_EXTENSION = iPhotoExporter;
+                       };
+                       name = Release;
+               };
+               1DEB913F08733D840010E9CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               DEPLOYMENT_LOCATION = NO;
+                               DSTROOT = "/tmp/$(PROJECT_NAME).dst";
+                               GCC_ENABLE_OBJC_GC = supported;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = "";
+                               PREBINDING = NO;
+                               SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+                       };
+                       name = Debug;
+               };
+               1DEB914008733D840010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = (
+                                       ppc,
+                                       i386,
+                               );
+                               DEPLOYMENT_LOCATION = NO;
+                               DSTROOT = /;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INSTALL_PATH = "";
+                               PREBINDING = NO;
+                               SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
+                       };
+                       name = Release;
+               };
+               B0BFBC730ED5B221006581A5 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               DEPLOYMENT_LOCATION = NO;
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               FRAMEWORK_VERSION = A;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+                               INFOPLIST_FILE = "XMLRPC-Info.plist";
+                               INSTALL_PATH = "@loader_path/../Frameworks";
+                               OTHER_LDFLAGS = (
+                                       "-framework",
+                                       Foundation,
+                                       "-framework",
+                                       AppKit,
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = XMLRPC;
+                               ZERO_LINK = YES;
+                       };
+                       name = Debug;
+               };
+               B0BFBC740ED5B221006581A5 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               DEPLOYMENT_LOCATION = NO;
+                               DSTROOT = "/tmp/$(PROJECT_NAME).dst";
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               FRAMEWORK_VERSION = A;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
+                               GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+                               INFOPLIST_FILE = "XMLRPC-Info.plist";
+                               INSTALL_PATH = "@loader_path/../Frameworks";
+                               OTHER_LDFLAGS = (
+                                       "-framework",
+                                       Foundation,
+                                       "-framework",
+                                       AppKit,
+                               );
+                               PREBINDING = NO;
+                               PRODUCT_NAME = XMLRPC;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "iPhoto2Ansel" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB913B08733D840010E9CD /* Debug */,
+                               1DEB913C08733D840010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "iPhoto2Ansel" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB913F08733D840010E9CD /* Debug */,
+                               1DEB914008733D840010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               B0BFBC750ED5B221006581A5 /* Build configuration list for PBXNativeTarget "XMLRPC" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               B0BFBC730ED5B221006581A5 /* Debug */,
+                               B0BFBC740ED5B221006581A5 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
diff --git a/iPhoto2Ansel/iPhoto2Ansel_Prefix.pch b/iPhoto2Ansel/iPhoto2Ansel_Prefix.pch
new file mode 100644 (file)
index 0000000..23836f4
--- /dev/null
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'iPhoto2Ansel' target in the 'iPhoto2Ansel' project.
+//
+
+#ifdef __OBJC__
+    #import <Cocoa/Cocoa.h>
+#endif
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSDataAdditions.h b/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSDataAdditions.h
new file mode 100644 (file)
index 0000000..c6d3d27
--- /dev/null
@@ -0,0 +1,39 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// NSDataAdditions.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/NSData.h>
+
+@class NSString;
+
+@interface NSData (NSDataAdditions)
+
++ (NSData *)base64DataFromString: (NSString *)string;
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSDataAdditions.m b/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSDataAdditions.m
new file mode 100644 (file)
index 0000000..6665249
--- /dev/null
@@ -0,0 +1,125 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// NSDataAdditions.m
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import "NSDataAdditions.h"
+
+@implementation NSData (NSDataAdditions)
+
++ (NSData *)base64DataFromString: (NSString *)string {
+       unsigned long ixtext, lentext;
+       unsigned char ch, input[4], output[3];
+       short i, ixinput;
+       Boolean flignore, flendtext = false;
+       const char *temporary;
+       NSMutableData *result;
+       
+       if (string == nil) {
+               return [NSData data];
+       }
+       
+       ixtext = 0;
+       
+       temporary = [string UTF8String];
+       
+       lentext = [string length];
+       
+       result = [NSMutableData dataWithCapacity: lentext];
+       
+       ixinput = 0;
+       
+       while (true) {
+               if (ixtext >= lentext) {
+                       break;
+               }
+               
+               ch = temporary[ixtext++];
+               
+               flignore = false;
+               
+               if ((ch >= 'A') && (ch <= 'Z')) {
+                       ch = ch - 'A';
+               } else if ((ch >= 'a') && (ch <= 'z')) {
+                       ch = ch - 'a' + 26;
+               } else if ((ch >= '0') && (ch <= '9')) {
+                       ch = ch - '0' + 52;
+               } else if (ch == '+') {
+                       ch = 62;
+               } else if (ch == '=') {
+                       flendtext = true;
+               } else if (ch == '/') {
+                       ch = 63;
+               } else {
+                       flignore = true; 
+               }
+               
+               if (!flignore) {
+                       short ctcharsinput = 3;
+                       Boolean flbreak = false;
+                       
+                       if (flendtext) {
+                               if (ixinput == 0) {
+                                       break;
+                               }
+                               
+                               if ((ixinput == 1) || (ixinput == 2)) {
+                                       ctcharsinput = 1;
+                               } else {
+                                       ctcharsinput = 2;
+                               }
+                               
+                               ixinput = 3;
+                               
+                               flbreak = true;
+                       }
+                       
+                       input[ixinput++] = ch;
+                       
+                       if (ixinput == 4) {
+                               ixinput = 0;
+                               
+                               output[0] = (input[0] << 2) | ((input[1] & 0x30) >> 4);
+                               output[1] = ((input[1] & 0x0F) << 4) | ((input[2] & 0x3C) >> 2);
+                               output[2] = ((input[2] & 0x03) << 6) | (input[3] & 0x3F);
+                               
+                               for (i = 0; i < ctcharsinput; i++) {
+                                       [result appendBytes: &output[i] length: 1];
+                               }
+                       }
+                       
+                       if (flbreak) {
+                               break;
+                       }
+               }
+       }
+       
+       return result;
+}
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSStringAdditions.h b/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSStringAdditions.h
new file mode 100644 (file)
index 0000000..bebaf61
--- /dev/null
@@ -0,0 +1,39 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// NSStringAdditions.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/NSString.h>
+
+@class NSData;
+
+@interface NSString (NSStringAdditions)
+
++ (NSString *)base64StringFromData: (NSData *)data length: (NSInteger)length;
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSStringAdditions.m b/iPhoto2Ansel/xmlrpc-1.5.1/Additions/NSStringAdditions.m
new file mode 100644 (file)
index 0000000..2fff8df
--- /dev/null
@@ -0,0 +1,119 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// NSStringAdditions.m
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import "NSDataAdditions.h"
+
+/* Base64 Encoding Table */
+static char base64EncodingTable[64] = {
+       'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+       'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+       'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
+
+@implementation NSString (NSStringExtensions)
+
++ (NSString *)base64StringFromData: (NSData *)data length: (NSInteger)length {
+       unsigned long ixtext, lentext;
+       long ctremaining;
+       unsigned char input[3], output[4];
+       short i, charsonline = 0, ctcopy;
+       const unsigned char *raw;
+       NSMutableString *result;
+    
+       lentext = [data length];
+       
+       if (lentext < 1) {
+               return @"";
+       }
+       
+       result = [NSMutableString stringWithCapacity: lentext];
+       
+       raw = [data bytes];
+       
+       ixtext = 0; 
+       
+       while (true) {
+               ctremaining = lentext - ixtext;
+               
+               if (ctremaining <= 0) {
+                       break;
+               }
+               
+               for (i = 0; i < 3; i++) { 
+                       unsigned long ix = ixtext + i;
+                       
+                       if (ix < lentext) {
+                               input[i] = raw[ix];
+                       } else {
+                               input[i] = 0;
+                       }
+               }
+               
+               output[0] = (input[0] & 0xFC) >> 2;
+               output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
+               output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
+               output[3] = input[2] & 0x3F;
+               
+               ctcopy = 4;
+               
+               switch (ctremaining) {
+                       case 1: 
+                               ctcopy = 2; 
+                               break;
+                       case 2: 
+                               ctcopy = 3; 
+                               break;
+               }
+               
+               for (i = 0; i < ctcopy; i++) {
+                       [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
+               }
+               
+               for (i = ctcopy; i < 4; i++) {
+                       [result appendString: @"="];
+               }
+               
+               ixtext += 3;
+               charsonline += 4;
+               
+               if (length > 0) {
+                       if (charsonline >= length) {
+                               charsonline = 0;
+                               
+                               [result appendString: @"\n"];
+                       }
+               }
+       }
+       
+       return result;
+}
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/Info.plist b/iPhoto2Ansel/xmlrpc-1.5.1/Info.plist
new file mode 100644 (file)
index 0000000..84c452a
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+       "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+       <dict>
+               <key>CFBundleDevelopmentRegion</key>
+               <string>English</string>
+               <key>CFBundleExecutable</key>
+               <string>${EXECUTABLE_NAME}</string>
+               <key>CFBundleIconFile</key>
+               <string></string>
+               <key>CFBundleIdentifier</key>
+               <string>com.divisiblebyzero.XMLRPC</string>
+               <key>CFBundleInfoDictionaryVersion</key>
+               <string>6.0</string>
+               <key>CFBundleName</key>
+               <string>${PRODUCT_NAME}</string>
+               <key>CFBundlePackageType</key>
+               <string>FMWK</string>
+               <key>CFBundleSignature</key>
+               <string>ZERO</string>
+               <key>CFBundleVersion</key>
+               <string>1.5.1</string>
+               <key>NSPrincipalClass</key>
+               <string></string>
+       </dict>
+</plist>
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/LICENSE b/iPhoto2Ansel/xmlrpc-1.5.1/LICENSE
new file mode 100644 (file)
index 0000000..d6da8bb
--- /dev/null
@@ -0,0 +1,23 @@
+== License
+
+= The Cocoa XML-RPC Framework is distributed under the MIT License:
+
+Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+
+Permission  is hereby granted, free of charge, to any person obtaining a copy of
+this  software  and  associated documentation files (the "Software"), to deal in
+the  Software  without  restriction,  including without limitation the rights to
+use,  copy,  modify,  merge, publish, distribute, sublicense, and/or sell copies
+of  the  Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The  above  copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO  THE  WARRANTIES  OF MERCHANTABILITY,
+FITNESS  FOR  A  PARTICULAR  PURPOSE  AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY  CLAIM,  DAMAGES  OR OTHER
+LIABILITY,  WHETHER  IN  AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT  OF  OR  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/Languages/English.lproj/Localizable.strings b/iPhoto2Ansel/xmlrpc-1.5.1/Languages/English.lproj/Localizable.strings
new file mode 100644 (file)
index 0000000..afec4bd
--- /dev/null
@@ -0,0 +1,3 @@
+/* ENGLISH */
+
+NSHumanReadableCopyright = "Cocoa XML-RPC Framework © 2008 Divisible by Zero";
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/README b/iPhoto2Ansel/xmlrpc-1.5.1/README
new file mode 100644 (file)
index 0000000..065233c
--- /dev/null
@@ -0,0 +1,208 @@
+== The Cocoa XML-RPC Framework
+
+The  Cocoa  XML-RPC  Framework  is  a  simple,  and  lightweight, XML-RPC client
+framework written in Objective-C.
+
+== Requirements
+
+The  Cocoa  XML-RPC  Framework  has  been  built, and designed, for OS X 10.4 or
+later.  The  framework  relies  on  NSURLConnection  and  NSURLRequest  for HTTP
+transport, and NSXMLDocument for parsing XML-RPC responses.
+
+This version of the framework will not work with the iPhone SDK.
+
+== Usage
+
+The  following  examples of the Cocoa XML-RPC Framework assume that the included
+XML-RPC test server are running. The test server can be found under:
+
+    XMLRPC\Tools\xmlrpc-server
+
+The  XML-RPC  test  server  is  written  in Java and utilizes the Apache XML-RPC
+server  library.  To  start  the  server simply call Ant from the same directory
+where the build.xml file is located:
+
+    ant <target>
+
+The  target  is  optional,  omitting  this  argument  will  execute  the default
+target (the default target is "run"). The following targets are available:
+
+  - compile
+  - jar
+  - run
+  - clean
+
+More information on the XML-RPC test server can be found below.
+
+= Asynchronous
+
+Making  an  asynchronous XML-RPC request is probably the best way to communicate
+with  an  XML-RPC server. After creating an XMLRPCConnection the XML-RPC request
+is  sent  to  the  XML-RPC  server in the background. This allows the requesting
+application to continue performing other functions.
+
+Sending an asynchronous XML-RPC request is simple:
+
+- (void)sendRequest {
+    NSURL *URL = [NSURL URLWithString: @"http://127.0.0.1/"];
+    XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithHost: URL];
+
+    [request setMethod: @"Echo.echo" withParameter: @"Hello World!"];
+    [request setUserAgent: @"XML-RPC Example"];
+       
+    XMLRPCConnection *connection = [[XMLRPCConnection alloc]
+        initWithXMLRPCRequest: request delegate: self];
+
+    if (connection == nil) {
+        NSLog(@"Connection failed.");
+    }
+}
+
+It  is  important to understand that the caller is responsible for releasing the
+connection  and  response  objects  at  the  end  of the connection response and
+connection  failure  delegate  methods. Do not attempt to release the connection
+object anywhere but within these two delegate methods.
+
+- (void)connection: (XMLRPCConnection *)connection didReceiveResponse:
+        (XMLRPCResponse *)response forMethod: (NSString *)method {
+    if (response != nil) {
+        if ([response isFault]) {
+            NSLog(@"Fault code: %@", [response faultCode]);
+        } else {
+            NSLog(@"Response object: %@", [response responseObject]);
+        }
+
+        NSLog(@"Response source: %@", [response responseSourceXML]);
+    } else {
+        NSLog(@"Unable to parse response.");
+    }
+
+    [response release];
+    [connection release];
+}
+
+= Synchronous
+
+Synchronous  XML-RPC requests may be suitable in some situations. Unlike sending
+an asynchronous request, a synchronous request is made in the foreground causing
+the calling application to await an XML-RPC response.
+
+- (void)sendRequest {
+    NSURL *URL = [NSURL URLWithString: @"http://127.0.0.1/"];
+    XMLRPCRequest *request = [[[XMLRPCRequest alloc] initWithHost: URL]];
+
+    [request setMethod: @"Echo.echo" setParameter: @"Hello World!"];
+    [request setUserAgent: @"XML-RPC Example"];
+
+    XMLRPCResponse *response = [XMLRPCConnection
+        sendSynchronousXMLRPCRequest: request];
+
+    if (response != nil) {
+        if ([response isFault]) {
+            NSLog(@"Fault: %@", [response fault]);
+        } else {
+            NSLog(@"Response object: %@", [response responseObject]);
+        }
+
+        NSLog(@"Response source: %@", [response responseSourceXML]);
+    } else {
+        NSLog(@"Unable to parse response.");
+    }
+
+    [request release];
+    [response release];
+}
+
+A response will always return nil upon creation if it is unable to parse the XML
+data.  However,  in the case of a synchronous request, a nil response can either
+mean  the  response  could  not  be parsed, or the connection failed to send the
+request.
+
+An  asynchronous connection will return nil if it fails to send the request. The
+response   passed   to   the  connection:didReceiveResponse:forMethod:  delegate
+method  will  be  nil if the response object is unable to parse the XML response
+data.
+
+Also  note  that you may have access to the raw XML source to either the request
+and/or  response.  Though you may be able to extract the source from the request
+at  any  moment  in the object's life, it is always best to get the source after
+invoking  the  setMethod:withParameters: or setMethod:withParameter: methods. If
+you  ask  for  the  source  too  early,  you won't receive the fully created XML
+request source.
+
+== Using the XML-RPC test server
+
+The  XML-RPC  test server is a simple Java application that allows developers to
+easily  develop  software with Cocoa XML-RPC Framework. The test server is built
+on top of the Apache XML-RPC library.
+
+Using  the  test  server  is easy, simply call Ant from the same location as the
+build.xml file:
+
+    ant
+
+The default target is the "run" target, which will compile the Java source code,
+build  the  executable JAR file, and run the application. Included with the test
+server  is  a server.sh script, this Bash script will launch the test server (if
+it has already been built with Ant).
+
+= Creating XML-RPC server handlers
+
+The  XML-RPC  test  server  exposes the methods defined in server handlers. Each
+server handler is simply a Java class that is registered with the Apache XML-RPC
+library. Here is an example of the Echo handler provided in the distribution:
+
+    public class Echo {
+        public String echo(String message) {
+            return message;
+        }
+    }
+
+This  handler simply takes a message provided in the XML-RPC request and returns
+it  in  the  XML-RPC  response. To register this handler with the XML-RPC server
+simply add it to the propertyHandlerMapping in Server.java:
+
+    import com.divisiblebyzero.xmlrpc.model.handlers.*;
+
+    ...
+
+    try {
+        propertyHandlerMapping.addHandler("Echo", Echo.class);
+
+        this.embeddedXmlRpcServer.setHandlerMapping(propertyHandlerMapping);
+    } catch (Exception e) {
+        this.controlPanel.addLogMessage(e.getMessage());
+    }
+
+The handler is now available to any incoming XML-RPC requests.
+
+== What if I find a bug, or what if I want to help?
+
+Please, contact me with any questions, comments, suggestions, or problems. I try
+to  make  the  time  to  answer  every  request.  If you find a bug, it would be
+helpful to also provide steps to reproduce the problem.
+
+Those  wishing  to contribute to the project should begin by obtaining a working
+copy of the trunk:
+
+    svn co http://svn.divisiblebyzero.com/xmlrpc/trunk/
+
+The trunk contains the most recent changes to the project. The modifications you
+make  should then be used to create a patch. Patches should be sent to me with a
+detailed description of every change.
+
+== Acknowledgments
+
+The  Base64  encoder/decoder found in NSStringAdditions and NSDataAdditions have
+been adapted from code provided by Dave Winer.
+
+The  idea  for  this framework came from examples provided by Brent Simmons, the
+creator of NetNewsWire.
+
+== License
+
+Copyright (c) 2008 Eric Czarny.
+
+The  Cocoa XML-RPC Framework  should  be  accompanied  by  a  LICENSE file, this
+file  contains  the  license relevant to this distribution. If no LICENSE exists
+please contact Eric Czarny <eczarny@gmail.com>.
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPC.h b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPC.h
new file mode 100644 (file)
index 0000000..09de627
--- /dev/null
@@ -0,0 +1,33 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPC.h
+// 
+// Created by Eric Czarny on Wednesday, February 10, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <XMLRPC/XMLRPCConnection.h>
+#import <XMLRPC/XMLRPCRequest.h>
+#import <XMLRPC/XMLRPCResponse.h>
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPC.pch b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPC.pch
new file mode 100644 (file)
index 0000000..ff9e4cd
--- /dev/null
@@ -0,0 +1,33 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPC.pch
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#ifdef __OBJC__
+       #import <Foundation/Foundation.h>
+#endif
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCConnection.h b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCConnection.h
new file mode 100644 (file)
index 0000000..9c6b94a
--- /dev/null
@@ -0,0 +1,73 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCConnection.h
+// 
+// Created by Eric Czarny on Thursday, January 15, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+#import <Foundation/Foundation.h>
+
+@class XMLRPCRequest, XMLRPCResponse;
+
+/* XML-RPC Connection Notifications */
+extern NSString *XMLRPCSentRequestNotification;
+extern NSString *XMLRPCRequestFailedNotification;
+extern NSString *XMLRPCReceivedAuthenticationChallengeNotification;
+extern NSString *XMLRPCCancelledAuthenticationChallengeNotification;
+extern NSString *XMLRPCReceivedResponseNotification;
+
+@interface XMLRPCConnection : NSObject {
+       NSURLConnection *currentConnection;
+       NSString *currentXMLRPCMethod;
+       NSMutableData *incomingXMLData;
+       id applicationDelegate;
+}
+
+- (id)initWithXMLRPCRequest: (XMLRPCRequest *)request delegate: (id)delegate;
+
+#pragma mark -
+
++ (XMLRPCResponse *)sendSynchronousXMLRPCRequest: (XMLRPCRequest *)request;
+
+#pragma mark -
+
+- (void)cancel;
+
+@end
+
+#pragma mark -
+
+@interface NSObject (XMLRPCConnectionDelegate)
+
+- (void)connection: (XMLRPCConnection *)connection didReceiveResponse: (XMLRPCResponse *)response forMethod: (NSString *)method;
+
+- (void)connection: (XMLRPCConnection *)connection didFailWithError: (NSError *)error forMethod: (NSString *)method;
+
+- (void)connection: (XMLRPCConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge forMethod: (NSString *)method;
+
+- (void)connection: (XMLRPCConnection *)connection didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge forMethod: (NSString *)method;
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCConnection.m b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCConnection.m
new file mode 100644 (file)
index 0000000..e9fb983
--- /dev/null
@@ -0,0 +1,188 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCConnection.m
+// 
+// Created by Eric Czarny on Thursday, January 15, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import "XMLRPCConnection.h"
+#import "XMLRPCRequest.h"
+#import "XMLRPCResponse.h"
+
+NSString *XMLRPCSentRequestNotification = @"XML-RPC Sent Request";
+NSString *XMLRPCRequestFailedNotification = @"XML-RPC Failed Receiving Response";
+NSString *XMLRPCReceivedAuthenticationChallengeNotification = @"XML-RPC Received Authentication Challenge";
+NSString *XMLRPCCancelledAuthenticationChallengeNotification = @"XML-RPC Cancelled Authentication Challenge";
+NSString *XMLRPCReceivedResponseNotification = @"XML-RPC Successfully Received Response";
+
+@interface XMLRPCConnection (XMLRPCConnectionPrivate)
+
+- (void)connection: (NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
+
+- (void)connection: (NSURLConnection *)connection didReceiveData: (NSData *)data;
+
+- (void)connection: (NSURLConnection *)connection didFailWithError: (NSError *)error;
+
+- (void)connection: (NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge;
+
+- (void)connection: (NSURLConnection *)connection didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge;
+
+- (void)connectionDidFinishLoading: (NSURLConnection *)connection;
+
+@end
+
+#pragma mark -
+
+@implementation XMLRPCConnection
+
+- (id)initWithXMLRPCRequest: (XMLRPCRequest *)request delegate: (id)delegate {
+       if (self = [super init]) {
+               incomingXMLData = [[NSMutableData alloc] init];
+               currentConnection = [[NSURLConnection alloc] initWithRequest: [request request] delegate: self];
+               
+               applicationDelegate = delegate;
+               
+               if (currentConnection != nil) {
+                       currentXMLRPCMethod = [[NSString alloc] initWithString: [request method]];
+                       
+                       [request release];
+                       
+                       [[NSNotificationCenter defaultCenter] postNotificationName: XMLRPCSentRequestNotification object: nil];
+               } else {
+                       if ([applicationDelegate respondsToSelector: @selector(connection:didFailWithError:forMethod:)]) {
+                               [applicationDelegate connection: self didFailWithError: nil forMethod: [request method]];
+                       }
+                       
+                       [request release];
+                                               
+                       return nil;
+               }
+       }
+       
+       return self;
+}
+
+#pragma mark -
+
++ (XMLRPCResponse *)sendSynchronousXMLRPCRequest: (XMLRPCRequest *)request {
+       NSData *data = [[[NSURLConnection sendSynchronousRequest: [request request] 
+               returningResponse: nil error: nil] retain] autorelease];
+       
+       [request release];
+       
+       if (data != nil) {
+               return [[[XMLRPCResponse alloc] initWithData: data] autorelease];
+       }
+       
+       return nil;
+}
+
+#pragma mark -
+
+- (void)cancel {
+       [currentConnection cancel];
+       
+       [currentConnection release];
+}
+
+#pragma mark -
+
+- (void)dealloc {
+       [currentXMLRPCMethod release];
+       [incomingXMLData release];
+       
+       [super dealloc];
+}
+
+@end
+
+#pragma mark -
+
+@implementation XMLRPCConnection (XMLRPCConnectionPrivate)
+
+- (void)connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response {
+       if([response respondsToSelector: @selector(statusCode)]) {
+               NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
+               
+               if(statusCode >= 400) {
+                       [connection cancel];
+                       
+                       if ([applicationDelegate respondsToSelector: @selector(connection:didFailWithError:forMethod:)]) {
+                               NSError *error = [NSError errorWithDomain: NSCocoaErrorDomain code: statusCode userInfo: nil];
+                               
+                               [applicationDelegate connection: self didFailWithError: error forMethod: currentXMLRPCMethod];
+                       }
+                       
+                       [connection release];
+               }
+       }
+       
+       [incomingXMLData setLength: 0];
+}
+
+- (void)connection: (NSURLConnection *)connection didReceiveData: (NSData *)data {
+       [incomingXMLData appendData: data];
+}
+
+- (void)connection: (NSURLConnection *)connection didFailWithError: (NSError *)error {
+       if ([applicationDelegate respondsToSelector: @selector(connection:didFailWithError:forMethod:)]) {
+               [applicationDelegate connection: self didFailWithError: error forMethod: currentXMLRPCMethod];
+       }
+       
+       [[NSNotificationCenter defaultCenter] postNotificationName: XMLRPCRequestFailedNotification object: nil];
+       
+       [connection release];
+}
+
+- (void)connection: (NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
+       if ([applicationDelegate respondsToSelector: @selector(connection:didReceiveAuthenticationChallenge:forMethod:)]) {
+               [applicationDelegate connection: self didReceiveAuthenticationChallenge: challenge forMethod: currentXMLRPCMethod];
+       }
+       
+       [[NSNotificationCenter defaultCenter] postNotificationName: XMLRPCReceivedAuthenticationChallengeNotification object: nil];
+}
+
+- (void)connection: (NSURLConnection *)connection didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge {
+       if ([applicationDelegate respondsToSelector: @selector(connection:didCancelAuthenticationChallenge:forMethod:)]) {
+               [applicationDelegate connection: self didCancelAuthenticationChallenge: challenge forMethod: currentXMLRPCMethod];
+       }
+       
+       [[NSNotificationCenter defaultCenter] postNotificationName: XMLRPCCancelledAuthenticationChallengeNotification object: nil];
+}
+
+- (void)connectionDidFinishLoading: (NSURLConnection *)connection {
+       XMLRPCResponse *response = [[XMLRPCResponse alloc] initWithData: incomingXMLData];
+       
+       if ([applicationDelegate respondsToSelector: @selector(connection:didReceiveResponse:forMethod:)]) {
+               [applicationDelegate connection: self didReceiveResponse: response forMethod: currentXMLRPCMethod];
+       }
+       
+       [[NSNotificationCenter defaultCenter] postNotificationName: XMLRPCReceivedResponseNotification object: nil];
+       
+       [connection release];
+}
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCDecoder.h b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCDecoder.h
new file mode 100644 (file)
index 0000000..e7207be
--- /dev/null
@@ -0,0 +1,48 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCDecoder.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/Foundation.h>
+
+@interface XMLRPCDecoder : NSObject {
+       NSXMLDocument *responseXMLDocument;
+       BOOL isFault;
+}
+
+- (id)initWithData: (NSData *)data;
+
+#pragma mark -
+
+- (id)decode;
+
+#pragma mark -
+
+- (BOOL)isFault;
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCDecoder.m b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCDecoder.m
new file mode 100644 (file)
index 0000000..914da62
--- /dev/null
@@ -0,0 +1,305 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCDecoder.m
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import "XMLRPCDecoder.h"
+#import "NSDataAdditions.h"
+
+@interface XMLRPCDecoder (XMLRPCDecoderPrivate)
+
+- (NSXMLElement *)getChildFromElement: (NSXMLElement *)element withName: (NSString *)name;
+
+#pragma mark -
+
+- (id)decodeObject: (NSXMLElement *)element;
+
+- (id)trueDecodeObject: (NSXMLElement *)element;
+
+#pragma mark -
+
+- (NSArray *)decodeArray: (NSXMLElement *)element;
+
+#pragma mark -
+
+- (NSDictionary *)decodeDictionary: (NSXMLElement *)element;
+
+#pragma mark -
+
+- (NSNumber *)decodeNumber: (NSXMLElement *)element isDouble: (BOOL)flag;
+
+- (CFBooleanRef)decodeBool: (NSXMLElement *)element;
+
+- (NSString *)decodeString: (NSXMLElement *)element;
+
+- (NSDate *)decodeDate: (NSXMLElement *)element;
+
+- (NSData *)decodeData: (NSXMLElement *)element;
+
+@end
+
+#pragma mark -
+
+@implementation XMLRPCDecoder
+
+- (id)initWithData: (NSData *)data {
+       if (data == nil) {
+               return nil;
+       }
+       
+       if (self = [super init]) {
+               NSError *error = nil;
+               responseXMLDocument = [[NSXMLDocument alloc] initWithData: data options: NSXMLDocumentTidyXML error: &error];
+               
+               if (responseXMLDocument == nil) {
+                       if (error) {
+                               NSLog(@"Encountered an XML error: %@", error);
+                       }
+                       
+                       return nil;
+               }
+               
+               if (error) {
+                       NSLog(@"Encountered an XML error: %@", error);
+                       
+                       return nil;
+               }
+       }
+       
+       return self;
+}
+
+#pragma mark -
+
+- (id)decode {
+       NSXMLElement *child, *root = [responseXMLDocument rootElement];
+       
+       if (root == nil) {
+               return nil;
+       }
+       
+       child = [self getChildFromElement: root withName: @"params"];
+       
+       if (child != nil) {
+               child = [self getChildFromElement: child withName: @"param"];
+               
+               if (child == nil) {
+                       return nil;
+               }
+               
+               child = [self getChildFromElement: child withName: @"value"];
+               
+               if (child == nil) {
+                       return nil;
+               }
+       } else {
+               child = [self getChildFromElement: root withName: @"fault"];
+               
+               if (child == nil) {
+                       return nil;
+               }
+               
+               child = [self getChildFromElement: child withName: @"value"];
+               
+               if (child == nil) {
+                       return nil;
+               }
+               
+               isFault = YES;
+       }
+       
+       return [self decodeObject: child];
+}
+
+#pragma mark -
+
+- (BOOL)isFault {
+       return isFault;
+}
+
+#pragma mark -
+
+- (void)dealloc {
+       [responseXMLDocument release];
+       
+       [super dealloc];
+}
+
+@end
+
+#pragma mark -
+
+@implementation XMLRPCDecoder (XMLRPCDecoderPrivate)
+
+- (NSXMLElement *)getChildFromElement: (NSXMLElement *)element withName: (NSString *)name {
+       NSArray *children = [element elementsForName: name];
+       
+       if ([children count] > 0) {
+               return [children objectAtIndex: 0];
+       }
+       
+       return nil;
+}
+
+#pragma mark -
+
+- (id)decodeObject: (NSXMLElement *)element {
+       NSXMLElement *child = (NSXMLElement *)[element childAtIndex: 0];
+       
+       if (child != nil) {
+               return [self trueDecodeObject: child];
+       }
+       
+       return nil;
+}
+
+- (id)trueDecodeObject: (NSXMLElement *)element {
+       NSString *name = [element name];
+       
+       if ([name isEqualToString: @"array"]) {
+               return [self decodeArray: element];
+       } else if ([name isEqualToString: @"struct"]) {
+               return [self decodeDictionary: element];
+       } else if ([name isEqualToString: @"int"] || [name isEqualToString: @"i4"]) {
+               return [self decodeNumber: element isDouble: NO];
+       } else if ([name isEqualToString: @"double"]) {
+               return [self decodeNumber: element isDouble: YES];
+       } else if ([name isEqualToString: @"boolean"]) {
+               return (id)[self decodeBool: element];
+       } else if ([name isEqualToString: @"string"]) {
+               return [self decodeString: element];
+       } else if ([name isEqualToString: @"dateTime.iso8601"]) {
+               return [self decodeDate: element];
+       } else if ([name isEqualToString: @"base64"]) {
+               return [self decodeData: element];
+       } else {
+               return [self decodeString: element];
+       }
+       
+       return nil;
+}
+
+#pragma mark -
+
+- (NSArray *)decodeArray: (NSXMLElement *)element {
+       NSXMLElement *parent = [self getChildFromElement: element withName: @"data"];
+       NSMutableArray *array = [NSMutableArray array];
+       NSInteger index;
+       
+       if (parent == nil) {
+               return nil;
+       }
+       
+       for (index = 0; index < [parent childCount]; index++) {
+               NSXMLElement *child = (NSXMLElement *)[parent childAtIndex: index];
+               
+               if (![[child name] isEqualToString: @"value"]) {
+                       continue;
+               }
+               
+               id value = [self decodeObject: child];
+               
+               if (value != nil) {
+                       [array addObject: value];
+               }
+       }
+       
+       return (NSArray *)array;
+}
+
+#pragma mark -
+
+- (NSDictionary *)decodeDictionary: (NSXMLElement *)element {
+       NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
+       NSInteger index;
+       
+       for (index = 0; index < [element childCount]; index++) {
+               NSXMLElement *child, *parent = (NSXMLElement *)[element childAtIndex: index];
+               
+               if (![[parent name] isEqualToString: @"member"]) {
+                       continue;
+               }
+               
+               child = [self getChildFromElement: parent withName: @"name"];
+               
+               if (child == nil) {
+                       continue;
+               }
+               
+               NSString *key = [child stringValue];
+               
+               child = [self getChildFromElement: parent withName: @"value"];
+               
+               if (child == nil) {
+                       continue;
+               }
+               
+               id object = [self decodeObject: child];
+               
+               if ((object != nil) && (key != nil) && ![key isEqualToString: @""]) {
+                       [dictionary setObject: object forKey: key];
+               }
+       }
+       
+       return (NSDictionary *)dictionary;
+}
+
+#pragma mark -
+
+- (NSNumber *)decodeNumber: (NSXMLElement *)element isDouble: (BOOL)flag {
+       if (flag) {
+               return [NSNumber numberWithDouble: [[element stringValue] intValue]];
+       }
+       
+       return [NSNumber numberWithInt: [[element stringValue] intValue]];
+}
+
+- (CFBooleanRef)decodeBool: (NSXMLElement *)element {
+       if ([[element stringValue] isEqualToString: @"1"]) {
+               return kCFBooleanTrue;
+       }
+       
+       return kCFBooleanFalse;
+}
+
+- (NSString *)decodeString: (NSXMLElement *)element {
+       return [element stringValue];
+}
+
+- (NSDate *)decodeDate: (NSXMLElement *)element {
+       NSCalendarDate *date = [NSCalendarDate dateWithString: [element stringValue] 
+               calendarFormat: @"%Y%m%dT%H:%M:%S" locale: nil];
+       
+       return date;
+}
+
+- (NSData *)decodeData: (NSXMLElement *)element {
+       return [NSData base64DataFromString: [element stringValue]];
+}
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCEncoder.h b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCEncoder.h
new file mode 100644 (file)
index 0000000..fe46abb
--- /dev/null
@@ -0,0 +1,53 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCEncoder.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/Foundation.h>
+
+@interface XMLRPCEncoder : NSObject {
+       NSString *currentXMLRPCMethod, *encoderSourceXML;
+       NSArray *currentXMLRPCParameters;
+}
+
+- (NSString *)encode;
+
+#pragma mark -
+
+- (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters;
+
+#pragma mark -
+
+- (NSString *)method;
+- (NSArray *)parameters;
+
+#pragma mark -
+
+- (NSString *)encoderSourceXML;
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCEncoder.m b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCEncoder.m
new file mode 100644 (file)
index 0000000..f230c1e
--- /dev/null
@@ -0,0 +1,285 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCEncoder.m
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import "XMLRPCEncoder.h"
+#import "NSStringAdditions.h"
+
+@interface XMLRPCEncoder (XMLRPCEncoderPrivate)
+
+- (NSString *)valueTag: (NSString *)tag value: (NSString *)value;
+
+#pragma mark -
+
+- (NSString *)replaceTarget: (NSString *)target withValue: (NSString *)value inString: (NSString *)string;
+
+- (NSString *)escapeValue: (NSString *)value;
+
+#pragma mark -
+
+- (NSString *)encodeObject: (id)object;
+
+#pragma mark -
+
+- (NSString *)encodeArray: (NSArray *)array;
+
+- (NSString *)encodeDictionary: (NSDictionary *)dictionary;
+
+#pragma mark -
+
+- (NSString *)encodeBoolean: (CFBooleanRef)boolean;
+
+- (NSString *)encodeNumber: (NSNumber *)number;
+
+- (NSString *)encodeString: (NSString *)string;
+
+- (NSString *)encodeDate: (NSDate *)date;
+
+- (NSString *)encodeData: (NSData *)data;
+
+@end
+
+#pragma mark -
+
+@implementation XMLRPCEncoder
+
+- (id)init {
+       if (self = [super init]) {
+               currentXMLRPCMethod = [[NSString alloc] init];
+               encoderSourceXML = [[NSString alloc] init];
+               currentXMLRPCParameters = [[NSArray alloc] init];
+       }
+       
+       return self;
+}
+
+#pragma mark -
+
+- (NSString *)encode {
+       NSMutableString *buffer = [NSMutableString stringWithString: @"<?xml version=\"1.0\"?><methodCall>"];
+       
+       [buffer appendFormat: @"<methodName>%@</methodName>", currentXMLRPCMethod];
+       
+       [buffer appendString: @"<params>"];
+       
+       if (currentXMLRPCParameters != nil) {
+               NSEnumerator *enumerator = [currentXMLRPCParameters objectEnumerator];
+               id parameter = nil;
+               
+               while (parameter = [enumerator nextObject]) {
+                       [buffer appendString: @"<param>"];
+                       [buffer appendString: [self encodeObject: parameter]];
+                       [buffer appendString: @"</param>"];
+               }
+       }
+       
+       [buffer appendString: @"</params>"];
+       
+       [buffer appendString: @"</methodCall>"];
+       
+       return buffer;
+}
+
+#pragma mark -
+
+- (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters {
+       if (currentXMLRPCMethod != nil) {
+               [currentXMLRPCMethod release];
+       }
+       
+       if (method == nil) {
+               currentXMLRPCMethod = nil;
+       } else {
+               currentXMLRPCMethod = [method retain];
+       }
+       
+       if (currentXMLRPCParameters != nil) {
+               [currentXMLRPCParameters release];
+       }
+       
+       if (parameters == nil) {
+               currentXMLRPCParameters = nil;
+       } else {
+               currentXMLRPCParameters = [parameters retain];
+       }
+}
+
+#pragma mark -
+
+- (NSString *)method {
+       return currentXMLRPCMethod;
+}
+
+- (NSArray *)parameters {
+       return currentXMLRPCParameters;
+}
+
+#pragma mark -
+
+- (NSString *)encoderSourceXML {
+       if (encoderSourceXML != nil) {
+               [encoderSourceXML release];
+       }
+       
+       encoderSourceXML = [[self encode] retain];
+       
+       return encoderSourceXML;
+}
+
+#pragma mark -
+
+- (void)dealloc {
+       [currentXMLRPCMethod release];
+       [encoderSourceXML release];
+       [currentXMLRPCParameters release];
+       
+       [super dealloc];
+}
+
+@end
+
+#pragma mark -
+
+@implementation XMLRPCEncoder (XMLRPCEncoderPrivate)
+
+- (NSString *)valueTag: (NSString *)tag value: (NSString *)value {
+       return [NSString stringWithFormat: @"<value><%@>%@</%@></value>", tag, [self escapeValue: value], tag];
+}
+
+#pragma mark -
+
+- (NSString *)replaceTarget: (NSString *)target withValue: (NSString *)value inString: (NSString *)string {
+       return [[string componentsSeparatedByString: target] componentsJoinedByString: value];  
+}
+
+- (NSString *)escapeValue: (NSString *)value {
+       value = [self replaceTarget: @"&" withValue: @"&amp;" inString: value];
+       value = [self replaceTarget: @"<" withValue: @"&lt;" inString: value];
+       
+       return value;
+}
+
+#pragma mark -
+
+- (NSString *)encodeObject: (id)object {
+       if (object == nil) {
+               return nil;
+       }
+       
+       if ([object isKindOfClass: [NSArray class]]) {
+               return [self encodeArray: object];
+       } else if ([object isKindOfClass: [NSDictionary class]]) {
+               return [self encodeDictionary: object];
+       } else if (((CFBooleanRef)object == kCFBooleanTrue) || ((CFBooleanRef)object == kCFBooleanFalse)) {
+               return [self encodeBoolean: (CFBooleanRef)object];
+       } else if ([object isKindOfClass: [NSNumber class]]) {
+               return [self encodeNumber: object];
+       } else if ([object isKindOfClass: [NSString class]]) {
+               return [self encodeString: object];
+       } else if ([object isKindOfClass: [NSDate class]]) {
+               return [self encodeDate: object];
+       } else if ([object isKindOfClass: [NSData class]]) {
+               return [self encodeData: object];
+       } else {
+               return [self encodeString: object];
+       }
+}
+
+#pragma mark -
+
+- (NSString *)encodeArray: (NSArray *)array {
+       NSMutableString *buffer = [NSMutableString string];
+       NSEnumerator *enumerator = [array objectEnumerator];
+       
+       [buffer appendString: @"<value><array><data>"];
+       
+       id object = nil;
+       
+       while (object = [enumerator nextObject]) {
+               [buffer appendString: [self encodeObject: object]];
+       }
+       
+       [buffer appendString: @"</data></array></value>"];
+       
+       return (NSString *)buffer;
+}
+
+- (NSString *)encodeDictionary: (NSDictionary *)dictionary {
+       NSMutableString * buffer = [NSMutableString string];
+       NSEnumerator *enumerator = [dictionary keyEnumerator];
+       
+       [buffer appendString: @"<value><struct>"];
+       
+       NSString *key = nil;
+       
+       while (key = [enumerator nextObject]) {
+               [buffer appendString: @"<member>"];
+               [buffer appendFormat: @"<name>%@</name>", key];
+               [buffer appendString: [self encodeObject: [dictionary objectForKey: key]]];
+               [buffer appendString: @"</member>"];
+       }
+       
+       [buffer appendString: @"</struct></value>"];
+       
+       return (NSString *)buffer;
+}
+
+#pragma mark -
+
+- (NSString *)encodeBoolean: (CFBooleanRef)boolean {
+       if (boolean == kCFBooleanTrue) {
+               return [self valueTag: @"boolean" value: @"1"];
+       } else {
+               return [self valueTag: @"boolean" value: @"0"];
+       }
+}
+
+- (NSString *)encodeNumber: (NSNumber *)number {
+       return [self valueTag: @"i4" value: [number stringValue]];
+}
+
+- (NSString *)encodeString: (NSString *)string {
+       return [self valueTag: @"string" value: string];
+}
+
+- (NSString *)encodeDate: (NSDate *)date {
+       NSString *buffer = [date descriptionWithCalendarFormat: @"%Y%m%dT%H:%M:%S"
+               timeZone: nil locale: nil];
+
+       return [self valueTag: @"dateTime.iso8601" value: buffer];
+}
+
+- (NSString *)encodeData: (NSData *)data {
+       NSString *buffer = [NSString base64StringFromData: data
+               length: [data length]];
+
+       return [self valueTag: @"base64" value: buffer];
+}
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCRequest.h b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCRequest.h
new file mode 100644 (file)
index 0000000..1db012e
--- /dev/null
@@ -0,0 +1,73 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCRequest.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/Foundation.h>
+
+@class XMLRPCEncoder;
+
+@interface XMLRPCRequest : NSObject {
+       NSMutableURLRequest *mutableRequest;
+       XMLRPCEncoder *requestXMLEncoder;
+}
+
+- (id)initWithHost: (NSURL *)host;
+
+#pragma mark -
+
+- (void)setHost: (NSURL *)host;
+- (NSURL *)host;
+
+#pragma mark -
+
+- (void)setUserAgent: (NSString *)userAgent;
+- (NSString *)userAgent;
+
+#pragma mark -
+
+- (void)setMethod: (NSString *)method;
+
+- (void)setMethod: (NSString *)method withParameter: (id)parameter;
+
+- (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters;
+
+#pragma mark -
+
+- (NSString *)method;
+- (NSArray *)parameters;
+
+#pragma mark -
+
+- (NSString *)requestSourceXML;
+
+#pragma mark -
+
+- (NSURLRequest *)request;
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCRequest.m b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCRequest.m
new file mode 100644 (file)
index 0000000..274c649
--- /dev/null
@@ -0,0 +1,142 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCRequest.m
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import "XMLRPCRequest.h"
+#import "XMLRPCEncoder.h"
+
+@implementation XMLRPCRequest
+
+- (id)initWithHost: (NSURL *)host {
+       if (self = [super init]) {
+               if (host != nil) {
+                       mutableRequest = [[NSMutableURLRequest alloc] initWithURL: host];
+               } else {
+                       mutableRequest = [[NSMutableURLRequest alloc] init];
+               }
+               
+               requestXMLEncoder = [[XMLRPCEncoder alloc] init];
+       }
+       
+       return self;
+}
+
+#pragma mark -
+
+- (void)setHost: (NSURL *)host {
+       [mutableRequest setURL: host];
+}
+
+- (NSURL *)host {
+       return [mutableRequest URL];
+}
+
+#pragma mark -
+
+- (void)setUserAgent: (NSString *)userAgent {
+       if ([self userAgent] == nil) {
+               [mutableRequest addValue: userAgent forHTTPHeaderField: @"User-Agent"];
+       } else {
+               [mutableRequest setValue: userAgent forHTTPHeaderField: @"User-Agent"];
+       }
+}
+
+- (NSString *)userAgent {
+       return [mutableRequest valueForHTTPHeaderField: @"User-Agent"];
+}
+
+#pragma mark -
+
+- (void)setMethod: (NSString *)method {
+       [requestXMLEncoder setMethod: method withParameters: nil];
+}
+
+- (void)setMethod: (NSString *)method withParameter: (id)parameter {
+       [requestXMLEncoder setMethod: method withParameters: [NSArray arrayWithObject: parameter]];
+}
+
+- (void)setMethod: (NSString *)method withParameters: (NSArray *)parameters {
+       [requestXMLEncoder setMethod: method withParameters: parameters];
+}
+
+#pragma mark -
+
+- (NSString *)method {
+       return [requestXMLEncoder method];
+}
+
+- (NSArray *)parameters {
+       return [requestXMLEncoder parameters];
+}
+
+#pragma mark -
+
+- (NSString *)requestSourceXML {
+       return [requestXMLEncoder encoderSourceXML];
+}
+
+#pragma mark -
+
+- (NSURLRequest *)request {
+       NSData *request = [[requestXMLEncoder encode] dataUsingEncoding: NSUTF8StringEncoding];
+       NSNumber *contentLength = [NSNumber numberWithInt: [request length]];
+       
+       if (request == nil) {
+               return nil;
+       }
+       
+       [mutableRequest setHTTPMethod: @"POST"];
+       
+       if ([mutableRequest valueForHTTPHeaderField: @"Content-Length"] == nil) {
+               [mutableRequest addValue: @"text/xml" forHTTPHeaderField: @"Content-Type"];
+       } else {
+               [mutableRequest setValue: @"text/xml" forHTTPHeaderField: @"Content-Type"];
+       }
+       
+       if ([mutableRequest valueForHTTPHeaderField: @"Content-Length"] == nil) {
+               [mutableRequest addValue: [contentLength stringValue] forHTTPHeaderField: @"Content-Length"];
+       } else {
+               [mutableRequest setValue: [contentLength stringValue] forHTTPHeaderField: @"Content-Length"];
+       }
+       
+       [mutableRequest setHTTPBody: request];
+       
+       return (NSURLRequest *)mutableRequest;
+}
+
+#pragma mark -
+
+- (void)dealloc {
+       [mutableRequest release];
+       [requestXMLEncoder release];
+       
+       [super dealloc];
+}
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCResponse.h b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCResponse.h
new file mode 100644 (file)
index 0000000..fe645a6
--- /dev/null
@@ -0,0 +1,60 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCResponse.h
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import <Foundation/Foundation.h>
+
+@class XMLRPCDecoder;
+
+@interface XMLRPCResponse : NSObject {
+       NSData *responseXMLData;
+       NSString *responseSourceXML;
+       id responseObject;
+       BOOL isFault;
+}
+
+- (id)initWithData: (NSData *)data;
+
+#pragma mark -
+
+- (BOOL)isFault;
+
+- (NSNumber *)faultCode;
+
+- (NSString *)faultString;
+
+#pragma mark -
+
+- (id)responseObject;
+
+#pragma mark -
+
+- (NSString *)responseSourceXML;
+
+@end
diff --git a/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCResponse.m b/iPhoto2Ansel/xmlrpc-1.5.1/XMLRPCResponse.m
new file mode 100644 (file)
index 0000000..0175f4c
--- /dev/null
@@ -0,0 +1,105 @@
+// 
+// Copyright (c) 2008 Eric Czarny <eczarny@gmail.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of  this  software  and  associated documentation files (the "Software"), to
+// deal  in  the Software without restriction, including without limitation the
+// rights  to  use,  copy,  modify,  merge,  publish,  distribute,  sublicense,
+// and/or sell copies  of  the  Software,  and  to  permit  persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+// 
+// The  above  copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE  SOFTWARE  IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED,  INCLUDING  BUT  NOT  LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY,  WHETHER  IN  AN  ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+// 
+
+// 
+// Cocoa XML-RPC Framework
+// XMLRPCResponse.m
+// 
+// Created by Eric Czarny on Wednesday, January 14, 2004.
+// Copyright (c) 2008 Divisible by Zero.
+// 
+
+#import "XMLRPCResponse.h"
+#import "XMLRPCDecoder.h"
+
+@implementation XMLRPCResponse
+
+- (id)initWithData: (NSData *)data
+{
+       if (data == nil) {
+               return nil;
+       }
+
+       if (self = [super init]) {
+               XMLRPCDecoder *responseXMLDecoder =[[XMLRPCDecoder alloc] initWithData: data];
+               
+               if (responseXMLDecoder == nil) {
+                       return nil;
+               }
+       
+               responseXMLData = [[NSData alloc] initWithData: data];
+               responseSourceXML = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
+               responseObject = [[responseXMLDecoder decode] retain];
+               
+               isFault = [responseXMLDecoder isFault];
+               
+               [responseXMLDecoder release];
+       }
+       
+       return self;
+}
+
+#pragma mark -
+
+- (BOOL)isFault {
+       return isFault;
+}
+
+- (NSNumber *)faultCode {
+       if (isFault) {
+               return [responseObject objectForKey: @"faultCode"];
+       }
+       
+       return nil;
+}
+
+- (NSString *)faultString {
+       if (isFault) {
+               return [responseObject objectForKey: @"faultString"];
+       }
+       
+       return nil;
+}
+
+#pragma mark -
+
+- (id)responseObject {
+       return responseObject;
+}
+
+#pragma mark -
+
+- (NSString *)responseSourceXML {
+       return responseSourceXML;
+}
+
+#pragma mark -
+
+- (void)dealloc {
+       [responseXMLData release];
+       [responseSourceXML release];
+       [responseObject release];
+       
+       [super dealloc];
+}
+
+@end