like_bomb 0.0.0
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/lib/like_bomb/like_bomb.rb +205 -0
- data/test/like_bomb_test.rb +21 -0
- metadata +85 -0
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'oj'
|
3
|
+
# LikeBomb, a fun way to mess with your friends on Facebook! This gem can be
|
4
|
+
# used to like and/or comment on every status and/or photo of one of your
|
5
|
+
# Facebook friends!
|
6
|
+
# @author Maxwell Elliott (mailto:elliott.432@buckeyemail.osu.edu)
|
7
|
+
# @license MIT
|
8
|
+
# @!attribute [r] key
|
9
|
+
# @return [String] The FB Graph API Key used to create the LikeBomb
|
10
|
+
#
|
11
|
+
# @!attribute [r] fb_name
|
12
|
+
# @return [String] The Facebook user name of the owner of the current
|
13
|
+
# instance's Graph API key
|
14
|
+
# @example
|
15
|
+
# lb = LikeBomb.new("<VALID_KEY>")
|
16
|
+
# friend_hash = lb.get_friends
|
17
|
+
# unliked_statuses = lb.get_statuses(friend_hash["Tim Tom"])[:not_liked] # Get not liked statuses
|
18
|
+
# lb.post_likes(unliked_statuses)
|
19
|
+
class LikeBomb
|
20
|
+
attr_reader :key,:fb_name
|
21
|
+
# @param [String] key A valid Facebook Graph API key which can be generated
|
22
|
+
# {http://developers.facebook.com/tools/explorer here},
|
23
|
+
# please consult README for additional directions.
|
24
|
+
# @raise [ArgumentError] if the provided Facebook Graph API key is invalid
|
25
|
+
# due to insufficent permissions
|
26
|
+
# @example Invalid key which will in turn throw an exception at runtime
|
27
|
+
# LikeBomb.new("HI") # "ArgumentError: The provided key is invalid..."
|
28
|
+
# @example Valid key created by Billy Bob and used for a LikeBomb
|
29
|
+
# lb = LikeBomb.new("<VALID KEY>")
|
30
|
+
# lb.fb_name # "Billy Bob"
|
31
|
+
# @todo Use watir-webdriver to automate grabbing of keys from Graph API site.
|
32
|
+
# Default String constructor
|
33
|
+
def initialize(key)
|
34
|
+
begin
|
35
|
+
permissions = Oj.load(Typhoeus::Request.get(
|
36
|
+
"https://graph.facebook.com/me/permissions?access_token=#{key}").body)["data"].first
|
37
|
+
if is_valid?(permissions)
|
38
|
+
@key = key
|
39
|
+
@fb_name = Oj.load(Typhoeus::Request.get(
|
40
|
+
"https://graph.facebook.com/me?access_token=#{@key}").body)["name"]
|
41
|
+
else
|
42
|
+
raise ArgumentError ,
|
43
|
+
"The provided key is invalid, please consult the README for how to generate a valid API key"
|
44
|
+
end
|
45
|
+
rescue
|
46
|
+
raise ArgumentError ,
|
47
|
+
"The provided key is invalid, please consult the README for how to generate a valid API key"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Hash<String,String>] a Hash containing all your friend's names as
|
52
|
+
# String keys and their unique ID as the corresponding String value
|
53
|
+
# @example Let's grab Spongebob's friends
|
54
|
+
# spongebob_lb = LikeBomb.new("<SPONGEBOB_KEY>")
|
55
|
+
# spongebob_lb.get_friends # "{"Patrick" => "111231321221", Squidward" => "22212221222"}"
|
56
|
+
# A method that can be used to retrieve user_id's of your friends. You will
|
57
|
+
# need to use these ids to get status and/or photo object_ids
|
58
|
+
def get_friends
|
59
|
+
res = Typhoeus::Request.get(
|
60
|
+
"https://graph.facebook.com/me/friends?access_token=#{@key}")
|
61
|
+
unless res.nil?
|
62
|
+
json_data = Oj.load res.body
|
63
|
+
friend_hash = Hash.new
|
64
|
+
json_data["data"].each do |x|
|
65
|
+
friend_hash[x["name"]] = x["id"]
|
66
|
+
end
|
67
|
+
return friend_hash
|
68
|
+
end
|
69
|
+
end
|
70
|
+
# @return [Hash<Symbol,Array<String>>] a Hash of Symbol, Array<String> pairs.
|
71
|
+
# Three keys exist, :all, :liked, :cooled, which represent all status ids,
|
72
|
+
# status ids that are liked and status ids that have been commented
|
73
|
+
# with "Cool!". These keys exist as to prevent double posting on a
|
74
|
+
# specific status. Negations :not_liked and :not_cooled also exist
|
75
|
+
# @param [String] user_id A user_id of one of your friends
|
76
|
+
# @see get_friends
|
77
|
+
# @example A typical use of get_statuses
|
78
|
+
# patrick_id = spongebob_lb.get_friends["Patrick"]
|
79
|
+
# spongebob_lb.get_statuses(patrick_id)[:all] # ["11123212333","33343444444",.....]
|
80
|
+
# Grabs all statuses of a specific user when provided a user_id
|
81
|
+
def get_statuses(user_id)
|
82
|
+
result_hash = Hash.new
|
83
|
+
result_hash[:all] = []
|
84
|
+
result_hash[:liked] = []
|
85
|
+
result_hash[:cooled] = []
|
86
|
+
all_links = []
|
87
|
+
res = Typhoeus::Request.get("https://graph.facebook.com/#{user_id}/statuses?access_token=#{@key}")
|
88
|
+
take_statuses = Oj.load(res.body)["data"].empty? ? false : true
|
89
|
+
while take_statuses
|
90
|
+
Oj.load(res.body)["data"].each do |status|
|
91
|
+
unless result_hash[:all].include? status["id"]
|
92
|
+
result_hash[:all].push status["id"]
|
93
|
+
result_hash[:liked].push status["id"] if liked?(status)
|
94
|
+
result_hash[:cooled].push status["id"] if cooled?(status)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
next_url = Oj.load(res.body)["paging"]["next"]
|
98
|
+
if all_links.include? next_url || next_url.nil?
|
99
|
+
take_statuses = false
|
100
|
+
else
|
101
|
+
all_links.push next_url
|
102
|
+
res = Typhoeus::Request.get("#{Oj.load(res.body)["paging"]["next"]}?access_token=#{@key}")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
result_hash[:not_liked] = result_hash[:all] - result_hash[:liked]
|
106
|
+
result_hash[:not_cooled] = result_hash[:all] - result_hash[:cooled]
|
107
|
+
result_hash
|
108
|
+
end
|
109
|
+
# @return [Hash<Symbol,Array<String>>] a Hash of Symbol, Array<String> pairs.
|
110
|
+
# Three keys exist, :all, :liked, :cooled, which represent all photo ids,
|
111
|
+
# photo ids that are liked and photo ids that have been commented
|
112
|
+
# with "Cool!". These keys exist as to prevent double posting on a
|
113
|
+
# specific photo. Negations :not_liked and :not_cooled also exist
|
114
|
+
# @param [String] user_id A user_id of one of your friends
|
115
|
+
# @see get_friends
|
116
|
+
# @example A typical use of get_photos
|
117
|
+
# patrick_id = spongebob_lb.get_friends["Patrick"]
|
118
|
+
# spongebob_lb.get_photos(patrick_id)[:all] # ["11123312333","33143444444",.....]
|
119
|
+
# Grabs all photos of a specific user when provided a user_id
|
120
|
+
def get_photos(user_id)
|
121
|
+
result_hash = Hash.new
|
122
|
+
result_hash[:all] = []
|
123
|
+
result_hash[:liked] = []
|
124
|
+
result_hash[:cooled] = []
|
125
|
+
all_links = []
|
126
|
+
res = Typhoeus::Request.get("https://graph.facebook.com/#{user_id}/photos?access_token=#{@key}")
|
127
|
+
take_photos = Oj.load(res.body)["data"].empty? ? false : true
|
128
|
+
while take_photos
|
129
|
+
unless Oj.load(res.body)["data"].nil?
|
130
|
+
Oj.load(res.body)["data"].each do |photo|
|
131
|
+
unless result_hash[:all].include? photo["id"]
|
132
|
+
result_hash[:all].push photo["id"]
|
133
|
+
result_hash[:liked].push photo["id"] if liked?(photo)
|
134
|
+
result_hash[:cooled].push photo["id"] if cooled?(photo)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
begin
|
139
|
+
next_url = Oj.load(res.body)["paging"]["next"]
|
140
|
+
rescue NoMethodError
|
141
|
+
break
|
142
|
+
end
|
143
|
+
if all_links.include? next_url || next_url.nil?
|
144
|
+
take_photos = false
|
145
|
+
else
|
146
|
+
all_links.push next_url
|
147
|
+
res = Typhoeus::Request.get("#{Oj.load(res.body)["paging"]["next"]}?access_token=#{@key}")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
result_hash[:not_liked] = result_hash[:all] - result_hash[:liked]
|
151
|
+
result_hash[:not_cooled] = result_hash[:all] - result_hash[:cooled]
|
152
|
+
result_hash
|
153
|
+
end
|
154
|
+
# @param [Array<String>] obj_ids an Array of Strings representing object_ids
|
155
|
+
# of statuses and/or photos
|
156
|
+
# @example common example
|
157
|
+
# unliked_ids = lb.get_statuses(friend_hash["Gumby"])[:not_liked] # Grab all previously unliked statuses
|
158
|
+
# lb.post_likes(unliked_ids) # Like all of Gumby's previously unliked statuses
|
159
|
+
# Likes any provided object_id
|
160
|
+
def post_likes(obj_ids)
|
161
|
+
hydra = Typhoeus::Hydra.new
|
162
|
+
complete_urls = obj_ids.collect{|id| "https://graph.facebook.com/#{id}/likes?access_token=#{@key}&publish_stream"}
|
163
|
+
complete_urls.each do |url|
|
164
|
+
hydra.queue Typhoeus::Request.new(url,
|
165
|
+
:method => :post,
|
166
|
+
:timeout => 50000,
|
167
|
+
:cache_timeout => 60)
|
168
|
+
end
|
169
|
+
hydra.run
|
170
|
+
end
|
171
|
+
|
172
|
+
# @param [Array<String>] obj_ids an Array of Strings representing object_ids
|
173
|
+
# of statuses and/or photos
|
174
|
+
# @example common example
|
175
|
+
# unliked_ids = lb.get_photos(friend_hash["Gumby"])[:not_cooled] # Grab all previously uncommented photos
|
176
|
+
# lb.post_cools(unliked_ids) # Comment "Cool!" on all of Gumby's previously uncommented photos
|
177
|
+
# Posts the comment "Cool!" on any provided object_id
|
178
|
+
def post_cools(obj_ids)
|
179
|
+
hydra = Typhoeus::Hydra.new
|
180
|
+
complete_urls = obj_ids.collect{|id| "https://graph.facebook.com/#{id}/comments?access_token=#{@key}&publish_stream&message=Cool!"}
|
181
|
+
complete_urls.each do |url|
|
182
|
+
Typhoeus::Request.post url
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
def is_valid?(permissions)
|
188
|
+
result = false
|
189
|
+
if permissions["publish_stream"] == 1 && permissions["friends_status"] == 1 &&
|
190
|
+
permissions["friends_photos"] == 1 && permissions["user_likes"] == 1 &&
|
191
|
+
permissions["publish_actions"] == 1 && permissions["read_stream"] ==1 &&
|
192
|
+
permissions["export_stream"] == 1
|
193
|
+
result = true
|
194
|
+
end
|
195
|
+
result
|
196
|
+
end
|
197
|
+
|
198
|
+
def liked?(item)
|
199
|
+
return item["likes"].nil? ? false : (item["likes"]["data"].collect{|x| x["name"]}.include? @fb_name)
|
200
|
+
end
|
201
|
+
|
202
|
+
def cooled?(item)
|
203
|
+
return item["comments"].nil? ? false : (item["comments"]["data"].collect{|x| x["from"]["name"]}.include? @fb_name)
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../lib/like_bomb/like_bomb.rb"
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestLikeBomb < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
#To run tests you will need to save your key in a key.txt file in the gem's root. This is done
|
7
|
+
#to prevent people from saving their key anywhere in the source.
|
8
|
+
@lb = LikeBomb.new(IO.readlines("#{File.dirname(__FILE__)}/../key.txt").first)
|
9
|
+
end
|
10
|
+
def test_get_friends
|
11
|
+
#Ids have a standard format
|
12
|
+
assert_match(/\A\d{7,}\z/, @lb.get_friends.values.first)
|
13
|
+
end
|
14
|
+
def test_get_statuses
|
15
|
+
#statuses are variable between each friend, therefore the only safe test is a kind test, same is true for get photos
|
16
|
+
assert_kind_of(Hash, @lb.get_statuses(@lb.get_friends.values.last))
|
17
|
+
end
|
18
|
+
def test_get_photos
|
19
|
+
assert_kind_of(Hash, @lb.get_photos(@lb.get_friends.values.first))
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: like_bomb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Maxwell Elliott
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: typhoeus
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.4.2
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.4.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: oj
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.3.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.3.0
|
46
|
+
description: ! "Likebomb is a quick and efficent way to annoy your Facebook friends
|
47
|
+
by liking or commenting on every status and/or photo \n belonging to them. This
|
48
|
+
gem is a great example of the possiblites with the new Facebook Graph API."
|
49
|
+
email: elliott.432@buckeyemail.osu.edu
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- lib/like_bomb/like_bomb.rb
|
55
|
+
- test/like_bomb_test.rb
|
56
|
+
homepage: http://rubygems.org/gems/like_bomb
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
post_install_message: Thanks for using LikeBomb! Have fun!
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.8.7
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
requirements:
|
76
|
+
- A Facebook account
|
77
|
+
- A Facebook Developer Graph API key
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.24
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Lets annoy some Facebook friends
|
83
|
+
test_files:
|
84
|
+
- test/like_bomb_test.rb
|
85
|
+
has_rdoc:
|