emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* org-attach and UUID case
@ 2019-07-09 17:46 Zachary Newman
  0 siblings, 0 replies; only message in thread
From: Zachary Newman @ 2019-07-09 17:46 UTC (permalink / raw)
  To: emacs-orgmode

*tl;dr*: ~org-id-new~ sometimes generates upcase UUIDs, sometimes downcase.
Combined with case-insensitive filesystems, this can be bad. I have a
workaround, wondering if a fix is appropriate.

It appears that on my MacBook, ~org-id-new~ uses upper-case while on my NixOS
box it uses lowercase (I believe because ~uuidgen~ is not available). This
*should* be fine, but I sync my org files via Dropbox, which will do things
*like: if there's a file ~FOO~ and you add a file ~foo~, it'll (very
*helpfully) rename ~foo~ to ~FOO (Case Conflict)~.
See https://help.dropbox.com/installs-integrations/sync-uploads/case-conflict

This means if we:

1. create an attachment with UUID beginning with e.g. ~ff~
2. create another attachment with UUID beginning with ~FF~ (pretty likely due
   to birthday paradox)
3. wait for Dropbox to rename the latter
4. try to do anything with the latter attachment

org cannot find the attachment directory!

I'd consider this mostly the fault of Dropbox, but in general I'd hope that
org would play nice when syncing across filesystems.

We can fix it pretty simply (thanks, Gustav Wikström, for commit ae9cd437!):

#+BEGIN_SRC emacs-lisp
(setq org-attach-id-to-path-function
  (lambda (id) (upcase (org-attach-id-folder-format id))))
#+END_SRC

However, if we have some pre-existing directories, we run into trouble (they can
no longer be found!). I patched mine up by hand (because I was doing this from a
case-insensitive filesystem, which made the whole thing a nightmare). See
post-script for an automated way to do it.

Is it worth trying to prevent this? We could:

- make generated UUIDs consistent case (upcase/downcase the output of
  ~org-id-uuid-program~)
- make ~org-attach-id-to-path-function~ upcase/downcase by default

I'd lean towards the latter option.

If we do that, we'd have to handle existing "wrong"-cased
attachment directories for users, but we have a few options for doing so:

- check all cases on disk when computing ~(org-attach-dir)~ and silently use the
  right one
- check all cases and set ~:DIR:~ (with prompt?) for the entry
- check all cases and move the dir to the right case (with prompt)
- provide a one-time migration function

I'd lean towards the second option, with a prompt.

I'm happy to work on it (and sign over the copyright etc.), but would like to
make sure that it's something we actually want to do and the approach is
acceptable before beginning. Or it might be too much of an edge-case to change
things for.

Cheers,
Zack

P.S. Something like the following should work if your filesystem is case-sensitive
(not totally tested):

#+BEGIN_SRC emacs-lisp
(defun get-path-variants (path)
  (let* ((path-parts (split-string path "/"))
         (basedir (mapconcat 'identity (butlast path-parts 2) "/"))
         (part1 (car (last path-parts 2)))
         (part2 (cadr (last path-parts 2))))
    (list (concat basedir "/" (downcase part1) "/" (downcase part2))
          (concat basedir "/" (downcase part1) "/" (upcase   part2))
          (concat basedir "/" (upcase   part1) "/" (downcase part2))
          (concat basedir "/" (upcase   part1) "/" (upcase   part2)))))

(defun normalize-attach-dir ()
  (let* ((attach-dir (org-attach-dir)))
    (mapc (lambda (attach-dir-variant)
            (if (and (file-exists-p attach-dir-variant)
                     (not (string= attach-dir-variant attach-dir)))
                (rename-file attach-dir-variant attach-dir)))
          (get-path-variants -attach-dir))
    (org-set-property "ID" (upcase (org-entry-get (point) "ID" nil)))))

(defun attach-dir-matcher (todo tags-list level)
  (not (eq (org-attach-dir) nil)))

(defun normalize-attach-dirs ()
  (mapc (lambda (file)
          (with-current-buffer (org-get-agenda-file-buffer file)
            (org-scan-tags #'normalize-attach-dir #'attach-dir-matcher nil)))
        (org-agenda-files t)))
#+END_SRC

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-07-09 17:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-07-09 17:46 org-attach and UUID case Zachary Newman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).