(* ********************************************************************* Address Book - check and fix country names & country codes This script will go through your Address Book and do two things: 1) standardize the country name (e.g. United States, instead of USA, United States of America, etc.); 2) add the country code for the each address, this will make sure the address is displayed properly. ********************************************************************* Winfred van Kuijk - http://winfred.vankuijk.net/2010/01/fixing-countries-in-address-book/ v1.0, 2010/01/03, initial release v1.1, 2010/01/04, added result display options, added ability to run as Address Book plugin, Growl support v1.2, 2010/01/10, added support for all known iso countries, write results to log file for easy copy/paste v1.2.1, 2010/01/11, small Growl fix for non-Growl users v1.2.2, 2010/01/12, leave iso code empty in lookup list to overwrite Apple's format + check small countries if not in large country list v1.3, 2010/01/12, added support for optional checking of latest version v1.4, 2010/01/15, added support for groups: adds missing/unknown country entries, extra check for problematic cards v1.5, 2010/02/06, using "iPhone" country list instead of ISO list, changed default values of some parameters v1.5.1, 2011/07/28, small fixes, Lion compatibility, changes default value of treat_iso_list_as_unknown and check_for_updates v.1.5.2, 2011/08/20, growl fix, user request: made preferred country case sensitive instructions ----------------- - use as address book plug-in (recommended): install in /Library/Address Book Plug-Ins or ~/Library/Address Book Plug-Ins - or run as standalone script - suggested: modify the sections between #### ... #### this specifies what your country lookup table should look like, and if you see a summary at the end, etc. - when running as plug-in, if you change any parameter (e.g. "add_to_groups"): restart Address Book Just in case: make sure you have a recent backup of your Address Book, e.g. Time Capsule or manual (File -> Export... -> Address Book Archive...) *) property current_version : "1.5.2" -- ########################################################## <<<<< EDIT FROM HERE vvvvvvv property add_to_groups : true -- create groups for entries with missing/unknown countries; is *add-only*, so clean up manually property show_results : true -- optional: show summary in TextEdit after running the script property check_for_updates : true -- optional: will check to see if there is an updated version of the script (no info is sent to server) -- I have show_results and check_for_updates normally set to "true", but that's completely up to you :-) property treat_iso_list_as_unknown : false -- if country code is found in iso list, still treat as unknown country? property plugin_only_selected : false -- when using as plug-in: only update selected person or run for every person? -- ########################################################## <<<<< EDIT TO HERE ^^^^^ global testing, fill_empty_country, default_country, use_growl global mycountries, big_iso_countries, small_iso_countries, log_unknown, log_missing global changes_country, changes_code, names_checked, addresses_checked, group_missing, group_unknown global list_of_isocodes, list_of_countries, list_of_aliases, list_of_missing_countries, list_of_unknown_countries --------------------------------------------------------------------------------------- -- both standalone script and plug-in will use this as the starting subroutine on country_name_code(LocalPeople) --------------------------------------------------------------------------------------- -- create list of countries -- mycountries: list of records {i,{p[,a]}} - iso code, *preferred country name*, 0 or more aliases set mycountries to {} set clist to a reference to mycountries -- ########################################################## <<<<< EDIT FROM HERE vvvvvvv -- ---------- update the list below to contain all the countries you are interested in --------------------- -- format of list: {isocode, {list of preferred name and -if wanted- aliases}} -- the first country name is the preferred name, this can be in your local language if you want -- you only need to add countries here if you want to a) use a non-iso country name and/or b) if you want to add aliases / fix mis-spellings -- the iso names can be found at the bottom of the script -- note: *only* use the ISO codes from the table at the bottom, Address Book will hide addresses with country codes not in its own table copy {"us", {"United States", "USA", "US", "United States of America", "Estados Unidos"}} to end of clist copy {"nl", {"Netherlands", "Nederland", "the Netherlands", "NL"}} to end of clist copy {"be", {"Belgium", "Belgi‘", "Belgique"}} to end of clist -- I like to use the English name for this country copy {"de", {"Germany", "Deutschland"}} to end of clist -- using the English name (in all caps) copy {"gb", {"United Kingdom", "UK"}} to end of clist -- note: Address Book uses "gb" as country code, not "uk" copy {"fr", {"France"}} to end of clist -- optional: direct copy from iso list, only advantage: faster search (* Examples: copy {"ca", {"Canada", "Canad","Kanada","Kanata"}} to end of clist -- correct typo's, update entries with incorrect spelling copy {"de", {"Deutschland", "Germany"}} to end of clist -- use the German name for this country copy {"ve", {"Venezuela"}} to end of clist -- example of overwriting the standard name from the iso list ("Venezuela, Bolivarian Republic Of") copy {"", {"Chile"}} to end of clist -- example: I donÕt like AppleÕs Chile address format, leave iso code empty for default country format copy {"np", {"NEPAL"}} to end of clist -- if it finds Nepal (or nePal etc.), it will be replaced with all caps NEPAL --copy {"??", {"Luxembourg"}} to end of clist -- *incorrect*, iso code is invalid --copy {"an", {"Netherlands Antilles"}} -- *incorrect*: Apple does not know this iso code, result: will no longer disply address -- add as many lines as you like... (and remove the ones you don't need) *) -- ########################################################## <<<<< EDIT TO HERE ^^^^^ -- ########################################################## <<<<< EDIT FROM HERE vvvvvvv -- these settings can normally be left alone set group_missing to "¥ without country" -- group for addresses without country name set group_unknown to "¥ unknown country" -- group for addresses with country not in the list from this script set fill_empty_country to false -- should we fill addresses that have empty country name fields with a default name? set default_country to "Netherlands" -- if the country name field is empty for a contact, what country should be used? set use_growl to true -- use Growl (is set to false automatically if Growl is not installed) set testing to false -- change this if you only want to modify cards that have last name "testing" (see vcard download) -- ########################################################## <<<<< EDIT TO HERE ^^^^^ if check_for_updates then set lets_get_new_version to check_latest_version(current_version) -- will show popup if there is a newer version if lets_get_new_version then return -- let's stop if the user wanted to open the browser to download the latest version end if (* workflow of script ----------------- - create list of countries: iso codes, preferred names and aliases (e.g.: iso = us, preferred = United States, aliases = USA, United States of America, etc.) - part 1: use the custom list provided by the user - part 2: add countries from the iso list (if not already in the list) - create lookup lists for the iso codes, preferred and all country names - go through each person - go through each address for that person - optional: if the address is there, but the country is empty, use the default country name - if the country is in the alias list: make sure the preferred country name and iso code are used *) tell current application to set startTime to (get current date) -- make preparations for Growl (http://www.growl.info) prepare_growl() -- use_growl is set if Growl is running send_growl_msg("Starting plug-in", "Now checking+fixing country names and codes. Can take a while.") load_iso_country_list() -- reads the iso country list -- for statistics at the end set changes_country to 0 set changes_code to 0 set names_checked to 0 set addresses_checked to 0 set list_of_countries to {} set list_of_aliases to {} set list_of_isocodes to {} set list_of_missing_countries to {} -- will be filled with names that have address without country set list_of_unknown_countries to {} -- will be filled with countries not in the lookup table set log_missing to "" -- will be filled with script-ready table based on unknown countries (alternative to list above) set log_unknown to "" -- will be filled with script-ready table based on unknown countries (alternative to list above) set locref to a reference to list_of_countries set loaref to a reference to list_of_aliases set loiref to a reference to list_of_isocodes -- to speed up lookup: extract data from the list of lists -- list_of_countries: all official/preferred country names -- list_of_aliases: all official/preferred country names *and* alias(es) -- list_of_isocodes: all iso codes repeat with mycountry in mycountries set myiso to item 1 of mycountry -- the iso code set calist to item 2 of mycountry -- preferred country name + any (optional) aliases set myc to item 1 of calist -- preferred country name if (myiso is not "??") and (myiso is not "") and (myiso is not in loiref) then -- ignore the record if the iso code is "??" set end of loiref to myiso set end of locref to myc repeat with myca in calist set end of loaref to contents of myca end repeat end if end repeat (* log "List of iso codes to look out for:" & (count (list_of_isocodes)) log list_of_isocodes log "List of countries to look out for:" & (count (list_of_countries)) log list_of_countries log "List of countries + aliases to look out for:" & (count (list_of_aliases)) log list_of_aliases *) -- example: lookup an alias or preferred country name, return iso and preferred name --set {myi, myc} to my find_iso_code_in_country_list("USA") --------------------------------------------------------------------------------------- -- load the records from Address Book in variable LocalPeople tell application "Address Book" -- if this subroutine is called from the application, then LocalPeople is empty -- if it is called as plugin, it could be set to the selected address if (count of LocalPeople) = 0 then if (testing is true) then log "*** only cards with last name 'testing' will be checked and updated ***" set LocalPeople to (get every person where the last name is "testing") -- testing names else set LocalPeople to (get every person) end if end if log "Processing " & (count of LocalPeople) & " persons" end tell --------------------------------------------------------------------------------------- -- ### optional: call subroutine to find all the countries in the address book ### -- can help to identify which countries should be added to the iso list --choose from list my list_of_countries_in_address_book(LocalPeople) with title "Countries in Address Book" with prompt "" --return -- in that case, you can stop here if you want to --------------------------------------------------------------------------------------- -- call the main subroutine check_and_fix_country_name_and_code(LocalPeople) tell current application to set endTime to (get current date) set duration to endTime - startTime set summary to "checked:" & return &  "¥ names: " & names_checked & return &  "¥ addresses: " & addresses_checked & return & return &  "updated:" & return &  "¥ countries: " & changes_country & return &  "¥ formats: " & changes_code & return & return &  "countries:" & return &  "¥ unknown: " & (count list_of_unknown_countries) & return &  "¥ missing: " & (count list_of_missing_countries) & return & return &  "process took " & duration & " seconds" log summary if (use_growl) then send_growl_msg("Summary of results", summary) if (show_results is false) and ((count list_of_unknown_countries) > 0) then send_growl_msg("Additional details", "enable show_results variable to see list of " & (count list_of_unknown_countries) & " unknown countries") end if end if if (show_results is true) then if ((count list_of_missing_countries) > 0) or ((count list_of_unknown_countries) > 0) then write_log_to_file() end if if (not use_growl) then -- not using Growl, then only show if show_results was set display dialog summary with title "Address Book: country names + formats" buttons "Ok" end if end if end country_name_code --------------------------------------------------------------------------------------- -- this is the entry point when script is run standalone, for plug-in entry: see bottom on run country_name_code({}) -- {} means: leave empty, the subroutine will then fill it later end run -------------------------------------------------------------------------------------------------------------------- -- subroutines -------------------------------------------------------------------------------------------------------------------- on list_of_countries_in_address_book(LocalPeople) set list_of_countries to {} tell application "Address Book" repeat with thePerson in LocalPeople repeat with theAddress in the address of thePerson set theCountry to get the country of theAddress if (theCountry is not missing value) and (theCountry is not in list_of_countries) then set end of list_of_countries to theCountry end if end repeat end repeat end tell log "Countries in address book: " log list_of_countries return list_of_countries end list_of_countries_in_address_book -------------------------------------------------------------------------------------------------------------------- on find_iso_code_in_country_list(country_alias, list_to_check) repeat with mycountry in list_to_check set myi to item 1 of mycountry set myca to item 2 of mycountry -- mycountry list format {iso,{country/countries}} -- big/small_iso_countries list format {iso, country} if class of myca is list then set myc to item 1 of myca else set myc to myca end if if country_alias is in myca then --log " looking for: " & country_alias & ", found: " & myi & " = " & myc return {myi, myc} end if end repeat -- if the country is not found return {"??", country_alias} end find_iso_code_in_country_list -------------------------------------------------------------------------------------------------------------------- on check_and_fix_country_name_and_code(LocalPeople) tell application "Address Book" repeat with thePerson in LocalPeople set changes_made to 0 set theName to the name of thePerson as string repeat with theAddress in the address of thePerson try -- a user reported an issue where it was not possible to read the label, so build in check set theAddressType to label of theAddress on error log theName & ": problem with address" exit repeat end try set message_str to theName & " (" & theAddressType & ")" set theCountry to (get the country of theAddress) set theCountryCode to (get the country code of theAddress) if (theCountry is missing value) then if (fill_empty_country) then --log " country is missing, set to default country: " & default_country set the country of theAddress to default_country set changes_made to changes_made + 1 else --log " country is missing, but -per user setting- not changing to " & default_country set end of list_of_missing_countries to message_str set log_missing to log_missing & message_str & return try add thePerson to group group_missing on error make new group with properties {name:group_missing} add thePerson to group group_missing end try end if end if set country_is_in_alias_list to false if (theCountry is in list_of_aliases) then set country_is_in_alias_list to true (* if (country_is_in_alias_list) then --log " " & theCountry & " is in list_of_aliases" else --log " " & theCountry & " is *not* in list_of_aliases" end if *) if (theCountry is not missing value) and (country_is_in_alias_list is not true) then -- Could not find country in my list, let's see if it is in the official iso list and if so: add to my list -- the official iso list is broken up in two parts: large countries and small countries -- this to speed up the search. -- Optional: still treat it as an "unknown" country, as it makes the script much faster if we do not have to do this fallback search --log message_str & ": can not find country " & theCountry & " in my list" set iso to "??" --log message_str & ": searching in large country list" set {iso, preferred} to my find_iso_code_in_country_list(theCountry, big_iso_countries) if (iso is "??") then -- could not find it in the list of large countries, let's try the small ones --log message_str & ": searching in small country list" set {iso, preferred} to my find_iso_code_in_country_list(theCountry, small_iso_countries) end if -- country was not in big country list, searched in small country list if (iso is not "??") then -- we found the country in the small country list --log " found in iso list: " & iso set end of list_of_aliases to theCountry set end of mycountries to {iso, {preferred}} end if -- country code was found in the large or small country list if (iso is "??") or (treat_iso_list_as_unknown is true) then set end of list_of_unknown_countries to theCountry set log_unknown to log_unknown & "copy {\"" & iso & "\", {\"" & theCountry & "\"}} to end of clist" & return --log message_str & ": unknown country " & theCountry & " (" & iso & ")" try add thePerson to group group_unknown on error make new group with properties {name:group_unknown} add thePerson to group group_unknown end try end if -- country code was found in the small country list, but treat as "unknown" end if -- country name was not in the user's list of countries if (theCountry is not missing value) and (country_is_in_alias_list is true) then --log " country is " & theCountry & ", check if it is the preferred name" set {iso, preferred} to my find_iso_code_in_country_list(theCountry, mycountries) if (iso is "") then set iso to the default country code -- this way you can overwrite the country code from the iso list considering case if (theCountry is not preferred) then --log " preferred name for " & theCountry & " is: " & preferred set the country of theAddress to preferred set changes_country to changes_country + 1 set changes_made to changes_made + 1 end if end considering if (iso is not "??") and ((theCountryCode is missing value) or (theCountryCode is not iso)) then --log message_str --log " country code for " & theCountry & " was " & theCountryCode & ", should be: " & iso set the country code of theAddress to iso set changes_made to changes_made + 1 set changes_code to changes_code + 1 else if ((theCountryCode is iso) and (theCountry is not preferred)) then -- this means: actual country name is not the preferred one -- leave it like that, up to the user to change in country list end if else --log " skipping, country is missing or not in lookup table: " & theCountry end if if (changes_made > 0) then --log "made changes to " & theName & " (" & theAddressType & ")" save end if --for testing: to reset everything to old situation --set the country code of theAddress to missing value -- iso set addresses_checked to addresses_checked + 1 end repeat -- loop of addresses for a person set names_checked to names_checked + 1 end repeat -- loop of persons save -- already did a save after each change, but just in case end tell end check_and_fix_country_name_and_code -------------------------------------------------------------------------------------------------------------------- on prepare_growl() if (use_growl) then tell application "System Events" to set use_growl to exists application process "GrowlHelperApp" if (not use_growl) then return -- using terms from application "GrowlHelperApp" tell application id "com.Growl.GrowlHelperApp" set the allNotificationsList to {"Alert"} set the enabledNotificationsList to allNotificationsList register as application  "Address Book country name plug-in" all notifications allNotificationsList  default notifications enabledNotificationsList  icon of application "Address Book" end tell -- end using terms from end if end prepare_growl on send_growl_msg(desc, msg) if (use_growl) then -- using terms from application "GrowlHelperApp" tell application id "com.Growl.GrowlHelperApp" notify with name  "Alert" title  desc description  msg application name "Address Book country name plug-in" end tell -- end using terms from end if end send_growl_msg -------------------------------------------------------------------------------------------------------------------- on check_latest_version(current_version) set myurl to "http://winfred.vankuijk.net/wp-content/uploads/latest_version_address_book_plugin.txt?" & current_version -- try to get the url with built in curl command, spend a maximum of 3 seconds to get it set mycmd to "/usr/bin/curl --fail --max-time 3 --output - " & myurl & " 2> /dev/null" set myloc to "http://winfred.vankuijk.net/2010/01/fixing-countries-in-address-book/#download" try set myoutput to do shell script mycmd on error -- could not check the latest version, will skip and go back to regular programme... return false end try set {latest_version, version_date, version_description} to parse_version_output(myoutput) if (current_version < latest_version) then try set open_site to display dialog "New version available: " & latest_version &  " (" & version_date & ")" & return & "You have version: " & current_version & return & return &  "New in this release: " & version_description & return & return & "Go to site?" buttons {"Skip", "Yes"}  default button "Yes" giving up after 20 with title "New version of plug-in available" on error return false -- user pressed Skip end try if button returned of open_site is "Yes" then try tell application "System Events" to open location myloc -- open in default browser on error return false end try return true -- if we arrive here: we opened the browser, user is going to download end if end if -- compare current_version to latest_version return false -- if we arrive here: we already have latest version end check_latest_version on parse_version_output(output) set savedDelimiters to AppleScript's text item delimiters try set AppleScript's text item delimiters to {"|"} -- output looks like "1.2.3|2010/01/12|what is new" set {myversion, mydate, mydesc} to text items of output on error set AppleScript's text item delimiters to savedDelimiters end try set AppleScript's text item delimiters to savedDelimiters -- reset the delimiter to the original state return {myversion, mydate, mydesc} end parse_version_output -------------------------------------------------------------------------------------------------------------------- on write_log_to_file() set mypath to (path to me) set the_content to "*** Address Book country names plug-in (v" & current_version & ") ***" & return &  "http://winfred.vankuijk.net/2010/01/fixing-countries-in-address-book/" & return & return &  ">>> Don't like to see this file? <<<" & return &  "Open script (location is mentioned below)" & return &  "and set *show_results* variable to false" & return & return if (count list_of_unknown_countries) > 0 then set the_content to the_content &  ("unknown countries in address book" & return &  "--------------------------------------------------------------------" & return &  "modify the list below: " & return &  "1) if missing (code='??'), add the official iso code (e.g. us, nl, fr, gb)" & return &  "2) if not missing: then it is not mandatory to add to table," & return &  " but you will get faster results if you add the row" & return &  " >>> don't want to see these in the list below? <<<" & return &  " Set *treat_iso_list_as_unknown* to false" & return &  "3) start with your preferred country name and add any aliases" & return &  " e.g. {\"de\", {\"Deutschland\",\"Germany\"}} -- prefer local name" & return &  " e.g. {\"es\", {\"Spain\",\"Spaain\"}} -- will fix incorrect spelling" & return &  "4) leave ISO code empty to use default country format" & return &  " e.g. {\"\", {\"Chile\"}} -- don't use Apple's format, use default format" & return &  return &  "note: *only* add ISO codes that are in the table at bottom of the script, " & return &  " Address Book hides addresses with ISO codes that it does not know!" & return &  return &  "##### start of list [copy lines below] ####################" & return &  log_unknown &  "##### end of list [copy lines above] ####################" & return &  return) end if if (count list_of_missing_countries) > 0 then tell application "Address Book" to set defco to default country code set the_content to the_content &  (return &  "FYI: contacts where address is available, but country is missing" & return &  "This is fine, however for missing countries the default format will be used" & return &  "In your case (Address Book > Settings > General): " & defco & return &  "--------------------------------------------------------------------" & return &  log_missing &  "--------------------------------------------------------------------" & return &  "") end if if ((count list_of_missing_countries) > 0 or (count list_of_unknown_countries) > 0) and (check_for_updates is not true) then set the_content to the_content &  (return & return &  ">>> want to get updated of new versions of this script? <<<" & return &  "set *check_for_updates* variable to true" & return &  "") end if if ((count list_of_missing_countries) > 0 or (count list_of_unknown_countries) > 0) then set the_content to the_content &  (return & return &  "===========================================================================" & return &  "modify the list & settings to the following file and restart Address Book: " & return &  (POSIX path of mypath) & return &  "===========================================================================" & return &  "") end if set the_file to (((path to desktop) as string) & "Address Book countries plug-in report.txt") set fp to open for access the_file with write permission try -- set eof fp to 0 write the_content to fp starting at 1 end try close access fp --tell application "TextEdit" to open alias the_file tell application "Finder" to open the_file end write_log_to_file -------------------------------------------------------------------------------------------------------------------- -- settings for the address-book plug-in -- to use: install in /Library/Address Book Plug-Ins or ~/Library/Address Book Plug-Ins using terms from application "Address Book" on action property return "address" end action property on should enable action for thePerson with theEntry return true end should enable action on action title for thePerson with theEntry if plugin_only_selected is true then return "Check country name and code" else return "Check all country names and codes" end if end action title on perform action for thePerson with theEntry if plugin_only_selected is true then country_name_code(thePerson) -- only pass this person to the subroutine else country_name_code({}) -- {} means: leave empty, the subroutine will fill it later (with all persons) end if end perform action end using terms from -------------------------------------------------------------------------------------------------------------------- -- load all iso countries on load_iso_country_list() -- list is broken up in two parts to speed up the search. first search the large countries if that fails: search the small ones. -- 103 large countries (population > 7 million) set big_iso_countries to {{"ao", "Angola"}, {"ar", "Argentina"}, {"at", "Austria"}, {"au", "Australia"}, {"az", "Azerbaijan"}, {"bd", "Bangladesh"}, {"be", "Belgium"}, {"bf", "Burkina Faso"}, {"bg", "Bulgaria"}, {"bi", "Burundi"}, {"bj", "Benin"}, {"bo", "Bolivia"}, {"br", "Brazil"}, {"by", "Belarus"}, {"ca", "Canada"}, {"cd", "Democratic Republic of the Congo"}, {"ch", "Switzerland"}, {"ci", "C™te d'Ivoire"}, {"cl", "Chile"}, {"cm", "Cameroon"}, {"cn", "China"}, {"co", "Colombia"}, {"cs", "Czech Republic"}, {"cu", "Cuba"}, {"de", "Germany"}, {"do", "Dominican Republic"}, {"dz", "Algeria"}, {"ec", "Ecuador"}, {"eg", "Egypt"}, {"es", "Spain"}, {"et", "Ethiopia"}, {"fr", "France"}, {"gb", "United Kingdom"}, {"gn", "Guinea"}, {"gr", "Greece"}, {"gt", "Guatemala"}, {"hk", "Hong Kong"}, {"hn", "Honduras"}, {"ht", "Haiti"}, {"hu", "Hungary"}, {"id", "Indonesia"}, {"il", "Israel"}, {"in", "India"}, {"iq", "Iraq"}, {"ir", "Iran"}, {"it", "Italy"}, {"ja", "Japan"}, {"ke", "Kenya"}, {"kh", "Cambodia"}, {"kp", "North Korea"}, {"kr", "South Korea"}, {"kz", "Kazakhstan"}, {"lk", "Sri Lanka"}, {"ma", "Morocco"}, {"mg", "Madagascar"}, {"ml", "Mali"}, {"mm", "Myanmar"}, {"mw", "Malawi"}, {"mx", "Mexico"}, {"my", "Malaysia"}, {"mz", "Mozambique"}, {"ne", "Niger"}, {"ng", "Nigeria"}, {"nl", "Netherlands"}, {"np", "Nepal"}, {"pe", "Peru"}, {"ph", "Philippines"}, {"pk", "Pakistan"}, {"pl", "Poland"}, {"pt", "Portugal"}, {"ro", "Romania"}, {"rs", "Serbia"}, {"ru", "Russian Federation"}, {"rw", "Rwanda"}, {"sa", "Saudi Arabia"}, {"sd", "Sudan"}, {"se", "Sweden"}, {"sn", "Senegal"}, {"so", "Somalia"}, {"sy", "Syrian Arab Republic"}, {"td", "Chad"}, {"th", "Thailand"}, {"tn", "Tunisia"}, {"tr", "Turkey"}, {"tw", "Taiwan"}, {"tz", "United Republic of Tanzania"}, {"ua", "Ukraine"}, {"ug", "Uganda"}, {"us", "United States"}, {"uz", "Uzbekistan"}, {"ve", "Venezuela"}, {"vn", "Viet Nam"}, {"ye", "Yemen"}, {"yu", "Serbia and Montenegro"}, {"za", "South Africa"}, {"zm", "Zambia"}, {"zw", "Zimbabwe"}} -- 97 small countries (population < 7 million) set small_iso_countries to {{"ad", "Andorra"}, {"ae", "United Arab Emirates"}, {"ag", "Antigua and Barbuda"}, {"al", "Albania"}, {"am", "Armenia"}, {"ba", "Bosnia and Herzegovina"}, {"bb", "Barbados"}, {"bh", "Bahrain"}, {"bm", "Bermuda"}, {"bn", "Brunei Darussalam"}, {"bs", "Bahamas"}, {"bt", "Bhutan"}, {"bw", "Botswana"}, {"bz", "Belize"}, {"cf", "Central African Republic"}, {"cg", "Congo"}, {"cr", "Costa Rica"}, {"cv", "Cape Verde"}, {"cy", "Cyprus"}, {"dj", "Djibouti"}, {"dk", "Denmark"}, {"dm", "Dominica"}, {"ee", "Estonia"}, {"er", "Eritrea"}, {"fi", "Finland"}, {"fj", "Fiji"}, {"fk", "Falkland Islands"}, {"fo", "Faroe Islands"}, {"ga", "Gabon"}, {"gd", "Grenada"}, {"ge", "Georgia"}, {"gl", "Greenland"}, {"gm", "Gambia"}, {"gq", "Equatorial Guinea"}, {"gs", "South Georgia and South Sandwich Islands"}, {"gw", "Guinea-Bissau"}, {"gy", "Guyana"}, {"hr", "Croatia"}, {"ie", "Ireland"}, {"im", "Isle of Man"}, {"is", "Iceland"}, {"jm", "Jamaica"}, {"jo", "Jordan"}, {"kg", "Kyrgyzstan"}, {"ki", "Kiribati"}, {"km", "Comoros"}, {"kw", "Kuwait"}, {"ky", "Cayman Islands"}, {"la", "Lao People's Democratic Republic"}, {"lb", "Lebanon"}, {"lc", "Saint Lucia"}, {"li", "Liechtenstein"}, {"lr", "Liberia"}, {"ls", "Lesotho"}, {"lt", "Lithuania"}, {"lu", "Luxembourg"}, {"lv", "Latvia"}, {"ly", "Libya"}, {"mc", "Monaco"}, {"md", "Moldova"}, {"me", "Montenegro"}, {"mk", "Macedonia"}, {"mn", "Mongolia"}, {"mo", "Macao"}, {"mr", "Mauritania"}, {"mt", "Malta"}, {"mu", "Mauritius"}, {"mv", "Maldives"}, {"na", "Namibia"}, {"nc", "New Caledonia"}, {"ni", "Nicaragua"}, {"no", "Norway"}, {"nr", "Republic of Nauru"}, {"nz", "New Zealand"}, {"om", "Oman"}, {"pa", "Panama"}, {"pf", "French Polynesia"}, {"pg", "Papua New Guinea"}, {"py", "Paraguay"}, {"qa", "Qatar"}, {"sb", "Solomon Islands"}, {"sc", "Seychelles"}, {"sg", "Singapore"}, {"sh", "Saint Helena"}, {"si", "Slovenia"}, {"sk", "Slovakia"}, {"sl", "Sierra Leone"}, {"sr", "Suriname"}, {"st", "Sao Tome and Principe"}, {"sv", "El Salvador"}, {"sz", "Swaziland"}, {"tg", "Togo"}, {"tj", "Tajikistan"}, {"tl", "Timor-Leste"}, {"tm", "Turkmenistan"}, {"to", "Tonga"}, {"tt", "Trinidad and Tobago"}, {"tv", "Tuvalu"}, {"uy", "Uruguay"}, {"va", "Vatican"}, {"vc", "Saint Vincent and the Grenadines"}, {"vu", "Vanuatu"}, {"ws", "Samoa"}} -- list of supported countries can be found here: -- http://developer.apple.com/library/ios/#documentation/AddressBook/Reference/ABPersonRef_iPhoneOS/Reference/reference.html#//apple_ref/c/data/kABPersonAddressCountryCodeKey -- http://developer.apple.com/library/mac/#documentation/UserExperience/Reference/AddressBook/Classes/ABPerson_Class/Reference/CountryCodes.html#//apple_ref/doc/uid/TP40003945-RH2 -- although the Address Book e.g. shows the country Afghanistan, but the list on the developer site does not show that one -- !!! do not add ISO codes to the above list, these are from Apple's own (iPhone) list and Apple will hide addresses with any other codes !!! end load_iso_country_list