fluent-plugin-jabber 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -40,8 +40,13 @@ See source for details.
40
40
  # To prevent it, specify unique nickname per plugin definition.
41
41
  room test@conference.localhost/unique_nickname
42
42
 
43
+ # Required, plain text message format.
43
44
  format Hello!\n${user.name} # ${user.name} replaced with record['user']['name']
44
45
 
46
+ # Optional, XHTML message format.
47
+ # NOTE: Use '\{sharp}' instead of '#' due to fluentd treat '#' to 'Begin of comment'
48
+ xhtml_format <span style="color:\{sharp}FF0000">Hello!<strong>${user.name}</strong></span>
49
+
45
50
  # Enable detailed log of XMPP4R
46
51
  jabber_debug_log true
47
52
  jabber_warnings_log true
@@ -63,6 +68,16 @@ If 'body' field not set, the plugin raises error.
63
68
 
64
69
  ## Changes
65
70
 
71
+ ### 0.3.0
72
+
73
+ * Add filter: br
74
+ * Fix xhtml message building
75
+ * Fix xhtml message encoding error
76
+
77
+ ### 0.2.0
78
+
79
+ * Add xhtml_format option
80
+
66
81
  ### 0.1.1
67
82
 
68
83
  * Fix Encoding::CompatibilityError while parsing XMPP messages caused by default_internal is ASCII_8BIT.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = "fluent-plugin-jabber"
3
- gem.version = "0.1.1"
3
+ gem.version = "0.3.0"
4
4
  gem.authors = ["todesking"]
5
5
  gem.email = ["discommunicative@gmail.com"]
6
6
  gem.summary = %q{Fluentd output plugin for XMPP(Jabber) protocol}
@@ -27,7 +27,9 @@ class Fluent::JabberOutput < Fluent::Output
27
27
  # Currently, output target is group chat only.
28
28
  config_param :room, :string
29
29
 
30
+ # Plain text/XHTML format. These options are exclusive.
30
31
  config_param :format, :string
32
+ config_param :xhtml_format, :string, default: nil
31
33
 
32
34
  # Enable error/warning logs of XMPP4R
33
35
  # This configuration is global
@@ -73,16 +75,67 @@ class Fluent::JabberOutput < Fluent::Output
73
75
 
74
76
  def emit(tag, es, chain)
75
77
  es.each do|time, record|
76
- send_message create_message(time, record)
78
+ send_message plain_text_format(time, record), xhtml_format(time, record)
77
79
  end
78
80
  chain.next
79
81
  end
80
82
 
81
- def create_message(time, record)
82
- message = @format.gsub(/\\n/, "\n").gsub(/\${([\w.]+)}/) { $1.split('.').inject(record) {|r,k| (r||{})[k]} }
83
+ def plain_text_format(time, record)
84
+ format_with(@format, time, record, false)
83
85
  end
84
86
 
85
- def send_message(message)
86
- @muc_client.send Jabber::Message.new(@room, message)
87
+ def xhtml_format(time, record)
88
+ format_with(@xhtml_format, time, record, true)
89
+ end
90
+
91
+ def format_with(format_string, time, record, need_escape)
92
+ return nil unless format_string
93
+ format_string.gsub(/\\n/, "\n").gsub(/\\{sharp}/,'#').gsub(/\${([\w.]+)(?:\|([\w]+))?}/) {
94
+ data = $1.split('.').inject(record) {|r,k| (r||{})[k]}
95
+ filter = $2
96
+ case filter
97
+ when nil
98
+ data = escape_xhtml(data) if need_escape
99
+ when 'br'
100
+ data = escape_xhtml(data).gsub(/\n/, '<br />')
101
+ else
102
+ raise "Unknown filter: #{filter}"
103
+ end
104
+ data
105
+ }
106
+ end
107
+
108
+ def escape_xhtml(data)
109
+ REXML::Text.new(data.to_s, true, nil, false).to_s
110
+ end
111
+
112
+ def send_message(plain_text, xhtml_text)
113
+ message = Jabber::Message.new(@room, plain_text.force_encoding(Encoding::UTF_8))
114
+ set_xhtml_message(message, xhtml_text) if xhtml_text
115
+
116
+ @muc_client.send message
117
+ end
118
+
119
+ def set_xhtml_message(message, xhtml_text)
120
+ # http://devblog.famundo.com/articles/2006/10/18/ruby-and-xmpp-jabber-part-3-adding-html-to-the-messages
121
+ # Create the html part
122
+ h = REXML::Element::new("html")
123
+ h.add_namespace('http://jabber.org/protocol/xhtml-im')
124
+
125
+ # The body part with the correct namespace
126
+ b = REXML::Element::new("body")
127
+ b.add_namespace('http://www.w3.org/1999/xhtml')
128
+
129
+ # This suggested method not works for me:
130
+ # REXML::Text.new( message, false, nil, true, nil, %r/.^/ )
131
+ # So I try alternative.
132
+ REXML::Document.new("<div>#{xhtml_text}</div>").children.each do|c|
133
+ b.add c
134
+ end
135
+
136
+ h.add(b)
137
+
138
+ # Add the html element to the message
139
+ message.add_element(h)
87
140
  end
88
141
  end
@@ -66,6 +66,15 @@ describe Fluent::JabberOutput do
66
66
  end
67
67
  end
68
68
 
69
+ context 'config not contains format' do
70
+ it 'should raise ConfigError' do
71
+ config_hash = default_config.reject{|k,v| [:format].include? k}
72
+ config = create_fluent_config(config_hash)
73
+
74
+ expect { subject.configure config }.to raise_error Fluent::ConfigError
75
+ end
76
+ end
77
+
69
78
  context 'connecting' do
70
79
  it 'should connect with configured parameters' do
71
80
  Pit.stub(:get).with('jabber', anything).and_return('jid' => 'jabber@example.com', 'password' => 'pa55w0rd')
@@ -96,7 +105,7 @@ describe Fluent::JabberOutput do
96
105
  end
97
106
 
98
107
  it 'should send message to jabber conference room' do
99
- subject.should_receive(:send_message).with('hello!').twice
108
+ subject.should_receive(:send_message).with('hello!', nil).twice
100
109
  chain.should_receive(:next).once
101
110
 
102
111
  subject.emit('tag', [[0, {}], [1, {'a'=>'b'}]], chain)
@@ -106,12 +115,57 @@ describe Fluent::JabberOutput do
106
115
  let(:format) { 'a=${a}, x.y=${x.y}' }
107
116
 
108
117
  it 'should format message with received record' do
109
- subject.should_receive(:send_message).with('a=1, x.y=2').ordered
110
- subject.should_receive(:send_message).with('a=1, x.y=').ordered
118
+ subject.should_receive(:send_message).with('a=1, x.y=2', nil).ordered
119
+ subject.should_receive(:send_message).with('a=1, x.y=', nil).ordered
111
120
  chain.should_receive(:next).once
112
121
 
113
122
  subject.emit('tag', [[0, {'a'=>1, 'x'=>{'y'=>2}}], [1, {'a'=>1}]], chain)
114
123
  end
115
124
  end
125
+
126
+ context 'special notations' do
127
+ let(:format) { 'a\n\{sharp}' }
128
+
129
+ it 'should handle some special notations' do
130
+ subject.should_receive(:send_message).with("a\n#", nil)
131
+ chain.should_receive(:next).once
132
+
133
+ subject.emit('tag', [[0, {}]], chain)
134
+ end
135
+ end
136
+ end
137
+
138
+ context 'filter' do
139
+ context '|br' do
140
+ it 'should convert CR to <br />' do
141
+ subject.format_with('${a|br}', 0, {'a'=>"a\nb"}, false).should == "a<br />b"
142
+ end
143
+ it 'should convert CR to <br />, after xhtml_escape' do
144
+ subject.format_with('${a|br}', 0, {'a'=>"<>\n"}, false).should == "&lt;&gt;<br />"
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'xhtml_format' do
150
+ let(:xhtml_format) { '<p>${message}</p>' }
151
+ let(:format) { '${message}' }
152
+ before :each do
153
+ config_hash = default_config.merge(
154
+ xhtml_format: xhtml_format,
155
+ format: format,
156
+ )
157
+ config = create_fluent_config(config_hash)
158
+
159
+ Pit.stub(:get).with('jabber', anything).and_return('jid' => 'jabber@example.com', 'password' => 'pa55w0rd')
160
+
161
+ subject.configure(config)
162
+ end
163
+
164
+ it 'should send xml-escaped record data to jabber' do
165
+ subject.should_receive(:send_message).with('><', '<p>&gt;&lt;</p>')
166
+ chain.should_receive(:next).once
167
+
168
+ subject.emit('tag', [[0, {'message' => '><'}]], chain)
169
+ end
116
170
  end
117
171
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-jabber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-29 00:00:00.000000000Z
12
+ date: 2013-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -109,10 +109,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  version: '0'
110
110
  requirements: []
111
111
  rubyforge_project:
112
- rubygems_version: 1.8.19
112
+ rubygems_version: 1.8.24
113
113
  signing_key:
114
114
  specification_version: 3
115
115
  summary: Fluentd output plugin for XMPP(Jabber) protocol
116
116
  test_files:
117
117
  - spec/out_jabber_spec.rb
118
- has_rdoc: