lita-reddit 0.0.7 → 0.0.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee46f86490552d2009ed559059a365cc58440049
4
- data.tar.gz: 0d3f1eb18bdd288aea454b932fd2957357900e7d
3
+ metadata.gz: 276e3bd121e48d563f8fd185f836cf5a135628f9
4
+ data.tar.gz: ef9ac64393a3d180ca496d2935fee4589c514206
5
5
  SHA512:
6
- metadata.gz: 989b6433a109c62679b1c26ff24e130f3e0037e2401f5fb060c29fb513e4caab22de44447aa96644009cd93d4eae0a3264d9c2f49354e7d0ceae8f40509a1e74
7
- data.tar.gz: f50dc828446ed92dca12e0ba2fc404694f815ac15c08746672d32f58674332fe600c597d31f43280f2e246f74e4ddc16253781219f5c92c3b872f43aa98335f8
6
+ metadata.gz: 311a90782184417049bb0ed2e61bd7c061bd753b1e5d8e16fb83c75159e18d45344c865b92b94ca780459d392f701083dff241bf0fb56ada30709d4fd27491d0
7
+ data.tar.gz: aba18ec03fc60acec0aa6a384c50b35fd2befede4da51d1c8cfd29b763a0e227cb1ace9958d9f429c08126a09938729a750d93924494c7b22b4343c5497fa789
data/.rubocop.yml ADDED
@@ -0,0 +1,46 @@
1
+ AbcSize:
2
+ Enabled: false
3
+ AlignParameters:
4
+ Enabled: false
5
+ AndOr:
6
+ Enabled: false
7
+ CaseEquality:
8
+ Enabled: false
9
+ ClassLength:
10
+ Enabled: false
11
+ Documentation:
12
+ Enabled: false
13
+ DoubleNegation:
14
+ Enabled: false
15
+ EachWithObject:
16
+ Enabled: false
17
+ EndAlignment:
18
+ AlignWith: variable
19
+ GuardClause:
20
+ Enabled: false
21
+ IndentHash:
22
+ Enabled: false
23
+ LineLength:
24
+ Max: 100
25
+ MethodLength:
26
+ Enabled: false
27
+ NonNilCheck:
28
+ Enabled: false
29
+ ParameterLists:
30
+ Max: 6
31
+ RegexpLiteral:
32
+ Enabled: false
33
+ RescueException:
34
+ Enabled: false
35
+ SignalException:
36
+ Enabled: false
37
+ SpecialGlobalVars:
38
+ Enabled: false
39
+ StringLiterals:
40
+ EnforcedStyle: double_quotes
41
+ TrailingComma:
42
+ Enabled: false
43
+ TrivialAccessors:
44
+ Enabled: false
45
+ Style/FileName:
46
+ Enabled: false
data/README.md CHANGED
@@ -13,16 +13,21 @@ gem "lita-reddit"
13
13
  ## Configuration
14
14
 
15
15
  ``` ruby
16
- # List of subreddit/channel to update pairs
17
- config.handlers.reddit.reddits = [{subreddit: "subreddit_name", channel: "##channel_to_update"}]
18
16
  # The client ID from the Reddit API
19
17
  config.handlers.reddit.client_id = "client_from_api"
20
18
  # The secret ID from the Reddit API
21
19
  config.handlers.reddit.client_secret = "secret_from_api"
20
+ # List of subreddit/channel to update pairs
21
+ config.handlers.reddit.reddits = [{subreddit: "subreddit_name", channel: "##channel_to_update"}]
22
22
  # The delay to wait before starting the polling in seconds (optional, defaults to 30s)
23
23
  config.handlers.reddit.startup_delay = 30
24
24
  # The interval in between requests (optional, defaults to 300s)
25
25
  config.handlers.reddit.poll_interval = 300
26
+ # The limit of number of posts to output from any sub per poll (optional, defaults to 3)
27
+ config.handlers.reddit.post_limit = 3
28
+ # The string to use when posting to the channel. Supports %{user}, %{title}, %{subreddit}, %{id},
29
+ # and ${shortlink}. (Optional, defaults to "/u/%{user}: %{title} | /r/%{subreddit} | %{shortlink}")
30
+ config.handlers.reddit.post_text = "/u/%{user}: %{title} | /r/%{subreddit} | %{shortlink}"
26
31
  ```
27
32
 
28
33
  ## Usage
data/lib/lita-reddit.rb CHANGED
@@ -5,6 +5,8 @@ Lita.load_locales Dir[File.expand_path(
5
5
  )]
6
6
 
7
7
  require "lita/handlers/reddit"
8
+ require "lita/handlers/reddit/base"
9
+ require "lita/handlers/reddit/subreddit_poster"
8
10
 
9
11
  Lita::Handlers::Reddit.template_root File.expand_path(
10
12
  File.join("..", "..", "templates"),
@@ -1,80 +1,22 @@
1
1
  module Lita
2
2
  module Handlers
3
3
  class Reddit < Handler
4
- config :reddits, types: Array, required: true
5
4
  config :client_id, type: String, required: true
6
5
  config :client_secret, type: String, required: true
7
- config :mod do
8
- config :reddits, type: Array
9
- end
10
6
  config :startup_delay, type: Integer, default: 30
11
- config :poll_interval, type: Integer, default: 300
12
-
13
- on :connected, :setup
14
-
15
- @@user_agent = 'ruby:lita-reddit:v0.0.7 (by /u/dosman711)'
16
7
 
17
- def setup(payload)
18
- after(config.startup_delay) do
19
- update_token
20
- refresh_posts
21
- end
22
- every (config.poll_interval) do
23
- refresh_posts
24
- end
25
- # update userless token once per hour
26
- every (3300) do
27
- update_token
28
- end
29
- end
8
+ config :reddits, types: Array, required: true
9
+ config :post_text,
10
+ type: String,
11
+ default: "/u/%{user}: %{title} | /r/%{subreddit} | %{shortlink}"
12
+ config :poll_interval, type: Integer, default: 300
13
+ config :post_limit, type: Integer, default: 3
30
14
 
31
- def update_token
32
- log.debug('lita-reddit: updating userless oauth token')
33
- request = http
34
- request.basic_auth(config.client_id, config.client_secret)
35
- auth_response = request.post do |req|
36
- req.url 'https://www.reddit.com/api/v1/access_token'
37
- req.headers['User-Agent'] = @@user_agent
38
- req.body = 'grant_type=client_credentials'
39
- end
40
- response = MultiJson.load(auth_response.body)
41
- @@access_token = response['access_token']
15
+ config :base_url, type: String
16
+ config :mod do
17
+ config :reddits, type: Array
42
18
  end
43
-
44
- def refresh_posts
45
- post_text = 'From /r/%s: %s (http://redd.it/%s)'
46
- base_redis_key = 'seen_list_%s_%s'
47
- config.reddits.each do |reddit|
48
- log.debug('lita-reddit: updating posts for /r/%s' % [reddit[:subreddit]])
49
- #new on the left
50
- redis_key = base_redis_key % [reddit[:channel], reddit[:subreddit]]
51
- post_limit = 3
52
- seen_reddits = redis.lrange(redis_key, 0, 10)
53
- request = http
54
- resp = request.get do |req|
55
- req.url 'https://oauth.reddit.com/r/%s/new.json' % [reddit[:subreddit]]
56
- req.headers['Authorization'] = 'bearer %s' % [@@access_token]
57
- req.headers['User-Agent'] = @@user_agent
58
- req.headers['Content-Type'] = 'Application/json'
59
- req.params['limit'] = post_limit
60
- req.params['before'] = redis.lindex(redis_key, 0)
61
- end
62
- log.debug('lita-reddit: HTTP result of request %s' % [resp.status])
63
- response_body = MultiJson.load(resp.body)
64
- results = response_body['data']['children']
65
- target = Source.new(room: reddit[:channel])
66
- results.reverse.each do |post|
67
- if !seen_reddits.include?(post['data']['id']) then
68
- robot.send_message(target, post_text % [post['data']['subreddit'], post['data']['title'], post['data']['id']])
69
- redis.lpush(redis_key, post['data']['id'])
70
- end
71
- # keep a few extra around, 10 is still instantaneous
72
- redis.ltrim(redis_key, 0, 10)
73
- end
74
- end
75
- end
76
19
  end
77
-
78
20
  Lita.register_handler(Reddit)
79
21
  end
80
22
  end
@@ -0,0 +1,56 @@
1
+ module Lita
2
+ module Handlers
3
+ class Reddit < Handler
4
+ class ApiCalls < Handler
5
+ def initialize(client_id, client_secret)
6
+ @client_id = client_id
7
+ @client_secret = client_secret
8
+ end
9
+
10
+ def user_agent
11
+ "ruby:lita-reddit:v0.0.8 (by /u/dosman711)"
12
+ end
13
+
14
+ def update_token
15
+ log.info("lita-reddit: updating userless auth token")
16
+ request = http
17
+ request.basic_auth(@client_id, @client_secret)
18
+ auth_response = request.post do |req|
19
+ req.url "https://www.reddit.com/api/v1/access_token"
20
+ req.headers["User-Agent"] = user_agent
21
+ req.body = "grant_type=client_credentials"
22
+ end
23
+ response = MultiJson.load(auth_response.body)
24
+ @access_token = response["access_token"]
25
+ rescue Exception => msg
26
+ log.error("lita-reddit: Exception during token update: #{msg}")
27
+ end
28
+
29
+ def get_posts(subreddit, redis_key, limit = 3)
30
+ resp = http.get do |req|
31
+ req.url "https://oauth.reddit.com/r/#{subreddit}/new.json"
32
+ req.headers["Authorization"] = "bearer #{@access_token}"
33
+ req.headers["User-Agent"] = user_agent
34
+ req.headers["Content-Type"] = "Application/json"
35
+ req.params["limit"] = limit
36
+ req.params["before"] = redis_key
37
+ end
38
+ response_body = MultiJson.load(resp.body)
39
+ results = response_body["data"]["children"]
40
+ results.collect do |r|
41
+ {
42
+ id: r["data"]["id"],
43
+ subreddit: r["data"]["subreddit"],
44
+ title: r["data"]["title"],
45
+ user: r["data"]["author"],
46
+ shortlink: format("http://redd.it/%s", r["data"]["id"])
47
+ }
48
+ end
49
+ rescue Exception => msg
50
+ log.error("lita-reddit: Exception during get_posts: #{msg}")
51
+ return []
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,37 @@
1
+ require_relative "api_calls"
2
+ module Lita
3
+ module Handlers
4
+ class Reddit < Handler
5
+ class Base < Handler
6
+ namespace "reddit"
7
+
8
+ def reddits
9
+ config.reddits
10
+ end
11
+
12
+ def startup_delay
13
+ config.startup_delay
14
+ end
15
+
16
+ def poll_interval
17
+ config.poll_interval
18
+ end
19
+
20
+ def post_limit
21
+ config.post_limit
22
+ end
23
+
24
+ def post_text
25
+ config.post_text
26
+ end
27
+
28
+ def client
29
+ if @client.nil?
30
+ @client = Lita::Handlers::Reddit::ApiCalls.new(config.client_id, config.client_secret)
31
+ end
32
+ @client
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,58 @@
1
+ module Lita
2
+ module Handlers
3
+ class Reddit < Handler
4
+ class SubredditPoster < Base
5
+ namespace "reddit"
6
+ on :connected, :setup
7
+ on :reddit_update_token, :update_token
8
+ on :reddit_refresh_posts, :refresh_posts
9
+
10
+ def setup(_payload)
11
+ after startup_delay do
12
+ robot.trigger(:reddit_update_token)
13
+ end
14
+ every poll_interval do
15
+ robot.trigger(:reddit_refresh_posts)
16
+ end
17
+ # update userless token once per hour
18
+ every 3300 do
19
+ robot.trigger(:reddit_update_token)
20
+ end
21
+ end
22
+
23
+ def update_token(_payload)
24
+ client.update_token
25
+ robot.trigger(:reddit_refresh_posts)
26
+ rescue Exception => msg
27
+ log.error("lita-reddit: Exception during token update: #{msg}")
28
+ end
29
+
30
+ def refresh_posts(_payload)
31
+ base_redis_key = "seen_list_%s_%s"
32
+ reddits.each do |reddit|
33
+ log.debug("lita-reddit: updating posts for /r/#{reddit[:subreddit]}")
34
+ # new on the left
35
+ redis_key = format(base_redis_key, reddit[:channel], reddit[:subreddit])
36
+ seen_reddits = redis.lrange(redis_key, 0, 10)
37
+ target = Source.new(room: reddit[:channel])
38
+ results = client.get_posts(reddit[:subreddit],
39
+ redis.lindex(redis_key, 0),
40
+ post_limit)
41
+ results.reverse.each do |post|
42
+ unless seen_reddits.include?(post[:id])
43
+ robot.send_message(target, post_text % post)
44
+ redis.lpush(redis_key, post[:id])
45
+ end
46
+
47
+ # keep a few extra around, 10 is still instantaneous
48
+ redis.ltrim(redis_key, 0, 10)
49
+ end
50
+ end
51
+ rescue Exception => msg
52
+ log.error("lita-reddit: Exception during post update #{msg}")
53
+ end
54
+ end
55
+ Lita.register_handler(SubredditPoster)
56
+ end
57
+ end
58
+ end
data/lita-reddit.gemspec CHANGED
@@ -1,10 +1,10 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "lita-reddit"
3
- spec.version = "0.0.7"
3
+ spec.version = "0.0.8"
4
4
  spec.authors = ["Chris Baker"]
5
5
  spec.email = ["dosman711@gmail.com"]
6
- spec.description = %q{A Reddit handler for Lita.}
7
- spec.summary = %q{A Reddit handler for the lita chat robot.}
6
+ spec.description = "A Reddit handler for Lita."
7
+ spec.summary = "A Reddit handler for the lita chat robot."
8
8
  spec.homepage = "https://github.com/dosman711/lita-reddit"
9
9
  spec.license = "MIT"
10
10
  spec.metadata = { "lita_plugin_type" => "handler" }
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
15
  spec.require_paths = ["lib"]
16
16
 
17
- spec.add_runtime_dependency "lita", ">= 4.2"
17
+ spec.add_runtime_dependency "lita", ">= 4.3"
18
18
 
19
19
  spec.add_development_dependency "bundler", "~> 1.3"
20
20
  spec.add_development_dependency "rake"
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rspec", ">= 3.0.0"
23
23
  spec.add_development_dependency "simplecov"
24
24
  spec.add_development_dependency "coveralls"
25
+ spec.add_development_dependency "rubocop"
25
26
  end
@@ -1,4 +1,55 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Lita::Handlers::Reddit, lita_handler: true do
3
+ describe Lita::Handlers::Reddit::SubredditPoster,
4
+ lita_handler: true,
5
+ additional_lita_handlers: Lita::Handlers::Reddit do
6
+ before :each do
7
+ registry.config.handlers.reddit.tap do |config|
8
+ config.client_id = "clientId"
9
+ config.client_secret = "clientSecret"
10
+ end
11
+ @standard_response = [{
12
+ id: "post_id",
13
+ subreddit: "test",
14
+ title: "title",
15
+ user: "user",
16
+ shortlink: "http://redd.it/post_id"
17
+ }]
18
+ end
19
+ it "outputs new posts to the specified channels" do
20
+ registry.config.handlers.reddit.tap do |config|
21
+ config.reddits = [{ subreddit: "test", channel: "test" }]
22
+ end
23
+ allow(subject.client).to receive(:get_posts).and_return(@standard_response)
24
+ robot.trigger(:reddit_refresh_posts)
25
+ expect(replies.last).to eq("/u/user: title | /r/test | http://redd.it/post_id")
26
+ end
27
+
28
+ it "does not output duplicate posts" do
29
+ registry.config.handlers.reddit.tap do |config|
30
+ config.reddits = [{ subreddit: "test", channel: "test" }]
31
+ end
32
+ allow(subject.client).to receive(:get_posts).and_return(@standard_response)
33
+ robot.trigger(:reddit_refresh_posts)
34
+ robot.trigger(:reddit_refresh_posts)
35
+ expect(replies.last).to eq("/u/user: title | /r/test | http://redd.it/post_id")
36
+ expect(replies.count).to be 1
37
+ end
38
+
39
+ it "still posts if there is an error during retrieval" do
40
+ registry.config.handlers.reddit.tap do |config|
41
+ config.reddits = [{ subreddit: "test", channel: "test" }]
42
+ end
43
+ allow(subject.client).to receive(:get_posts).and_raise(RuntimeError)
44
+ robot.trigger(:reddit_refresh_posts)
45
+ allow(subject.client).to receive(:get_posts).and_return(@standard_response)
46
+ robot.trigger(:reddit_refresh_posts)
47
+ expect(replies.last).to eq("/u/user: title | /r/test | http://redd.it/post_id")
48
+ expect(replies.count).to be 1
49
+ end
50
+
51
+ it "handles exception during update_token" do
52
+ allow(subject.client).to receive(:update_token).and_raise(RuntimeError)
53
+ expect { subject.update_token(nil) }.not_to raise_error
54
+ end
4
55
  end
metadata CHANGED
@@ -1,111 +1,125 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita-reddit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Baker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-24 00:00:00.000000000 Z
11
+ date: 2015-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lita
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '4.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '4.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rack-test
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: 3.0.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 3.0.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: coveralls
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  description: A Reddit handler for Lita.
@@ -115,14 +129,18 @@ executables: []
115
129
  extensions: []
116
130
  extra_rdoc_files: []
117
131
  files:
118
- - .gitignore
119
- - .travis.yml
132
+ - ".gitignore"
133
+ - ".rubocop.yml"
134
+ - ".travis.yml"
120
135
  - Gemfile
121
136
  - LICENSE
122
137
  - README.md
123
138
  - Rakefile
124
139
  - lib/lita-reddit.rb
125
140
  - lib/lita/handlers/reddit.rb
141
+ - lib/lita/handlers/reddit/api_calls.rb
142
+ - lib/lita/handlers/reddit/base.rb
143
+ - lib/lita/handlers/reddit/subreddit_poster.rb
126
144
  - lita-reddit.gemspec
127
145
  - locales/en.yml
128
146
  - spec/lita/handlers/reddit_spec.rb
@@ -139,17 +157,17 @@ require_paths:
139
157
  - lib
140
158
  required_ruby_version: !ruby/object:Gem::Requirement
141
159
  requirements:
142
- - - '>='
160
+ - - ">="
143
161
  - !ruby/object:Gem::Version
144
162
  version: '0'
145
163
  required_rubygems_version: !ruby/object:Gem::Requirement
146
164
  requirements:
147
- - - '>='
165
+ - - ">="
148
166
  - !ruby/object:Gem::Version
149
167
  version: '0'
150
168
  requirements: []
151
169
  rubyforge_project:
152
- rubygems_version: 2.0.14
170
+ rubygems_version: 2.4.6
153
171
  signing_key:
154
172
  specification_version: 4
155
173
  summary: A Reddit handler for the lita chat robot.