;;; recent-changes.el -- handling updating of pages in web trees (provide 'recent-changes) ;;; Manage a list of locally edited pages (require 'cl) (require 'buffer-matched) (require 'page-file-name) (defun eligible-for-recenting (filename) "Return whether FILENAME should be logged in recent-changes-file." (and (> (length filename) (length recent-changes-base-directory)) (string= recent-changes-base-directory (standardize-pathname-delimiters (substring filename 0 (length recent-changes-base-directory)))))) (defvar recent-changes-move-on-change t "*Whether to move recent changes to the insertion point on each change.") (defvar recent-changes-added-here-string "Changes added here!" "Marker for adding or moving changes.") (defun update-recent-changes-file (filename) "Update the recent changes file, which is named by recent-changes-file." (save-window-excursion (find-file recent-changes-file) (if (and (eligible-for-recenting filename) (not (string= (buffer-file-name) ; check it isn't the recent.html! filename))) (save-excursion (let* ((trimmed-name (standardize-pathname-delimiters (trimmed-name filename))) (found-it (progn (goto-char (point-min)) (search-forward trimmed-name (point-max) t)))) (if found-it (progn (if recent-changes-move-on-change (let ((eol (progn (end-of-line 1) (point)))) (beginning-of-line 1) (let ((old-change-string (buffer-substring (point) eol))) (delete-region (point) eol) (delete-blank-lines) (if (search-forward recent-changes-added-here-string (point-max) t) (progn (beginning-of-line 1) (insert old-change-string "\n") (beginning-of-line 0) )) ))) (let ((eol (progn (end-of-line 1) (point)))) (beginning-of-line 1) (if (re-search-forward "(\\(.\\))" eol t) (progn (if (not (string= (buffer-matched 1) "n")) (replace-match "(e)"))) (progn (goto-char eol) (insert "(e)"))) (beginning-of-line 1) (if (re-search-forward " *(.+)" eol t) (progn (replace-match (format " (%s)" (current-time-string)))) (progn (goto-char eol) (insert (format " (%s)" (current-time-string))))))) (if (search-forward recent-changes-added-here-string (point-max) t) (progn (beginning-of-line 1) (insert "
  • " trimmed-name (format " (e) (%s)\n" (current-time-string))))))))) ;; hmmm, my loop detection hasn't worked in this case! ;; (basic-save-buffer) (bury-buffer) )) (defun make-recent-changes-transfer-script (pattern rcpscriptfile rcp-remote-prefix ftpscriptfile ftp-remote-directory) "Mark changed pages matching PATTERN for uploading via RCPSCRIPTFILE, staging at RCP-REMOTE-PREFIX, and FTPSCRIPTFILE, into FTP-REMOTE-DIRECTORY. See update-recent-changes-file for more about this package." (interactive "sMark for upload pages matching regexp: Frcp script file for uploading pages matching %s: srcp remote prefix: Fftp script file for uploading pages matching %s: sftp remote directory: ") (save-window-excursion (let ((pages nil)) (find-file recent-changes-file) (save-excursion (goto-char (point-min)) (while (re-search-forward pattern (point-max) t) (end-of-line 1) (let ((eol (point))) (beginning-of-line 1) (if (re-search-forward "href=\"\\([^\"]+\\).+(\\(e\\))" eol t) (progn (setq pages (cons (buffer-substring (match-beginning 1) (match-end 1)) pages)) (delete-region (match-beginning 2) (match-end 2)) (goto-char (match-beginning 2)) (insert "p") )) (goto-char eol)))) (basic-save-buffer) (let ((rcp-pages pages)) (find-file rcpscriptfile) (erase-buffer) (insert "rcp " ftpscriptfile " " rcp-remote-prefix ftpscriptfile "\n") (while rcp-pages (insert "rcp " (car rcp-pages) " " rcp-remote-prefix (car rcp-pages) "\n") (setq rcp-pages (cdr rcp-pages))) (basic-save-buffer)) (let ((ftp-pages pages)) (find-file ftpscriptfile) (erase-buffer) (insert "cd " ftp-remote-directory "\nverbose\nhash\n") (while ftp-pages (insert "put " (car ftp-pages) " " (car ftp-pages) "\n") (setq ftp-pages (cdr ftp-pages))) (insert "quit\n") (basic-save-buffer))))) (defun mark-transfers-as-done () "Mark transfers, as scripted by make-recent-changes-transfer-script, as done." (interactive) (save-window-excursion (find-file recent-changes-file) (save-excursion (goto-char (point-min)) (search-forward "
  • ") (while (search-forward "(p)" (point-max) t) (replace-match "(t)")) (basic-save-buffer)))) (defun changed-pages-list () "Return an alist of titles of recently changed pages, against filename and date changed." (save-window-excursion (find-file recent-changes-file) (save-excursion (goto-char (point-min)) (let ((the-files nil)) (while (re-search-forward "
  • \\([^<]+\\) (.) (\\([^)]+\\))" (point-max) t) (push (list (buffer-matched 2) (expand-file-name (buffer-matched 1) recent-changes-base-directory) (buffer-matched 3)) the-files)) (nreverse the-files))))) (defun find-changed-pages (pattern) "Find all changed pages whose title matches PATTERN. Report on any that did not exist." (interactive "sFind changed pages matching regexp: ") (with-output-to-temp-buffer "*Missing pages*" (let ((changed-pages (changed-pages-list))) (while changed-pages (let ((this-page (pop changed-pages))) (when (string-match pattern (car this-page)) (let ((filename (cadr this-page))) (unless (file-exists-p filename) (princ (format "\"%s\" in file %s -- last edited %s\n" (car this-page) (cadr this-page) (caddr this-page)))) (find-file filename)))))))) ;;; end of recent-changes.el