From 37c884aa2ed04dde4daf00b5ca19efd7e2a6dbaf Mon Sep 17 00:00:00 2001 From: djcb Date: Tue, 13 Dec 2011 07:44:45 +0200 Subject: [PATCH] * mm + mm-cmd-server: implement 'ping' -> startup version check --- src/mu-cmd-server.c | 18 ++++++++++-------- toys/mm/TODO | 3 +-- toys/mm/mm-proc.el | 37 ++++++++++++++++++++++++++----------- toys/mm/mm.el | 41 +++++++++++++++++++---------------------- 4 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/mu-cmd-server.c b/src/mu-cmd-server.c index 5cb28fbd..0107b978 100644 --- a/src/mu-cmd-server.c +++ b/src/mu-cmd-server.c @@ -178,7 +178,7 @@ enum _Cmd { CMD_QUIT, CMD_REMOVE, CMD_SAVE, - CMD_INFO, + CMD_PING, CMD_VIEW, CMD_IGNORE @@ -205,7 +205,7 @@ cmd_from_string (const char *str) { CMD_QUIT, "quit"}, { CMD_REMOVE, "remove" }, { CMD_SAVE, "save"}, - { CMD_INFO, "info"}, + { CMD_PING, "ping"}, { CMD_VIEW, "view"} }; @@ -292,18 +292,20 @@ check_param_num (GSList *lst, unsigned min, unsigned max) } - +/* -> ping + * <- (:pong mu :version :doccount ) + */ static MuError -cmd_info (MuStore *store, GSList *lst, GError **err) +cmd_ping (MuStore *store, GSList *lst, GError **err) { if (!check_param_num (lst, 0, 0)) return server_error (NULL, MU_ERROR_IN_PARAMETERS, "usage: version"); - send_expr ("(:info version " + send_expr ("(:pong \"" PACKAGE_NAME "\" " ":version \"" VERSION "\" " - ":doccount %u " - ")", + ":doccount %u" + ")\n", mu_store_count (store, err)); return MU_OK; @@ -897,7 +899,7 @@ handle_command (Cmd cmd, MuStore *store, MuQuery *query, GSList *args, case CMD_QUIT: rv = cmd_quit (args, err); break; case CMD_REMOVE: rv = cmd_remove (store, args, err); break; case CMD_SAVE: rv = cmd_save (store, args, err); break; - case CMD_INFO: rv = cmd_info (store, args, err); break; + case CMD_PING: rv = cmd_ping (store, args, err); break; case CMD_VIEW: rv = cmd_view (store, args, err); break; case CMD_IGNORE: return TRUE; diff --git a/toys/mm/TODO b/toys/mm/TODO index 16cc2448..9268fe1a 100644 --- a/toys/mm/TODO +++ b/toys/mm/TODO @@ -8,7 +8,6 @@ ** Features i -*** version check at startup *** documentation *** emacs install @@ -60,7 +59,7 @@ ** raw-mode / quit ** customizable bookmarks ** fix queued sending - +** version check at startup # Local Variables: # mode: org; org-startup-folded: nil diff --git a/toys/mm/mm-proc.el b/toys/mm/mm-proc.el index 6c1c7b96..065a28d8 100644 --- a/toys/mm/mm-proc.el +++ b/toys/mm/mm-proc.el @@ -33,49 +33,51 @@ (defvar mm/mu-proc nil "*internal* The mu-server process") -(defvar mm/proc-error-func nil +(defvar mm/proc-error-func 'mm/default-handler "*internal* A function called for each error returned from the server process; the function is passed an error plist as argument. See `mm/proc-filter' for the format.") -(defvar mm/proc-update-func nil +(defvar mm/proc-update-func 'mm/default-handler "*internal* A function called for each :update sexp returned from the server process; the function is passed a msg sexp as argument. See `mm/proc-filter' for the format.") -(defvar mm/proc-remove-func nil +(defvar mm/proc-remove-func 'mm/default-handler "*internal* A function called for each :remove sexp returned from the server process, when some message has been deleted. The function is passed the docid of the removed message.") -(defvar mm/proc-view-func nil +(defvar mm/proc-view-func 'mm/default-handler "*internal* A function called for each single message sexp returned from the server process. The function is passed a message sexp as argument. See `mm/proc-filter' for the format.") -(defvar mm/proc-header-func nil +(defvar mm/proc-header-func 'mm/default-handler "*internal* A function called for each message returned from the server process; the function is passed a msg plist as argument. See `mm/proc-filter' for the format.") -(defvar mm/proc-found-func nil +(defvar mm/proc-found-func 'mm/default-handler "*internal* A function called for when we received a :found sexp after the headers have returns, to report on the number of matches. See `mm/proc-filter' for the format.") - -(defvar mm/proc-compose-func nil +(defvar mm/proc-compose-func 'mm/default-handler "*internal* A function called for each message returned from the server process that is used as basis for composing a new message (ie., either a reply or a forward); the function is passed msg and a symbol (either reply or forward). See `mm/proc-filter' for the format of .") -(defvar mm/proc-info-func nil +(defvar mm/proc-info-func 'mm/default-handler "*internal* A function called for each (:info type ....) sexp received from the server process.") +(defvar mm/proc-pong-func 'mm/default-handler + "*internal* A function called for each (:pong type ....) sexp +received from the server process.") (defvar mm/buf nil "*internal* Buffer for results data.") @@ -112,10 +114,13 @@ process." ((plist-get info :message) (message "%s" (plist-get info :message)))))) +(defun mm/default-handler (&rest args) + "Dummy handler function." + (error "Not handled: %S" args)) + (defconst mm/server-name "*mm-server" "*internal* Name of the server process, buffer.") - (defun mm/start-proc () "Start the mu server process." ;; TODO: add version check @@ -247,7 +252,7 @@ updated as well, with all processed sexp data removed." ((plist-get sexp :date) (funcall mm/proc-header-func sexp)) - ;; the found sexp, we receive after gett all the headers + ;; the found sexp, we receive after getting all the headers ((plist-get sexp :found) (funcall mm/proc-found-func (plist-get sexp :found))) @@ -255,6 +260,11 @@ updated as well, with all processed sexp data removed." ((plist-get sexp :view) (funcall mm/proc-view-func (plist-get sexp :view))) + ;; receive a pong message + ((plist-get sexp :pong) + (funcall mm/proc-pong-func + (plist-get sexp :version) (plist-get sexp :doccount))) + ;; something got moved/flags changed ((plist-get sexp :update) (funcall mm/proc-update-func @@ -397,6 +407,11 @@ set to e.g. '/drafts'; if this works, we will receive (:info :path "Open attachment PARTIDX from message with DOCID." (mm/proc-send-command "open %d %d" docid partidx)) +(defun mm/proc-ping () + "Sends a ping to the mu server, expecting a (:pong ...) in +response." + (mm/proc-send-command "ping")) + (defun mm/proc-view-msg (docid) "Get one particular message based on its DOCID. The result will be delivered to the function registered as `mm/proc-message-func'." diff --git a/toys/mm/mm.el b/toys/mm/mm.el index 0aa530d1..64db17de 100644 --- a/toys/mm/mm.el +++ b/toys/mm/mm.el @@ -34,14 +34,16 @@ (require 'mm-send) (require 'mm-proc) +(require 'mm-version) ;; auto-generated + ;; mm-version.el is autogenerated, and defines mm/mu-version (require 'mm-version) ;; Customization (defgroup mm nil - "Mm." :group 'local) - + "mm - the mu mail client" + :group 'local) (defcustom mm/mu-home nil "Location of the mu homedir, or nil for the default." @@ -309,8 +311,6 @@ headers)." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; internal variables / constants -(defconst mm/mm-buffer-name "*mm*" - "*internal* Name of the mm main buffer.") (defconst mm/header-names '( (:attachments . "Attach") @@ -330,25 +330,22 @@ view). Most fields should be self-explanatory. A special one is `:from-or-to', which is equal to `:from' unless `:from' matches , in which case it will be equal to `:to'.)") - -;; General helper functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; TODO: make this recursive -(defun mm/get-sub-maildirs (maildir) - "Get all readable sub-maildirs under MAILDIR." - (let ((maildirs (remove-if - (lambda (dentry) - (let ((path (concat maildir "/" dentry))) - (or - (string= dentry ".") - (string= dentry "..") - (not (file-directory-p path)) - (not (file-readable-p path)) - (file-exists-p (concat path "/.noindex"))))) - (directory-files maildir)))) - (map 'list (lambda (dir) (concat "/" dir)) maildirs))) - +;; mm startup function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun mm () + "Start mm. We do this by sending a 'ping' to the mu server +process, and start the main view if the 'pong' we receive from the +server has the expected values." + (interactive) + (if (buffer-live-p mm/main-buffer-name) + (switch-to-buffer mm/main-buffer-name) + (setq mm/proc-pong-func + (lambda (version doccount) + (unless (string= version mm/mu-version) + (error "mu server has version %s, but we need %s" + version mm/mu-version)) + (mm/main-view))) + (mm/proc-ping))) (defun mm/ask-maildir (prompt) "Ask the user for a shortcut (using PROMPT) as defined in