Commit 1cc6151a authored by David Byers's avatar David Byers
Browse files

Lots of changes. Mostly features. New message handling. Ansaphone. Remote...

Lots of changes. Mostly features. New message handling. Ansaphone. Remote control and more. See the ChangeLog.
parent 54a8f419
No preview for this file type
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
# $Id$ # $Id$
# #
CLIENTVERSION = 0.39 CLIENTVERSION = 0.39a
GENERIC-CLEAN = *~ *.o core GENERIC-CLEAN = *~ *.o core
GENERIC-DIST-CLEAN = TAGS GENERIC-DIST-CLEAN = TAGS
...@@ -43,7 +43,7 @@ PARTS-EL = komtypes.el clienttypes.el startup.el \ ...@@ -43,7 +43,7 @@ PARTS-EL = komtypes.el clienttypes.el startup.el \
commands1.el commands2.el review.el edit-text.el \ commands1.el commands2.el review.el edit-text.el \
filter.el filter-edit.el lyskom-buttons.el \ filter.el filter-edit.el lyskom-buttons.el \
view-text.el async.el completing-read.el \ view-text.el async.el completing-read.el \
prioritize.el flags.el \ prioritize.el flags.el messages.el ansaphone.el remote-control.el \
elib-string.el \ elib-string.el \
lyskom-rest.el lyskom-rest.el
HEADER-EL = macros.el vars.el HEADER-EL = macros.el vars.el
...@@ -58,7 +58,7 @@ SRC-ELC = komtypes.elc clienttypes.elc startup.elc \ ...@@ -58,7 +58,7 @@ SRC-ELC = komtypes.elc clienttypes.elc startup.elc \
commands1.elc commands2.elc review.elc edit-text.elc \ commands1.elc commands2.elc review.elc edit-text.elc \
filter.elc filter-edit.elc lyskom-buttons.elc \ filter.elc filter-edit.elc lyskom-buttons.elc \
view-text.elc async.elc completing-read.elc \ view-text.elc async.elc completing-read.elc \
prioritize.elc flags.elc \ prioritize.elc flags.elc messages.elc ansaphone.elc remote-control.elc \
elib-string.elc \ elib-string.elc \
lyskom-rest.elc lyskom-rest.elc
PARTS-ELC = $(SRC-ELC) PARTS-ELC = $(SRC-ELC)
......
;;;;;
;;;;; $Id$
;;;;; Copyright (C) 1991 Lysator Academic Computer Association.
;;;;;
;;;;; This file is part of the LysKOM server.
;;;;;
;;;;; LysKOM is free software; you can redistribute it and/or modify it
;;;;; under the terms of the GNU General Public License as published by
;;;;; the Free Software Foundation; either version 1, or (at your option)
;;;;; any later version.
;;;;;
;;;;; LysKOM is distributed in the hope that it will be useful, but WITHOUT
;;;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;;;;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
;;;;; for more details.
;;;;;
;;;;; You should have received a copy of the GNU General Public License
;;;;; along with LysKOM; see the file COPYING. If not, write to
;;;;; Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
;;;;; or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
;;;;; MA 02139, USA.
;;;;;
;;;;; Please mail bug reports to bug-lyskom@lysator.liu.se.
;;;;;
;;;; ================================================================
;;;; ================================================================
;;;;
;;;; File: ansaphone.el
;;;; Author: David Byers
;;;;
;;;; This file implements the auto-reply facility.
;;;; It must be loaded after messages.el
;;;;
(setq lyskom-clientversion-long
(concat lyskom-clientversion-long
"$Id$\n"))
(defvar kom-ansaphone-replies
'((group nil nil nil nil)
(common nil nil nil nil))
"*List of automatic replies to various messages.
A list of (MESSAGE-TYPE SENDER RECIPIENT TEXT REPLY)
MESSAGE-TYPE is one of personal, group or common or nil
SENDER is a list of integers or a single integer or nil
RECIPIENT is a list of integers or a single integer or nil
TEXT is a regular expression or nil
REPLY is a string or nil
When an incoming message arrives and the auto-reply facility is on,
this list is checked for automatic replies. The message type, sender,
recipient and text of the incoming messages is matched against the
elements of this list. If a match is found, the corresponding reply is
send. A nil in one of the message-type, sender, recipient or text
components in the list is taken to mean a wildcard. A null reply means
don't send a reply.
If none of the elements match, KOM-ANSAPHONE-DEFAULT-REPLY is sent.")
(defvar lyskom-ansaphone-messages nil
"Messages collected by the automatic reply facility.")
(defvar lyskom-ansaphone-when-set (current-time-string)
"Time when the auto-reply facility was enabled.")
(defconst lyskom-ansaphone-tag "Auto-reply:\n")
;;;============================================================
;;;
;;; User functions
;;;
(def-kom-command kom-change-auto-reply (&optional message)
"Change the default automatic reply message."
(interactive)
(let ((message (or message
(read-from-minibuffer
(lyskom-get-string 'ansaphone-new-message)))))
(setq kom-ansaphone-default-reply message)
(lyskom-format-insert (lyskom-get-string 'ansaphone-message)
kom-ansaphone-default-reply)))
(def-kom-command kom-toggle-auto-reply ()
"Toggle automatic replies to personal messages."
(interactive)
(setq kom-ansaphone-on (not kom-ansaphone-on))
(lyskom-format-insert (lyskom-get-string 'ansaphone-state-r)
(lyskom-get-string (if kom-ansaphone-on
'state-on
'state-off)))
(if kom-ansaphone-on
(progn
(setq lyskom-ansaphone-when-set (current-time-string))
(lyskom-format-insert (lyskom-get-string 'ansaphone-message)
kom-ansaphone-default-reply))))
(def-kom-command kom-list-messages ()
"List collected messages"
(interactive)
(if (null lyskom-ansaphone-messages)
(lyskom-format-insert (lyskom-get-string 'ansaphone-no-messages))
(progn
(lyskom-format-insert (lyskom-get-string 'ansaphone-message-list-start))
(mapcar (function
(lambda (msg)
(lyskom-show-personal-message
(blocking-do 'get-conf-stat (elt msg 0))
(blocking-do 'get-conf-stat (elt msg 1))
(elt msg 2)
(elt msg 3)
'nobeep)))
lyskom-ansaphone-messages)
(lyskom-format-insert (lyskom-get-string 'ansaphone-message-list-end)))))
(def-kom-command kom-erase-messages ()
"Erase collected messages"
(interactive)
(lyskom-message (lyskom-get-string 'ansaphone-messages-gone))
(setq lyskom-ansaphone-messages nil))
(defun lyskom-ansaphone-send-message (recipient message)
(initiate-send-message 'async
nil
(if (numberp recipient)
recipient
(conf-stat->conf-no recipient))
(concat lyskom-ansaphone-tag
message)))
(defun lyskom-ansaphone-message-handler (message-type sender recipient text)
"Personal message handler.
Automatically reply to certain personal messages and strip auto-reply
identification from messages.
See kom-ansaphone-on"
(let ((is-automatic (eq 0 (string-match lyskom-ansaphone-tag text))))
(if is-automatic
(progn
(string-match (concat "^"
lyskom-ansaphone-tag
"\\(\\(.\\|\n\\)*\\)") text)
(lyskom-set-current-message-text (substring text
(match-beginning 1)
(match-end 1)))))
(if (and kom-ansaphone-on
sender
(not (eq sender 0))
(not is-automatic))
(let ((reply (lyskom-ansaphone-find-reply
message-type
(conf-stat->conf-no sender)
(conf-stat->conf-no recipient)
text)))
(if (and reply (elt reply 4))
(progn
(setq reply
(concat
(lyskom-format
(lyskom-get-string 'ansaphone-message-header)
lyskom-ansaphone-when-set)
(elt reply 4)))
(lyskom-ansaphone-send-message sender reply)))))
(if (and kom-ansaphone-on sender)
(lyskom-ansaphone-record-message sender
recipient
lyskom-message-current-text)))
nil)
(defun lyskom-ansaphone-find-reply (message-type sender recipient text)
"Find an automatic reply suitable for messages of type MESSAGE-TYPE from
SENDER to RECIPIENT consisting of TEXT. See the documentation for
kom-ansaphone-default-reply and kom-ansaphone-replies."
(let ((exprs kom-ansaphone-replies)
(result nil))
(while exprs
(if (and (or (null (elt (car exprs) 0))
(eq (elt (car exprs) 0) message-type))
(or (null (elt (car exprs) 1))
(eq (elt (car exprs) 1) sender)
(and (listp (elt (car exprs) 1))
(memq sender (elt (car exprs) 1))))
(or (null (elt (car exprs) 2))
(eq (elt (car exprs) 2) recipient)
(and (listp (elt (car exprs) 2))
(memq recipient (elt (car exprs) 2))))
(or (null (elt (car exprs) 3))
(string-match (elt (car exprs) 3) text)))
(progn
(setq result (car exprs))
(setq exprs nil)))
(setq exprs (cdr-safe exprs)))
(or result (and (eq message-type 'personal)
(list nil nil nil nil kom-ansaphone-default-reply)))))
(defun lyskom-ansaphone-record-message (sender recipient text)
(if (not (numberp sender))
(setq sender (conf-stat->conf-no sender)))
(if (not (numberp recipient))
(setq recipient (conf-stat->conf-no recipient)))
(setq lyskom-ansaphone-messages (cons (list sender recipient text
(current-time-string))
lyskom-ansaphone-messages)))
(lyskom-add-personal-message-handler 'lyskom-ansaphone-message-handler
'before
nil
t)
...@@ -164,25 +164,16 @@ this function shall be with current-buffer the BUFFER." ...@@ -164,25 +164,16 @@ this function shall be with current-buffer the BUFFER."
(message (lyskom-parse-string))) (message (lyskom-parse-string)))
(lyskom-save-excursion (lyskom-save-excursion
(set-buffer buffer) (set-buffer buffer)
(cond
((string= message " ")
(initiate-send-message 'follow nil sender
(format "emacs-version: %s\nclient-version: %s"
(emacs-version)
lyskom-clientversion)))
(t
(if (zerop recipient) (if (zerop recipient)
(initiate-get-conf-stat 'async (initiate-get-conf-stat 'async
'lyskom-show-personal-message 'lyskom-handle-personal-message
sender sender
0 0
message) message)
(lyskom-collect 'async) (lyskom-collect 'async)
(initiate-get-conf-stat 'async nil sender) (initiate-get-conf-stat 'async nil sender)
(initiate-get-conf-stat 'async nil recipient) (initiate-get-conf-stat 'async nil recipient)
(lyskom-use 'async (lyskom-use 'async 'lyskom-handle-personal-message message)))))
'lyskom-show-personal-message
message)))))))
((eq msg-no 13) ; New logout ((eq msg-no 13) ; New logout
(let ((pers-no (lyskom-parse-num)) (let ((pers-no (lyskom-parse-num))
...@@ -264,86 +255,121 @@ this function shall be with current-buffer the BUFFER." ...@@ -264,86 +255,121 @@ this function shall be with current-buffer the BUFFER."
(not (zerop (minibuffer-depth)))) (not (zerop (minibuffer-depth))))
(defun lyskom-show-personal-message (sender recipient message) (defun lyskom-show-personal-message (sender recipient message
&optional when nobeep)
"Insert a personal message into the lyskom buffer. "Insert a personal message into the lyskom buffer.
Args: SENDER: conf-stat for the person issuing the broadcast message or a Args: SENDER: conf-stat for the person issuing the broadcast message or a
string that is the sender. string that is the sender.
RECIPIENT: 0 if this message is for everybody, otherwise the conf-stat RECIPIENT: 0 if this message is for everybody, otherwise the conf-stat
of the recipient. of the recipient.
MESSAGE: A string containing the message." MESSAGE: A string containing the message.
(lyskom-insert-personal-message sender recipient message) WHEN: Optional time of arrival. Same format as (current-time-string)
(setq lyskom-last-personal-message-sender NOBEEP: True means don't beep. No matter what."
(if (stringp sender) sender (conf-stat->name sender))) (lyskom-insert-personal-message sender recipient message when nobeep)
(setq lyskom-last-group-message-recipient (setq lyskom-last-personal-message-sender
(if (and recipient (if (stringp sender) sender (conf-stat->name sender)))
(/= (conf-stat->conf-no recipient) (setq lyskom-last-group-message-recipient
lyskom-pers-no)) (if (and recipient
(conf-stat->name recipient) (not (eq 0 recipient))
nil)) (not (eq (conf-stat->conf-no recipient)
lyskom-pers-no)))
(conf-stat->name recipient)
nil))
(run-hooks 'lyskom-personal-message-hook)) (run-hooks 'lyskom-personal-message-hook))
(defun lyskom-insert-personal-message (sender recipient message) (defun lyskom-insert-personal-message (sender recipient message
&optional when nobeep)
"Insert a personal message in the current buffer. "Insert a personal message in the current buffer.
Arguments: SENDER RECIPIENT MESSAGE. Arguments: SENDER RECIPIENT MESSAGE.
SENDER is a conf-stat (possibly nil) or a string. SENDER is a conf-stat (possibly nil) or a string.
RECIPIENT is 0 if the message is public, otherwise the pers-no of the user. RECIPIENT is 0 if the message is public, otherwise the pers-no of the user.
MESSAGE is a string containing the message. MESSAGE is a string containing the message.
INSERT-FUNCTION is a function that given a string inserts it into the WHEN, if given, is the time when the message arrived. It must be of the same
current buffer." format at (current-time-string)
Non-nil NOBEEP means don't beep."
(lyskom-handle-as-personal-message (lyskom-handle-as-personal-message
(cond ((eq recipient 0) ; Public message (lyskom-format-as-personal-message sender recipient message when nobeep)
(if (eq t kom-ding-on-personal-messages) (beep)) (conf-stat->conf-no sender)
(lyskom-format 'message-broadcast nil))
(cond
((stringp sender) sender) (defun lyskom-format-as-personal-message (sender
(sender sender) recipient
(t (lyskom-get-string 'unknown))) message
message &optional when nobeep)
(substring (current-time-string) 11 19))) "Formats a personal message, returning it as a string.
((= (conf-stat->conf-no recipient) lyskom-pers-no) ; Private Arguments: SENDER RECIPIENT MESSAGE.
(if (memq kom-ding-on-personal-messages '(t personal)) (beep)) SENDER is a conf-stat (possibly nil) or a string.
(lyskom-format 'message-from RECIPIENT is 0 if the message is public, otherwise the pers-no of the user.
(cond MESSAGE is a string containing the message.
((stringp sender) sender) WHEN, if given, is the time when the message arrived. It must be of the same
(sender sender) format at (current-time-string)
(t (lyskom-get-string 'unknown))) Non-nil NOBEEP means don't beep."
message (progn
(substring (current-time-string) 11 19))) (if (null when)
(t ; Group message (setq when (current-time-string)))
(if (memq kom-ding-on-personal-messages '(t group)) (beep)) (if (not (string= (substring when 0 10)
(lyskom-format 'message-from-to (substring (current-time-string) 0 10)))
message (setq when (substring when 4 19))
(cond (setq when (substring when 11 19)))
((stringp sender) sender)
(sender (conf-stat->name sender)) (cond ((eq recipient 0) ; Public message
(t (lyskom-get-string 'unknown))) (lyskom-beep (if (not nobeep) kom-ding-on-common-messages 0))
(cond (lyskom-format 'message-broadcast
((stringp recipient) recipient) (cond
(recipient (conf-stat->name recipient)) ((stringp sender) sender)
(t (lyskom-get-string 'unknown))) (sender sender)
(substring (current-time-string) 11 19)))) (t (lyskom-get-string 'unknown)))
(conf-stat->conf-no sender))) message
when))
((= (conf-stat->conf-no recipient) lyskom-pers-no) ; Private
(lyskom-beep (if (not nobeep) kom-ding-on-personal-messages 0))
(lyskom-format 'message-from
(cond
((stringp sender) sender)
(sender sender)
(t (lyskom-get-string 'unknown)))
message
when))
(t ; Group message
(lyskom-beep (if (not nobeep) kom-ding-on-group-messages 0))
(lyskom-format 'message-from-to
message
(cond
((stringp sender) sender)
(sender (conf-stat->name sender))
(t (lyskom-get-string 'unknown)))
(cond
((stringp recipient) recipient)
(recipient (conf-stat->name recipient))
(t (lyskom-get-string 'unknown)))
when)))))
(defun lyskom-handle-as-personal-message (string from) (defun lyskom-handle-as-personal-message (string from &optional filter)
"Insert STRING (a format state) as a personal message and beep if "Insert STRING as a personal message and beep if not from me and
not from me and supposed to. The buffer, is chosen according to the supposed to. The buffer, is chosen according to the
kom-show-personal-messages-in-buffer variable value. The text is kom-show-personal-messages-in-buffer variable value. The text is
converted, before insertion." converted, before insertion."
(lyskom-save-excursion (if (and filter
(cond (or
((eq kom-show-personal-messages-in-buffer t) (eq 0 (string-match "^Remote-command: [0-9]+ [0-9]+\n" string))
(lyskom-insert-before-prompt string)) (eq 0 (string-match "^Auto-reply:\n" string))))
((null kom-show-personal-messages-in-buffer)) nil
(t (lyskom-save-excursion
(set-buffer (get-buffer-create kom-show-personal-messages-in-buffer)) (cond
(goto-char (point-max)) ((eq kom-show-personal-messages-in-buffer t)
(insert (if kom-emacs-knows-iso-8859-1 (lyskom-insert-before-prompt string))
string ((null kom-show-personal-messages-in-buffer))
(iso-8859-1-to-swascii string))))) (t
(if kom-pop-personal-messages (set-buffer (get-buffer-create kom-show-personal-messages-in-buffer))
(display-buffer (current-buffer))))) (goto-char (point-max))
(insert (if kom-emacs-knows-iso-8859-1
string
(iso-8859-1-to-swascii string)))))
(if kom-pop-personal-messages
(display-buffer (current-buffer))))))
;;; ================================================================ ;;; ================================================================
......
...@@ -119,26 +119,29 @@ ...@@ -119,26 +119,29 @@
;;; Author: Inge Wallin ;;; Author: Inge Wallin
(defun kom-review-presentation () (defun kom-review-presentation (&optional who)
"Review the presentation for a person or a conference." "Review the presentation for a person or a conference."
(interactive) (interactive)
(lyskom-start-of-command 'kom-review-presentation) (lyskom-start-of-command 'kom-review-presentation)
(let ((end-of-command-taken-care-of)) (let ((end-of-command-taken-care-of))
(unwind-protect (unwind-protect
(let ((conf-stat (lyskom-read-conf-stat (let ((conf-stat
(lyskom-get-string 'presentation-for-whom) (if who
'all))) (blocking-do 'get-conf-stat who)
(if (null conf-stat) (lyskom-read-conf-stat
(lyskom-insert-string 'somebody-deleted-that-conf) (lyskom-get-string 'presentation-for-whom)
(lyskom-format-insert 'review-presentation-of 'all))))
conf-stat) (if (null conf-stat)
(if (/= (conf-stat->presentation conf-stat) 0) (lyskom-insert-string 'somebody-deleted-that-conf)
(lyskom-view-text (conf-stat->presentation conf-stat)) (lyskom-format-insert 'review-presentation-of
(lyskom-format-insert 'has-no-presentation conf-stat)
conf-stat)))) (if (/= (conf-stat->presentation conf-stat) 0)
(lyskom-view-text (conf-stat->presentation conf-stat))
(lyskom-format-insert 'has-no-presentation
conf-stat))))
(if end-of-command-taken-care-of (if end-of-command-taken-care-of
nil nil
(lyskom-end-of-command))))) (lyskom-end-of-command)))))
...@@ -210,37 +213,39 @@ as TYPE. If no such misc-info, return NIL" ...@@ -210,37 +213,39 @@ as TYPE. If no such misc-info, return NIL"
;;; Author: Inge Wallin ;;; Author: Inge Wallin
;;; Rewritten using read-conf-no by Linus Tolke (4=>1) ;;; Rewritten using read-conf-no by Linus Tolke (4=>1)
(defun kom-send-letter () (defun kom-send-letter (&optional pers-no)
"Send a personal letter to a person or a conference." "Send a personal letter to a person or a conference."
(interactive) (interactive)
(condition-case error (condition-case error
(progn (progn
(lyskom-start-of-command 'kom-send-letter) (lyskom-start-of-command 'kom-send-letter)
(lyskom-tell-internat 'kom-tell-write-letter) (lyskom-tell-internat 'kom-tell-write-letter)
(let* ((tono (lyskom-read-conf-no (lyskom-get-string 'who-letter-to) (let* ((tono (or pers-no
'all)) (lyskom-read-conf-no
(conf-stat (blocking-do 'get-conf-stat tono))) (lyskom-get-string 'who-letter-to)
(if (if (zerop (conf-stat->msg-of-day conf-stat)) 'all)))
t (conf-stat (blocking-do 'get-conf-stat tono)))
(progn (if (if (zerop (conf-stat->msg-of-day conf-stat))
(recenter 0) t
(lyskom-format-insert 'has-motd (progn
conf-stat) (recenter 0)
(lyskom-view-text (conf-stat->msg-of-day conf-stat)) (lyskom-format-insert 'has-motd
(if (lyskom-j-or-n-p (lyskom-get-string 'motd-persist-q)) conf-stat)
t (lyskom-view-text (conf-stat->msg-of-day conf-stat))
(lyskom-end-of-command) (if (lyskom-j-or-n-p (lyskom-get-string 'motd-persist-q))
nil))) t
(if (= tono lyskom-pers-no) (lyskom-end-of-command)
(lyskom-edit-text lyskom-proc nil)))
(lyskom-create-misc-list 'recpt tono) (if (= tono lyskom-pers-no)
"" "") (lyskom-edit-text lyskom-proc
(lyskom-edit-text lyskom-proc (lyskom-create-misc-list 'recpt tono)
(lyskom-create-misc-list 'recpt tono "" "")
'recpt lyskom-pers-no) (lyskom-edit-text lyskom-proc
"" ""))))) (lyskom-create-misc-list 'recpt tono
'recpt lyskom-pers-no)
"" "")))))
(quit (lyskom-end-of-command) (quit (lyskom-end-of-command)
(signal 'quit "Quitting in letter")))) (signal 'quit "Quitting in letter"))))
;;; ================================================================ ;;; ================================================================
...@@ -269,16 +274,17 @@ Ask for the name of the person, the conference to add him/her to." ...@@ -269,16 +274,17 @@ Ask for the name of the person, the conference to add him/her to."
;; Add self ;; Add self
(def-kom-command kom-add-self () (def-kom-command kom-add-self (&optional conf)
"Add this person as a member of a conference." "Add this person as a member of a conference."