like_bomb 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|