usaidwat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in usaidwat.gemspec
4
+ gemspec
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
@@ -0,0 +1,3 @@
1
+ module USaidWat
2
+ VERSION = "0.0.1"
3
+ end
data/lib/usaidwat.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'usaidwat/version'
2
+ require 'usaidwat/reddit'
3
+
4
+
5
+ module USaidWat
6
+ BASE_CACHE_DIR = File.join File.expand_path('~'), '.usaidwat'
7
+ end
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: []