{"id":490,"date":"2012-02-24T22:19:14","date_gmt":"2012-02-25T05:19:14","guid":{"rendered":"http:\/\/10.0.1.201\/?p=490"},"modified":"2012-02-24T22:19:14","modified_gmt":"2012-02-25T05:19:14","slug":"iphoto-import-from-folders-applescript","status":"publish","type":"post","link":"https:\/\/strawhousepig.net\/wordpress\/2012\/02\/24\/iphoto-import-from-folders-applescript\/","title":{"rendered":"iPhoto import from folders AppleScript"},"content":{"rendered":"<p>Preface: Having upgraded my phone (Nokia N8) firmware to &#8220;Belle&#8221; \u2014 whatever version that is, the Nokia Multimedia Transfer application no longer imports photos to iPhoto.* Tragic because the camera is the sole reason I bought this phone. Ordinarily this would not be a problem since the phone uses a &#8220;DCIM&#8221; folder at the drive root and can store images with 8 character names (5 of which you set yourself). But not every photo app does store them there or with a &#8220;proper&#8221; name. Even though there exists an &#8220;Images&#8221; folder in the drive root that I know gets used, Mass Storage.app does not access it. Could be another naming convention similar to <a href=\"http:\/\/en.wikipedia.org\/wiki\/Design_rule_for_Camera_File_system\">DCF<\/a><\/p>\n<p>This is an AppleScript to get around this limitation, and to allow (in my case at least) the importing of camera files named by date. In short you choose which folders you want this script to tell iPhoto to import from and can be used with any folder(s), no specific device required.<\/p>\n<p>Notable: Uses &#8216;defaults&#8217; to store and load folder paths in a property list (.plist) file.<br \/>\n<!--more--><br \/>\nA little more use shows this to have some bugs. This cannot be run as a stand alone script; it must be saved as an application.<\/p>\n<p>I cannot assume responsibility should you lose data while using the &#8220;Delete&#8221; option, although it does not delete a file from the device until after the file has been moved (copied) to your Temporary Items Folder where it should still be. This script is put up as an example for anyone to use, modify, or learn from, not to solve any issues other than my own. If any errors are reported while running this you should click &#8220;Cancel&#8221;.<\/p>\n<p>To open the Temporary Items folder:<br \/>\n<code>tell application \"Finder\" to reveal (path to temporary items folder)<\/code><\/p>\n<p><code>(*<br \/>\nhttp:\/\/strawhousepig.net\/<\/p>\n<p>Can be run from the script menuextra if saved as an application,<br \/>\nor by a Folder Action via AppleScript or Automator (probably easiest).<\/p>\n<p>THERE MAY BE ISSUES WITH REPLACING FILES. Script *should* die in that event (untested).<br \/>\nTrying to keep read_array() and write_array() as generic as possible for use else where. *hint-hint*<br \/>\nDoing a lot of re-reading of the plist array to be able to repeat functions after adding to or deleting from it<br \/>\nProperty list array delimiter is \"%%\"<\/p>\n<p>Structure<br \/>\n----------------<br \/>\nStart<br \/>\nCount items to import.<br \/>\nIf nothing to count: Add folder<br \/>\nIf > 0: ask to import, manage folders, or cancel.<br \/>\n\tElse: Manage folders.<br \/>\nIf mange folders: Ask to add, or remove folders, prompt for another, Start.<br \/>\nIf import: Ask to delete from device<br \/>\n\tIf delete: Move items to temp dir, tell iPhoto to import temp dir<br \/>\n\t\t(iPhoto is slower than the script and does not return true or false on completion of import.<br \/>\n\t\tMake iPhoto work away from the folders so the script doesn't run ahead deleting items.<br \/>\n\t\tUnfortunately telling Finder to \"move\" a file from one disk to another leaves the original<br \/>\n\t\tso we are 'rm 'ing the files one by one as they are moved.<br \/>\n\t\tAlso there are no auto increments in the case of multiple files with the same name.)<br \/>\n\tElse: Tell iPhoto to import folders.<br \/>\nIf cancel:<\/p>\n<p>*)<\/p>\n<p>property the_dom : \"iphoto.import.this\"<br \/>\nproperty the_key : \"folders\"<br \/>\nstart()<\/p>\n<p>on start()<br \/>\n\tset import_folders to read_array(the_dom, the_key)<br \/>\n\tif import_folders is not false then<br \/>\n\t\tset image_count to count_folder(import_folders)<br \/>\n\t\tif image_count is greater than 0 then<br \/>\n\t\t\tset start_button to button returned of (display dialog (image_count as text) & \" items in import folders.\" buttons {\"Cancel\", \"Manage Folders...\", \"Import...\"} default button 3)<br \/>\n\t\t\tif start_button is \"Import...\" then<br \/>\n\t\t\t\timport_files(import_folders)<br \/>\n\t\t\telse<br \/>\n\t\t\t\tmanage_folders(\"You rang?\")<br \/>\n\t\t\tend if<br \/>\n\t\telse<br \/>\n\t\t\tmanage_folders(\"No items to import.\")<br \/>\n\t\tend if<br \/>\n\telse<br \/>\n\t\tadd_folder()<br \/>\n\tend if<br \/>\nend start<\/p>\n<p>on import_files(import_folders)<br \/>\n\tset import_button to button returned of (display dialog \"Delete imported items from device?\" buttons {\"Cancel\", \"Keep\", \"Delete\"} default button 3)<br \/>\n\tif import_button is not false then<br \/>\n\t\ttry<br \/>\n\t\t\tset the_date to (month of (current date) as string) & \" \" & day of (current date) & \" \" & year of (current date) & \" \" & hours of (current date) & \"h\" & minutes of (current date) & \"m\" & seconds of (current date) & \"s\"<br \/>\n\t\t\ttell application \"Finder\"<br \/>\n\t\t\t\tset temp_folder to (make new folder at (path to temporary items folder) with properties {name:the_date}) as alias<br \/>\n\t\t\t\trepeat with i in import_folders<br \/>\n\t\t\t\t\tset these_items to every item of folder (i as POSIX file)<br \/>\n\t\t\t\t\trepeat with ii in these_items<br \/>\n\t\t\t\t\t\tmove ii to temp_folder<br \/>\n\t\t\t\t\t\tif import_button is \"Delete\" then<br \/>\n\t\t\t\t\t\t\tdo shell script \"rm \" & quoted form of (POSIX path of (ii as alias))<br \/>\n\t\t\t\t\t\tend if<br \/>\n\t\t\t\t\tend repeat<br \/>\n\t\t\t\tend repeat<br \/>\n\t\t\t\tset import_folders to {POSIX path of temp_folder}<br \/>\n\t\t\tend tell<br \/>\n\t\ton error theMsg<br \/>\n\t\t\tdisplay dialog theMsg<br \/>\n\t\tend try<br \/>\n\t\ttell application \"iPhoto\"<br \/>\n\t\t\tactivate<br \/>\n\t\t\ttry<br \/>\n\t\t\t\trepeat with i in import_folders<br \/>\n\t\t\t\t\timport from i<br \/>\n\t\t\t\tend repeat<br \/>\n\t\t\tend try<br \/>\n\t\tend tell<br \/>\n\tend if<br \/>\nend import_files<\/p>\n<p>on manage_folders(the_dialog)<br \/>\n\tset import_folders to read_array(the_dom, the_key)<br \/>\n\tset manage_button to button returned of (display dialog the_dialog buttons {\"Cancel\", \"Delete Folders...\", \"Add Folder...\"} default button 1)<br \/>\n\tif manage_button is \"Add Folder...\" then<br \/>\n\t\tadd_folder()<br \/>\n\telse<br \/>\n\t\tif manage_button is \"Delete Folders...\" then<br \/>\n\t\t\tdelete_folders()<br \/>\n\t\tend if<br \/>\n\tend if<br \/>\nend manage_folders<\/p>\n<p>on count_folder(import_folders)<br \/>\n\tset item_count to 0<br \/>\n\trepeat with i in import_folders<br \/>\n\t\ttry<br \/>\n\t\t\tset item_count to item_count + (do shell script \"ls '\" & i & \"' | wc -l\")<br \/>\n\t\ton error errMsg<br \/>\n\t\t\tdisplay dialog errMsg<br \/>\n\t\tend try<br \/>\n\tend repeat<br \/>\n\treturn item_count<br \/>\nend count_folder<\/p>\n<p>on add_folder()<br \/>\n\tset import_folders to read_array(the_dom, the_key)<br \/>\n\ttry<br \/>\n\t\tset this_folder to POSIX path of (choose folder)<br \/>\n\ton error<br \/>\n\t\tstart()<br \/>\n\tend try<br \/>\n\tif this_folder is not false then<br \/>\n\t\t-- write_array will return true on success or an error if a duplicate entry is found.<br \/>\n\t\tset is_written to write_array(the_dom, the_key, this_folder, import_folders)<br \/>\n\t\tif is_written is true then<br \/>\n\t\t\tset add_button to button returned of (display dialog ((this_folder) as text) & \" added to import list.\" buttons {\"Back\", \"Another\"})<br \/>\n\t\t\tif add_button is \"Back\" then<br \/>\n\t\t\t\tstart()<br \/>\n\t\t\telse<br \/>\n\t\t\t\tadd_folder()<br \/>\n\t\t\tend if<br \/>\n\t\telse<br \/>\n\t\t\tdisplay dialog \"Oops!: \" & is_written<br \/>\n\t\t\tmanage_folders(\"You rang?\")<br \/>\n\t\tend if<br \/>\n\tend if<br \/>\n\tstart()<br \/>\nend add_folder<\/p>\n<p>on delete_folders()<br \/>\n\tset import_folders to read_array(the_dom, the_key)<br \/>\n\tset new_folders to \"\"<br \/>\n\tset the_goner to choose from list import_folders with prompt \"Choose folders to remove from the import list.\" OK button name \"Delete\" with multiple selections allowed<br \/>\n\tif the_goner is not false then<br \/>\n\t\trepeat with i in import_folders<br \/>\n\t\t\tif i is not in the_goner then<br \/>\n\t\t\t\tset new_folders to new_folders & \"\\\"%%\" & i & \"%%\\\",\"<br \/>\n\t\t\tend if<br \/>\n\t\tend repeat<br \/>\n\t\tset new_folders to characters 1 through ((count of characters of new_folders) - 1) of new_folders as string<br \/>\n\t\tdo shell script \"defaults write \" & the_dom & \" '{ \" & the_key & \" = (\" & new_folders & \"); }'\"<br \/>\n\tend if<br \/>\n\tstart()<br \/>\nend delete_folders<\/p>\n<p>on read_array(the_dom, the_key)<br \/>\n\ttry<br \/>\n\t\tset {tid, text item delimiters} to {text item delimiters, \"%%\"}<br \/>\n\t\tset read_plist to text items of (do shell script \"defaults read \" & the_dom & \" \" & the_key)<br \/>\n\t\tset str2array to {}<br \/>\n\t\trepeat with i from 2 to (count read_plist) by 2<br \/>\n\t\t\tset this_item to item i of read_plist<br \/>\n\t\t\tset end of str2array to this_item<br \/>\n\t\tend repeat<br \/>\n\t\tset text item delimiters to tid<br \/>\n\t\treturn str2array<br \/>\n\ton error<br \/>\n\t\treturn false<br \/>\n\tend try<br \/>\nend read_array<\/p>\n<p>on write_array(the_dom, the_key, the_value, old_values)<br \/>\n\t-- old_values is what is already in the array. Used for duplicate checking.<br \/>\n\ttry<br \/>\n\t\tif old_values is not false then<br \/>\n\t\t\tif the_value is not in old_values then<br \/>\n\t\t\t\tdo shell script \"defaults write \" & the_dom & \" \" & the_key & \" -array-add '%%\" & the_value & \"%%'\"<br \/>\n\t\t\telse<br \/>\n\t\t\t\terror \"Item is already added.\"<br \/>\n\t\t\tend if<br \/>\n\t\telse<br \/>\n\t\t\tdo shell script \"defaults write \" & the_dom & \" \" & the_key & \" -array-add '%%\" & the_value & \"%%'\"<br \/>\n\t\tend if<br \/>\n\t\treturn true<br \/>\n\ton error theMsg<br \/>\n\t\treturn theMsg<br \/>\n\tend try<br \/>\nend write_array<\/code><\/p>\n<p>*UPDATE: Turns out the camera was set to name photos using the date, rather than incremental numbers. The DCIM 8 character naming spec apparently applies to folders and the files they contain. Why? Oh well. Always good to flex the brain to solve a problem manually.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Preface: Having upgraded my phone (Nokia N8) firmware to &#8220;Belle&#8221; \u2014 whatever version that is, the Nokia Multimedia Transfer application no longer imports photos to iPhoto.* Tragic because the camera is the sole reason I bought this phone. Ordinarily this would not be a problem since the phone uses a &#8220;DCIM&#8221; folder at the drive [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3],"tags":[10,15,20],"class_list":["post-490","post","type-post","status-publish","format-standard","hentry","category-code","category-hardware","tag-applescript-2","tag-fixit","tag-iphoto"],"_links":{"self":[{"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/posts\/490","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/comments?post=490"}],"version-history":[{"count":0,"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/posts\/490\/revisions"}],"wp:attachment":[{"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/media?parent=490"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/categories?post=490"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/strawhousepig.net\/wordpress\/wp-json\/wp\/v2\/tags?post=490"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}