usaidwat 0.0.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 +4 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/bin/usaidwat +32 -0
- data/lib/usaidwat/reddit.rb +150 -0
- data/lib/usaidwat/version.rb +3 -0
- data/lib/usaidwat.rb +7 -0
- data/usaidwat.gemspec +22 -0
- metadata +65 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/usaidwat
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'usaidwat'
|
4
|
+
|
5
|
+
|
6
|
+
def die(code=1)
|
7
|
+
$stderr.puts "Usage: #{File.basename $0} <user> [<subreddit>]"
|
8
|
+
exit code
|
9
|
+
end
|
10
|
+
|
11
|
+
die if $*.length < 1 or $*.length > 2
|
12
|
+
|
13
|
+
subreddit = $*.length == 2 ? $*.last : nil
|
14
|
+
reddit_user = USaidWat::RedditUser.new $*.first
|
15
|
+
unless subreddit
|
16
|
+
comments = reddit_user.retrieve_comments
|
17
|
+
exit 2 unless comments
|
18
|
+
max_key = 1
|
19
|
+
puts reddit_user.username
|
20
|
+
puts '-' * reddit_user.username.length
|
21
|
+
comments.each { |c| max_key = c.first.length if c.first.length > max_key }
|
22
|
+
comments.each { |c| printf "%-*s %s\n", max_key, c.first, c.last }
|
23
|
+
else
|
24
|
+
comments = reddit_user.comments_for_subreddit subreddit
|
25
|
+
is_first = true
|
26
|
+
width = `tput cols`.to_i rescue 80
|
27
|
+
comments.each do |c|
|
28
|
+
puts '-' * width unless is_first
|
29
|
+
puts c
|
30
|
+
is_first = false
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,150 @@
|
|
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 = self.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
|
+
|
21
|
+
attr_reader :username
|
22
|
+
|
23
|
+
def initialize(username)
|
24
|
+
@username = username
|
25
|
+
self.ensure_cache_dir!
|
26
|
+
end
|
27
|
+
|
28
|
+
def profile_url
|
29
|
+
"http://www.reddit.com/user/#{self.username}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def comments_url
|
33
|
+
"#{self.profile_url}/comments"
|
34
|
+
end
|
35
|
+
|
36
|
+
def last_update
|
37
|
+
return Time.at 0 unless File.exists? self.cache_timestamp_file
|
38
|
+
Time.parse File.open(self.cache_timestamp_file).read.chomp
|
39
|
+
end
|
40
|
+
|
41
|
+
def retrieve_comments(options={})
|
42
|
+
return self.retrieve_comments_from_cache unless Time.now - self.last_update > 300
|
43
|
+
count = options[:count] || COMMENT_COUNT
|
44
|
+
cache = options[:cache] || true
|
45
|
+
self.destroy_cache!
|
46
|
+
comments = self.fetch_comments count
|
47
|
+
return nil unless comments
|
48
|
+
self.cache_comments comments if cache
|
49
|
+
subreddits = Hash.new { |h,k| h[k] = 0 }
|
50
|
+
comments.each do |comment|
|
51
|
+
subreddit = comment['data']['subreddit'].to_sym
|
52
|
+
subreddits[subreddit] += 1
|
53
|
+
end
|
54
|
+
subreddits.sort { |a,b| b[1] <=> a[1] }
|
55
|
+
end
|
56
|
+
|
57
|
+
def comments_for_subreddit(subreddit)
|
58
|
+
self.retrieve_comments
|
59
|
+
comments = []
|
60
|
+
subreddit_dir = File.join self.comments_dir, subreddit
|
61
|
+
Dir.chdir(subreddit_dir) do
|
62
|
+
Dir['*'].each do |f|
|
63
|
+
path = File.join subreddit_dir, f
|
64
|
+
comment = File.open(path).read.chomp
|
65
|
+
comments << comment
|
66
|
+
end
|
67
|
+
end
|
68
|
+
comments
|
69
|
+
end
|
70
|
+
|
71
|
+
def retrieve_comments_from_cache
|
72
|
+
subreddits = Hash.new { |h,k| h[k] = 0 }
|
73
|
+
Dir.chdir(self.comments_dir) do
|
74
|
+
Dir['*'].each do |sr|
|
75
|
+
next unless File.directory? sr
|
76
|
+
Dir["#{sr}/*"].each { |f| subreddits[sr] += 1 }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
subreddits.sort { |a,b| b[1] <=> a[1] }
|
80
|
+
end
|
81
|
+
|
82
|
+
def fetch_comments(count)
|
83
|
+
comments = Array.new
|
84
|
+
after = nil
|
85
|
+
last_page = count / COMMENTS_PER_PAGE
|
86
|
+
(1..last_page).each do |i|
|
87
|
+
query = i == 1 ? '' : {:count => COMMENTS_PER_PAGE, :after => after}.to_query
|
88
|
+
url = "#{self.comments_url}.json?#{query}"
|
89
|
+
resp = Net::HTTP.get_response 'www.reddit.com', url
|
90
|
+
unless resp.code.to_i == 200
|
91
|
+
$stderr.puts "Could not retrieve comments: #{resp.message}"
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
resp = JSON.parse resp.body
|
95
|
+
if resp.key? 'error'
|
96
|
+
$stderr.puts "Could not retrieve comments: #{resp['error'] || 'Unknown error'}"
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
comments += resp['data']['children']
|
100
|
+
after = resp['data']['after']
|
101
|
+
end
|
102
|
+
comments
|
103
|
+
end
|
104
|
+
|
105
|
+
def cache_comments(comments)
|
106
|
+
comments.each do |c|
|
107
|
+
cid = c['data']['id']
|
108
|
+
sr = c['data']['subreddit']
|
109
|
+
body = c['data']['body']
|
110
|
+
parent_cache_dir = self.subreddit_directory! sr
|
111
|
+
cache_file = File.join parent_cache_dir, cid
|
112
|
+
File.open(cache_file, 'w') { |f| f.write body }
|
113
|
+
end
|
114
|
+
File.open(self.cache_timestamp_file, 'w') { |f| f.write Time.now }
|
115
|
+
end
|
116
|
+
|
117
|
+
def cache_dir
|
118
|
+
File.join USaidWat::BASE_CACHE_DIR, self.username
|
119
|
+
end
|
120
|
+
|
121
|
+
def cache_timestamp_file
|
122
|
+
File.join self.cache_dir, 'updated'
|
123
|
+
end
|
124
|
+
|
125
|
+
def comments_dir
|
126
|
+
File.join self.cache_dir, 'comments'
|
127
|
+
end
|
128
|
+
|
129
|
+
def subreddit_directory!(subreddit)
|
130
|
+
Dir.mkdir self.comments_dir unless File.exists? self.comments_dir
|
131
|
+
cache = File.join self.comments_dir, subreddit
|
132
|
+
Dir.mkdir cache unless File.exists? cache
|
133
|
+
cache
|
134
|
+
end
|
135
|
+
|
136
|
+
def ensure_cache_dir!
|
137
|
+
Dir.mkdir USaidWat::BASE_CACHE_DIR unless File.exists? USaidWat::BASE_CACHE_DIR
|
138
|
+
Dir.mkdir self.cache_dir unless File.exists? self.cache_dir
|
139
|
+
end
|
140
|
+
|
141
|
+
def destroy_cache!
|
142
|
+
FileUtils.rm_rf self.cache_dir
|
143
|
+
self.ensure_cache_dir!
|
144
|
+
end
|
145
|
+
|
146
|
+
def to_s
|
147
|
+
"Reddit user: #{self.username}"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/lib/usaidwat.rb
ADDED
data/usaidwat.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "usaidwat/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "usaidwat"
|
7
|
+
s.version = USaidWat::VERSION
|
8
|
+
s.authors = ["Michael Dippery"]
|
9
|
+
s.email = ["michael@monkey-robot.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{View a user's last 100 Reddit comments}
|
12
|
+
s.description = %q{View a user's last 100 Reddit comments, organized by subreddit.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "usaidwat"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'json'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: usaidwat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michael Dippery
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: &70171046145340 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70171046145340
|
25
|
+
description: View a user's last 100 Reddit comments, organized by subreddit.
|
26
|
+
email:
|
27
|
+
- michael@monkey-robot.com
|
28
|
+
executables:
|
29
|
+
- usaidwat
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- Gemfile
|
35
|
+
- Rakefile
|
36
|
+
- bin/usaidwat
|
37
|
+
- lib/usaidwat.rb
|
38
|
+
- lib/usaidwat/reddit.rb
|
39
|
+
- lib/usaidwat/version.rb
|
40
|
+
- usaidwat.gemspec
|
41
|
+
homepage: ''
|
42
|
+
licenses: []
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project: usaidwat
|
61
|
+
rubygems_version: 1.8.11
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: View a user's last 100 Reddit comments
|
65
|
+
test_files: []
|