Commit d212c418 authored by David Byers's avatar David Byers
Browse files

New FAQ support.

Initial conference recmomendataion support
parent aa44fb6a
......@@ -173,6 +173,11 @@ b - Boolean. The first subformat is chosen if the argument is non-nil
variable "answer" as "yes" or "no" for t and nil using
(lyskom-format "%#1?b%[yes%]%[no%]" answer).
z - Zero. The first subformat is chosen if the argument is zero and
the second if the argument is nonzero. You could format a conf-no
variable as a "does not exist" or the conference name using
(lyskom-format "%#1?z%[does not exist%]%[%#1M%]")
3. FORMATTING FUNCTIONS
......
2002-04-13 David Byers <david.byers@swipnet.se>
New FAQ support:
* faqs.el: New file contains all FAQ-related stuff.
(lyskom-register-read-faq): New function.
(lyskom-update-read-faqs): New function.
(lyskom-do-review-faq): New function.
* lyskom-rest.el (lyskom-format-aux-help): Support ?z format code.
* commands2.el (lyskom-list-summary): Support REVIEW-FAQ.
* lyskom-rest.el (kom-view-next-text): Add support for REVIEW-FAQ.
(lyskom-update-prompt): Ditto.
(lyskom-what-to-do): Ditto.
* aux-items.el: Added read-action that records all read FAQs.
* commands1.el: Moved all FAQ-related commands to faqs.el.
* commands2.el: Moved all FAQ-related commands to faqs.el.
* lyskom-rest.el (lyskom-read-num-range): Handle prompt which is a
symbol and not a string.
Initial support for conference recommendataions:
* commands2.el (kom-recommend-conference): New command.
* utilities.el (lyskom-read-membership-type): New function.
Fix language consistency:
* english-strings.el: Changed "article" to "text" in a bunch of
strings.
......@@ -244,6 +272,11 @@
* distribution-configure.in: Corrected help text for
--with-default-language.
2002-03-24 Joel Rosdahl <joel@lysator.liu.se>
* Release of 0.46.2-BETA-2 (approximately: there was originally no
ChangeLog entry for this release). This entry was added after the
fact by David Byers.
2002-03-23 Joel Rosdahl <joel@lysator.liu.se>
Fix bug 422:
......
......@@ -102,6 +102,7 @@ SOURCES = komtypes.el \
elib-string.el \
option-edit.el \
talkback.el \
faqs.el \
lyskom-rest.el
# lyskom-rest.el should be the last file!
......
......@@ -274,7 +274,9 @@ return non-nil if the item is to be included in the list."
(def-aux-item faq-for-conf 28
(text-print . lyskom-print-faq-for-conf)
(text-print-when . header)
(info . lyskom-aux-item-info))
(info . lyskom-aux-item-info)
(read-action . lyskom-faq-for-conf-action))
(def-aux-item recommended-conf 29
(status-print . lyskom-print-recommended-conf)
......@@ -301,7 +303,9 @@ return non-nil if the item is to be included in the list."
(edit-insert . lyskom-edit-insert-world-readable)
(text-print-when . header))
(def-aux-item elisp-client-read-faq 10000
(info . lyskom-aux-item-info)
(status-print . lyskom-print-elisp-client-read-faq))
;;; ================================================================
......@@ -480,6 +484,12 @@ return non-nil if the item is to be included in the list."
(lyskom-format 'request-confirmation-edit-aux)
(lyskom-edit-generate-aux-item-flags (aux-item->flags item))))
(defun lyskom-faq-for-conf-action (text-stat)
(let ((faqs (text-stat-find-aux text-stat 28)))
(lyskom-traverse aux faqs
(lyskom-register-read-faq (string-to-int (aux-item->data aux))
(text-stat->text-no text-stat)))))
(defun lyskom-request-confirmation-action (text-stat)
(let ((confirmations (text-stat-find-aux text-stat 7))
(have-confirmation nil))
......@@ -640,10 +650,19 @@ return non-nil if the item is to be included in the list."
(lyskom-aux-item-terminating-button item obj)))
(defun lyskom-print-recommended-conf (item &optional obj)
(let ((conf-no (string-to-int (if (string-match " " (aux-item->data item))
(substring (aux-item->data item) 0 (match-beginning 0))
(aux-item->data item)))))
(lyskom-format-insert 'recommended-conf-aux conf-no)))
(lyskom-format-insert 'recommended-conf-aux conf-no)
(lyskom-aux-item-terminating-button item obj)))
(defun lyskom-print-elisp-client-read-faq (item &optional obj)
(when (string-match "^\\([0-9]+\\) \\([0-9]+\\)" (aux-item->data item))
(let ((conf-no (string-to-int (match-string 1 (aux-item->data item))))
(text-no (string-to-int (match-string 2 (aux-item->data item)))))
(lyskom-format-insert 'status-read-aux-item
conf-no
text-no
(lyskom-aux-item-terminating-button item obj)))))
(provide 'lyskom-aux-items)
......@@ -54,6 +54,7 @@
;;; REVIEW-TREE - List of texts created by one of the tree-reading
;;; commands: kom-find-root-review, kom-review-tree
;;; REVIEW-MARK - List of texts created by the review-mark command
;;; REVIEW-FAQ - List of texts created by kom-review-faq or similar
;;; COMM-IN - Type containing the list of comments to a text
;;; FOOTN-IN - Type containing the list of footnotes to a text
;;; CONF - Basic type of unread in a conf.
......@@ -63,8 +64,9 @@
;;; The types REVIEW-TREE, COMM-IN and FOOTN-IN are created for new for
;;; every text read (recursively) when appropriate.
;;;
;;; The difference between REVIEW and REVIEW-MARK is just that there
;;; generate different prompts and different text from kom-review-stack.
;;; The difference between REVIEW, REVIEW-MARK and REVIEW-FAQ is just
;;; that there generate different prompts and different text from
;;; kom-review-stack.
;;;
......@@ -243,8 +245,8 @@ Returns t if there was a conference to insert this text into."
(defun read-list-delete-text (text-no rlist)
"Destructively delete all occurances of TEXT-NO from RLIST.
RLIST is a list of read-info.
Entries of the type REVIEW, REVIEW-TREE or REVIEW-MARK are not changed
except if they were empty in which case they are removed.
Entries of the type REVIEW, REVIEW-FAQ, REVIEW-TREE or REVIEW-MARK are
not changed except if they were empty in which case they are removed.
Returns the modified RLIST.
TEXT-NO may be nil, in which case only empty read-infos on RLIST are removed."
(let* ((prev rlist) ;"Previous" cons-celll
......
......@@ -152,32 +152,39 @@
;;; Author: Inge Wallin
(def-kom-command kom-review-presentation (&optional text-no)
(def-kom-command kom-review-presentation (&optional text-or-conf-no)
"Review the presentation for a person or a conference. If a prefix argument
is given, the presentation of the author of that text will be shown."
(interactive (and current-prefix-arg ; only peek at textno:s when prefixed!
(list (lyskom-read-text-no-prefix-arg
'text-to-see-author-of))))
(let ((conf-stat
(if text-no
(if text-or-conf-no
(blocking-do 'get-conf-stat
(text-stat->author (blocking-do 'get-text-stat text-no)))
(if (interactive-p)
(text-stat->author
(blocking-do 'get-text-stat text-or-conf-no))
text-or-conf-no))
(lyskom-read-conf-stat
(lyskom-get-string 'presentation-for-whom)
'(all)
nil "" t))))
(if (null conf-stat)
(lyskom-insert-string 'somebody-deleted-that-conf)
(lyskom-format-insert 'review-presentation-of
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))
(lyskom-traverse faq (lyskom-get-aux-item
(conf-stat->aux-items conf-stat)
14)
(lyskom-print-comment-like-aux faq conf-stat)))))
(lyskom-review-presentation conf-stat)))
(defun lyskom-review-presentation (conf-stat)
"Review the presentation of conference CONF-STAT."
(if (null conf-stat)
(lyskom-insert-string 'somebody-deleted-that-conf)
(lyskom-format-insert 'review-presentation-of
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))
(lyskom-traverse faq (lyskom-get-aux-item
(conf-stat->aux-items conf-stat)
14)
(lyskom-print-comment-like-aux faq conf-stat))))
(defun lyskom-print-comment-like-aux (item object)
(let* ((text-no (string-to-int (aux-item->data item)))
......@@ -1232,143 +1239,7 @@ Don't ask for confirmation."
(blocking-do 'get-conf-stat no))
'pres))
(def-kom-command kom-change-server-faq ()
"Change a FAQ for the server."
(interactive)
(lyskom-change-faq nil (lyskom-get-aux-item (server-info->aux-item-list
(blocking-do 'get-server-info))
14)))
(def-kom-command kom-change-conf-faq ()
"Change a FAQ fo a conference."
(interactive)
(let* ((conf-no (lyskom-read-conf-no
(lyskom-get-string 'what-to-change-faq-you)
'(conf pers)
nil
(cons (if lyskom-current-conf
(let ((tmp (blocking-do 'get-uconf-stat lyskom-current-conf)))
(if tmp (uconf-stat->name tmp) ""))
"") 0)
t))
(conf-stat (when conf-no ; Need this to make sure the conf-stat is up-to-date!
(cache-del-conf-stat conf-no)
(blocking-do 'get-conf-stat conf-no))))
(if conf-stat
(lyskom-change-faq conf-stat (lyskom-get-aux-item
(conf-stat->aux-items conf-stat)
14))
(lyskom-insert (lyskom-get-string 'conf-does-not-exist)))))
(defun lyskom-change-faq (conf-stat aux-list)
"Change a FAQ for a conference."
(if (null aux-list)
(lyskom-format-insert 'conf-has-no-faq conf-stat)
;; Get a list of FAQ texts and corresponding aux-item-numbers
;; Get the FAQ to change
(let* ((faq-list (mapcar (lambda (x)
(cons (aux-item->data x)
(aux-item->aux-no x)))
aux-list))
(text-no-aux (cond ((= (length faq-list) 1) (car faq-list))
(t (lyskom-string-assoc
(lyskom-completing-read
(lyskom-get-string 'text-to-change-as-faq)
(lyskom-maybe-frob-completion-table
faq-list)
nil t)
faq-list))))
(text-no (string-to-int (car text-no-aux)))
(aux-no (cdr text-no-aux)))
(cond
;; If conf-stat is null we are changing the FAQ for the server.
;; Don't do this unless we are running enabled and have the right
;; privileges.
((and (null conf-stat)
(or (not lyskom-is-administrator)
(not (privs->admin (pers-stat->privileges
(blocking-do 'get-pers-stat
lyskom-pers-no))))))
(lyskom-format-insert 'not-supervisor-for-server))
;; If we have a conf-stat and are not administrator and not
;; supervisor for the conf, then we are not allowed to change
;; the FAQ.
((and conf-stat
(not lyskom-is-administrator)
(not (lyskom-is-supervisor (conf-stat->conf-no conf-stat)
lyskom-pers-no)))
(lyskom-format-insert 'not-supervisor-for conf-stat))
;; OK, it looks like we are allowed to change the FAQ.
(t
(blocking-do-multiple ((text-stat (get-text-stat text-no))
(text-mass (get-text text-no)))
(let* ((str (and text-mass (text->decoded-text-mass text-mass
text-stat)))
(subject (if (and str (string-match "\n" str))
(substring str 0 (match-beginning 0))
""
))
(body (if (and str (string-match "\n" str))
(substring str (match-end 0))
(or str ""))))
(lyskom-dispatch-edit-text
lyskom-proc
(apply 'lyskom-create-misc-list
(if (and text-stat text-mass)
(append (lyskom-get-recipients-from-misc-list
(text-stat->misc-info-list text-stat))
(list 'comm-to (text-stat->text-no text-stat)))
(list 'recpt (conf-stat->conf-no conf-stat))))
subject
body
'lyskom-change-faq-2
conf-stat
(text-stat->text-no text-stat)
aux-no))))))))
(defun lyskom-change-faq-2 (text-no conf-stat old-text-no old-aux-no)
(let ((aux-item (lyskom-create-aux-item
0 14 0 0
(lyskom-create-aux-item-flags nil nil nil nil
nil nil nil nil)
0
(int-to-string text-no))))
(if conf-stat
(progn
(cache-del-conf-stat (conf-stat->conf-no conf-stat))
(initiate-modify-conf-info 'background
'lyskom-change-faq-3
(conf-stat->conf-no conf-stat)
(when old-aux-no (list old-aux-no))
(list aux-item)
conf-stat
old-text-no
text-no))
(initiate-modify-server-info 'background
'lyskom-change-faq-3
(when old-aux-no (list old-aux-no))
(list aux-item)
conf-stat
old-text-no
text-no))))
(defun lyskom-change-faq-3 (retval conf-stat old-text-no text-no)
(if retval
(lyskom-format-insert-before-prompt 'changed-faq-for-conf-done conf-stat
old-text-no
text-no)
(lyskom-format-insert-before-prompt 'changed-faq-for-conf-failed conf-stat
old-text-no text-no
(lyskom-current-error))))
(def-kom-command kom-change-conf-motd ()
"Change motd for a person or a conference."
......@@ -1668,7 +1539,8 @@ Args: CONF-STAT MEMBERSHIP"
conf-stat)
(lyskom-run-hook-with-args 'lyskom-after-change-conf-hook
lyskom-current-conf
(conf-stat->conf-no conf-stat)))
(conf-stat->conf-no conf-stat))
(lyskom-change-conf-check-faqs conf-stat))
......
......@@ -972,7 +972,7 @@ the text on one line."
(read-list->nth read-list r)))))
(and (null conf-no)
(memq (read-info->type (read-list->nth read-list r))
'(CONF REVIEW-MARK REVIEW))))
'(CONF REVIEW-MARK REVIEW REVIEW-FAQ))))
(setq len 0)
(setq r (1+ r))))
(setq read-info (read-list->nth read-list r))
......@@ -2200,148 +2200,6 @@ Return-value: 'no-session if there is no suitable session to switch to
0 message)))))
;;; ======================================================================
;;; FAQ Management
;;;
(def-kom-command kom-add-faq (&optional conf-no text-no)
"Add a FAQ to a conference"
(interactive (list (lyskom-read-conf-no 'conf-to-add-faq '(conf pers) nil nil t)
(lyskom-read-text-no-prefix-arg 'text-to-add-as-faq nil 'last-seen-written)))
(lyskom-add-faq conf-no text-no))
(def-kom-command kom-add-server-faq (&optional text-no)
"Add a FAQ to the server"
(interactive (list (lyskom-read-text-no-prefix-arg 'text-to-add-as-faq nil 'last-seen-written)))
(lyskom-add-faq nil text-no))
(defun lyskom-add-faq (conf-no text-no)
"Add a FAQ to a conference or the server.
Add to the server if CONF-NO is nil, otherwise add to conference CONF-NO.
The text to add is passed in TEXT-NO"
(let ((text (blocking-do 'get-text-stat text-no)))
(if (null text)
(lyskom-format-insert 'no-such-text-no text-no)
(lyskom-format-insert 'adding-faq text-no conf-no)
(cache-del-text-stat text-no)
(when conf-no
(cache-del-conf-stat conf-no))
(let ((aux-item (lyskom-create-aux-item
0 14 0 0
(lyskom-create-aux-item-flags nil nil nil nil
nil nil nil nil)
0
(int-to-string text-no))))
(lyskom-report-command-answer
(if conf-no
(blocking-do 'modify-conf-info
conf-no
nil
(list aux-item))
(blocking-do 'modify-server-info
nil
(list aux-item))))))))
(def-kom-command kom-del-server-faq ()
"Remove a FAQ from the server"
(interactive)
(lyskom-del-faq nil))
(def-kom-command kom-del-faq ()
"Remove a FAQ from a conference"
(interactive)
(let* ((conf-stat (lyskom-read-conf-stat 'conf-to-del-faq
'(conf pers) nil nil t)))
(lyskom-del-faq conf-stat)))
(defun lyskom-del-faq (conf-stat)
(let ((faq-list
(mapcar (lambda (aux)
(cons (aux-item->data aux)
(aux-item->aux-no aux)))
(lyskom-get-aux-item
(if (null conf-stat)
(server-info->aux-item-list
(blocking-do 'get-server-info))
(conf-stat->aux-items conf-stat))
14)))
(text-no nil))
(cond
((null faq-list)
(lyskom-format-insert 'conf-has-no-faq conf-stat))
(t (setq text-no
(if (eq 1 (length faq-list))
(car (car faq-list))
(lyskom-completing-read (lyskom-get-string 'text-to-del-as-faq)
(lyskom-maybe-frob-completion-table
faq-list)
nil t)))
(when text-no
(lyskom-format-insert 'deleting-faq
(string-to-int text-no)
conf-stat)
(cache-del-text-stat (string-to-int text-no))
(when conf-stat
(cache-del-conf-stat (conf-stat->conf-no conf-stat)))
(lyskom-report-command-answer
(if conf-stat
(blocking-do 'modify-conf-info
(conf-stat->conf-no conf-stat)
(list (cdr (lyskom-string-assoc text-no faq-list)))
nil)
(blocking-do 'modify-server-info
(list (cdr (lyskom-string-assoc text-no faq-list)))
nil))))))))
(def-kom-command kom-review-server-faq ()
"View the FAQs for the server"
(interactive)
(lyskom-review-faq nil (server-info->aux-item-list
(blocking-do 'get-server-info))))
(def-kom-command kom-review-faq (&optional conf-no)
"View the FAQs for a conference"
(interactive (list (lyskom-read-conf-no 'view-which-faq '(conf pers) t nil t)))
(if (zerop conf-no)
(lyskom-review-faq nil (server-info->aux-item-list
(blocking-do 'get-server-info)))
(let ((conf-stat (blocking-do 'get-conf-stat conf-no)))
(if conf-stat
(lyskom-review-faq conf-stat (conf-stat->aux-items conf-stat))
(lyskom-format-insert 'conf-no-does-not-exist-r conf-no)))))
(defun lyskom-review-faq (conf-stat aux-list)
(let ((faq-list (mapcar (lambda (aux)
(string-to-int (aux-item->data aux)))
(lyskom-get-aux-item aux-list 14))))
(cond
((null faq-list)
(lyskom-format-insert 'conf-has-no-faq conf-stat))
((eq 1 (length faq-list))
(lyskom-format-insert 'review-faq-for-r conf-stat)
(lyskom-view-text (car faq-list)
nil ;mark-as-read
nil ;follow-comments
nil ;conf-stat
nil ;priority
nil ;build-review-tree
t ;flat-review
))
(t
(lyskom-format-insert 'review-faq-for-r conf-stat)
(read-list-enter-read-info
(lyskom-create-read-info 'REVIEW
nil
(lyskom-review-get-priority)
(lyskom-create-text-list faq-list)
nil t)
lyskom-reading-list t)))))
;;; ============================================================
;;; Various aux-item stuff
......@@ -2852,3 +2710,48 @@ to the first text that NEW is a comment or footnote to."
(lyskom-view-text (server-info->motd-of-lyskom server-info)))
)))
;;; ================================================================
;;; Rekommendera mte
(def-kom-command kom-recommend-conference ()
"Recommend a conference to new LysKOM users"
(interactive)
(let* ((conf-stat (lyskom-read-conf-stat 'recommend-which-conf
'(conf)
nil
nil
t))
(priority (and (lyskom-j-or-n-p 'recommend-set-priority-q)
(lyskom-read-num-range 0 255 'priority-q)))
(mship-type (and priority
(lyskom-j-or-n-p 'recommend-set-mship-type-q)
(lyskom-read-membership-type)))
(aux-item (lyskom-create-aux-item
0
29
nil
nil
(lyskom-create-aux-item-flags nil
nil
nil
nil
nil
nil
nil
nil)
0
(mapconcat 'lyskom-format-object
(list (conf-stat->conf-no conf-stat)
priority
mship-type)
" "))))
(lyskom-format-insert 'recommending-conf
conf-stat
priority
(lyskom-return-membership-type mship-type))
(lyskom-report-command-answer (blocking-do 'modify-server-info
nil
(list aux-item)))))
......@@ -600,7 +600,8 @@ Read all about it at http://www.lysator.liu.se/history/")
(status-conf-generic . "%-40#1s %#2s\n")
(status-aux-item . "Unknown auxiliary information: %11#1s%#3s (skapad av %#2M)\n")
(conf-mx-list-name . "Imported mailing list: %#1s %#2s\n")
(recommended-conf-aux . "Recommended conference: %#1M <%#1m>\n")
(recommended-conf-aux . "Recommended conference: %#1M <%#1m> %#2s\n")
(status-read-aux-item . "Read FAQ: %15#2n for %#1?z%[%#1M <%#1m>%]%[the server%] %#3s\n")
(Everybody . "Everyone")
(show-members-list-also-q . "List members? ")
......@@ -1117,6 +1118,7 @@ You should set it to a better value.\n")
(review-next-text-prompt . "Review next text")
(review-next-comment-prompt . "Review next comment")
(review-next-marked-prompt . "Review next marked text")
(review-next-faq-prompt . "Review next FAQ")
(read-next-letter-prompt . "Read next letter")
(read-next-footnote-prompt . "Read next footnote")
(read-next-comment-prompt . "Read next comment")
......@@ -1125,6 +1127,7 @@ You should set it to a better value.\n")
(go-to-conf-of-marked-prompt . "Resume reviewing marked")
(go-to-conf-of-review-tree-prompt . "Resume reviewing comments")
(go-to-conf-of-review-prompt . "Resume reviewing texts")
(go-to-conf-of-review-faq-prompt . "Resume reviewing FAQs")
(go-to-next-conf-prompt . "Go to next conference")
(go-to-your-mailbox-prompt . "Go to your mailbox")
(next-pri-session-prompt . "Go to prioritized LysKOM \"%#1s\"")
......@@ -1401,7 +1404,7 @@ On since %#8s%#9s")
%]%[%]%#4s")
(faq-in-text . "FAQ in text %#1n %#3s%#4s")
(faq-in-text-by . "FAQ in text %#1n %#5s %#3sby %#2P %#4s")
(there-are-server-faqs . "There %#1?d%[is%]%[are%] %#1d (%#1d not marked as read) FAQ%#1?d%[%]%[s%] for this server:\n")
(there-are-faqs . "You have %#1?d%[is%]%[are%] %#1d unread FAQ%#1?d%[%]%[s%] for %#2?b%[%#1M%]%[the server%]::\n")
(too-many-languages . "Cannot code that many character sets. Send uncoded? ")
(too-many-content-types . "Cannot figure out what content type you want. Simplify the text.")
......@@ -1667,6 +1670,14 @@ Number of sessions: %21#1d (total)
(server-status-last-text . "Youngest existing text: %15#1n\n")
(server-status-has-motd . "\nThe server has a notice:\n")
(server-status-time . "Serverns tid: %#1s\n")
(mship-type-invitation-q . "Membership invitation? ")
(mship-type-passive-q . "Passive membership? ")
(mship-type-secret-q . "Secret membership? ")
(recommend-which-conf . "Which conference do you want to recommend? ")
(recommend-set-priority-q . "Recommend a priority? ")
(recommend-set-mship-type-q . "Recommend a membership type? ")
(recommending-conf . "Recommending %#1M%#2?b%[ (priority %#2d)%]%[%]%#3?b%[ %#3s%]%[%]...")
))
......@@ -1866,6 +1877,7 @@ Number of sessions: %21#1d (total)
(kom-del-server-faq . "Remove server FAQ")