How to automatically do org-mobile-push org-mobile pull in emacs

Since I am using org-mode to track my todo list in emacs, I like the iPhone app: MobileOrg, with it, I can access my todo list all day.

But here's the problem:

I have to manually org-mobile-push my changes from local file to mobile phone through dropbox, and org-mobile-pull the changes made by phone back.

How to make that automatically? Like adding some recipes in dotemacs file.

Answers


Add these two lines to dot emacs file:

(add-hook 'after-init-hook 'org-mobile-pull)
(add-hook 'kill-emacs-hook 'org-mobile-push) 

With them, it automatically pulls the changes on emacs startup, and pushes the changes before emacs exits.

-- Update

If you never exit your Emacs, this solution might not work for you. So, another solution using idle timer

;; moble sync
(defvar org-mobile-sync-timer nil)
(defvar org-mobile-sync-idle-secs (* 60 10))
(defun org-mobile-sync ()
  (interactive)
  (org-mobile-pull)
  (org-mobile-push))
(defun org-mobile-sync-enable ()
  "enable mobile org idle sync"
  (interactive)
  (setq org-mobile-sync-timer
        (run-with-idle-timer org-mobile-sync-idle-secs t
                             'org-mobile-sync)));
(defun org-mobile-sync-disable ()
  "disable mobile org idle sync"
  (interactive)
  (cancel-timer org-mobile-sync-timer))
(org-mobile-sync-enable)

I just found out it is same as below answer, so, if you prefer the idle timer solution, please upvote tkf's answer.


I have something like this in my Emacs setting to do push and pull when I am away from computer.

(defvar my-org-mobile-sync-timer nil)

(defvar my-org-mobile-sync-secs (* 60 20))

(defun my-org-mobile-sync-pull-and-push ()
  (org-mobile-pull)
  (org-mobile-push)
  (when (fboundp 'sauron-add-event)
    (sauron-add-event 'my 3 "Called org-mobile-pull and org-mobile-push")))

(defun my-org-mobile-sync-start ()
  "Start automated `org-mobile-push'"
  (interactive)
  (setq my-org-mobile-sync-timer
        (run-with-idle-timer my-org-mobile-sync-secs t
                             'my-org-mobile-sync-pull-and-push)))

(defun my-org-mobile-sync-stop ()
  "Stop automated `org-mobile-push'"
  (interactive)
  (cancel-timer my-org-mobile-sync-timer))

(my-org-mobile-sync-start)

Alternative is to put the following in cron job (I found this here https://github.com/matburt/mobileorg-android/wiki/Scripting/):

emacs --batch --load ~/.emacs --eval "(org-mobile-pull)" --eval "(org-mobile-push)"

As a side solution, similar to Sandeep C's

;; for Emacs 24.3.1 insert next line
(require 'cl)  
;; automatically org-mobile-push on save of a file
(add-hook 
 'after-save-hook 
 (lambda ()
   (let (
         (org-filenames (mapcar 'file-name-nondirectory (directory-files org-directory))) ; list of org file names (not paths)
         (filename (file-name-nondirectory buffer-file-name)) ; list of the buffers filename (not path)
         )
     (if (find filename org-filenames :test #'string=)
         (org-mobile-push)        
       )
     )
   )
)

This code is taken from http://kenmankoff.com/2012/08/17/emacs-org-mode-and-mobileorg-auto-sync/, with a couple of details changed. You need to configure the variables in the beginning. This code will

  • Check every 30s whether MobileOrg has synced, and if so

    • Pull from MobileOrg.
    • Push to MobileOrg.

      This is necessary to update the agenda views in MobileOrg. With this behavior, you can be away from your computer, update some things in MobileOrg, sync, wait 30 seconds, sync again, and your mobile agenda view will be updated.

  • Whenever an org file is saved
    • Check whether the saved org file is supposed to be synced with MobileOrg, and if so
      • Wait for the user to become idle
      • Push to MobileOrg

Code for your .emacs file:

(require 'org-mobile)
;; Configure these two variables
(setq org-mobile-inbox-for-pull "~/Dropbox/org/mobile.org" 
      org-mobile-directory "~/Dropbox/MobileOrg")
(require 'gnus-async) 
;; Define a timer variable
(defvar org-mobile-push-timer nil
  "Timer that `org-mobile-push-timer' used to reschedule itself, or nil.")
;; Push to mobile when the idle timer runs out
(defun org-mobile-push-with-delay (secs)
   (when org-mobile-push-timer
    (cancel-timer org-mobile-push-timer))
  (setq org-mobile-push-timer
        (run-with-idle-timer
         (* 1 secs) nil 'org-mobile-push)))
;; After saving files, start an idle timer after which we are going to push 
(add-hook 'after-save-hook 
 (lambda () 
   (if (or (eq major-mode 'org-mode) (eq major-mode 'org-agenda-mode))
     (dolist (file (org-mobile-files-alist))
       (if (string= (expand-file-name (car file)) (buffer-file-name))
           (org-mobile-push-with-delay 10))))))
;; watch mobileorg.org for changes, and then call org-mobile-pull
(defun org-mobile-install-monitor (file secs)
  (run-with-timer
   0 secs
   (lambda (f p)
     (unless (< p (second (time-since (elt (file-attributes f) 5))))
       (org-mobile-pull)
       (org-mobile-push)))
   file secs))
(defvar monitor-timer (org-mobile-install-monitor (concat org-mobile-directory "/mobileorg.org") 30)
  "Check if file changed every 30 s.")

you can also push right after saving a note, like this:

(add-hook 
  'after-save-hook 
  (lambda () 
     (if (string= buffer-file-name "<path to my notes.org>") 
        (org-mobile-push)
     )
  ))

I use this elisp code from gist on my init.el and it works pretty well, except it doesn't have org-mobile-pull built in.


I opted to simply push when saving, so I added this to my emacs init file:

(defun org-mobile-push-on-save ()
  "Used in `after-save-hook'."
  (when (memq this-command '(save-buffer save-some-buffers))
    (org-mobile-push)))

(add-hook 'org-mode-hook
          (lambda ()
            (add-hook 'after-save-hook 'org-mobile-push-on-save nil 'make-local)))

In a nutshell, it adds an after-save-hook to org-mode buffers.

More info on the code:

For auto-pull, a timer as in other answers is probably a good way.


Need Your Help

How to get the number of days of difference between two dates on mysql?

mysql date

I need to get the number of days contained within a couple of dates on MySQL.