File: message.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 (226 lines) | stat: -rw-r--r-- 5,524 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
216
217
218
219
220
221
222
223
224
225
226
# =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/xmppstanza'
require 'xmpp4r/x'

module Jabber
  ##
  # The Message class manages the <message/> stanzas,
  # which is used for all messaging communication.
  class Message < XMPPStanza

    CHAT_STATES = %w(active composing gone inactive paused).freeze

    name_xmlns 'message', 'jabber:client'
    force_xmlns true

    include XParent

    ##
    # Create a new message
    # >to:: a JID or a String object to send the message to.
    # >body:: the message's body
    def initialize(to = nil, body = nil)
      super()
      if not to.nil?
        set_to(to)
      end
      if !body.nil?
        add_element(REXML::Element.new("body").add_text(body))
      end
    end

    ##
    # Get the type of the Message stanza
    #
    # The following Symbols are allowed:
    # * :chat
    # * :error
    # * :groupchat
    # * :headline
    # * :normal
    # result:: [Symbol] or nil
    def type
      case super
        when 'chat' then :chat
        when 'error' then :error
        when 'groupchat' then :groupchat
        when 'headline' then :headline
        when 'normal' then :normal
        else nil
      end
    end

    ##
    # Set the type of the Message stanza (see Message#type for details)
    # v:: [Symbol] or nil
    def type=(v)
      case v
        when :chat then super('chat')
        when :error then super('error')
        when :groupchat then super('groupchat')
        when :headline then super('headline')
        when :normal then super('normal')
        else super(nil)
      end
    end

    ##
    # Set the type of the Message stanza (chaining-friendly)
    # v:: [Symbol] or nil
    def set_type(v)
      self.type = v
      self
    end

    ##
    # Returns the message's body, or nil.
    # This is the message's plain-text content.
    def body
      first_element_text('body')
    end

    ##
    # Sets the message's body
    #
    # b:: [String] body to set
    def body=(b)
      replace_element_text('body', b)
    end

    ##
    # Sets the message's body
    #
    # b:: [String] body to set
    # return:: [REXML::Element] self for chaining
    def set_body(b)
      self.body = b
      self
    end

    ##
    # Returns the message's xhtml body, or nil.
    # This is the message's xhtml-text content.
    def xhtml_body
      html = first_element('html', 'http://jabber.org/protocol/xhtml-im')

      if html
        html.first_element_content('body', 'http://www.w3.org/1999/xhtml')
      else
        first_element_content('body', 'http://www.w3.org/1999/xhtml')
      end
    end

    ##
    # Sets the message's xhtml body
    #
    # b:: [String] xhtml body to set (Note: must be a valid xhtml)
    def xhtml_body=(b)
      begin
        b = REXML::Document.new("<root>#{b}</root>")
      rescue REXML::ParseException
        raise ArgumentError, "Body is not a valid xhtml. Have you forgot to close some tag?"
      end
      
      html = first_element('html', 'http://jabber.org/protocol/xhtml-im')
      
      if html
        html.replace_element_content('body', b, 'http://www.w3.org/1999/xhtml')
      else
        el = REXML::Element.new('html')
        el.add_namespace('http://jabber.org/protocol/xhtml-im')
        el.replace_element_content('body', b, 'http://www.w3.org/1999/xhtml')
        add_element(el)
      end
    end

    ##
    # Sets the message's xhtml body
    #
    # b:: [String] xhtml body to set (Note: must be a valid xhtml)
    # return:: [REXML::Element] self for chaining
    def set_xhtml_body(b)
      self.xhtml_body = b
      self
    end

    ##
    # sets the message's subject
    #
    # s:: [String] subject to set
    def subject=(s)
      replace_element_text('subject', s)
    end

    ##
    # sets the message's subject
    #
    # s:: [String] subject to set
    # return:: [REXML::Element] self for chaining
    def set_subject(s)
      self.subject = s
      self
    end

    ##
    # Returns the message's subject, or nil
    def subject
      first_element_text('subject')
    end

    ##
    # sets the message's thread
    # s:: [String] thread to set
    def thread=(s)
      delete_elements('thread')
      replace_element_text('thread', s) unless s.nil?
    end

    ##
    # gets the message's thread (chaining-friendly)
    # Please note that this are not [Thread] but a [String]-Identifier to track conversations
    # s:: [String] thread to set
    def set_thread(s)
      self.thread = s
      self
    end

    ##
    # Returns the message's thread, or nil
    def thread
      first_element_text('thread')
    end

    ##
    # Returns the current chat state, or nil if no chat state is set
    def chat_state
      each_elements(*CHAT_STATES) { |el| return el.name.to_sym }
      return nil
    end

    ##
    # Sets the chat state :active, :composing, :gone, :inactive, :paused
    def chat_state=(s)
      s = s.to_s
      raise InvalidChatState, "Chat state must be one of #{CHAT_STATES.join(', ')}" unless CHAT_STATES.include?(s)
      CHAT_STATES.each { |state| delete_elements(state) }
      add_element(REXML::Element.new(s).add_namespace('http://jabber.org/protocol/chatstates'))
    end

    ##
    # Sets the message's chat state
    def set_chat_state(s)
      self.state = s
      self
    end

    CHAT_STATES.each do |state|
      define_method("#{state}?") do
        chat_state == state.to_sym
      end
    end

  end
end