fluent-plugin-twitter 0.1.1 → 0.2.1

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
@@ -2,7 +2,7 @@ fluent-plugin-twitter
2
2
  =====================
3
3
 
4
4
  ## Component
5
- Fluentd Input/Output plugin. You can create your own "Twitter Bot" with fluentd messaging system.
5
+ Fluentd Input/Output plugin to process tweets with Twitter Streaming API.
6
6
 
7
7
  ## Installation
8
8
 
@@ -29,8 +29,9 @@ gem install fluent-plugin-twitter
29
29
  oauth_token_secret YOUR_OAUTH_TOKEN_SECRET # Required
30
30
  tag input.twitter.sampling # Required
31
31
  timeline sampling # Required (sampling or userstream)
32
- keyword Ruby,Python # Optional (userstream not supported yet)
32
+ keyword Ruby,Python # Optional (only work with `timeline` is sampling)
33
33
  lang ja,en # Optional
34
+ output_format nest # Optional (nest or flat or simple[default])
34
35
  </source>
35
36
 
36
37
  <match input.twitter.sampling>
@@ -71,6 +72,9 @@ $ curl http://localhost:8888/notify.twitter -F 'json={"message":"foo"}'
71
72
  ### Twitter OAuth Guide
72
73
  http://pocketstudio.jp/log3/2012/02/12/how_to_get_twitter_apikey_and_token/
73
74
 
75
+ ### Quick Tour to count a tweet with fluent-plugin-twitter and fluent-plugin-datacounter
76
+ http://qiita.com/items/fe4258b394190f23fece
77
+
74
78
  ## TODO
75
79
  patches welcome!
76
80
 
@@ -3,11 +3,11 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "fluent-plugin-twitter"
6
- s.version = "0.1.1"
6
+ s.version = "0.2.1"
7
7
  s.authors = ["Kentaro Yoshida"]
8
8
  s.email = ["y.ken.studio@gmail.com"]
9
9
  s.homepage = "https://github.com/y-ken/fluent-plugin-twitter"
10
- s.summary = %q{Fluentd Input/Output plugin. You can create your own "Twitter Bot" with fluentd messaging system.}
10
+ s.summary = %q{Fluentd Input/Output plugin to process tweets with Twitter Streaming API.}
11
11
 
12
12
  s.files = `git ls-files`.split("\n")
13
13
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,6 +1,7 @@
1
1
  module Fluent
2
2
  class TwitterInput < Fluent::Input
3
3
  TIMELINE_TYPE = %w(userstream sampling)
4
+ OUTPUT_FORMAT_TYPE = %w(nest flat simple)
4
5
  Plugin.register_input('twitter', self)
5
6
 
6
7
  config_param :consumer_key, :string
@@ -10,7 +11,9 @@ module Fluent
10
11
  config_param :tag, :string
11
12
  config_param :timeline, :string
12
13
  config_param :keyword, :string, :default => nil
13
- config_param :lang, :string, :default => ''
14
+ config_param :lang, :string, :default => nil
15
+ config_param :output_format, :string, :default => 'simple'
16
+ config_param :flatten_separator, :string, :default => '_'
14
17
 
15
18
  def initialize
16
19
  super
@@ -19,7 +22,14 @@ module Fluent
19
22
 
20
23
  def configure(conf)
21
24
  super
22
- raise Fluent::ConfigError, "timeline value undefined #{@timeline}" if !TIMELINE_TYPE.include?(@timeline)
25
+
26
+ if !TIMELINE_TYPE.include?(@timeline)
27
+ raise Fluent::ConfigError, "timeline value undefined #{@timeline}"
28
+ end
29
+ if !OUTPUT_FORMAT_TYPE.include?(@output_format)
30
+ raise Fluent::ConfigError, "output_format value undefined #{@output_format}"
31
+ end
32
+
23
33
  TweetStream.configure do |config|
24
34
  config.consumer_key = @consumer_key
25
35
  config.consumer_secret = @consumer_secret
@@ -31,6 +41,9 @@ module Fluent
31
41
 
32
42
  def start
33
43
  @thread = Thread.new(&method(:run))
44
+ @any = Proc.new do |hash|
45
+ get_message(hash) if is_message?(hash)
46
+ end
34
47
  end
35
48
 
36
49
  def shutdown
@@ -38,57 +51,69 @@ module Fluent
38
51
  end
39
52
 
40
53
  def run
54
+ client = get_twitter_connection
41
55
  if @timeline == 'sampling' && @keyword
42
- start_twitter_track
56
+ client.track(@keyword)
43
57
  elsif @timeline == 'sampling' && @keyword.nil?
44
- start_twitter_sample
58
+ client.sample
45
59
  elsif @timeline == 'userstream'
46
- start_twitter_userstream
60
+ client.userstream
61
+ #elsif @timeline == 'follow'
62
+ # client.follow(@follow_ids)
47
63
  end
48
64
  end
49
65
 
50
- def start_twitter_track
51
- $log.info "starting twitter keyword tracking. tag:#{@tag} lang:#{@lang} keyword:#{@keyword}"
66
+ def get_twitter_connection
67
+ notice = "twitter: starting Twitter Streaming API for #{@timeline}."
68
+ notice << " tag:#{@tag}"
69
+ notice << " lang:#{@lang}" unless @lang.nil?
70
+ notice << " keyword:#{@keyword}" unless @keyword.nil?
71
+ $log.info notice
52
72
  client = TweetStream::Client.new
53
- client.track(@keyword) do |status|
54
- next unless status.text
55
- next unless @lang.include?(status.user.lang)
56
- get_message(status)
73
+ client.on_anything(&@any)
74
+ client.on_error do |message|
75
+ $log.info "twitter: unexpected error has occured. #{message}"
57
76
  end
77
+ return client
58
78
  end
59
79
 
60
- def start_twitter_sample
61
- $log.info "starting twitter sampled streaming. tag:#{@tag} lang:#{@lang}"
62
- client = TweetStream::Client.new
63
- client.sample do |status|
64
- next unless status.text
65
- next unless @lang.include?(status.user.lang)
66
- get_message(status)
67
- end
80
+ def is_message?(status)
81
+ return false if !status.include?(:text)
82
+ return false if !status.include?(:user)
83
+ return false if (!@lang.nil? && @lang != '') && !@lang.include?(status[:user][:lang])
84
+ return true
68
85
  end
69
86
 
70
- def start_twitter_userstream
71
- $log.info "starting twitter userstream tracking. tag:#{@tag} lang:#{@lang}"
72
- client = TweetStream::Client.new
73
- client.userstream do |status|
74
- next unless status.text
75
- next unless @lang.include?(status.user.lang)
76
- get_message(status)
87
+ def get_message(status)
88
+ case @output_format
89
+ when 'nest'
90
+ record = status.inject({}){|f,(k,v)| f[k.to_s] = v; f}
91
+ when 'flat'
92
+ record = hash_flatten(status)
93
+ when 'simple'
94
+ record = Hash.new
95
+ record.store('message', status[:text])
96
+ record.store('geo', status[:geo])
97
+ record.store('place', status[:place])
98
+ record.store('created_at', status[:place])
99
+ record.store('user_name', status[:user][:name])
100
+ record.store('user_screen_name', status[:user][:screen_name])
101
+ record.store('user_profile_image_url', status[:user][:profile_image_url])
102
+ record.store('user_time_zone', status[:user][:time_zone])
103
+ record.store('user_lang', status[:user][:lang])
77
104
  end
105
+ Engine.emit(@tag, Engine.now, record)
78
106
  end
79
107
 
80
- def get_message(status)
81
- record = Hash.new
82
- record.store('message', status.text)
83
- record.store('geo', status.geo)
84
- record.store('place', status.place)
85
- record.store('created_at', status.created_at)
86
- record.store('user_name', status.user.name)
87
- record.store('user_screen_name', status.user.screen_name)
88
- record.store('user_profile_image_url', status.user.profile_image_url)
89
- record.store('user_time_zone', status.user.time_zone)
90
- record.store('user_lang', status.user.lang)
91
- Engine.emit(@tag, Engine.now, record)
108
+ def hash_flatten(record, prefix = nil)
109
+ record.inject({}) do |d, (k, v)|
110
+ k = prefix.to_s + k.to_s
111
+ if v.is_a?(Hash)
112
+ d.merge(hash_flatten(v, k + @flatten_separator))
113
+ else
114
+ d.merge(k => v)
115
+ end
116
+ end
92
117
  end
93
118
  end
94
119
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-twitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-14 00:00:00.000000000 Z
12
+ date: 2013-03-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd
16
- requirement: &11259400 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *11259400
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: fluentd
27
- requirement: &11258160 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *11258160
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: twitter
38
- requirement: &11257360 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *11257360
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: tweetstream
49
- requirement: &11283100 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,7 +69,12 @@ dependencies:
54
69
  version: '0'
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *11283100
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
58
78
  description:
59
79
  email:
60
80
  - y.ken.studio@gmail.com
@@ -93,11 +113,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
113
  version: '0'
94
114
  requirements: []
95
115
  rubyforge_project:
96
- rubygems_version: 1.8.11
116
+ rubygems_version: 1.8.23
97
117
  signing_key:
98
118
  specification_version: 3
99
- summary: Fluentd Input/Output plugin. You can create your own "Twitter Bot" with fluentd
100
- messaging system.
119
+ summary: Fluentd Input/Output plugin to process tweets with Twitter Streaming API.
101
120
  test_files:
102
121
  - test/helper.rb
103
122
  - test/plugin/test_in_twitter.rb