Revision: mange@freemail.hu--2005/emacs-jabber--cvs-head--0--patch-556
[emacs-jabber.git] / jabber-newdisco.el
blobf4b2a15e2e8950d0b69ff78322137a732c667aac
1 ;;; jabber-newdisco.el --- caching disco API
3 ;; Copyright (C) 2005, 2008 Magnus Henoch
5 ;; Author: Magnus Henoch <mange@freemail.hu>
7 ;; This file is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
12 ;; This file is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
22 ;;---
23 ;; Keys are ("jid" . "node"), where "node" is nil if appropriate.
24 ;; Values are (identities features), where each identity is ["name"
25 ;; "category" "type"], and each feature is a string.
26 (defvar jabber-disco-info-cache (make-hash-table :test 'equal))
28 ;; Keys are ("jid" . "node"). Values are (items), where each
29 ;; item is ["name" "jid" "node"] (some values may be nil).
30 (defvar jabber-disco-items-cache (make-hash-table :test 'equal))
32 ;;; Info
34 (defun jabber-disco-get-info (jc jid node callback closure-data &optional force)
35 "Get disco info for JID and NODE, using connection JC.
36 Call CALLBACK with JC and CLOSURE-DATA as first and second
37 arguments and result as third argument when result is available.
38 On success, result is (IDENTITIES FEATURES), where each identity is [\"name\"
39 \"category\" \"type\"], and each feature is a string.
40 On error, result is the error node, recognizable by (eq (car result) 'error).
42 If CALLBACK is nil, just fetch data. If FORCE is non-nil,
43 invalidate cache and get fresh data."
44 (when force
45 (remhash (cons jid node) jabber-disco-info-cache))
46 (let ((result (gethash (cons jid node) jabber-disco-info-cache)))
47 (if result
48 (and callback (run-with-timer 0 nil callback jc closure-data result))
49 (jabber-send-iq jc jid
50 "get"
51 `(query ((xmlns . "http://jabber.org/protocol/disco#info")
52 ,(when node `(node . ,node))))
53 #'jabber-disco-got-info (cons callback closure-data)
54 (lambda (jc xml-data callback-data)
55 (when (car callback-data)
56 (funcall (car callback-data) jc (cdr callback-data) (jabber-iq-error xml-data))))
57 (cons callback closure-data)))))
59 (defun jabber-disco-got-info (jc xml-data callback-data)
60 (let ((jid (jabber-xml-get-attribute xml-data 'from))
61 (node (jabber-xml-get-attribute (jabber-iq-query xml-data)
62 'node))
63 (result
64 (list
65 (mapcar
66 #'(lambda (id)
67 (vector (jabber-xml-get-attribute id 'name)
68 (jabber-xml-get-attribute id 'category)
69 (jabber-xml-get-attribute id 'type)))
70 (jabber-xml-get-children (jabber-iq-query xml-data) 'identity))
71 (mapcar
72 #'(lambda (feature)
73 (jabber-xml-get-attribute feature 'var))
74 (jabber-xml-get-children (jabber-iq-query xml-data) 'feature)))))
75 (puthash (cons jid node) result jabber-disco-info-cache)
76 (when (car callback-data)
77 (funcall (car callback-data) jc (cdr callback-data) result))))
79 (defun jabber-disco-get-info-immediately (jid node)
80 "Get cached disco info for JID and NODE.
81 Return nil if no info available.
83 Fill the cache with `jabber-disco-get-info'."
84 (gethash (cons jid node) jabber-disco-info-cache))
86 ;;; Items
88 (defun jabber-disco-get-items (jc jid node callback closure-data &optional force)
89 "Get disco items for JID and NODE, using connection JC.
90 Call CALLBACK with JC and CLOSURE-DATA as first and second
91 arguments and items result as third argument when result is
92 available.
93 On success, result is a list of items, where each
94 item is [\"name\" \"jid\" \"node\"] (some values may be nil).
95 On error, result is the error node, recognizable by (eq (car result) 'error).
97 If CALLBACK is nil, just fetch data. If FORCE is non-nil,
98 invalidate cache and get fresh data."
99 (when force
100 (remhash (cons jid node) jabber-disco-items-cache))
101 (let ((result (gethash (cons jid node) jabber-disco-items-cache)))
102 (if result
103 (and callback (run-with-timer 0 nil callback jc closure-data result))
104 (jabber-send-iq jc jid
105 "get"
106 `(query ((xmlns . "http://jabber.org/protocol/disco#items")
107 ,(when node `(node . ,node))))
108 #'jabber-disco-got-items (cons callback closure-data)
109 (lambda (jc xml-data callback-data)
110 (when (car callback-data)
111 (funcall (car callback-data) jc (cdr callback-data) (jabber-iq-error xml-data))))
112 (cons callback closure-data)))))
114 (defun jabber-disco-got-items (jc xml-data callback-data)
115 (let ((jid (jabber-xml-get-attribute xml-data 'from))
116 (node (jabber-xml-get-attribute (jabber-iq-query xml-data)
117 'node))
118 (result
119 (mapcar
120 #'(lambda (item)
121 (vector
122 (jabber-xml-get-attribute item 'name)
123 (jabber-xml-get-attribute item 'jid)
124 (jabber-xml-get-attribute item 'node)))
125 (jabber-xml-get-children (jabber-iq-query xml-data) 'item))))
126 (puthash (cons jid node) result jabber-disco-items-cache)
127 (when (car callback-data)
128 (funcall (car callback-data) jc (cdr callback-data) result))))
130 (defun jabber-disco-get-items-immediately (jid node)
131 (gethash (cons jid node) jabber-disco-items-cache))
133 ;;; Publish
135 (defun jabber-disco-publish (jc node item-name item-jid item-node)
136 "Publish the given item under disco node NODE."
137 (jabber-send-iq jc nil
138 "set"
139 `(query ((xmlns . "http://jabber.org/protocol/disco#items")
140 ,(when node `(node . ,node)))
141 (item ((action . "update")
142 (jid . ,item-jid)
143 ,(when item-name
144 `(name . ,item-name))
145 ,(when item-node
146 `(node . ,item-node)))))
147 'jabber-report-success "Disco publish"
148 'jabber-report-success "Disco publish"))
150 (defun jabber-disco-publish-remove (jc node item-jid item-node)
151 "Remove the given item from published disco items."
152 (jabber-send-iq jc nil
153 "set"
154 `(query ((xmlns . "http://jabber.org/protocol/disco#items")
155 ,(when node `(node . ,node)))
156 (item ((action . "remove")
157 (jid . ,item-jid)
158 ,(when item-node
159 `(node . ,item-node)))))
160 'jabber-report-success "Disco removal"
161 'jabber-report-success "Disco removal"))
163 (provide 'jabber-newdisco)
165 ;; arch-tag: b47c06aa-cae6-11d9-b1c0-000a95c2fcd0