1 ;;; navi2ch-message.el --- write message module for navi2ch -*- coding: iso-2022-7bit; -*-
3 ;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009
6 ;; Author: Taiki SUGAWARA <taiki@users.sourceforge.net>
7 ;; Keywords: network, 2ch
9 ;; This file is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; This file is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
29 (provide 'navi2ch-message
)
30 (defconst navi2ch-message-ident
32 (defconst navi2ch-message-samba24-sambatxt-url
33 "http://nullpo.s101.xrea.com/samba24/conv.xcg?browser=bbs2chreader&decsec=majority&offset=0&newline=crlf&output=download")
37 (require 'navi2ch-decls
)
38 (require 'navi2ch-inline
))
39 (require 'navi2ch-vars
)
42 (when (featurep 'xemacs
)
45 (defvar navi2ch-message-aa-map nil
)
46 (unless navi2ch-message-aa-map
47 (let ((map (make-sparse-keymap "Type ? for further options")))
48 (navi2ch-set-keymap-default-binding map
'navi2ch-message-self-insert-aa
)
49 (define-key map
"?" 'navi2ch-message-insert-aa
)
50 (setq navi2ch-message-aa-map map
)))
52 (defvar navi2ch-message-mode-map nil
)
53 (unless navi2ch-message-mode-map
54 (let ((map (make-sparse-keymap)))
55 (set-keymap-parent map navi2ch-global-map
)
56 (define-key map
"\C-c\C-c" 'navi2ch-message-send-message
)
57 (define-key map
"\C-c\C-k" 'navi2ch-message-exit
)
58 (define-key map
"\C-c\C-y" 'navi2ch-message-cite-original
)
59 (define-key map
"\C-c\C-j" 'navi2ch-message-cite-original-from-number
)
60 (define-key map
"\C-c\C-i" 'navi2ch-message-insert-backup
)
61 (define-key map
"\C-c\C-b" 'navi2ch-base64-insert-file
)
62 (define-key map navi2ch-message-aa-prefix-key navi2ch-message-aa-map
)
63 (setq navi2ch-message-mode-map map
)))
65 (defvar navi2ch-message-mode-menu-spec
67 ["Toggle offline" navi2ch-toggle-offline
]
68 ["Send message" navi2ch-message-send-message
]
69 ["Cancel" navi2ch-message-exit
]
70 ["Cite message" navi2ch-message-cite-original
]))
72 (defvar navi2ch-message-buffer-name
"*navi2ch message*")
73 (defvar navi2ch-message-backup-buffer-name
"*navi2ch message backup*")
74 (defvar navi2ch-message-current-article-buffer nil
)
75 (defvar navi2ch-message-current-article nil
)
76 (defvar navi2ch-message-current-board nil
)
77 (defvar navi2ch-message-new-message-p nil
)
78 (defvar navi2ch-message-window-configuration nil
)
79 (defvar navi2ch-message-header-separator
"----------------\n")
81 (defvar navi2ch-message-paragraph-separate
82 (concat (regexp-quote navi2ch-message-header-separator
) "\\|"
84 "[ \t]*$") ; \e$B6u9T\e(B
85 "*`navi2ch-message-mode' \e$B$G;HMQ$5$l$k\e(B `paragraph-separate'\e$B!#\e(B")
87 (defvar navi2ch-message-paragraph-start
88 navi2ch-message-paragraph-separate
89 "*`navi2ch-message-mode' \e$B$G;HMQ$5$l$k\e(B `paragraph-start'\e$B!#\e(B")
91 (defvar navi2ch-message-sendlog-board
92 `((name .
"\e$BAw?.95$(\e(B")
96 (uri .
,(concat "x-localbbs://" (navi2ch-expand-file-name "sendlog/")))))
98 (defvar navi2ch-message-font-lock-keywords
99 `(("^>\\s-+.*$" . navi2ch-message-citation-face
)
100 ("[>\e$B!d\e(B]+[0-9\e$B#0\e(B-\e$B#9\e(B]+" 0 navi2ch-message-link-face t
)
101 (,navi2ch-article-url-regexp
0 navi2ch-message-url-face t
)))
103 (defvar navi2ch-message-link-face
'navi2ch-message-link-face
)
104 (defvar navi2ch-message-url-face
'navi2ch-message-url-face
)
105 (defvar navi2ch-message-citation-face
'navi2ch-message-citation-face
)
107 ;; SAMBA24\e$B$N%G!<%?\e(B(url\e$B$@$NHDL>$@$N;~4V$@$N\e(B)
108 (defvar navi2ch-message-samba24-samba-data nil
)
109 (defvar navi2ch-message-samba24-send-time nil
110 "\e$BHD\e(BID\e$B$H=q$-9~$_;~4V$rJ];}\e(B")
111 ;; \e$B%b!<%I%i%$%s$KI=<($9$k%+%&%s%H%@%&%s\e(B
112 (defvar navi2ch-message-samba24-mode-string nil
)
113 (defvar navi2ch-message-samba24-show t
114 "non-nil \e$B$J$i=q$-9~$_5,@);~4V$rI=<(\e(B.")
115 ;; \e$B8=:_I=<(Cf$N=q$-9~$_5,@);~4V%b!<%I%i%$%s\e(B
116 (defvar navi2ch-message-samba24-mode-string nil
)
117 (defvar navi2ch-message-samba24-file-name
"samba.txt"
118 "Samba24 \e$B$N5,@)IC?t>pJs$rJ];}$9$k%U%!%$%k$N%U%!%$%kL>\e(B.")
119 (defvar navi2ch-message-samba24-update-timer nil
)
121 (defun navi2ch-message-write-message (board article
&optional new sage cite
)
122 (when (or (not navi2ch-message-ask-before-write
)
123 (if (functionp navi2ch-message-ask-before-write
)
124 (funcall navi2ch-message-ask-before-write
"Write new message? ")
125 (y-or-n-p "Write new message? ")))
126 (if (and (get-buffer navi2ch-message-buffer-name
)
127 (or navi2ch-message-always-pop-message
128 (not (navi2ch-message-kill-message))))
129 (navi2ch-message-pop-message-buffer)
130 (setq navi2ch-message-window-configuration
131 (current-window-configuration))
132 (delete-other-windows)
133 (split-window-vertically)
135 (setq navi2ch-message-current-article article
)
136 (setq navi2ch-message-current-board board
)
137 (setq navi2ch-message-new-message-p new
)
138 (setq navi2ch-message-current-article-buffer
139 (if new nil
(current-buffer)))
140 (switch-to-buffer (get-buffer-create navi2ch-message-buffer-name
))
141 (navi2ch-message-mode)
143 (navi2ch-message-insert-header new sage
)
144 (setq navi2ch-mode-line-identification
145 (navi2ch-message-make-mode-line-identification new
))
146 (navi2ch-set-mode-line-identification)
148 (navi2ch-message-cite-original))
149 (run-hooks 'navi2ch-message-setup-message-hook
)
151 (run-hooks 'navi2ch-message-setup-sage-message-hook
)))))
153 (defun navi2ch-message-make-mode-line-identification (new)
155 (format "*new message* [%s]"
156 (cdr (assq 'name navi2ch-message-current-board
)))
157 (format "Re: %s [%s]"
158 (cdr (assq 'subject navi2ch-message-current-article
))
159 (cdr (assq 'name navi2ch-message-current-board
)))))
161 (defun navi2ch-message-pop-message-buffer ()
163 (let ((buf (get-buffer navi2ch-message-buffer-name
)))
165 (cond ((get-buffer-window buf
)
166 (select-window (get-buffer-window buf
)))
168 (setq navi2ch-message-window-configuration
169 (current-window-configuration))
170 (delete-other-windows)
171 (split-window-vertically)
173 (switch-to-buffer navi2ch-message-buffer-name
))))))
175 (defun navi2ch-message-insert-backup ()
177 (when (get-buffer navi2ch-message-backup-buffer-name
)
178 (let ((inhibit-read-only t
))
180 (insert-buffer-substring navi2ch-message-backup-buffer-name
)))
182 (defun navi2ch-message-insert-header (new sage
)
183 (and sage
(setq sage
"sage"))
185 (insert (navi2ch-read-only-string "Subject: ")
186 (navi2ch-read-only-string "\n" t
)))
187 (insert (navi2ch-read-only-string "From: ")
188 (or (and navi2ch-message-remember-user-name
189 (cdr (assq 'name navi2ch-message-current-article
)))
190 (cdr (assoc (cdr (assq 'id navi2ch-message-current-board
))
191 navi2ch-message-user-name-alist
))
192 navi2ch-message-user-name
"")
193 (navi2ch-read-only-string "\n" t
)
194 (navi2ch-read-only-string "Mail: ")
196 (and navi2ch-message-remember-user-name
197 (cdr (assq 'mail navi2ch-message-current-article
)))
198 (cdr (assoc (cdr (assq 'id navi2ch-message-current-board
))
199 navi2ch-message-mail-address-alist
))
200 navi2ch-message-mail-address
"")
201 (navi2ch-read-only-string "\n" t
)
202 (navi2ch-read-only-string
203 (navi2ch-propertize navi2ch-message-header-separator
204 'navi2ch-message-header-separator t
)))
205 (setq buffer-undo-list nil
)
206 (set-buffer-modified-p nil
))
208 (defun navi2ch-message-header-end ()
211 (if (get-text-property (point-min) 'navi2ch-message-header-separator
)
213 (next-single-property-change (point-min) 'navi2ch-message-header-separator
))))
215 (defun navi2ch-message-cleanup-message ()
217 (let ((start (progn (goto-char (navi2ch-message-header-end))
220 (when navi2ch-message-cleanup-trailing-whitespace
222 (while (re-search-forward "[ \t]+$" nil t
)
224 (when navi2ch-message-cleanup-trailing-newline
226 (if (re-search-forward "[ \t\n]+\\'" nil t
)
227 (replace-match ""))))))
229 (defun navi2ch-message-insert-notice (msg)
230 "\e$B%a%C%;!<%8Ej9F%P%C%U%!$K2r@b$d%(%i!<%a%C%;!<%8$J$I\e(B `msg' \e$B$rI=<($9$k!#\e(B
232 \e$B>r7o\e(B: \e$B%a%C%;!<%8Ej9F%P%C%U%!Fb$G8F$P$l$k$3$H!#\e(B"
233 (let ((inhibit-read-only t
)
234 (end (navi2ch-message-header-end))
238 ;; (point-min) \e$B$G$O\e(B text-property `navi2ch-message-notice' \e$B$,$J$$!"\e(B
239 ;; \e$B$^$?$O\e(B nil \e$B$G$"$k$3$H$,J]>Z$5$l$k!#\e(B \e$B$^$?!"\e(B text-property
240 ;; `navi2ch-message-notice' \e$B$,\e(B non-nil \e$B$G$"$kE@$+$i\e(B
241 ;; (navi2ch-message-header-end) \e$B$^$G$O\e(B notice \e$B$N$_$,F~$k$H$9$k!#\e(B
242 (when (setq pos
(next-single-property-change (point-min)
243 'navi2ch-message-notice
))
244 (delete-region pos end
))
245 (goto-char (navi2ch-message-header-end))
247 (navi2ch-read-only-string
248 (navi2ch-propertize navi2ch-message-header-separator
249 'navi2ch-message-notice t
))
250 (navi2ch-read-only-string (concat msg
"\n")))))))
252 (defun navi2ch-message-send-message ()
255 (message "Now offline")
256 (when (or (not navi2ch-message-ask-before-send
)
257 (if (functionp navi2ch-message-ask-before-send
)
258 (funcall navi2ch-message-ask-before-send
"Send message? ")
259 (y-or-n-p "Send message? ")))
261 (run-hooks 'navi2ch-message-before-send-hook
)
262 (navi2ch-message-cleanup-message)
265 (let ((end (navi2ch-message-header-end))
269 (goto-char (point-min))
270 (when navi2ch-message-new-message-p
271 (if (re-search-forward "^Subject: ?\\(.*\\)" end t
)
272 (setq subject
(match-string 1))
274 (goto-char (point-min))
275 (when (re-search-forward "^From: ?\\(.*\\)" end t
)
276 (setq from
(match-string 1))
277 (when (and (not navi2ch-message-new-message-p
)
278 navi2ch-message-remember-user-name
)
279 (navi2ch-message-set-name from
)))
280 (goto-char (point-min))
281 (when (re-search-forward "^Mail: ?\\(.*\\)" end t
)
282 (setq mail
(match-string 1))
283 (when (and (not navi2ch-message-new-message-p
)
284 navi2ch-message-remember-user-name
)
285 (navi2ch-message-set-mail mail
)))
288 (setq message
(buffer-substring-no-properties (point) (point-max)))
289 (let ((buffer (current-buffer))
290 (inhibit-read-only t
))
291 (with-current-buffer (get-buffer-create
292 navi2ch-message-backup-buffer-name
)
294 (insert-buffer-substring buffer
)))
295 (when navi2ch-message-trip
296 (setq from
(concat from
"#" navi2ch-message-trip
)))
297 (let ((board navi2ch-message-current-board
)
298 (article navi2ch-message-current-article
))
299 (navi2ch-net-cleanup)
300 ;; \e$B"-\e(Bresult\e$B$r8E$$;EMM$KLa$7$?!#\e(Bspid\e$B$O!"\e(Bnavi2ch-multibbs.el\e$B$N\e(B
301 ;; \e$B"-\e(B navi2ch-2ch-send-message \e$B$G=hM}$9$k!#\e(B
302 (setq result
(navi2ch-multibbs-send-message
303 from mail message subject board article
))
304 (navi2ch-net-cleanup)
306 (when navi2ch-message-save-sendlog
307 (navi2ch-message-add-sendlog from mail message subject
309 (message "Waiting new message...")
310 (sleep-for navi2ch-message-wait-time
)
311 (message "%s%s" (current-message) "done")
313 (if navi2ch-message-new-message-p
315 (set-buffer navi2ch-board-buffer-name
)
316 (navi2ch-board-sync))
317 (when (buffer-live-p navi2ch-message-current-article-buffer
)
318 (set-buffer navi2ch-message-current-article-buffer
)
319 (navi2ch-article-sync navi2ch-message-force-sync
)))))
320 (when (get-buffer navi2ch-message-backup-buffer-name
)
321 (bury-buffer navi2ch-message-backup-buffer-name
)))))
322 (navi2ch-message-samba24)
323 (run-hooks 'navi2ch-message-after-send-hook
)
325 (navi2ch-message-exit 'after-send
)
326 (let ((errmsg (current-message)))
328 (string-match ": " errmsg
))
329 (setq errmsg
(substring errmsg
(match-end 0)))
330 (navi2ch-message-insert-notice (concat "\e$BEj9F%(%i!<\e(B: " errmsg
)))))))))
332 (defun navi2ch-message-set-name (name)
334 (if (buffer-live-p navi2ch-message-current-article-buffer
)
335 (set-buffer navi2ch-message-current-article-buffer
)
336 (navi2ch-article-view-article navi2ch-message-current-board
337 navi2ch-message-current-article
339 (setq navi2ch-article-current-article
340 (navi2ch-put-alist 'name name
341 navi2ch-article-current-article
))))
343 (defun navi2ch-message-set-mail (mail)
344 (let ((case-fold-search t
))
345 (unless (string-match "sage" mail
)
347 (if (buffer-live-p navi2ch-message-current-article-buffer
)
348 (set-buffer navi2ch-message-current-article-buffer
)
349 (navi2ch-article-view-article navi2ch-message-current-board
350 navi2ch-message-current-article
352 (setq navi2ch-article-current-article
353 (navi2ch-put-alist 'mail mail
354 navi2ch-article-current-article
))))))
356 (defun navi2ch-message-cite-original (&optional arg
)
361 (with-current-buffer (navi2ch-article-current-buffer)
362 (if (navi2ch-region-active-p)
364 (setq from
(save-excursion
365 (goto-char (region-beginning))
366 (navi2ch-article-get-current-number))
368 (goto-char (region-end))
369 (navi2ch-article-get-current-number)))
370 (navi2ch-number-sequence from to
))
371 `(,(navi2ch-article-get-current-number)))))
374 (navi2ch-message-cite-original-from-number (or from
(car nums
))
377 (goto-char (1- (point)))
378 (insert "-" (number-to-string to
))
379 (goto-char (1+ (point)))))
381 (navi2ch-message-cite-original-from-number n
)))))
383 (defun navi2ch-message-cite-original-from-number (num &optional arg
)
384 "\e$BHV9f$rA*$s$G!"0zMQ$
9$k
!#\e(B"
385 (interactive "nInput number
: \nP
")
386 (when (< (point) (navi2ch-message-header-end))
387 (error "Cannot cite in header
"))
388 (let (same msg board article)
389 (with-current-buffer (navi2ch-article-current-buffer)
390 (setq msg (navi2ch-article-get-message-string num))
391 (setq article navi2ch-article-current-article)
392 (setq board navi2ch-article-current-board)
393 (setq same (and (string-equal (cdr (assq 'id board))
394 (cdr (assq 'id navi2ch-message-current-board)))
395 (string-equal (cdr (assq 'artid article))
396 (cdr (assq 'artid navi2ch-message-current-article))))))
398 (insert ">>" (number-to-string num) "\n")
399 (insert (navi2ch-article-to-url board article num num nil) "\n"))
402 (let ((point (point)))
404 (string-rectangle point (point) navi2ch-message-cite-prefix)))))
406 (defun navi2ch-message-exit (&optional after-send)
408 (run-hooks 'navi2ch-message-exit-hook)
409 (when (navi2ch-message-kill-message after-send)
410 ;; \e$B$`$%!"\e(Bset-window-configuration \e$B$r
;H$&$H%+!<%=%k0LCV$,JQ$K$J$k$s$+$$!)\e(B
411 (set-window-configuration navi2ch-message-window-configuration
)
412 (when (and (not navi2ch-message-new-message-p
)
414 (if (buffer-live-p navi2ch-message-current-article-buffer
)
415 (set-buffer navi2ch-message-current-article-buffer
)
416 (navi2ch-article-view-article navi2ch-message-current-board
417 navi2ch-message-current-article
418 navi2ch-message-force-sync
)))
419 (navi2ch-article-load-number)))
421 (defun navi2ch-message-kill-message (&optional no-ask
)
423 (not navi2ch-message-ask-before-kill
)
424 (if (functionp navi2ch-message-ask-before-kill
)
425 (funcall navi2ch-message-ask-before-kill
"Kill current message? ")
426 (y-or-n-p "Kill current message? ")))
427 (kill-buffer navi2ch-message-buffer-name
)
430 (easy-menu-define navi2ch-message-mode-menu
431 navi2ch-message-mode-map
432 "Menu used in navi2ch-message"
433 navi2ch-message-mode-menu-spec
)
435 (defun navi2ch-message-setup-menu ()
436 (easy-menu-add navi2ch-message-mode-menu
))
438 (defun navi2ch-message-fill-paragraph (arg)
440 (let ((before (point)))
443 (or (bolp) (newline 1))
445 (beg (progn (backward-paragraph) (point))))
446 (when (eq beg
(point-min))
450 (fill-region-as-paragraph beg end arg
)
453 (defun navi2ch-message-substitute-key-definitions ()
455 '((beginning-of-line . navi2ch-message-beginning-of-line
)
456 (back-to-indentation . navi2ch-message-back-to-indentation
)))
457 (substitute-key-definition (car old-new-def
) (cdr old-new-def
)
458 navi2ch-message-mode-map
(current-global-map))))
460 (define-derived-mode navi2ch-message-mode text-mode
462 "\\{navi2ch-message-mode-map}"
463 (set (make-local-variable 'fill-paragraph-function
)
464 'navi2ch-message-fill-paragraph
)
465 (set (make-local-variable 'paragraph-separate
)
466 navi2ch-message-paragraph-separate
)
467 (set (make-local-variable 'paragraph-start
)
468 navi2ch-message-paragraph-start
)
469 (set (make-local-variable 'auto-fill-inhibit-regexp
)
470 "^[A-Z][^: \n\t]+:") ; \e$B%X%C%@\e(B
471 (set (make-local-variable 'font-lock-defaults
)
472 '(navi2ch-message-font-lock-keywords t
))
473 (navi2ch-message-setup-menu)
474 (navi2ch-message-substitute-key-definitions))
476 (defun navi2ch-message-self-insert-aa ()
477 "\e$B:G8eF~NO$7$?%-!<$K$7$?$,$C$F\e(B AA \e$B$rF~NO$9$k!#\e(B"
479 (let ((char last-command-event
) aa
)
480 (if (and (navi2ch-char-valid-p char
)
481 (setq aa
(cdr (assoc (string last-command-event
)
482 (append navi2ch-message-aa-alist
483 navi2ch-message-aa-default-alist
)))))
487 (defun navi2ch-message-insert-aa-list ()
488 (let ((aa-width navi2ch-message-popup-aa-width
)
491 (dolist (elt (append navi2ch-message-aa-alist
492 navi2ch-message-aa-default-alist
))
493 (when (and (not (member (car elt
) keys
))
496 (setq alist
(cons elt alist
))
497 (setq keys
(cons (car elt
) keys
))))
498 (dolist (key (sort keys
'string
<))
499 (let ((val (cdr (assoc key alist
)))
501 (setq string
(format "%s: %s" (key-description key
) val
)
502 width
(string-width string
))
503 (if (> width aa-width
)
504 (setq string
(concat (navi2ch-truncate-string-to-width
505 string
(- aa-width
3))
507 (insert (navi2ch-truncate-string-to-width string aa-width nil ?\
)
509 (setq nl
(not nl
))))))
511 (defun navi2ch-message-popup-aa-list ()
512 "aa \e$B$N%j%9%H$rI=<($9$k!#\e(B"
514 (let ((buffer (get-buffer-create "*AA List*"))
518 (save-window-excursion
519 (with-current-buffer buffer
521 (navi2ch-message-insert-aa-list)
522 (goto-char (point-min))
523 (pop-to-buffer (current-buffer))
525 (setq c
(navi2ch-read-char
526 "Type key for AA (or SPC forward, DEL back): "))
528 ((memq c
'(?\ ?\C-v
))
529 (ignore-errors (scroll-up)))
530 ((memq c
'(?\C-h ?
\177))
531 (ignore-errors (scroll-down)))
534 (t (setq continue nil
)))))
537 (kill-buffer buffer
)))))
539 (defun navi2ch-message-insert-aa ()
540 "aa \e$B$rF~NO$9$k!#\e(B"
542 (let* ((char (navi2ch-message-popup-aa-list))
543 (aa (cdr (assoc (char-to-string char
)
544 (append navi2ch-message-aa-alist
545 navi2ch-message-aa-default-alist
)))))
550 (defun navi2ch-message-jump-to-message-buffer ()
551 "message buffer \e$B$,$"$k$H$-
!"=q$-9~$_@h$N%9%l\e(B/\e$BHD$rI=<($7\e(B message buffer \e$B$K@Z$jBX$(!#\e(B"
553 (if (not (get-buffer navi2ch-message-buffer-name
))
554 (message "No message buffer")
555 (delete-other-windows)
556 (if navi2ch-message-current-article-buffer
557 ;; \e$B4{B8%9%l$K=q$-9~$_\e(B \e$B"*\e(B \e$B=q$-9~$_@h$N%9%l$rI=<(\e(B
558 (if (buffer-live-p navi2ch-message-current-article-buffer
)
559 (switch-to-buffer navi2ch-message-current-article-buffer
)
560 (navi2ch-article-view-article navi2ch-message-current-board
561 navi2ch-message-current-article
)
562 (setq navi2ch-message-current-article-buffer
(current-buffer)))
563 ;; \e$B?75,%9%lN)$F\e(B \e$B"*\e(B \e$B=q$-9~$_@h$NHD$rI=<(\e(B
564 (or (and (get-buffer navi2ch-board-buffer-name
)
565 (progn (switch-to-buffer (get-buffer
566 navi2ch-board-buffer-name
))
568 (eq major-mode
'navi2ch-board-mode
)
569 (eq navi2ch-board-current-board
570 navi2ch-message-current-board
))
571 (navi2ch-bm-select-board navi2ch-message-current-board
)))
572 (split-window-vertically)
574 (switch-to-buffer (get-buffer navi2ch-message-buffer-name
))))
576 (defun navi2ch-message-beginning-of-line (&optional n
)
577 "\e$B9T$N@hF,$X0\F0!#\e(B
578 header field \e$B$X0\F0$7$J$$0J30$O\e(B `beginning-of-line' \e$B$HF1$8!#\e(B"
580 (beginning-of-line n
)
581 (when (< (point) (navi2ch-message-header-end))
582 (search-forward ": " nil t
)))
584 (defun navi2ch-message-back-to-indentation ()
585 "\e$B9T$N:G=i$N6uGr$G$J$$2U=j$X0\F0!#\e(B
586 header field \e$B$X0\F0$7$J$$0J30$O\e(B `back-to-indentation' \e$B$HF1$8!#\e(B"
588 (navi2ch-message-beginning-of-line)
589 (skip-chars-forward " \t"))
591 ;; sendlog\e$B5!G=\e(B
592 (defun navi2ch-message-sendlog-subject (board article
)
593 ;; \e$BAw?.$7$?%l%9$rJ]B8$9$k%9%l$N%?%$%H%k$rJV$9!#\e(B
594 ;; \e$B%?%$%H%k$r:Y$+$/;XDj$7$?$$$H$-$O$3$N4X?t$r>e=q$-$7$F$M!#\e(B
595 ;; nil \e$B$rJV$9$H!"MzNr$OJ]B8$5$l$^$;$s!#\e(B
596 navi2ch-message-sendlog-subject
)
598 (defun navi2ch-message-sendlog-subject-with-volume (base format limit
601 (regexp (concat "\\`"
602 (format (regexp-quote format
)
603 (regexp-quote base
) "\\([0-9]+\\)")
608 (dolist (x subject-list
)
609 (let ((sbj (cdr (assq 'subject x
)))
611 (when (and (or (and (string= base sbj
)
613 (and (string-match regexp sbj
)
615 (string-to-number (match-string 1 sbj
)))))
620 (if (>= (string-to-number (cdr (assq 'response article
))) limit
)
621 (setq subject
(format format base
(number-to-string (1+ max
))))
622 (setq subject
(cdr (assq 'subject article
))))))
625 (defun navi2ch-message-add-sendlog (from mail message subject board article
)
626 (let ((navi2ch-localfile-default-file-modes (* 64 7))
627 ;; \e$BAw?.95$(\e(B \e$B$N%9%l%?%$$K\e(B ♥ \e$B$H$+$r;H$($k$h$&$K!#\e(B
628 (navi2ch-decode-character-references nil
)
629 (url (navi2ch-article-to-url board article
))
630 (sbj (or subject
(cdr (assq 'subject article
))))
631 (lsubject (navi2ch-message-sendlog-subject board article
))
632 (lboard navi2ch-message-sendlog-board
)
633 (fmt navi2ch-message-sendlog-volume-format
)
634 (limit navi2ch-message-sendlog-response-limit
)
636 (when (and lsubject lboard
)
637 (setq message
(funcall navi2ch-message-sendlog-message-format-function
638 message sbj url board article
)
639 lsbj-list
(navi2ch-board-get-updated-subject-list lboard
)
640 lsubject
(navi2ch-message-sendlog-subject-with-volume
641 lsubject fmt limit lsbj-list
))
643 (dolist (s lsbj-list
)
644 (when (string= (cdr (assq 'subject s
)) lsubject
)
645 (throw 'loop
(setq larticle s
)))))
646 (when larticle
(setq lsubject nil
))
647 (navi2ch-multibbs-send-message from mail message
648 lsubject lboard larticle
))))
650 (defun navi2ch-message-sendlog-simple-message-format
651 (message subject url board article
)
652 "\e$BAw?.95$($N%l%9$N%7%s%W%k$J%U%)!<%^%C%H!#\e(B"
653 (format "Subject: %s\nURL: %s\n\n%s" subject url message
))
655 (defun navi2ch-message-sendlog-message-format-with-board-name
656 (message subject url board article
)
657 "\e$BAw?.95$($N%l%9$NHDL>IU$-$N%U%)!<%^%C%H!#\e(B"
658 (format "[%s]: %s\nURL: %s\n\n%s" (cdr (assq 'name board
)) subject url message
))
660 ;; TODO: 2ch \e$BFb$K$*$$$F$OHD\e(BID\e$B$,=EJ#$7$J$$$3$H$rA0Ds$H$7$F$$$k!#:#$N$H$3\e(B
661 ;; \e$B$m$OM-8z$@$,>-Mh$N$3$H$b9M$($k$HD>$9$Y$-!#\e(B
663 (defun navi2ch-message-samba24-modeline ()
664 "\e$B=q$-9~$_7P2a;~4V$r%+%&%s%H%@%&%s$9$k\e(B."
665 (let* ((tmp-time (current-time))
666 (now-time (+ (lsh (car tmp-time
) 16) (nth 1 tmp-time
)))
667 samba-time time-diff
)
668 (setq navi2ch-message-samba24-mode-string
"")
669 (dolist (x navi2ch-message-samba24-send-time
)
671 (id-normalized (if (string-match "^\\([^:]*\\):" id
)
674 (setq time-diff
(- now-time
(cdr x
)))
676 (navi2ch-message-samba24-search-samba
677 (navi2ch-message-samba24-board-conversion 'id id-normalized
'uri
)
680 (if (<= time-diff samba-time
)
681 (setq navi2ch-message-samba24-mode-string
683 (navi2ch-message-samba24-board-conversion 'id id
'name
)
684 (- samba-time time-diff
)
685 navi2ch-message-samba24-mode-string
))
686 (setq navi2ch-message-samba24-send-time
687 (delete x navi2ch-message-samba24-send-time
))
688 (unless navi2ch-message-samba24-send-time
689 (cancel-timer navi2ch-message-samba24-update-timer
)
690 (setq navi2ch-message-samba24-update-timer nil
))))))
691 (force-mode-line-update t
)))
693 (defun navi2ch-message-samba24 ()
694 "SAMBA24(\e$BO"B3Ej9F5
,@)\e(B)\e$B$NBP1~$N$?$a
!"=q$-9~$_5v2DBT$A;~4V$rI=<($9$k!#\e(B
695 \e$B%l%9Aw?.;~$K%3!<%k$5$l!"%b
!<%I%i%$%s$G%
+%
&%s%H%
@%
&%s$rI
=<($
9$k
\e(B"
696 (when navi2ch-message-samba24-show
697 (if (and (null navi2ch-message-samba24-samba-data)
698 (null (navi2ch-message-samba24-read-samba)))
699 (message "samba.txt
\e$B$
,$
"$j$^$;$s\e(B")
700 (let* ((tmp-time (current-time))
701 (last-write-time (+ (lsh (car tmp-time
) 16) (cadr tmp-time
)))
702 (id (cdr (assq 'id navi2ch-message-current-board
)))
703 (id-list (assoc id navi2ch-message-samba24-send-time
))
704 (id-normalized (if (string-match "^\\([^:]*\\):" id
)
707 (when (navi2ch-message-samba24-search-samba
708 (navi2ch-message-samba24-board-conversion 'id id-normalized
'uri
)
711 (setq navi2ch-message-samba24-send-time
712 (delete id-list navi2ch-message-samba24-send-time
)))
713 (setq navi2ch-message-samba24-send-time
714 (cons (cons id last-write-time
)
715 navi2ch-message-samba24-send-time
))
716 (setq navi2ch-message-samba24-update-timer
717 (or navi2ch-message-samba24-update-timer
718 (run-at-time 1 1 'navi2ch-message-samba24-modeline
))))))))
720 (defun navi2ch-message-samba24-board-conversion (src val dst
)
721 "\e$BHDL>!"\e(BID\e$B
!"\e(BURL\e$B$J$I$NAj8_JQ49!#\e(B
722 SRC=\e$BJQ4985$NO"A
[%j%
9%H
:8B
&\e(B VAL
=\e$BJQ4985$NCM
\e(B(\e$B1
&B
&\e(B) DST
=\e$BJQ49
@h$N
:8B
&;XDj\e(B"
724 (dolist (x navi2ch-list-board-name-list
)
725 (if (string= val
(cdr (assq src x
)))
726 (throw 'loop
(cdr (assq dst x
)))))))
728 (defun navi2ch-message-samba24-read-samba ()
729 "samba.txt \e$B$+$i3F%5!<%P!"HD$
4$H$NO
"B3Ej9F5,@);~4V$rFI$_9~$_!"%j%
9%H$H$
7$FJ
];}$9$k\e(B.
730 samba.txt
\e$B$O
\e(B http
://nullpo.s101.xrea.com
/samba24
/ \e$B$
+$i
<hF
@\e(B.
"
732 (let (navi2ch-message-samba24-file)
733 ;; \e$B:G?7$N\e(Bsamba.txt\e$B$r<hF@\e(B
734 (navi2ch-message-samba24-update)
735 (setq navi2ch-message-samba24-samba-data nil)
736 (setq navi2ch-message-samba24-file
737 (navi2ch-expand-file-name navi2ch-message-samba24-file-name))
738 (when (and (file-exists-p navi2ch-message-samba24-file)
739 (file-readable-p navi2ch-message-samba24-file))
741 (insert-file-contents navi2ch-message-samba24-file)
742 (goto-char (point-min))
743 (while (re-search-forward "\\([a-z0-9.
]+\\)=\\([0-
9]+\\)" nil t)
744 (setq navi2ch-message-samba24-samba-data
745 (cons (cons (match-string 1)
746 (string-to-number (match-string 2)))
747 navi2ch-message-samba24-samba-data)))))
748 navi2ch-message-samba24-samba-data))
750 ;; FIXME: defsubst \e$B$K$7$?$$!#\e(B
751 (defun navi2ch-message-samba24-search-samba (url id)
752 "\e$B%
5!<%PL
>!"HDL>$+$iO"B3Ej9F5
,@);~4V$rF@$k\e(B.p2\e$B$G$N=q$-9~$_$N>l9g!"\e(B10\e$BIC%W%i%9$N%Z%J%k%F%#$,$"$k\e(B"
755 (when (and (stringp url
)
756 (string-match "http://\\([^/]+\\)" url
))
757 (when (navi2ch-p2-board-p id
)
758 (setq samba-p2-time
10))
759 (setq samba-time
(or (cdr (assoc id navi2ch-message-samba24-samba-data
))
760 (cdr (assoc (match-string 1 url
) navi2ch-message-samba24-samba-data
))))
762 (+ samba-time samba-p2-time
)))))
764 (defun navi2ch-message-samba24-update ()
765 "samba24 \e$B$N5,@)>pJs$r99?7\e(B."
766 ;; \e$B%U%!%$%k$,F0E*@8@.$C$]$$$N$G\e(BIf-Modified-Since\e$B8+$J$$!)!J9bIi2Y!)!K\e(B
767 (navi2ch-net-update-file navi2ch-message-samba24-sambatxt-url
768 (navi2ch-expand-file-name navi2ch-message-samba24-file-name
)
771 (defun navi2ch-message-samba24-check (board)
772 "Samba24 \e$B$K$R$C$+$+$k$+$I$&$+%A%'%C%/\e(B."
773 (let* ((id (cdr (assq 'id board
)))
774 (last-write-time (cdr (assoc id
775 navi2ch-message-samba24-send-time
))))
776 (or (null last-write-time
)
777 (let* ((samba-time (navi2ch-message-samba24-search-samba
778 (navi2ch-message-samba24-board-conversion 'id id
'uri
)
780 (tmp-time (current-time))
781 (cur-time (+ (lsh (car tmp-time
) 16) (cadr tmp-time
)))
782 (diff-time (- (+ last-write-time samba-time
)
785 (if navi2ch-message-samba24-wait-sleep
787 (while (> diff-time
0)
788 (message "samba\e$BCY1d=q$-9~$_%U%j!<%:Cf\e(B %s sec %s %s" diff-time
(current-time-string) samba-time
)
790 (setq diff-time
(1- diff-time
)))
791 (message "samba\e$BCY1d=q$-9~$_%U%j!<%:=*N;\e(B %s" (current-time-string)))
793 "\e$B$"$H
\e(B %d
\e$BICBT$C$?$
[$
&$
,$$$$$H
;W$&$1$I!"K\Ev$K=q$-$3$`\e(B? "
796 (defun navi2ch-message-samba24-modify-by-error (id error
)
797 "\e$B%5!<%P$+$i<u$1<h$C$?%(%i!<%a%C%;!<%8$+$i\e(Bsamba\e$BIC?t$r@_Dj\e(B"
798 (when (string-match "593 \\([0-9]+\\) sec \e$B$?$?$J$$$H=q$1$^$;$s!#\e(B" error
)
799 (navi2ch-message-samba24-modify id
(string-to-number (match-string 1 error
)))))
801 (defun navi2ch-message-samba24-modify (id samba-time
)
802 (when (assoc id navi2ch-message-samba24-samba-data
)
803 (setq navi2ch-message-samba24-samba-data
804 (delq (assoc id navi2ch-message-samba24-samba-data
) navi2ch-message-samba24-samba-data
)))
805 (setq navi2ch-message-samba24-samba-data
806 (cons (cons id samba-time
) navi2ch-message-samba24-samba-data
)))
808 (run-hooks 'navi2ch-message-load-hook
)
809 ;;; navi2ch-message.el ends here