Найти пропущенные дни рождения в Apple Addressbook - PullRequest
0 голосов
/ 26 мая 2010

Я пытаюсь очистить дыры в моей адресной книге Mac. В качестве первого шага я хочу попросить всех своих друзей на день рождения, чтобы они могли поздравить их с сырными карточками Hallmark .

Мне нужна «группа» в моей адресной книге, чтобы отправлять по почте персонализированные сообщения.

Это приложение, которое я придумал:

tell application "Address Book"

make new group with properties {name:"No Birthday"}

set birthdayPeople to (get every person whose birth date is greater than date "Monday, January 1, 1900 12:00:00 AM")

repeat with i from 1 to number of items in people

    set thePerson to item i of people

    if not (birthdayPeople contains thePerson) then
        add thePerson to group "No Birthday"
    end if

end repeat
save 
end tell

Он ломается, но из сообщений об ошибках не могу понять, что не так:

Результат: ошибка «Невозможно сделать« class azf4 » Я бы \ "05F770BA-7492-436B-9B58-E24F494702F8: ABPerson \" приложения \ "Адресная книга \" в тип вектора. "число -1700 от« класса azf4 »id «05F770BA-7492-436B-9B58-E24F494702F8: ABPerson» к вектору

(Кстати: я упоминал, что это мой первый код AppleScript, КОГДА-ЛИБО? Итак, если этот код можно упростить или сделать более элегантным, это тоже приветствуется.)

1 Ответ

4 голосов
/ 26 мая 2010

Мы можем упростить это до пяти строк:

tell application "Address Book"
    add (every person whose birth date is missing value) to ¬
        make new group with properties {name:"No Birthday"}
    save addressbook
end tell

Оказывается, что add может принимать список, а также отдельный объект, поэтому мы можем пропустить цикл. (Обратите внимание, что если бы вы использовали цикл, вы могли бы использовать форму repeat with thePerson in people ... end repeat, так как она чище, чем у вас.) Затем, похоже, что в Адресной книге пропущенные дни рождения хранятся как missing value (фактически null), поэтому мы должны проверить это, а не сравнивать с ранней датой. Таким образом, чтобы получить список людей без дня рождения, мы пишем every person whose birth date is missing value, что в точности соответствует тому, что написано. Предложение whose фильтрует предыдущий список, так что он содержит только значения, соответствующие данному предикату. Затем мы add получаем этот список для новой группы, которую мы создаем inline. Наконец, save addressbook сохраняет изменения и делает их видимыми.

Однако , в этом случае вам вообще не нужен AppleScript. Адресная книга поддерживает умные группы; чтобы создать его, нажмите на кнопку «Новая группа». Выберите «Нет дней рождения» в качестве имени смарт-группы и скажите, чтобы он соответствовал карточкам, для которых «День рождения» (из первого раскрывающегося списка) «не установлен» (из второго раскрывающегося списка). Это даст вам динамически обновляемую группу людей, у которых не установлен день рождения.


Редактировать: Кажется, что в то время как add берет список на Leopard, он не на Snow Leopard, поэтому нам нужно использовать явный цикл repeat (который работает на Leopard тоже):

tell application "Address Book"
    set noBirthdays to make new group with properties {name:"No Birthday"}

    repeat with p in (every person whose birth date is missing value)
        add p to noBirthdays
    end repeat

    save addressbook
end tell

Это работает почти так же, как и в приведенном выше решении, за исключением того, что мы заранее создаем группу, а затем добавляем каждый элемент по отдельности. Вместо того, чтобы перебирать индексы, мы перебираем элементы напрямую, так как это все, что нас волнует.


Редактировать: Для других свойств вещи похожи; на самом деле, при использовании смарт-группы, вещи идентичны. Со стороны AppleScript вопрос заключается в формате данных. Большинство слотов имеют missing value, когда они не установлены, но email является исключением. Как мы видим из тестирования, они хранятся в списке, поэтому нам нужно every person whose email is {}. Тем не менее, это не работает для меня - вероятно, потому что email - это список, но я не уверен - поэтому вы вместо этого захотите

    repeat with p in every person
        if email of p is {} then add p to noEmails
    end repeat

И вуаля, все должно работать.

Вводить и исключать компании также легко, но, насколько я могу судить, Адресная книга не предоставляет способ создать для них умную группу. Однако соответствующим свойством является company, что составляет true для предприятий и false для других. Таким образом, для создания списка без компаний, вы хотите сделать

    repeat with p in (every person whose company is false)
        add p to noCompanies
    end repeat

Если вам нужен один основной список со всеми этими критериями, есть два способа. Сначала из AppleScript вы берете два условия и and их, а затем добавляете условие того, есть ли у них электронное письмо:

    repeat with p in (every person whose company is false and ¬
                                         birth date is missing value)
        if email of p is {} then add p to masterGroup
    end repeat

Другой вариант - сделать это из адресной книги. Сначала вам нужно создать группу No Companies в стиле AppleScript. Затем вы создаете умную группу, соответствующую всем трем условиям (вы добавляете их с помощью кнопки +): «Электронная почта не установлена», «День рождения не установлен» и «Карта является участником« Нет компаний »». Это, вероятно, лучший вариант, хотя, к сожалению, вы должны использовать AppleScript для группы No Companies (я чувствую, что должен быть способ, но я не вижу, что это).

...