emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/plz f1a89a8816 68/81: Add: Download :as file


From: ELPA Syncer
Subject: [elpa] externals/plz f1a89a8816 68/81: Add: Download :as file
Date: Wed, 11 May 2022 17:58:03 -0400 (EDT)

branch: externals/plz
commit f1a89a8816f56c1560044bfd54ca3d56824ef2f8
Author: Adam Porter <adam@alphapapa.net>
Commit: Adam Porter <adam@alphapapa.net>

    Add: Download :as file
---
 README.org        |  2 ++
 plz.el            | 39 +++++++++++++++++++++++++++++++++++++++
 tests/test-plz.el | 30 ++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/README.org b/README.org
index 9d9f8c259a..f96317c442 100644
--- a/README.org
+++ b/README.org
@@ -115,6 +115,8 @@ Synchronously download a JPEG file, then create an Emacs 
image object from the d
     - ~string~ to pass the response body as a decoded string.
     - ~response~ to pass a ~plz-response~ struct.
     - A function, to pass its return value; it is called in the response 
buffer, which is narrowed to the response body (suitable for, e.g. ~json-read~).
+    - ~file~ to pass a temporary filename to which the response body has been 
saved without decoding.
+    - ~(file FILENAME)~ to pass ~FILENAME~ after having saved the response 
body to it without decoding.  ~FILENAME~ must be a non-existent file; if it 
exists, it will not be overwritten, and an error will be signaled.
 
   If ~DECODE~ is non-nil, the response body is decoded automatically.  For 
binary content, it should be nil.  When ~AS~ is ~binary~, ~DECODE~ is 
automatically set to nil.
 
diff --git a/plz.el b/plz.el
index 86a9a270b5..81c2112d84 100644
--- a/plz.el
+++ b/plz.el
@@ -231,9 +231,21 @@ THEN, or the kind of result to return for synchronous 
requests.
 It may be:
 
 - `buffer' to pass the response buffer.
+
 - `binary' to pass the response body as an undecoded string.
+
 - `string' to pass the response body as a decoded string.
+
 - `response' to pass a `plz-response' struct.
+
+- `file' to pass a temporary filename to which the response body
+  has been saved without decoding.
+
+- `(file FILENAME)' to pass FILENAME after having saved the
+  response body to it without decoding.  FILENAME must be a
+  non-existent file; if it exists, it will not be overwritten,
+  and an error will be signaled.
+
 - A function, which is called in the response buffer with it
   narrowed to the response body (suitable for, e.g. `json-read').
 
@@ -330,6 +342,33 @@ NOQUERY is passed to `make-process', which see."
                                (funcall then (current-buffer))))
                     ('response (lambda ()
                                  (funcall then (plz--response :decode-p 
decode))))
+                    ('file (lambda ()
+                             (set-buffer-multibyte nil)
+                             (plz--narrow-to-body)
+                             (let ((filename (make-temp-file "plz-")))
+                               (condition-case err
+                                   (write-region (point-min) (point-max) 
filename)
+                                 ;; In case of an error writing to the file, 
delete the temp file
+                                 ;; and signal the error.  Ignore any errors 
encountered while
+                                 ;; deleting the file, which would obscure the 
original error.
+                                 (error (ignore-errors
+                                          (delete-file filename))
+                                        (signal (car err) (cdr err))))
+                               (funcall then filename))))
+                    (`(file ,(and (pred stringp) filename))
+                     (lambda ()
+                       (set-buffer-multibyte nil)
+                       (plz--narrow-to-body)
+                       (condition-case err
+                           (write-region (point-min) (point-max) filename nil 
nil nil 'excl)
+                         ;; Since we are creating the file, it seems sensible 
to delete it in case of an
+                         ;; error while writing to it (e.g. a disk-full 
error).  And we ignore any errors
+                         ;; encountered while deleting the file, which would 
obscure the original error.
+                         (error (ignore-errors
+                                  (when (file-exists-p filename)
+                                    (delete-file filename)))
+                                (signal (car err) (cdr err))))
+                       (funcall then filename)))
                     ((pred functionp) (lambda ()
                                         (let ((coding-system (or 
(plz--coding-system) 'utf-8)))
                                           (plz--narrow-to-body)
diff --git a/tests/test-plz.el b/tests/test-plz.el
index 6cc3f3397f..49fd0271df 100644
--- a/tests/test-plz.el
+++ b/tests/test-plz.el
@@ -346,6 +346,36 @@
                 :as 'binary :then 'sync)))
     (should (equal 'jpeg (image-type-from-data jpeg)))))
 
+;;;;; Downloading to files
+
+(ert-deftest plz-get-temp-file ()
+  (let ((filename (plz 'get "https://httpbin.org/image/jpeg";
+                    :as 'file :then 'sync)))
+    (unwind-protect
+        (let ((jpeg-data (with-temp-buffer
+                           (insert-file-contents filename)
+                           (buffer-string))))
+          (should (equal 'jpeg (image-type-from-data jpeg-data))))
+      ;; It's a temp file, so it should always be deleted.
+      (delete-file filename))))
+
+(ert-deftest plz-get-named-file ()
+  (let ((filename (make-temp-file "plz-")))
+    ;; HACK: Delete the temp file and reuse its name, because
+    ;; `make-temp-name' is less convenient to use.
+    (delete-file filename)
+    (unwind-protect
+        (progn
+          (plz 'get "https://httpbin.org/image/jpeg";
+            :as `(file ,filename) :then 'sync)
+          (let ((jpeg-data (with-temp-buffer
+                             (insert-file-contents filename)
+                             (buffer-string))))
+            (should (equal 'jpeg (image-type-from-data jpeg-data)))))
+      ;; It's a temp file, so it should always be deleted.
+      (when (file-exists-p filename)
+        (delete-file filename)))))
+
 ;;;; Footer
 
 (provide 'test-plz)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]