‘The half minute which we daily devote to the winding-up of our watches is an exertion of labour almost insensible; yet, by the aid of a few wheels, its effect is spread over the whole twenty-four hours.’

Automatically adding information to Org-roam file properties

Benjamin Slade

This expands on a feature I included in the setup for using Org-roam on Android/LineageOS in the last post, specifically automatically adding properties to newly created Org-roam files.

Since Org-roam v2 creates a top properties drawer (with an :ID: tag) anyway, it is nice to stick other information there as well. Specifically, information that could be useful in some situation, but which usually we don’t want to see, like :AUTHOR: (it’s probably you, and you know who you are), :CREATION_TIME: (and why not use Unix epoch time?), and so on. I have org drawers fold themselves automatically, so the normally-useless information doesn’t distract me.

We can do this by leveraging Org-roam’s org-roam-capture-new-node-hook, and some org-roam-add-property function calls, as below.

But, while we’re at it, we might also record where a note was made from. There are a number of ways we might do this, but an easy one (only requiring curl and an active Internet connection) is using ipinfo.io. curl ipinfo.io will give you a bunch of information in JSON format about your internet provider, including latitude and longitude, which will likely be at least somewhere near your present location. And curl ipinfo.io/loc will return just latitude,longitude.

  (defun bms/add-other-auto-props-to-org-roam-properties ()
    ;; if the file already exists, don't do anything, otherwise...
    (unless (file-exists-p (buffer-file-name))
      ;; if there's also a CREATION_TIME property, don't modify it
      (unless (org-find-property "CREATION_TIME")
        ;; otherwise, add a Unix epoch timestamp for CREATION_TIME prop
        ;; (this is what "%s" does - see http://doc.endlessparentheses.com/Fun/format-time-string )
        (org-roam-add-property
         (format-time-string "%s"
                             (nth 5
                                  (file-attributes (buffer-file-name))))
         "CREATION_TIME"))
      ;; similarly for AUTHOR and MAIL properties
      (unless (org-find-property "AUTHOR")
        (org-roam-add-property roam-user "AUTHOR"))
      (unless (org-find-property "MAIL")
        (org-roam-add-property roam-email "MAIL"))
      ;; also add the latitude and longitude
      (unless (org-find-property "LAT_LONG")
        ;; recheck location:
        (bms/get-lat-long-from-ipinfo)
        (org-roam-add-property (concat (number-to-string calendar-latitude) "," (number-to-string calendar-longitude)) "LAT-LONG"))))

  ;; hook to be run whenever an org-roam capture completes
  (add-hook 'org-roam-capture-new-node-hook #'bms/add-other-auto-props-to-org-roam-properties)

;; function to find latitude & longitude
;;                      (requires curl to be installed on system)
(setq calendar-latitude 0)
(setq calendar-longitude 0)
(defun bms/get-lat-long-from-ipinfo ()
  (let*
      ((latlong (substring
                 (shell-command-to-string "curl -s 'ipinfo.io/loc'")
                   0 -1))
       (latlong-list (split-string latlong ",")))
    (setq calendar-latitude (string-to-number (car latlong-list)))
    (setq calendar-longitude (string-to-number (cadr latlong-list)))))

You might also calculate/set calendar-latitude and calendar-longitude in other ways. Including just hard-coding them for stationary machines. On Android, we could in theory make use of the Termux command termux-location, which queries the device’s GPS. But unfortunately it doesn’t always work (if it can’t find a good connection to a GPS satellite) and even when it does work it’s slow, so it’s not something you’d want to call every time you made a note. GeoClue would be another possible source.

(If you’re using a VPN, you’ll want to escape from it somehow to get something closer to your real location. How you do this will vary based on your VPN provider and other factors. (If you’re calling from Emacs, and you use something like Mullvad, you may want to revise the shell-command-to-string to call up a bash session/script, then exclude that specific bash session/script from the VPN, and then call curl, so that the call references your “real” IP. E.g. if you’re using Mullvad, then:

#!/bin/bash
PID=`echo $$`
mullvad split-tunnel pid add "${PID}"
curl ipinfo.io/loc # for lat/long ; `curl ipinfo.io` for full info

might give you a start on something.))

Let me know if you think of other properties that could be useful to automatically add to Org-roam file properties.

If you have written a response to this, enter your response post's URL below.

Or, you can send a "comment" webmention (it's OK if you don't know what that means). When asked about your website on an IndieAuth login screen, simply type https://commentpara.de.

Markdown Support**bold**, _italics_, ~~strikethrough~~, [descr](link), `monospace`, ```LANG\nline1\nline2\n``` (Yep, multi-line code blocks too, with syntax highlighting!), auto-hyperlinking.

Webmentions #

Comment by Anonymous on Mon Mar 7, 2022 07:26 UTC
This looks fascinating. I didn’t know about functions like org-roam-add-property. (I’m also curious about WebMentions on your blog.)
Comment by B. Slade on Tue Aug 17, 2021 01:54 UTC
I’ve been working a bit more on this, including fiddling with termux-location. Perhaps will write up a follow-up later on. (also testing to see if webmentions are triggering rebuilds or not.)