From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tino Calancha Newsgroups: gmane.emacs.devel Subject: image-dired: Check all external programs available Date: Sun, 28 Aug 2016 23:58:59 +0900 (JST) Message-ID: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; format=flowed; charset=US-ASCII X-Trace: blaine.gmane.org 1472396426 18315 195.159.176.226 (28 Aug 2016 15:00:26 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 28 Aug 2016 15:00:26 +0000 (UTC) User-Agent: Alpine 2.20 (DEB 67 2015-01-07) Cc: tino.calancha@gmail.com To: Emacs developers Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Aug 28 17:00:22 2016 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1be1ZN-0004Oh-K8 for ged-emacs-devel@m.gmane.org; Sun, 28 Aug 2016 17:00:21 +0200 Original-Received: from localhost ([::1]:39674 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1be1ZL-00087s-5l for ged-emacs-devel@m.gmane.org; Sun, 28 Aug 2016 11:00:19 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:47561) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1be1ZC-00080t-0g for emacs-devel@gnu.org; Sun, 28 Aug 2016 11:00:11 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1be1Z5-0002aw-Tp for emacs-devel@gnu.org; Sun, 28 Aug 2016 11:00:09 -0400 Original-Received: from mail-pf0-f193.google.com ([209.85.192.193]:32990) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1be1Z5-0002Zx-LL for emacs-devel@gnu.org; Sun, 28 Aug 2016 11:00:03 -0400 Original-Received: by mail-pf0-f193.google.com with SMTP id i6so7772048pfe.0 for ; Sun, 28 Aug 2016 08:00:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:date:to:cc:subject:message-id:user-agent:mime-version; bh=lXN3+I1rLUqUGlEHbI+CMa9cwCunqRtjrlO8+Ff5TIs=; b=gt+cS1yUECZPfZHL9nawD/I6ETtEi2lgn/tAGVvwJWU8ENxX4vTKQ3tLoB5E34I2G/ sZEfF9caBU1X3pA0vKWjjxzhjZFJTR8H4AqRnLlmHkJukZx6aYzktnPeTCyW6dpXtt2m TBZHFlWZH+upxlHO24HWnbRiZY+HG1MXWqbnp3QYgLCpjhvH/JA+ryaKFLXFaFizfLdX HhslFM602TRXUr6F/kC5hUICnKeUZ0exTTKWauQLcXdIBiWha4y71hXVwgaUe+4HdFtx eOr2/HUF71qXfAR36mmNPQwfp4+XGl1MtxkTxgmUK2yd/+CxB8k8VNf29G1MRMRdPIQm pH0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:date:to:cc:subject:message-id:user-agent :mime-version; bh=lXN3+I1rLUqUGlEHbI+CMa9cwCunqRtjrlO8+Ff5TIs=; b=U6uBa+SblU8VGUZv/sf4VAZLmSn0JXq+wK0Af/5LlaMLK0nQ6QT46m4WLC39KhpBMS icftSx7UFYSRRU5PMxvoXct+Cei5rcGulQAClkdmBYCein5Ka11nGQHHxPvtsLMvqObt dSkX7u7cG9WkQQt3dBiMJ/PS7wvmvh+XzL9Up/C9KtAYWSdGkts3vO7+Cuz9K8AUYpLC +InMF8fvGUd35H6HgMxY1KuMvs1hOiWqTdTYsEgQ1ZS0mKIb8m6WynZ9Tg/UchsmM0q0 ena68iNszEFNWACSUjtstQ0UUcv7rVKvnc+S8SlLKFy9Oh0OpXjNhxnKp2wqesl9QkHS WjsA== X-Gm-Message-State: AE9vXwOaXANGgW28dRXAiGVV8q5rbMcDIBgfN4oqxYXNrLSuAD8Xank7jckcxHSk6+UEmA== X-Received: by 10.98.23.134 with SMTP id 128mr24098300pfx.96.1472396342881; Sun, 28 Aug 2016 07:59:02 -0700 (PDT) Original-Received: from calancha-pc ([210.160.37.25]) by smtp.gmail.com with ESMTPSA id k78sm42454983pfa.78.2016.08.28.07.59.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 28 Aug 2016 07:59:02 -0700 (PDT) X-Google-Original-From: Tino Calancha X-X-Sender: calancha@calancha-pc X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.192.193 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:206846 Archived-At: image-dired uses several external programs. The file introduces user options with the name of the executables; for instance, image-dired-cmd-create-thumbnail-program has default value 'convert'. If an user don't have installed one of these external programs, and s?he run one function requiring that missing executable, then the error is not very clear. For instance, calling image-dired-rotate-original when image-dired-cmd-rotate-original-program is not installed throw an error: 'Could not rotate image'. For this case seems better to report that the required executable is not available. Such error would avoid the need to read the code to understand what was actually wrong. I propose a patch which set default value nil for the option if the executable is not found. Every function using an external program has a nil check for the option storing the executable name: when the option is nil, the function throw an error reporting that the option is nil. Do you think this proposal is useful? ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >From 4cf0cb63adec2d5b6c89eee78645106d2479462f Mon Sep 17 00:00:00 2001 From: Tino Calancha Date: Sun, 28 Aug 2016 23:33:09 +0900 Subject: [PATCH] image-dired: Report when a necessary executable is not found * lisp/image-dired.el (image-dired-cmd-rotate-original-program) (image-dired-cmd-create-thumbnail-program) (image-dired-cmd-create-temp-image-program) (image-dired-cmd-rotate-thumbnail-program) (image-dired-cmd-write-exif-data-program) (image-dired-cmd-read-exif-data-program): Use executable-find to set the defaut value for this option. (image-dired-cmd-rotate-original-program): Search for program 'convert' if 'jpegtran' is not found. (image-dired-cmd-rotate-original-options): Set the default value consistent with the executable in image-dired-cmd-rotate-original-program. (image-dired-thumb-name, image-dired-display-image) (image-dired-image-at-point-p, image-dired-rotate-original) (image-dired-thumbnail-set-image-description) (image-dired-set-exif-data): Throw and error when the executable used in the function is not found. --- lisp/image-dired.el | 110 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 46 deletions(-) diff --git a/lisp/image-dired.el b/lisp/image-dired.el index 67b023d..2511e13 100644 --- a/lisp/image-dired.el +++ b/lisp/image-dired.el @@ -224,7 +224,7 @@ image-dired-gallery-thumb-image-root-url :group 'image-dired) (defcustom image-dired-cmd-create-thumbnail-program - "convert" + (executable-find "convert") "Executable used to create thumbnail. Used together with `image-dired-cmd-create-thumbnail-options'." :type 'string @@ -242,7 +242,7 @@ image-dired-cmd-create-thumbnail-options :group 'image-dired) (defcustom image-dired-cmd-create-temp-image-program - "convert" + (executable-find "convert") "Executable used to create temporary image. Used together with `image-dired-cmd-create-temp-image-options'." :type 'string @@ -308,7 +308,7 @@ image-dired-cmd-create-standard-thumbnail-command :group 'image-dired) (defcustom image-dired-cmd-rotate-thumbnail-program - "mogrify" + (executable-find "mogrify") "Executable used to rotate thumbnail. Used together with `image-dired-cmd-rotate-thumbnail-options'." :type 'string @@ -326,14 +326,20 @@ image-dired-cmd-rotate-thumbnail-options :group 'image-dired) (defcustom image-dired-cmd-rotate-original-program - "jpegtran" + (cond ((executable-find "jpegtran")) + ((executable-find "convert"))) "Executable used to rotate original image. Used together with `image-dired-cmd-rotate-original-options'." :type 'string :group 'image-dired) (defcustom image-dired-cmd-rotate-original-options - "%p -rotate %d -copy all -outfile %t \"%o\"" + (when image-dired-cmd-rotate-original-program + (pcase image-dired-cmd-rotate-original-program + ((pred (lambda (x) (string-match "jpegtran" x))) + "%p -rotate %d -copy all -outfile %t \"%o\"") + ((pred (lambda (x) (string-match "convert" x))) + "%p -rotate %d \"%o\" %t"))) "Format of command used to rotate original image. Available options are %p which is replaced by `image-dired-cmd-rotate-original-program', %d which is replaced by the @@ -358,7 +364,7 @@ image-dired-rotate-original-ask-before-overwrite :group 'image-dired) (defcustom image-dired-cmd-write-exif-data-program - "exiftool" + (executable-find "exiftool") "Program used to write EXIF data to image. Used together with `image-dired-cmd-write-exif-data-options'." :type 'string @@ -375,7 +381,7 @@ image-dired-cmd-write-exif-data-options :group 'image-dired) (defcustom image-dired-cmd-read-exif-data-program - "exiftool" + (executable-find "exiftool") "Program used to read EXIF data to image. Used together with `image-dired-cmd-read-exif-data-program-options'." :type 'string @@ -615,6 +621,8 @@ image-dired-thumb-name (defun image-dired-create-thumb (original-file thumbnail-file) "For ORIGINAL-FILE, create thumbnail image named THUMBNAIL-FILE." + (unless image-dired-cmd-create-thumbnail-program + (error "image-dired-cmd-create-thumbnail-program is nil")) (let* ((width (int-to-string image-dired-thumb-width)) (height (int-to-string image-dired-thumb-height)) (modif-time (format "%.0f" (float-time (nth 5 (file-attributes @@ -1810,6 +1818,8 @@ image-dired-display-image (progn (setq width (image-dired-display-window-width)) (setq height (image-dired-display-window-height)) + (unless image-dired-cmd-create-temp-image-program + (error "image-dired-cmd-create-temp-image-program is nil")) (setq command (format-spec image-dired-cmd-create-temp-image-options @@ -1866,20 +1876,22 @@ image-dired-image-at-point-p (defun image-dired-rotate-thumbnail (degrees) "Rotate thumbnail DEGREES degrees." - (if (not (image-dired-image-at-point-p)) - (message "No thumbnail at point") - (let ((file (image-dired-thumb-name (image-dired-original-file-name))) - command) - (setq command (format-spec - image-dired-cmd-rotate-thumbnail-options - (list - (cons ?p image-dired-cmd-rotate-thumbnail-program) - (cons ?d degrees) - (cons ?t (expand-file-name file))))) - (call-process shell-file-name nil nil nil shell-command-switch command) - ;; Clear the cache to refresh image. I wish I could just refresh - ;; the current file but I do not know how to do that. Yet... - (clear-image-cache)))) + (unless (image-dired-image-at-point-p) + (message "No thumbnail at point")) + (unless image-dired-cmd-rotate-thumbnail-program + (error "image-dired-cmd-rotate-thumbnail-program is nil")) + (let ((file (image-dired-thumb-name (image-dired-original-file-name))) + command) + (setq command (format-spec + image-dired-cmd-rotate-thumbnail-options + (list + (cons ?p image-dired-cmd-rotate-thumbnail-program) + (cons ?d degrees) + (cons ?t (expand-file-name file))))) + (call-process shell-file-name nil nil nil shell-command-switch command) + ;; Clear the cache to refresh image. I wish I could just refresh + ;; the current file but I do not know how to do that. Yet... + (clear-image-cache))) (defun image-dired-rotate-thumbnail-left () "Rotate thumbnail left (counter clockwise) 90 degrees. @@ -1908,31 +1920,33 @@ image-dired-refresh-thumb (defun image-dired-rotate-original (degrees) "Rotate original image DEGREES degrees." - (if (not (image-dired-image-at-point-p)) - (message "No image at point") - (let ((file (image-dired-original-file-name)) - command) - (if (not (string-match "\\.[jJ][pP[eE]?[gG]$" file)) - (error "Only JPEG images can be rotated!")) - (setq command (format-spec - image-dired-cmd-rotate-original-options - (list - (cons ?p image-dired-cmd-rotate-original-program) - (cons ?d degrees) - (cons ?o (expand-file-name file)) - (cons ?t image-dired-temp-rotate-image-file)))) - (if (not (= 0 (call-process shell-file-name nil nil nil - shell-command-switch command))) - (error "Could not rotate image") - (image-dired-display-image image-dired-temp-rotate-image-file) - (if (or (and image-dired-rotate-original-ask-before-overwrite - (y-or-n-p - "Rotate to temp file OK. Overwrite original image? ")) - (not image-dired-rotate-original-ask-before-overwrite)) - (progn - (copy-file image-dired-temp-rotate-image-file file t) - (image-dired-refresh-thumb)) - (image-dired-display-image file)))))) + (unless (image-dired-image-at-point-p) + (message "No image at point")) + (unless image-dired-cmd-rotate-original-program + (error "image-dired-cmd-rotate-original-program is nil")) + (let ((file (image-dired-original-file-name)) + command) + (if (not (string-match "\\.[jJ][pP[eE]?[gG]$" file)) + (error "Only JPEG images can be rotated!")) + (setq command (format-spec + image-dired-cmd-rotate-original-options + (list + (cons ?p image-dired-cmd-rotate-original-program) + (cons ?d degrees) + (cons ?o (expand-file-name file)) + (cons ?t image-dired-temp-rotate-image-file)))) + (if (not (= 0 (call-process shell-file-name nil nil nil + shell-command-switch command))) + (error "Could not rotate image") + (image-dired-display-image image-dired-temp-rotate-image-file) + (if (or (and image-dired-rotate-original-ask-before-overwrite + (y-or-n-p + "Rotate to temp file OK. Overwrite original image? ")) + (not image-dired-rotate-original-ask-before-overwrite)) + (progn + (copy-file image-dired-temp-rotate-image-file file t) + (image-dired-refresh-thumb)) + (image-dired-display-image file))))) (defun image-dired-rotate-original-left () "Rotate original image left (counter clockwise) 90 degrees." @@ -1987,6 +2001,8 @@ image-dired-thumbnail-set-image-description (defun image-dired-set-exif-data (file tag-name tag-value) "In FILE, set EXIF tag TAG-NAME to value TAG-VALUE." + (unless image-dired-cmd-write-exif-data-program + (error "image-dired-cmd-write-exif-data-program is nil")) (let (command) (setq command (format-spec image-dired-cmd-write-exif-data-options @@ -1999,6 +2015,8 @@ image-dired-set-exif-data (defun image-dired-get-exif-data (file tag-name) "From FILE, return EXIF tag TAG-NAME." + (unless image-dired-cmd-read-exif-data-program + (error "image-dired-cmd-read-exif-data-program is nil")) (let ((buf (get-buffer-create "*image-dired-get-exif-data*")) command tag-value) (setq command (format-spec -- 2.9.3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; In GNU Emacs 25.1.50.1 (x86_64-pc-linux-gnu, GTK+ Version 3.20.9) of 2016-08-28 Repository revision: 7fcce24e75b8281621a0b8816dc58cbdc05fdc91