1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-14 16:50:58 +00:00

EUDC: Add macOS Contacts backend

* lisp/net/eudcb-macos-contacts.el: New file.
* doc/misc/eudc.texi (macOS Contacts): New section.
(macOS Contacts Configuration): Likewise.
* etc/NEWS: Mention new macOS Contacts backend.
This commit is contained in:
Alexander Adolf 2020-05-02 11:13:20 -04:00 committed by Thomas Fitzsimmons
parent 2d7c3e49b0
commit 814e3b0b17
3 changed files with 177 additions and 0 deletions

View File

@ -83,6 +83,8 @@ Currently supported back-ends are:
LDAP, Lightweight Directory Access Protocol
@item
BBDB, Big Brother's Insidious Database
@item
macOS Contacts
@end itemize
The main features of the EUDC interface are:
@ -107,6 +109,7 @@ Interface to BBDB to let you insert server records into your own BBDB database
@menu
* LDAP:: What is LDAP ?
* BBDB:: What is BBDB ?
* macOS Contacts:: What is macOS Contacts ?
@end menu
@ -159,6 +162,21 @@ queries on multiple servers.
EUDC also offers a means to insert results from directory queries into
your own local BBDB (@pxref{Creating BBDB Records})
@node macOS Contacts
@section macOS Contacts
macOS Contacts is the rolodex-like application that ships with the
macOS operating system@footnote{Apple have changed the names of their
operating system and some applications over time. macOS used to be
called Mac OS X in the past, and the Contacts application was
previously called Address Book.}.
EUDC considers macOS Contacts as a directory server back end just like
LDAP, though the macOS Contacts application always resides locally on
your machine.
@node Installation
@chapter Installation
@ -185,6 +203,7 @@ email composition buffers (@pxref{Inline Query Expansion})
@menu
* LDAP Configuration:: EUDC needs external support for LDAP
* macOS Contacts Configuration:: Enable the macOS Contacts backend
@end menu
@node LDAP Configuration
@ -379,6 +398,39 @@ The @command{ldapsearch} command is formatted such that it can be
copied and pasted into a terminal. Set the @command{ldapsearch} debug
level to 5 by appending @code{-d 5} to the command line.
@node macOS Contacts Configuration
@section macOS Contacts Configuration
macOS Contacts support is added by means of @file{eudcb-mab.el}, or
@file{eudcb-macos-contacts.el} which are part of Emacs.
To enable a macOS Contacts backend, first `require' the respective
library to load it, and then set the `eudc-server' to localhost in
your init file:
@lisp
(require 'eudcb-macos-contacts)
(eudc-macos-contacts-set-server "localhost")
@end lisp
@file{eudcb-macos-contacts.el} uses the public scripting interfaces
offered by the Contacts app via the macOS Open Scripting Architecture
(OSA). To accomplish this, @file{eudcb-macos-contacts.el} uses an
external command line utility named osascript, which is included with
all macOS versions since 10.0 (which was released 2001).
@file{eudcb-macos-contacts.el} is hence recommended for all new
configurations.
@file{eudcb-mab.el} reverse engineers the format of the database file
used by the macOS Contacts app, and accesses its contents directly.
While this may promise some performance advantages, it comes at the
cost of using an undocumented interface. Hence, users of
@file{eudcb-mab.el} are recommended to double check the compatibility
of @file{eudcb-mab.el} before upgrading to a new version of macOS.
@file{eudcb-mab.el} is retained for backwards compatibility with
existing configurations, and may be removed in a future release.
@node Usage
@chapter Usage

View File

@ -279,6 +279,13 @@ This allows users to use (define-key eshell-mode-map ...) as usual.
Some modules have their own minor mode now to account for these
changes.
** EUDC
+++
*** New macOS Contacts backend.
This backend works on newer versions of macOS and is generally
preferred over the eudcb-mab.el backend.
** Tramp
+++

View File

@ -0,0 +1,118 @@
;;; eudcb-macos-contacts.el --- EUDC - macOS Contacts backend
;; Copyright (C) 2020 condition-alpha.com
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This library provides an interface to the macOS Contacts app as
;; an EUDC data source. It uses AppleScript to interface with the
;; Contacts app on localhost, so no 3rd party tools are needed.
;;; Usage:
;; (require 'eudcb-macos-contacts)
;; (eudc-macos-contacts-set-server "localhost")
;;; Code:
(require 'eudc)
(require 'executable)
;;{{{ Internal cooking
(defvar eudc-macos-contacts-conversion-alist nil)
;; hook ourselves into the EUDC framework
(eudc-protocol-set 'eudc-query-function
'eudc-macos-contacts-query-internal
'macos-contacts)
(eudc-protocol-set 'eudc-list-attributes-function
nil
'macos-contacts)
(eudc-protocol-set 'eudc-macos-contacts-conversion-alist
nil
'macos-contacts)
(eudc-protocol-set 'eudc-protocol-has-default-query-attributes
nil
'macos-contacts)
(defun eudc-macos-contacts-search-helper (str)
"Helper function to query the Contacts app via AppleScript.
Searches for all persons with a case-insensitive substring match
of STR in any of their name fields (first, middle, or last)."
(if (executable-find "osascript")
(call-process "osascript" nil t nil
"-e"
(format "
set results to {}
tell application \"Address Book\"
set pList to every person whose (name contains \"%s\")
repeat with pers in pList
repeat with emailAddr in emails of pers
set results to results & {name of pers & \":\" & value ¬
of emailAddr & \"\n\"}
end repeat
end repeat
get results as text
end tell" str))
(message (concat "[eudc] Error in macOS Contacts backend: "
"`osascript' executable not found. "
"Is this is a macOS 10.0 or later system?"))))
(defun eudc-macos-contacts-query-internal (query &optional return-attrs)
"Query macOS Contacts with QUERY.
QUERY is a list of cons cells (ATTR . VALUE) where ATTRs should be valid
macOS Contacts attribute names.
RETURN-ATTRS is a list of attributes to return, defaulting to
`eudc-default-return-attributes'."
(let ((macos-contacts-buffer (get-buffer-create " *macOS Contacts*"))
result)
(with-current-buffer macos-contacts-buffer
(erase-buffer)
(dolist (term query)
(eudc-macos-contacts-search-helper (cdr term)))
(delete-duplicate-lines (point-min) (point-max))
(goto-char (point-min))
(while (not (eobp))
(if (not (equal (line-beginning-position) (line-end-position)))
(let* ((args (split-string (buffer-substring
(point) (line-end-position))
":"))
(name (nth 0 args))
(email (nth 1 args)))
(setq result (cons `((name . ,name)
(email . ,email)) result))))
(forward-line))
result)))
;;}}}
;;{{{ High-level interfaces (interactive functions)
(defun eudc-macos-contacts-set-server (dummy)
"Set the EUDC server to macOS Contacts app.
The server in DUMMY is not actually used, since this backend
always and implicitly connetcs to an instance of the Contacts app
running on the local host."
(interactive)
(eudc-set-server dummy 'macos-contacts)
(message "[eudc] macOS Contacts app server selected"))
;;}}}
(eudc-register-protocol 'macos-contacts)
(provide 'eudcb-macos-contacts)
;;; eudcb-macos-contacts.el ends here