<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/assets/rss.xsl" type="text/xsl"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"

>
<channel>
	<title>Sacha Chua - tag - hacks</title>
	<atom:link href="https://sachachua.com/blog/tag/hacks/feed/index.xml" rel="self" type="application/rss+xml" />
	<atom:link href="https://sachachua.com/blog/tag/hacks" rel="alternate" type="text/html" />
	<link>https://sachachua.com/blog/tag/hacks/feed/index.xml</link>
	<description>Emacs, sketches, and life</description>
  
	<lastBuildDate>Thu, 09 Jul 2026 00:30:29 GMT</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>11ty</generator>
  <item>
		<title>Emacs + LinkedIn: Another totally idiosyncratic bit of code</title>
		<link>https://sachachua.com/blog/2006/09/emacs-linkedin-another-totally-idiosyncratic-bit-of-code/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Thu, 28 Sep 2006 05:55:00 GMT</pubDate>
    <category>connecting</category>
<category>emacs</category>
		<guid isPermaLink="false">https://sachachua.com/blog/?p=3884</guid>
		<description><![CDATA[<p>The following code should not be run until you've backed up your Big<br>
Brother Database and sacrificed a chicken. It goes through the list of<br>
people in your exported LinkedIn CSV, creates BBDB records if<br>
necessary, adds a linkedin mail alias, and notices new e-mail<br>
addresses and job titles. Call sacha/linkedin-import from the CSV.<br>
Needs <a href="http://de.geocities.com/ulf_jasper/lisp/csv.el.txt">csv.el</a><br>
and<br>
<a href="http://de.geocities.com/ulf_jasper/lisp/lookout.el.txt">lookout.el</a>,<br>
which you should load before running this code.</p>
<p>If anyone else ever finds this useful, I'll be quite surprised.</p>
<pre class="example">
(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)))
</pre>


<p>You can <a href="https://sachachua.com/blog/2006/09/emacs-linkedin-another-totally-idiosyncratic-bit-of-code/#comment">view 3 comments</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2006%2F09%2Femacs-linkedin-another-totally-idiosyncratic-bit-of-code%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item>
	</channel>
</rss>