Collect notes in one pass

This commit is contained in:
louie 2020-02-24 17:16:20 +08:00
parent 7dcae54caa
commit c47dfade3a

View file

@ -713,6 +713,13 @@ Return a list of cons of (FIELD-NAME . FIELD-CONTENT)."
;;; Commands ;;; Commands
(defvar anki-editor--note-markers nil)
(defun anki-editor--collect-note-marker ()
(message "Scanning notes %d (%s@%d), wait a moment..."
(length anki-editor--note-markers) (buffer-name) (point))
(push (point-marker) anki-editor--note-markers))
(defun anki-editor-push-notes (&optional scope match) (defun anki-editor-push-notes (&optional scope match)
"Build notes from headings that match MATCH within SCOPE and push them to Anki. "Build notes from headings that match MATCH within SCOPE and push them to Anki.
@ -741,32 +748,48 @@ of that heading."
((equal current-prefix-arg '(16)) 'file) ((equal current-prefix-arg '(16)) 'file)
((equal current-prefix-arg '(64)) 'agenda) ((equal current-prefix-arg '(64)) 'agenda)
(t nil)))) (t nil))))
(unwind-protect
(let ((total (progn (progn
(message "Counting notes...") (anki-editor-map-note-entries #'anki-editor--collect-note-marker match scope)
(length (anki-editor-map-note-entries t match scope)))) (setq anki-editor--note-markers (reverse anki-editor--note-markers))
(acc 0) (let ((count 0)
(failed 0)) (failed 0))
(save-excursion
(anki-editor--with-collection-data-updated (anki-editor--with-collection-data-updated
(anki-editor-map-note-entries (cl-loop with bar-width = 30
(lambda () for marker in anki-editor--note-markers
(message "[%d/%d] Processing notes in buffer \"%s\", wait a moment..." for progress = (/ (float (cl-incf count)) (length anki-editor--note-markers))
(cl-incf acc) total (buffer-name)) do
(anki-editor--clear-failure-reason) (goto-char marker)
(condition-case-unless-debug err (message "Uploading notes in buffer %s%s [%s%s] %d/%d (%.2f%%)"
(anki-editor--push-note (anki-editor-note-at-point)) (marker-buffer marker)
(error (cl-incf failed) (if (zerop failed)
(anki-editor--set-failure-reason (error-message-string err))))) ""
match scope)) (propertize (format " %d failed" failed)
'face `(:foreground "red")))
(message (make-string (truncate (* bar-width progress)) ?#)
(cond (make-string (- bar-width (truncate (* bar-width progress))) ?.)
((zerop total) "Nothing to push") count
((zerop failed) (format "Pushed %d notes to Anki successfully" acc)) (length anki-editor--note-markers)
(t (format "Pushed %d notes in total, among which %d were failed. Check property drawers for failure reasons. (* 100 progress))
When the issues are resolved, you could repush the failed ones with `anki-editor-retry-failed-notes'." (anki-editor--clear-failure-reason)
acc failed)))))) (condition-case-unless-debug err
(anki-editor--push-note (anki-editor-note-at-point))
(error (cl-incf failed)
(anki-editor--set-failure-reason (error-message-string err))))
;; free marker
(set-marker marker nil))))
(message
(cond
((zerop (length anki-editor--note-markers)) "Nothing to push")
((zerop failed) (format "Successfully pushed %d notes to Anki" count))
(t (format "Pushed %d notes to Anki, with %d failed. Check property drawers for details.
When you have fixed those issues, try re-push the failed ones with `anki-editor-retry-failed-notes'."
count failed))))))
;; clean up markers
(cl-loop for m in anki-editor--note-markers
do (set-marker m nil)
finally do (setq anki-editor--note-markers nil))))
(defun anki-editor-push-new-notes (&optional scope) (defun anki-editor-push-new-notes (&optional scope)
"Push note entries without ANKI_NOTE_ID in SCOPE to Anki." "Push note entries without ANKI_NOTE_ID in SCOPE to Anki."