usaidwat 0.0.10 → 0.1.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/.gitignore +3 -3
- data/Gemfile +1 -1
- data/LICENSE.txt +20 -0
- data/README.md +29 -0
- data/Rakefile +5 -0
- data/bin/usaidwat +1 -55
- data/features/browse.feature +1003 -0
- data/features/fixtures/comments.json +1 -0
- data/features/help.feature +20 -0
- data/features/server/reddit.rb +12 -0
- data/features/step_definitions/reddit_steps.rb +3 -0
- data/features/support/aruba.rb +1 -0
- data/lib/usaidwat/application.rb +77 -0
- data/lib/usaidwat/client.rb +28 -0
- data/lib/usaidwat/formatter.rb +33 -0
- data/lib/usaidwat/version.rb +1 -1
- data/lib/usaidwat.rb +4 -7
- data/spec/spec_helper.rb +2 -0
- data/spec/usaidwat/client_spec.rb +46 -0
- data/spec/usaidwat/formatter_spec.rb +45 -0
- data/usaidwat.gemspec +22 -19
- metadata +86 -20
- data/README.textile +0 -51
- data/lib/usaidwat/reddit.rb +0 -136
- data/lib/usaidwat/utils.rb +0 -31
- data/spec/utils_spec.rb +0 -9
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module USaidWat
|
4
|
+
module CLI
|
5
|
+
describe CommentFormatter do
|
6
|
+
let(:formatter) { CommentFormatter.new }
|
7
|
+
|
8
|
+
describe "#format" do
|
9
|
+
it "should return a string containing the formatted comment" do
|
10
|
+
comment = double("comment")
|
11
|
+
comment.should_receive(:subreddit).twice.and_return("programming")
|
12
|
+
comment.should_receive(:link_id).and_return("t3_13f783")
|
13
|
+
comment.should_receive(:id).and_return("c73qhxi")
|
14
|
+
comment.should_receive(:body).and_return("Welcome to the wonderful world of Python drama!")
|
15
|
+
expected = <<-EXPECTED
|
16
|
+
programming
|
17
|
+
http://www.reddit.com/r/programming/comments/13f783/z/c73qhxi
|
18
|
+
|
19
|
+
Welcome to the wonderful world of Python drama!
|
20
|
+
EXPECTED
|
21
|
+
actual = formatter.format(comment)
|
22
|
+
actual.should == expected
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should print a horizontal rule for subsequent comments" do
|
26
|
+
expected = "-" * 80
|
27
|
+
comment1 = double("first comment")
|
28
|
+
comment1.should_receive(:subreddit).twice.and_return("programming")
|
29
|
+
comment1.should_receive(:link_id).and_return("t3_13f783")
|
30
|
+
comment1.should_receive(:id).and_return("c73qhxi")
|
31
|
+
comment1.should_receive(:body).and_return("Welcome to the wonderful world of Python drama!")
|
32
|
+
comment2 = double("second comment")
|
33
|
+
comment2.should_receive(:subreddit).twice.and_return("programming")
|
34
|
+
comment2.should_receive(:link_id).and_return("t3_13f783")
|
35
|
+
comment2.should_receive(:id).and_return("c73qhxi")
|
36
|
+
comment2.should_receive(:body).and_return("Welcome to the wonderful world of Python drama!")
|
37
|
+
s = formatter.format(comment1)
|
38
|
+
s = formatter.format(comment2)
|
39
|
+
actual = s.split("\n")[0]
|
40
|
+
actual.should == expected
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/usaidwat.gemspec
CHANGED
@@ -1,24 +1,27 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'usaidwat/version'
|
4
5
|
|
5
|
-
Gem::Specification.new do |
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "usaidwat"
|
8
|
+
gem.version = USaidWat::VERSION
|
9
|
+
gem.authors = ["Michael Dippery"]
|
10
|
+
gem.email = ["michael@monkey-robot.com"]
|
11
|
+
gem.homepage = "https://github.com/mdippery/usaidwat"
|
12
|
+
gem.description = %q{View a user's last 100 Reddit comments, organized by subreddit.}
|
13
|
+
gem.summary = %q{Answers the age-old question, "Where does a Redditor comment the most?"}
|
13
14
|
|
14
|
-
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
s.add_development_dependency 'rspec', '~> 2.8.0'
|
20
|
+
gem.add_dependency('snooby')
|
21
|
+
|
22
|
+
gem.add_development_dependency('rspec')
|
23
|
+
gem.add_development_dependency('cucumber')
|
24
|
+
gem.add_development_dependency('aruba')
|
25
|
+
gem.add_development_dependency('webmock')
|
26
|
+
gem.add_development_dependency('sinatra')
|
24
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: usaidwat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,16 +9,16 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11
|
12
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: snooby
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,39 +26,87 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: '0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: rspec
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
38
|
-
type: :
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: '0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: cucumber
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ! '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: '0'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: aruba
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: webmock
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: sinatra
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
60
108
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
109
|
+
version: '0'
|
62
110
|
description: View a user's last 100 Reddit comments, organized by subreddit.
|
63
111
|
email:
|
64
112
|
- michael@monkey-robot.com
|
@@ -69,14 +117,24 @@ extra_rdoc_files: []
|
|
69
117
|
files:
|
70
118
|
- .gitignore
|
71
119
|
- Gemfile
|
72
|
-
-
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
73
122
|
- Rakefile
|
74
123
|
- bin/usaidwat
|
124
|
+
- features/browse.feature
|
125
|
+
- features/fixtures/comments.json
|
126
|
+
- features/help.feature
|
127
|
+
- features/server/reddit.rb
|
128
|
+
- features/step_definitions/reddit_steps.rb
|
129
|
+
- features/support/aruba.rb
|
75
130
|
- lib/usaidwat.rb
|
76
|
-
- lib/usaidwat/
|
77
|
-
- lib/usaidwat/
|
131
|
+
- lib/usaidwat/application.rb
|
132
|
+
- lib/usaidwat/client.rb
|
133
|
+
- lib/usaidwat/formatter.rb
|
78
134
|
- lib/usaidwat/version.rb
|
79
|
-
- spec/
|
135
|
+
- spec/spec_helper.rb
|
136
|
+
- spec/usaidwat/client_spec.rb
|
137
|
+
- spec/usaidwat/formatter_spec.rb
|
80
138
|
- usaidwat.gemspec
|
81
139
|
homepage: https://github.com/mdippery/usaidwat
|
82
140
|
licenses: []
|
@@ -97,10 +155,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
155
|
- !ruby/object:Gem::Version
|
98
156
|
version: '0'
|
99
157
|
requirements: []
|
100
|
-
rubyforge_project:
|
158
|
+
rubyforge_project:
|
101
159
|
rubygems_version: 1.8.23
|
102
160
|
signing_key:
|
103
161
|
specification_version: 3
|
104
162
|
summary: Answers the age-old question, "Where does a Redditor comment the most?"
|
105
163
|
test_files:
|
106
|
-
-
|
164
|
+
- features/browse.feature
|
165
|
+
- features/fixtures/comments.json
|
166
|
+
- features/help.feature
|
167
|
+
- features/server/reddit.rb
|
168
|
+
- features/step_definitions/reddit_steps.rb
|
169
|
+
- features/support/aruba.rb
|
170
|
+
- spec/spec_helper.rb
|
171
|
+
- spec/usaidwat/client_spec.rb
|
172
|
+
- spec/usaidwat/formatter_spec.rb
|
data/README.textile
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
h1(#usaidwat). usaidwat
|
2
|
-
|
3
|
-
Are you a Redditor? Do you use Ruby? Do you want to view the subreddits in which a particular user commonly posts? If you answered "yes" to all three of these questions, then *usaidwat* is the gem for you!
|
4
|
-
|
5
|
-
h2(#install). Installation
|
6
|
-
|
7
|
-
*usaidwat* can be installed via RubyGems:
|
8
|
-
|
9
|
-
bc. $ gem install usaidwat
|
10
|
-
|
11
|
-
h2(#usage). Usage
|
12
|
-
|
13
|
-
A @usaidwat@ binary is installed with the gem. @usaidwat@ will analyze a user's last 100 comments and provide statistics.
|
14
|
-
|
15
|
-
To list a count of subreddits in which a user has posted, simply plug in a username:
|
16
|
-
|
17
|
-
bc. # usaidwat jedberg
|
18
|
-
|
19
|
-
You will see output like the following:
|
20
|
-
|
21
|
-
bc. jedberg
|
22
|
-
-------
|
23
|
-
blog 26
|
24
|
-
funny 15
|
25
|
-
unitedkingdom 12
|
26
|
-
Random_Acts_Of_Pizza 11
|
27
|
-
AskReddit 7
|
28
|
-
entertainment 4
|
29
|
-
politics 4
|
30
|
-
TheoryOfReddit 3
|
31
|
-
Frugal 3
|
32
|
-
technology 2
|
33
|
-
fffffffuuuuuuuuuuuu 2
|
34
|
-
wikipedia 2
|
35
|
-
pics 1
|
36
|
-
programming 1
|
37
|
-
sex 1
|
38
|
-
space 1
|
39
|
-
movies 1
|
40
|
-
geek 1
|
41
|
-
comics 1
|
42
|
-
videos 1
|
43
|
-
apple 1
|
44
|
-
|
45
|
-
Which indicates that jedberg has commented in @/r/funny@ 15 times (out of his last 100 comments).
|
46
|
-
|
47
|
-
To see the comments for a specific subreddit, tack on that subreddit:
|
48
|
-
|
49
|
-
bc. $ usaidwat jedberg funny
|
50
|
-
|
51
|
-
All the comments for the given subreddit will be printed.
|
data/lib/usaidwat/reddit.rb
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'net/http'
|
3
|
-
require 'time'
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'json'
|
7
|
-
|
8
|
-
|
9
|
-
class Hash
|
10
|
-
def to_query
|
11
|
-
data = keys.inject([]) { |parts, key| parts << [URI.encode(key.to_s), URI.encode(self[key].to_s)] }
|
12
|
-
data.map{ |t| t.join '=' }.join '&'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module USaidWat
|
17
|
-
class RedditUser
|
18
|
-
COMMENT_COUNT = 100
|
19
|
-
COMMENTS_PER_PAGE = 25
|
20
|
-
CACHE_AGE = 300
|
21
|
-
|
22
|
-
attr_reader :username
|
23
|
-
|
24
|
-
def initialize(username)
|
25
|
-
@username = username
|
26
|
-
end
|
27
|
-
|
28
|
-
def profile_url
|
29
|
-
"http://www.reddit.com/user/#{username}"
|
30
|
-
end
|
31
|
-
|
32
|
-
def comments_url
|
33
|
-
"#{profile_url}/comments"
|
34
|
-
end
|
35
|
-
|
36
|
-
def last_update
|
37
|
-
return Time.at 0 unless File.exists? cache_timestamp_file
|
38
|
-
Time.parse File.open(cache_timestamp_file).read.chomp
|
39
|
-
end
|
40
|
-
|
41
|
-
def update_cache(force=false)
|
42
|
-
FileUtils.mkdir_p cache_dir
|
43
|
-
|
44
|
-
is_outdated = Time.now - last_update > CACHE_AGE
|
45
|
-
if force or is_outdated
|
46
|
-
FileUtils.rm_rf cache_dir
|
47
|
-
FileUtils.mkdir_p cache_dir
|
48
|
-
|
49
|
-
comments = Array.new
|
50
|
-
after = nil
|
51
|
-
pages = COMMENT_COUNT / COMMENTS_PER_PAGE
|
52
|
-
pages.times do |i|
|
53
|
-
query = i == 0 ? '' : {:count => COMMENTS_PER_PAGE, :after => after}.to_query
|
54
|
-
url = "#{comments_url}.json?#{query}"
|
55
|
-
resp = Net::HTTP.get_response 'www.reddit.com', url
|
56
|
-
unless resp.code.to_i == 200
|
57
|
-
STDERR.puts "Could not retrieve comments: #{resp.message}"
|
58
|
-
return nil
|
59
|
-
end
|
60
|
-
resp = JSON.parse resp.body
|
61
|
-
if resp.key? 'error'
|
62
|
-
STDERR.puts "Could not retrieve comments: #{resp['error'] || 'Unknown error'}"
|
63
|
-
return nil
|
64
|
-
end
|
65
|
-
comments += resp['data']['children']
|
66
|
-
after = resp['data']['after']
|
67
|
-
end
|
68
|
-
cache_comments comments
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def retrieve_comments
|
73
|
-
update_cache
|
74
|
-
subreddits = Hash.new { |h,k| h[k] = 0 }
|
75
|
-
Dir.chdir(comments_dir) do
|
76
|
-
Dir['*'].each do |sr|
|
77
|
-
next unless File.directory? sr
|
78
|
-
Dir["#{sr}/*"].each { |f| subreddits[sr] += 1 }
|
79
|
-
end
|
80
|
-
end
|
81
|
-
subreddits.sort { |a,b| a[0].downcase <=> b[0].downcase }
|
82
|
-
rescue Errno::ENOENT
|
83
|
-
nil
|
84
|
-
end
|
85
|
-
|
86
|
-
def comments_for_subreddit(subreddit)
|
87
|
-
update_cache
|
88
|
-
comments = []
|
89
|
-
subreddit_dir = File.join comments_dir, subreddit
|
90
|
-
return nil unless File.exists? subreddit_dir
|
91
|
-
Dir.chdir(subreddit_dir) do
|
92
|
-
Dir['*'].each do |f|
|
93
|
-
path = File.join subreddit_dir, f
|
94
|
-
comment = File.open(path).read.chomp
|
95
|
-
comments << comment
|
96
|
-
end
|
97
|
-
end
|
98
|
-
comments
|
99
|
-
end
|
100
|
-
|
101
|
-
def to_s
|
102
|
-
"Reddit user: #{username}"
|
103
|
-
end
|
104
|
-
|
105
|
-
private
|
106
|
-
def cache_dir
|
107
|
-
File.join USaidWat::BASE_CACHE_DIR, username
|
108
|
-
end
|
109
|
-
|
110
|
-
def cache_timestamp_file
|
111
|
-
File.join cache_dir, 'updated'
|
112
|
-
end
|
113
|
-
|
114
|
-
def comments_dir
|
115
|
-
File.join cache_dir, 'comments'
|
116
|
-
end
|
117
|
-
|
118
|
-
def cache_comments(comments)
|
119
|
-
comments.each do |c|
|
120
|
-
cid = c['data']['id']
|
121
|
-
sr = c['data']['subreddit']
|
122
|
-
body = c['data']['body']
|
123
|
-
parent_cache_dir = subreddit_directory! sr
|
124
|
-
cache_file = File.join parent_cache_dir, cid
|
125
|
-
File.open(cache_file, 'w') { |f| f.write body }
|
126
|
-
end
|
127
|
-
File.open(cache_timestamp_file, 'w') { |f| f.write Time.now }
|
128
|
-
end
|
129
|
-
|
130
|
-
def subreddit_directory!(subreddit)
|
131
|
-
path = File.join comments_dir, subreddit
|
132
|
-
FileUtils.mkdir_p path
|
133
|
-
path
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
data/lib/usaidwat/utils.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
class Array
|
2
|
-
def longest_subreddit
|
3
|
-
max_by { |s| s.first.length }.first
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
7
|
-
# Inspired by: http://nex-3.com/posts/73-git-style-automatic-paging-in-ruby
|
8
|
-
def run_pager
|
9
|
-
return if RUBY_PLATFORM =~ /win32/
|
10
|
-
return unless STDOUT.tty?
|
11
|
-
|
12
|
-
read, write = IO.pipe
|
13
|
-
|
14
|
-
unless Kernel.fork
|
15
|
-
STDOUT.reopen(write)
|
16
|
-
STDERR.reopen(write) if STDERR.tty?
|
17
|
-
read.close
|
18
|
-
write.close
|
19
|
-
return
|
20
|
-
end
|
21
|
-
|
22
|
-
STDIN.reopen(read)
|
23
|
-
read.close
|
24
|
-
write.close
|
25
|
-
|
26
|
-
#ENV['LESS'] = 'FSRX'
|
27
|
-
|
28
|
-
Kernel.select [STDIN]
|
29
|
-
pager = ENV['PAGER'] || 'less'
|
30
|
-
exec pager rescue exec '/bin/sh', '-c', pager
|
31
|
-
end
|
data/spec/utils_spec.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
-
require 'usaidwat/utils'
|
3
|
-
|
4
|
-
describe 'USaidWat::Array' do
|
5
|
-
it 'should return the longest string from a list of tuples' do
|
6
|
-
list = [['Short Name', 0], ['Really Long Name', 1], ['Medium Name', 2]]
|
7
|
-
list.longest_subreddit.should == 'Really Long Name'
|
8
|
-
end
|
9
|
-
end
|