File: roster.rb

package info (click to toggle)
ruby-xmpp4r 0.5.6-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 1,384 kB
  • sloc: ruby: 17,382; xml: 74; sh: 12; makefile: 4
file content (215 lines) | stat: -rwxr-xr-x 5,797 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# =XMPP4R - XMPP Library for Ruby
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
# Website::http://xmpp4r.github.io

require 'xmpp4r/query'

module Jabber
  module Roster
    ##
    # Class for handling roster updates
    #
    # You must do 'client.send(Iq.new_rosterget)' or else you will
    # have nothing to put in receive_iq()
    #
    # You must require 'xmpp4r/rosterquery' to use this class
    # as its functionality is not needed for a working XMPP implementation.
    # This will make [IqQuery] convert all Queries with namespace 'jabber:iq:roster'
    # to [IqQueryRoster]
    #
    # This <query/> contains multiple <item/> children. See RosterItem.
    class IqQueryRoster < IqQuery
      name_xmlns 'query', 'jabber:iq:roster'

      ##
      # Iterate through all items
      # &block:: Yield for every [RosterItem]
      def each(&block)
        each_element { |item|
          # XPath won't work here as it's missing a prefix...
          yield(item) if item.kind_of?(RosterItem)
        }
      end

      ##
      # Get roster item by JID
      # jid:: [JID] or [Nil]
      # result:: [RosterItem]
      def [](jid)
        each { |item|
          return(item) if item.jid == jid
        }
        nil
      end

      ##
      # Get all items
      # result:: [Array] of [RosterItem]
      def to_a
        a = []
        each { |item|
          a.push(item)
        }
        a
      end

      ##
      # Update roster by <iq/> stanza
      # (to be fed by an iq_callback)
      # iq:: [Iq] Containing new roster
      # filter:: [Boolean] If false import non-roster-like results too
      def receive_iq(iq, filter=true)
        if filter && (((iq.type != :set) && (iq.type != :result)) || (iq.queryns != 'jabber:iq:roster'))
          return
        end

        import(iq.query)
      end

      ##
      # Output for "p"
      #
      # JIDs of all contained [RosterItem] elements are joined with a comma
      # result:: [String]
      def inspect
        jids = to_a.collect { |item| item.jid.inspect }
        jids.join(', ')
      end
    end

    ##
    # Class containing the <item/> elements of the roster
    #
    # The 'name' attribute has been renamed to 'iname' here
    # as 'name' is already used by REXML::Element for the
    # element's name. It's still name='...' in XML.
    class RosterItem < XMPPElement
      name_xmlns 'item', 'jabber:iq:roster'

      ##
      # Construct a new roster item
      # jid:: [JID] Jabber ID
      # iname:: [String] Name in the roster
      # subscription:: [Symbol] Type of subscription (see RosterItem#subscription=)
      # ask:: [Symbol] or [Nil] Can be :subscribe
      def initialize(jid=nil, iname=nil, subscription=nil, ask=nil)
        super()
        self.jid = jid
        self.iname = iname
        self.subscription = subscription
        self.ask = ask
      end

      ##
      # Get name of roster item
      #
      # names can be set by the roster's owner himself
      # return:: [String]
      def iname
        attributes['name']
      end

      ##
      # Set name of roster item
      # val:: [String] Name for this item
      def iname=(val)
        attributes['name'] = val
      end

      ##
      # Get JID of roster item
      # Resource of the JID will _not_ be stripped
      # return:: [JID]
      def jid
        (a = attributes['jid']) ? JID.new(a) : nil
      end

      ##
      # Set JID of roster item
      # val:: [JID] or nil
      def jid=(val)
        attributes['jid'] = val.nil? ? nil : val.to_s
      end

      ##
      # Get subscription type of roster item
      # result:: [Symbol] or [Nil] The following values are valid according to RFC3921:
      # * :both
      # * :from
      # * :none
      # * :remove
      # * :to
      def subscription
        case attributes['subscription']
          when 'both' then :both
          when 'from' then :from
          when 'none' then :none
          when 'remove' then :remove
          when 'to' then :to
          else nil
        end
      end

      ##
      # Set subscription type of roster item
      # val:: [Symbol] or [Nil] See subscription for possible Symbols
      def subscription=(val)
        case val
          when :both then attributes['subscription'] = 'both'
          when :from then attributes['subscription'] = 'from'
          when :none then attributes['subscription'] = 'none'
          when :remove then attributes['subscription'] = 'remove'
          when :to then attributes['subscription'] = 'to'
          else attributes['subscription'] = nil
        end
      end

      ##
      # Get if asking for subscription
      # result:: [Symbol] nil or :subscribe
      def ask
        case attributes['ask']
          when 'subscribe' then :subscribe
          else nil
        end
      end

      ##
      # Set if asking for subscription
      # val:: [Symbol] nil or :subscribe
      def ask=(val)
        case val
          when :subscribe then attributes['ask'] = 'subscribe'
          else attributes['ask'] = nil
        end
      end

      ##
      # Get groups the item belongs to
      # result:: [Array] of [String] The groups
      def groups
        result = []
        each_element('group') { |group|
          result.push(group.text)
        }
        result.uniq
      end

      ##
      # Set groups the item belongs to,
      # deletes old groups first.
      #
      # See JEP 0083 for nested groups
      # ary:: [Array] New groups, duplicate values will be removed
      def groups=(ary)
        # Delete old group elements
        delete_elements('group')

        # Add new group elements
        ary.uniq.each { |group|
          add_element('group').text = group
        }
      end
    end
  end #Module Roster
end #Module Jabber