Emacs + LinkedIn: Another totally idiosyncratic bit of code

The following code should not be run until you’ve backed up your Big
Brother Database and sacrificed a chicken. It goes through the list of
people in your exported LinkedIn CSV, creates BBDB records if
necessary, adds a linkedin mail alias, and notices new e-mail
addresses and job titles. Call sacha/linkedin-import from the CSV.
Needs csv.el
and
lookout.el,
which you should load before running this code.

If anyone else ever finds this useful, I’ll be quite surprised.

(require 'csv)
(require 'lookout)

(setq lookout-bbdb-mapping-table
      '(("lastname" "Last Name")
        ("firstname" "First Name")
        ("company" "Company")
        ("job" "Job Title")
        ("net" "E-mail Address")))

(defun sacha/lookout-bbdb-check-linkedin (line)
  (let* ((lastname  (lookout-bbdb-get-value "lastname" line))
	 (firstname (lookout-bbdb-get-value "firstname" line))
	 (company   (lookout-bbdb-get-value "company" line))
         (job       (lookout-bbdb-get-value "job" line))
	 (net       (lookout-bbdb-get-value "net" line))
	 (addr1     (lookout-bbdb-get-value "addr1" line))
	 (addr2     (lookout-bbdb-get-value "addr2" line))
	 (addr3     (lookout-bbdb-get-value "addr3" line))
	 (phones    (lookout-bbdb-get-value "phones" line t)) ;; !
	 (notes     (lookout-bbdb-get-value "notes" line ))
         (j (concat job ", " company))
	 (otherfields (lookout-bbdb-get-value "otherfields" line t))
	 (addrs nil)
         (n (concat "^" firstname " " lastname))
	 (record (or (bbdb-search (bbdb-records) n)
                     (bbdb-search (bbdb-records) nil nil net)))
	 (message ""))
    (unless record
      (if (string= company "") (setq company nil))
      (if (string= notes "") (setq notes nil))
      (if (and addr1 (> (length addr1) 0))
	  (add-to-list 'addrs (vector "Address 1" (list addr1) "" "" "" "")))
      (if (and addr2 (> (length addr2) 0))
	  (add-to-list 'addrs (vector "Address 2" (list addr2) "" "" "" "")))
      (if (and addr3 (> (length addr3) 0))
	  (add-to-list 'addrs (vector "Address 3" (list addr3) "" "" "" "")))
      (setq record (list
                    (lookout-bbdb-create-entry (concat firstname " " lastname)
                                               (concat job ", " company)
                                               net
                                               addrs
                                               phones
                                               notes
                                               otherfields))))
    ;; Check if net has changed
    (when record
      (setq record (car record))
      (let ((nets (bbdb-record-net record)))
        (unless (member net nets)
          ;; New e-mail address noticed, add to front of list
          (add-to-list 'nets net)
          (bbdb-record-set-net record nets)
          (message "%s %s: New e-mail address noticed: %s" firstname lastname net)))
      ;; Check if job title and company have changed
      (when (or job company)
        (cond
         ((string= (or (bbdb-record-company record) "") "")
          (bbdb-record-set-company record j))
         ((string= (bbdb-record-company record) j)
          nil)
         (t
          (bbdb-record-set-notes
           record
           (concat "Noticed change from job title of "
                   (bbdb-record-company record)
           "\n"
           (bbdb-record-notes record)))
          (message "%s %s: Noticed change from job title of %s to %s"
                   firstname lastname (bbdb-record-company record) j)
          (bbdb-record-set-company record j))))
      (let* ((propsym bbdb-define-all-aliases-field)
             (oldaliases (bbdb-record-getprop record propsym)))
        (if oldaliases (setq oldaliases
                             (if (stringp oldaliases)
                                 (bbdb-split oldaliases ",")
                               oldaliases)))
        (add-to-list 'oldaliases "linkedin")
        (setq oldaliases (bbdb-join oldaliases ", "))
        (bbdb-record-putprop record propsym oldaliases)))))

(defun lookout-bbdb-create-entry (name company net addrs phones notes
				       &optional otherfields)
  (when (or t (y-or-n-p (format "Add %s to bbdb? " name)))
    ;;(message "Adding record to bbdb: %s" name)
    (let ((record (bbdb-create-internal name company net addrs phones notes)))
      (unless record (error "Error creating bbdb record"))
      (mapcar (lambda (i)
		(let ((field (make-symbol (aref i 0)))
		      (value (aref i 1)))
		  (when (and value (not (string= "" value)))
		    (bbdb-insert-new-field record field value))))
	      otherfields)
      record)))

(defun lookout-bbdb-get-value (key entry &optional as-vector-list)
  "Returns the value for a key from a lispified csv line, using the mapping
table."
  (let* ((table (if (listp lookout-bbdb-mapping-table)
		    lookout-bbdb-mapping-table
		  (symbol-value lookout-bbdb-mapping-table)))
	 (mapped-keys (cdr (assoc key table)))
	 (result nil)
	 (separator ""))




    (unless as-vector-list
      (setq result ""))
    (when mapped-keys
      (if (stringp mapped-keys)
          (setq mapped-keys (list mapped-keys)))
      (mapcar (lambda (i)
                ;;(message "%s...%s" i (cdr (assoc i entry)))
                (let ((value (cdr (assoc i entry))))
                  (unless (string= "" value)
                    (if as-vector-list
                        (add-to-list 'result (vector i value))
                      (setq result (concat result separator value)))
                    (setq separator " "))))
              mapped-keys))
    ;;(message "%s" result)
    result))

(defun sacha/linkedin-import ()
  (interactive)
  (mapcar
   'sacha/lookout-bbdb-check-linkedin
   (csv-parse-buffer)))

On Technorati: , , ,

3 responses to “Emacs + LinkedIn: Another totally idiosyncratic bit of code”

  1. Gijs says:

    Hi Sacha!

    well, testing this potentially useful code: I get

    Making completion list…
    mapcar: Wrong number of arguments: (lambda (first-line-contains-keys &optional buffer coding-system) “Parse a buffer containing CSV data, return data as a list of alists.

    Regards

    Gijs

  2. Ramon says:

    Gijs…

    did you actually sacrifice a chicken like the instruction says? Pics man – or it didn’t happen.
    I’m sticking w/ vim thanks.

    Mon

  3. Sacha Chua says:

    Gijs: Might be a problem with csv.el? Maybe doublecheck that that works…

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>