001package com.hfg.image;
002
003import com.hfg.util.Executor;
004import com.hfg.util.StringUtil;
005import com.hfg.xml.parser.SaxyParser;
006import com.hfg.xml.parser.AbstractContentHandler;
007import org.xml.sax.InputSource;
008import org.xml.sax.Attributes;
009
010import java.io.StringReader;
011import java.io.File;
012
013
014//------------------------------------------------------------------------------
015/**
016 * Functions for interfacing with Apple's iPhoto.
017 *
018 * @author J. Alex Taylor, hairyfatguy.com
019 */
020//------------------------------------------------------------------------------
021// com.hfg XML/HTML Coding Library
022//
023// This library is free software; you can redistribute it and/or
024// modify it under the terms of the GNU Lesser General Public
025// License as published by the Free Software Foundation; either
026// version 2.1 of the License, or (at your option) any later version.
027//
028// This library is distributed in the hope that it will be useful,
029// but WITHOUT ANY WARRANTY; without even the implied warranty of
030// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
031// Lesser General Public License for more details.
032//
033// You should have received a copy of the GNU Lesser General Public
034// License along with this library; if not, write to the Free Software
035// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
036//
037// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
038// jataylor@hairyfatguy.com
039//------------------------------------------------------------------------------
040
041public class IPhoto
042{
043   private static File mIPhotoPlistFile = new File(System.getProperties().getProperty("user.home")
044                                          + "/Library/Preferences/com.apple.iPhoto.plist");
045
046   //###########################################################################
047   // PUBLIC FUNCTIONS
048   //###########################################################################
049
050   //--------------------------------------------------------------------------
051   /**
052    This function retrieves the current default iPhoto library path.
053    Compatible with iPhoto Library Manager.
054    */
055   public static File getLibraryPath()
056         throws Exception
057   {
058      if (! mIPhotoPlistFile.exists())
059      {
060         throw new RuntimeException("It does not appear that iPhoto is installed on this system.");
061      }
062
063      String cmd = "/usr/bin/plutil -convert xml1 -o - " + mIPhotoPlistFile.getPath();
064      Executor executor = new Executor(cmd);
065      int retVal = executor.exec();
066      if (retVal != 0)
067      {
068         throw new RuntimeException("Error executing " + StringUtil.singleQuote(cmd) + ": " + executor.getSTDERR());
069      }
070
071      /*
072      Looking for:
073              ...
074              <key>RootDirectory</key>
075              <string>/Photos/iPhoto Library (2006 - 2007)</string>
076              ...
077      */
078      PlistContentHandler handler = new IPhoto().new PlistContentHandler("RootDirectory");
079      SaxyParser parser = new SaxyParser();
080      parser.setContentHandler(handler);
081      parser.parse(new InputSource(new StringReader(executor.getSTDOUT())));
082
083      return new File(handler.getTargetPropertyValue());
084   }
085
086   //###########################################################################
087   // INNER CLASS
088   //###########################################################################
089
090   private class PlistContentHandler extends AbstractContentHandler
091   {
092      private String mTargetPropertyKey;
093      private String mTargetPropertyValue;
094      private String mCurrentTagName;
095      private boolean mTargetPropertyFound = false;
096
097      //-----------------------------------------------------------------------
098      public PlistContentHandler(String inTargetPropertyKey)
099      {
100         mTargetPropertyKey = inTargetPropertyKey;
101      }
102
103      //-----------------------------------------------------------------------
104      public String getTargetPropertyValue()
105      {
106         return mTargetPropertyValue;
107      }
108
109      //-----------------------------------------------------------------------
110      public void startElement(String inURI, String inLocalName, String inName, Attributes inAttributes)
111      {
112         mCurrentTagName = inLocalName;
113      }
114
115      //-----------------------------------------------------------------------
116      public void characters(char[] inChars, int offset, int length)
117      {
118         if (mCurrentTagName.equals("key"))
119         {
120            String key = new String(inChars, offset, length);
121            if (key.equals(mTargetPropertyKey))
122            {
123               mTargetPropertyFound = true;
124            }
125         }
126         else if (mCurrentTagName.equals("string")
127                  && mTargetPropertyFound)
128         {
129            mTargetPropertyValue = new String(inChars, offset, length);
130            mTargetPropertyFound = false;
131         }
132      }
133   }
134
135}