emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] scratch/gnus-cloud 1a30c81 2/2: Get Gnus cloud upload and


From: Teodor Zlatanov
Subject: [Emacs-diffs] scratch/gnus-cloud 1a30c81 2/2: Get Gnus cloud upload and download working
Date: Sat, 2 Jul 2016 00:55:56 +0000 (UTC)

branch: scratch/gnus-cloud
commit 1a30c814a5c45bfbe378d90e00753528f193e396
Author: Ted Zlatanov <address@hidden>
Commit: Ted Zlatanov <address@hidden>

    Get Gnus cloud upload and download working
---
 lisp/gnus/gnus-cloud.el |  108 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 74 insertions(+), 34 deletions(-)

diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el
index f17a6d0..4b56788 100644
--- a/lisp/gnus/gnus-cloud.el
+++ b/lisp/gnus/gnus-cloud.el
@@ -88,12 +88,10 @@
                           length))
           (insert data)
           (insert "\n")))
-       ((eq (plist-get elem :type) :data)
-        (insert (format "(:type :data :name %S :length %d)\n"
-                        (plist-get elem :name)
-                        (with-current-buffer (plist-get elem :buffer)
-                          (buffer-size))))
-        (insert-buffer-substring (plist-get elem :buffer))
+       ((eq (plist-get elem :type) :newsrc-data)
+        (let ((print-level nil)
+              (print-length nil))
+          (print elem (current-buffer)))
         (insert "\n"))
        ((eq (plist-get elem :type) :delete)
         (insert (format "(:type :delete :file-name %S)\n"
@@ -144,8 +142,8 @@
            (data (epg-decrypt-string context (buffer-substring-no-properties
                                               (point-min)
                                               (point-max)))))
-        (delete-region (point-min) (point-max))
-        (insert data)))
+      (delete-region (point-min) (point-max))
+      (insert data)))
 
    ((null gnus-cloud-storage-method)
     (gnus-message 5 "Reading cloud data as plaintext"))
@@ -179,47 +177,73 @@
       (unless (eobp)
         (let ((spec (ignore-errors (read (current-buffer))))
               length)
-          (when (and (consp spec)
-                     (memq (plist-get spec :type) '(:file :data :delete)))
-            (setq length (plist-get spec :length))
-            (push (append spec
-                          (list
-                           :contents (buffer-substring (1+ (point))
-                                                       (+ (point) 1 length))))
-                  elems)
-            (goto-char (+ (point) 1 length))))))
+          (when (consp spec)
+            (cond
+             ((memq (plist-get spec :type) '(:file :delete))
+              (setq length (plist-get spec :length))
+              (push (append spec
+                            (list
+                             :contents (buffer-substring (1+ (point))
+                                                         (+ (point) 1 
length))))
+                    elems)
+              (goto-char (+ (point) 1 length)))
+             ((memq (plist-get spec :type) '(:newsrc-data))
+              (push spec elems)))))))
     (nreverse elems)))
 
 (defun gnus-cloud-update-all (elems)
   (dolist (elem elems)
     (let ((type (plist-get elem :type)))
       (cond
-       ((eq type :data)
-        (gnus-cloud-update-data elem))
+       ((eq type :newsrc-data)
+        (gnus-cloud-update-newsrc-data (plist-get elem :name) elem))
        ((memq type '(:delete :file))
         (gnus-cloud-update-file elem type))
        (t
         (gnus-message 1 "Unknown type %s; ignoring" type))))))
 
-(defun gnus-cloud-update-data (elem)
-  (gnus-error 1 "TODO: update newsrc data"))
+(defun gnus-cloud-update-newsrc-data (group elem)
+  "Update the newsrc data for GROUP from ELEM."
+  (let* ((contents (plist-get elem :contents))
+         (group-info (gnus-get-info group)))
+    (if (and contents
+             (stringp (nth 0 contents))
+             (integerp (nth 1 contents)))
+        (if group-info
+            (if (equal (format "%S" group-info)
+                       (format "%S" contents))
+                (gnus-message 3 "Skipping cloud update of group %s, the info 
is the same" group)
+              (gnus-message 2 "Installing cloud update of group %s" group)
+              (gnus-set-info group contents)
+              (gnus-group-update-group group))
+          (gnus-error 1 "Sorry, group %s is not subscribed" group))
+      (gnus-error 1 "Sorry, could not update newsrc for group %s (invalid data 
%S)"
+                  group elem))))
 
 (defun gnus-cloud-update-file (elem op)
-  (let ((file-name (plist-get elem :file-name))
-        (date (plist-get elem :timestamp))
-        (contents (plist-get elem :contents)))
+  "Apply Emacs Cloud data ELEM and operation OP to a file."
+  (let* ((file-name (plist-get elem :file-name))
+         (date (plist-get elem :timestamp))
+         (contents (plist-get elem :contents))
+         (exists (file-exists-p file-name)))
     (if (gnus-cloud-file-covered-p file-name)
         (cond
          ((eq op :delete)
-          (if (file-exists-p file-name)
+          (if (and exists
+                   ;; prompt only if the file exists already
+                   (gnus-y-or-n-p (format "%s has been deleted as of %s, 
delete it locally? "
+                                          file-name date)))
               (rename-file file-name (car (find-backup-file-name file-name)))
             (gnus-message 3 "%s was already deleted before the cloud got it" 
file-name)))
          ((eq op :file)
-          (when (or (not (file-exists-p file-name))
-                    (and (file-exists-p file-name)
+          (when (or (not exists)
+                    (and exists
                          (mm-with-unibyte-buffer
                            (insert-file-contents-literally file-name)
-                           (not (equal (buffer-string) contents)))))
+                           (not (equal (buffer-string) contents)))
+                         ;; prompt only if the file exists already
+                         (gnus-y-or-n-p (format "%s has updated contents as of 
%s, update it? "
+                                                file-name date))))
             (gnus-cloud-replace-file file-name date contents))))
       (gnus-message 2 "%s isn't covered by the cloud; ignoring" file-name))))
 
@@ -275,9 +299,12 @@
           (push `(:type :delete :file-name ,file) files))))
     (nreverse files)))
 
+(defun gnus-cloud-timestamp (time)
+  "Return a general timestamp string for TIME."
+  (format-time-string "%FT%T%z" time))
+
 (defun gnus-cloud-file-new-p (file full)
-  (let ((timestamp (format-time-string
-                    "%FT%T%z" (nth 5 (file-attributes file))))
+  (let ((timestamp (gnus-cloud-timestamp (nth 5 (file-attributes file))))
         (old (cadr (assoc file gnus-cloud-file-timestamps))))
     (when (or full
               (null old)
@@ -300,10 +327,20 @@
            (gnus-activate-group gnus-cloud-group-name nil nil 
gnus-cloud-method)
            (gnus-subscribe-group gnus-cloud-group-name)))))
 
+(defun gnus-cloud-upload-all-data ()
+  "Upload all data (newsrc and files) to the Emacs Cloud."
+  (interactive)
+  (gnus-cloud-upload-data t))
+
 (defun gnus-cloud-upload-data (&optional full)
+  "Upload data (newsrc and files) to the Emacs Cloud.
+When FULL is t, upload everything, not just a difference from the last full."
+  (interactive)
   (gnus-cloud-ensure-cloud-group)
   (with-temp-buffer
-    (let ((elems (gnus-cloud-files-to-upload full))
+    (let ((elems (append
+                  (gnus-cloud-files-to-upload full)
+                  (gnus-cloud-collect-full-newsrc)))
           (group (gnus-group-full-name gnus-cloud-group-name 
gnus-cloud-method)))
       (insert (format "Subject: (sequence: %d type: %s storage-method: %s)\n"
                       (or gnus-cloud-sequence "UNKNOWN")
@@ -398,7 +435,7 @@ Otherwise, returns the Gnus Cloud data chunks."
           (push (gnus-cloud-parse-chunk) chunks)
           (forward-line 1))))
     (if update
-        (gnus-cloud-update-all chunks)
+        (mapcar #'gnus-cloud-update-all chunks)
       chunks)))
 
 (defun gnus-cloud-server-p (server)
@@ -408,13 +445,16 @@ Otherwise, returns the Gnus Cloud data chunks."
   (equal gnus-cloud-method server))
 
 (defun gnus-cloud-collect-full-newsrc ()
+  "Collect all the Gnus newsrc data in a portable format."
   (let ((infos nil))
     (dolist (info (cdr gnus-newsrc-alist))
       (when (gnus-cloud-server-p
              (gnus-method-to-server
               (gnus-find-method-for-group (gnus-info-group info))))
-        (push info infos)))
-    ))
+
+        (push `(:type :newsrc-data :name ,(gnus-info-group info) :contents 
,info :timestamp ,(gnus-cloud-timestamp (current-time)))
+              infos)))
+    infos))
 
 (provide 'gnus-cloud)
 



reply via email to

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