public void Run(string[] args) { bool unflaggedToExtras; bool copyOriginals; bool writeMetadataFiles; bool alwaysWriteMetadata; bool prependDateToEventNames; bool generateSynoCovers; if (!GetOptions(ref args, out unflaggedToExtras, out copyOriginals, out writeMetadataFiles, out alwaysWriteMetadata, out prependDateToEventNames, out generateSynoCovers)) { PrintUsage(); return; } if (args.Length != 3) { PrintUsage(); return; } string mode = args[0]; string iPhotoLibraryPath = args[1]; string outputFolderPath = args[2]; if (mode != "preview" && mode != "copy") { Console.Error.WriteLine("Invalid mode '" + mode + "'."); PrintUsage(); return; } if (!Directory.Exists(iPhotoLibraryPath)) { Console.Error.WriteLine("Can't find iphoto library folder '" + iPhotoLibraryPath + "'."); PrintUsage(); return; } if (!Directory.Exists(outputFolderPath)) { Console.Error.WriteLine("Can't find output folder'" + outputFolderPath + "'."); PrintUsage(); return; } string iPhotoXmlPath = Path.Combine(iPhotoLibraryPath, "AlbumData.xml"); if (!File.Exists(iPhotoXmlPath)) { Console.Error.WriteLine("Can't find iphoto ablum data XML '" + iPhotoXmlPath + "'."); PrintUsage(); return; } bool preview = mode == "preview"; albumData = AlbumData.Load(iPhotoXmlPath); RemoveUnreferencedRolls(); if (prependDateToEventNames) { PrependDateToEventNames(); } MakeRollNamesUnique(); List <MasterImage> masterImages = albumData.MasterImages.Values.ToList(); for (int imageIndex = 0; imageIndex < masterImages.Count; imageIndex++) { if (imageIndex % 500 == 0) { Console.WriteLine(String.Format("Copying {0:0.0}% complete ({1:n0} of {2:n0})", imageIndex / (float)masterImages.Count * 100, imageIndex, masterImages.Count)); } MasterImage masterImage = masterImages[imageIndex]; Roll roll = albumData.Rolls[(int)masterImage.Roll]; string destRollPath = roll.RollName; if (unflaggedToExtras && !masterImage.Flagged) { destRollPath = Path.Combine(destRollPath, "Extras"); } string destFileName = GetUniqueFileNameForImage(destRollPath, masterImage); string destFilePath = Path.Combine(outputFolderPath, destRollPath, destFileName); if (CopyFile(iPhotoLibraryPath, masterImage.ImagePath, destFilePath, preview)) { if (writeMetadataFiles || alwaysWriteMetadata) { WriteXmpMetaData(destFilePath, masterImage, alwaysWriteMetadata, preview); } if (copyOriginals && masterImage.OriginalPath != null && masterImage.OriginalPath != masterImage.ImagePath) { string originalDestFilePath = Path.Combine(Path.GetDirectoryName(destFilePath), "Originals", Path.GetFileNameWithoutExtension(destFilePath) + Path.GetExtension(masterImage.OriginalPath)); CopyFile(iPhotoLibraryPath, masterImage.OriginalPath, originalDestFilePath, preview); } } } if (generateSynoCovers) { // Caution using this, it is not complete/robust. Console.WriteLine("Generating covers for Synology Photo Station."); foreach (Roll roll in albumData.Rolls.Values) { GenerateSynoCover(roll, outputFolderPath, preview); } } Console.WriteLine(String.Format("Done. {0} files copied, {1} metadata files written.", numFilesCopied, numMetadataFilesCreated)); }