tweetganic 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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/MyClass.rb +344 -0
- data/lib/tweetganic.rb +5 -0
- data/lib/tweetganic/version.rb +3 -0
- data/tweetganic +12 -0
- data/tweetganic.gemspec +24 -0
- metadata +105 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 brianpetro
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Tweetganic
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'tweetganic'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install tweetganic
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/MyClass.rb
ADDED
@@ -0,0 +1,344 @@
|
|
1
|
+
|
2
|
+
require 'tweetstream'
|
3
|
+
require 'twitter'
|
4
|
+
require 'net/http'
|
5
|
+
require 'json'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
# GET's settings from tweetganic server
|
9
|
+
def get_user_ctrls
|
10
|
+
settings_response = Net::HTTP.get_response('tweetganic.herokuapp.com', "/settings/#{ARGV[0]}.json").body
|
11
|
+
JSON.parse(settings_response)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Action On/Off Controls
|
15
|
+
def favorite_ctrl(json)
|
16
|
+
return false if json['favorite_ctrl'] == "false"
|
17
|
+
return true if json['favorite_ctrl'] == "true"
|
18
|
+
end
|
19
|
+
|
20
|
+
def follow_ctrl(json)
|
21
|
+
return false if json['follow_ctrl'] == "false"
|
22
|
+
return true if json['follow_ctrl'] == "true"
|
23
|
+
end
|
24
|
+
|
25
|
+
def retweet_ctrl(json)
|
26
|
+
return false if json['retweet_ctrl'] == "false"
|
27
|
+
return true if json['retweet_ctrl'] == "true"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Configure Twitter Connections
|
31
|
+
def twitter_config(c_key, c_secret, o_token, o_token_secret)
|
32
|
+
TweetStream.configure do |config|
|
33
|
+
config.consumer_key = c_key
|
34
|
+
config.consumer_secret = c_secret
|
35
|
+
config.oauth_token = o_token
|
36
|
+
config.oauth_token_secret = o_token_secret
|
37
|
+
config.auth_method = :oauth
|
38
|
+
end
|
39
|
+
|
40
|
+
Twitter.configure do |config|
|
41
|
+
config.consumer_key = c_key
|
42
|
+
config.consumer_secret = c_secret
|
43
|
+
config.oauth_token = o_token
|
44
|
+
config.oauth_token_secret = o_token_secret
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Numeric
|
49
|
+
def to_rad
|
50
|
+
self * Math::PI / 180
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Used to find distance for relativity. loc1 and loc2 are arrays of [latitude, longitude]
|
55
|
+
def distance loc1, loc2
|
56
|
+
lat1, lon1 = loc1
|
57
|
+
lat2, lon2 = loc2
|
58
|
+
dLat = (lat2-lat1).to_rad;
|
59
|
+
dLon = (lon2-lon1).to_rad;
|
60
|
+
a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
61
|
+
Math.cos(lat1.to_rad) * Math.cos(lat2.to_rad) *
|
62
|
+
Math.sin(dLon/2) * Math.sin(dLon/2);
|
63
|
+
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
64
|
+
d = 6371 * c; # Multiply by 6371 to get Kilometers
|
65
|
+
end
|
66
|
+
# Gets given points difference of distance, returns usable twitter loc geocode
|
67
|
+
def get_twit_loc_area(center, selected_radius)
|
68
|
+
loc_adjust_by = distance([center[0],center[1]],[center[0]+0.01,center[1]+0.01])
|
69
|
+
loc_adjusted = selected_radius/loc_adjust_by
|
70
|
+
twitter_loc=[]
|
71
|
+
twitter_loc << (center[1] - loc_adjusted/200.0).round(2)
|
72
|
+
twitter_loc << (center[0] - loc_adjusted/200.0).round(2)
|
73
|
+
twitter_loc << (center[1] + loc_adjusted/200.0).round(2)
|
74
|
+
twitter_loc << (center[0] + loc_adjusted/200.0).round(2)
|
75
|
+
return twitter_loc
|
76
|
+
end
|
77
|
+
|
78
|
+
# Is user using location?
|
79
|
+
def check_using_location(json)
|
80
|
+
return false if json['using_location'] == "false"
|
81
|
+
return true if json['using_location'] == "true"
|
82
|
+
end
|
83
|
+
|
84
|
+
# To Avoid Tweets with offsite Links
|
85
|
+
def check_avoiding_links(json)
|
86
|
+
return false if json['avoid_promos'] == "false"
|
87
|
+
return true if json['avoid_promos'] == "true"
|
88
|
+
end
|
89
|
+
# To avoid people you are following
|
90
|
+
def check_avoid_people_i_follow(json)
|
91
|
+
return false if json['avoid_accounts_i_follow'] == "false"
|
92
|
+
return true if json['avoid_accounts_i_follow'] == "true"
|
93
|
+
end
|
94
|
+
# To avoid tweets containing 'RT' as a word
|
95
|
+
def check_avoid_tweets_containing_rt(json)
|
96
|
+
return false if json['avoid_tweets_with_rt'] == "false"
|
97
|
+
return true if json['avoid_tweets_with_rt'] == "true"
|
98
|
+
end
|
99
|
+
|
100
|
+
def record_data(args)
|
101
|
+
Net::HTTP.post_form(URI("http://tweetganic.herokuapp.com/raws.json"), args)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Used to double filter twitters shitty(inaccurate) GPS search
|
105
|
+
def is_from_user_set_location(status, gen_coords)
|
106
|
+
lat, lon = status.geo.coordinates
|
107
|
+
if lat >= gen_coords[1] && lat <= gen_coords[3] && lon >= gen_coords[0] && lon <= gen_coords[2]
|
108
|
+
return true
|
109
|
+
else
|
110
|
+
return false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def is_my_friend(user_obj)
|
115
|
+
# status.user.following is DEPRECATED
|
116
|
+
# write method after array of friends is available
|
117
|
+
end
|
118
|
+
|
119
|
+
# Checks if two word lists contain matching words.
|
120
|
+
def matching_keywords(current, ref)
|
121
|
+
if (current & ref).empty?
|
122
|
+
return false
|
123
|
+
else
|
124
|
+
return true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
## Twetganic Controller Variables
|
130
|
+
json = get_user_ctrls # Get json from tweetganic ctrls db
|
131
|
+
|
132
|
+
# Set Oauth Keys
|
133
|
+
c_key = json['consumer_key']
|
134
|
+
c_secret = json['consumer_secret']
|
135
|
+
o_token = json['oauth_token']
|
136
|
+
o_token_secret = json['oauth_token_secret']
|
137
|
+
|
138
|
+
avoiding_links=check_avoiding_links(json) # Does Tweet include third party url?
|
139
|
+
avoid_tweets_containing_rt=check_avoid_tweets_containing_rt(json) # Does Tweet text include 'RT'?
|
140
|
+
min_actions_before_re_engage=json['min_actions_before_re_engage'].to_i # How many other actionable users before a user can become actionable again?
|
141
|
+
|
142
|
+
keywords_raw = json['track'] # String of keywords extracted from JSON
|
143
|
+
keywords = keywords_raw.split(', ') # Parse Keywords into array/list
|
144
|
+
|
145
|
+
neg_keywords_raw=json['negative_keywords'] # String of negative keywords extracted from JSON
|
146
|
+
negative_keywords=neg_keywords_raw.split(', ') # Parse Negative Keywords into array/list
|
147
|
+
|
148
|
+
using_location=check_using_location(json) # Is user tracking locations?
|
149
|
+
if using_location # Set location vars if using location
|
150
|
+
set_lat=json['center_lat'].to_f # Center latitude point for location tracking
|
151
|
+
set_lon=json['center_lon'].to_f # Center longitude point for location tracking
|
152
|
+
set_radius=json['radius_distance'].to_f # Distance from center point for location tracking
|
153
|
+
location_keywords=json['location_keywords'].split(', ') # Additional keywords for filtering location tweets
|
154
|
+
## Generated for location tracking
|
155
|
+
keyword_ref = location_keywords|keywords # Reference list of keywords and location_keywords, for matching (array)
|
156
|
+
gen_coords=get_twit_loc_area([set_lat, set_lon], set_radius) # Generated Twitter location tracking coordinates
|
157
|
+
end
|
158
|
+
|
159
|
+
# Mains Switches for Actions
|
160
|
+
favorite_on = favorite_ctrl(json)
|
161
|
+
follow_on = follow_ctrl(json)
|
162
|
+
retweet_on = retweet_ctrl(json)
|
163
|
+
|
164
|
+
# Vars for Favoriting Action
|
165
|
+
favoriting_friends_min=json['favoriting_friends_min'].to_i
|
166
|
+
favoriting_friends_max=json['favoriting_friends_max'].to_i
|
167
|
+
favoriting_followers_min=json['favoriting_followers_min'].to_i
|
168
|
+
favoriting_followers_max=json['favoriting_followers_max'].to_i
|
169
|
+
|
170
|
+
# Vars for Following Action
|
171
|
+
following_friends_min=json['following_friends_min'].to_i
|
172
|
+
following_friends_max=json['following_friends_max'].to_i
|
173
|
+
following_followers_min=json['following_followers_min'].to_i
|
174
|
+
following_followers_max=json['following_followers_max'].to_i
|
175
|
+
|
176
|
+
# Vars for Retweeting Action
|
177
|
+
rt_friends_min=json['rt_friends_min'].to_i
|
178
|
+
rt_friends_max=json['rt_friends_max'].to_i
|
179
|
+
rt_followers_min=json['rt_followers_min'].to_i
|
180
|
+
rt_followers_max=json['rt_followers_max'].to_i
|
181
|
+
|
182
|
+
# Get random wait times and convert mins to seconds
|
183
|
+
favoriting_wait_min = (json['favoriting_wait_min'].to_i)*60
|
184
|
+
favoriting_wait_max = (json['favoriting_wait_max'].to_i)*60
|
185
|
+
following_wait_min = (json['following_wait_min'].to_i)*60
|
186
|
+
following_wait_max = (json['following_wait_max'].to_i)*60
|
187
|
+
rt_wait_min = (json['rt_wait_min'].to_i)*60
|
188
|
+
rt_wait_max = (json['rt_wait_max'].to_i)*60
|
189
|
+
|
190
|
+
## Generated Variables For Tweet Processing
|
191
|
+
twitter_config(c_key, c_secret, o_token, o_token_secret) # Runs config for 'twitter' and 'tweetstream' gems
|
192
|
+
|
193
|
+
# Gets boundaries for initial filtering
|
194
|
+
friends_presets=[favoriting_friends_min, favoriting_friends_max, following_friends_min, following_friends_max, rt_friends_min, rt_friends_max]
|
195
|
+
followers_presets=[favoriting_followers_min, favoriting_followers_max, following_followers_min, following_followers_max, rt_followers_min, rt_followers_max]
|
196
|
+
min_friends=friends_presets.min
|
197
|
+
max_friends=friends_presets.max
|
198
|
+
min_followers=followers_presets.min
|
199
|
+
max_followers=followers_presets.max
|
200
|
+
|
201
|
+
start_time=Time.now.to_i # Start time equals run time
|
202
|
+
next_favorite_time=start_time # Set to favorite first eligible tweet
|
203
|
+
next_follow_time=start_time # Set to follow first eligible tweet
|
204
|
+
next_retweet_time=start_time # Set to retweet first eligible tweet
|
205
|
+
|
206
|
+
## Vars Set By Twitter API Response
|
207
|
+
screen_name = Twitter.user.screen_name
|
208
|
+
user_id = Twitter.user.id
|
209
|
+
|
210
|
+
puts "### Welcome, #{screen_name} ###"
|
211
|
+
puts "Tracking:"
|
212
|
+
puts keywords
|
213
|
+
puts "Location Monitoring: #{using_location}"
|
214
|
+
puts "Center: Within #{set_radius}km of #{set_lat}, #{set_lon}" if using_location
|
215
|
+
puts "Bounds: #{gen_coords}" if using_location
|
216
|
+
puts "Consumer Key: #{c_key}"
|
217
|
+
puts "Consumer Secret: #{c_secret}"
|
218
|
+
puts "Oauth Token: #{o_token}"
|
219
|
+
puts "Oauth Secret: #{o_token_secret}"
|
220
|
+
puts "Avoiding Links: #{avoiding_links}"
|
221
|
+
puts "Avoiding Tweets Containing 'RT': #{avoid_tweets_containing_rt}"
|
222
|
+
puts "Avoids Re-engaging user before #{min_actions_before_re_engage} actions on others"
|
223
|
+
puts "Avoiding these negative keywords:"
|
224
|
+
puts negative_keywords
|
225
|
+
puts "Targets users with between #{min_friends} and #{max_friends} friends"
|
226
|
+
puts "Targets users with between #{min_followers} and #{max_followers} followers"
|
227
|
+
|
228
|
+
## Fresh for running the script
|
229
|
+
i=0 # Tweets analysed this run
|
230
|
+
favorited=[] # Stores user_id's of users who were favorited
|
231
|
+
followed=[] # Stores user_id's of users who were followed
|
232
|
+
retweeted=[] # Stores user_id's of users who were retweeted
|
233
|
+
actionabled=[] # Stores user_id's of users who were declared actionable
|
234
|
+
recently_engaged=[] # Collection of recently engaged users for re-engage method
|
235
|
+
|
236
|
+
puts "Stream connecting..."
|
237
|
+
client = TweetStream::Client.new
|
238
|
+
puts "Stream Connnected."
|
239
|
+
client.filter({track: keywords, locations: gen_coords}) do |status|
|
240
|
+
tweet_breakdown=status.text.split(' ')
|
241
|
+
actionable=true
|
242
|
+
favoritable=false
|
243
|
+
followable=false
|
244
|
+
retweetable=false
|
245
|
+
dmable=false
|
246
|
+
reportable=true
|
247
|
+
tweet_score=0
|
248
|
+
i=i+1
|
249
|
+
tweeter_user_id=status.user.id
|
250
|
+
tweet_id=status.id
|
251
|
+
followers_count = status.user.followers_count.to_i
|
252
|
+
friends_count = status.user.friends_count.to_i
|
253
|
+
tweet_score = followers_count-friends_count
|
254
|
+
puts ""
|
255
|
+
puts "#{i}"
|
256
|
+
puts "#{status.text}"
|
257
|
+
|
258
|
+
if using_location # Runs 'double check' when running location because of Twitters inferior filtering methods
|
259
|
+
if !status.geo.nil?
|
260
|
+
actionable=false unless is_from_user_set_location(status, gen_coords)
|
261
|
+
end
|
262
|
+
# Double check keyword is causing non geoed to stop
|
263
|
+
actionable=false unless matching_keywords(tweet_breakdown, keyword_ref)
|
264
|
+
end
|
265
|
+
## Initial Validations for Speed, 'actionable=true' if they pass user set validations
|
266
|
+
if avoid_tweets_containing_rt
|
267
|
+
negative_keywords << "RT"
|
268
|
+
end
|
269
|
+
if avoiding_links
|
270
|
+
actionable=false unless status.urls.empty?
|
271
|
+
end
|
272
|
+
actionable=false unless friends_count.between?(min_friends, max_friends)
|
273
|
+
actionable=false unless followers_count.between?(min_followers, max_followers)
|
274
|
+
actionable=false if recently_engaged.include?(tweeter_user_id)
|
275
|
+
actionable=false if matching_keywords(tweet_breakdown, negative_keywords)
|
276
|
+
|
277
|
+
if actionabled.count >=100 # Submit data when able to record 100 data points
|
278
|
+
user_followers=Twitter.user.followers_count
|
279
|
+
record_data({"data_id" => "1",
|
280
|
+
"user_id" => "#{user_id}",
|
281
|
+
"user_followers" => "#{user_followers}",
|
282
|
+
"favorited" => "#{favorited}",
|
283
|
+
"followed" => "#{followed}",
|
284
|
+
"retweeted" => "#{retweeted}",
|
285
|
+
"actionabled" => "#{actionabled}",
|
286
|
+
"keywords" => "#{keywords_raw}",
|
287
|
+
"negative_keywords" => "#{neg_keywords_raw}"
|
288
|
+
})
|
289
|
+
# Resets Lists of user_id's to submit in data
|
290
|
+
favorited=[]
|
291
|
+
followed=[]
|
292
|
+
retweeted=[]
|
293
|
+
actionabled=[]
|
294
|
+
end
|
295
|
+
|
296
|
+
if recently_engaged.count >= min_actions_before_re_engage
|
297
|
+
recently_engaged=[]
|
298
|
+
end
|
299
|
+
|
300
|
+
if actionable
|
301
|
+
puts "Actionable"
|
302
|
+
actionabled << tweeter_user_id
|
303
|
+
favoritable=true if favorite_on && friends_count.between?(favoriting_friends_min, favoriting_friends_max) && followers_count.between?(favoriting_followers_min, favoriting_followers_max)
|
304
|
+
followable=true if follow_on && friends_count.between?(following_friends_min, following_friends_max) && followers_count.between?(following_followers_min, following_followers_max)
|
305
|
+
retweetable=true if retweet_on && friends_count.between?(rt_friends_min, rt_friends_max) && followers_count.between?(rt_followers_min, rt_followers_max)
|
306
|
+
|
307
|
+
if favoritable
|
308
|
+
if Time.now.to_i >= next_favorite_time
|
309
|
+
Twitter.favorite(tweet_id)
|
310
|
+
next_favorite_time=(Time.now.to_i)+rand(favoriting_wait_min..favoriting_wait_max)
|
311
|
+
favorited << tweeter_user_id
|
312
|
+
recently_engaged << tweeter_user_id
|
313
|
+
else
|
314
|
+
puts "To Soon To Favorite"
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
if followable
|
320
|
+
if Time.now.to_i >= next_follow_time
|
321
|
+
Twitter.follow(tweeter_user_id)
|
322
|
+
next_follow_time=(Time.now.to_i)+rand(following_wait_min..following_wait_max)
|
323
|
+
followed << tweeter_user_id
|
324
|
+
recently_engaged << tweeter_user_id
|
325
|
+
else
|
326
|
+
puts "To Soon To Follow"
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
if retweetable
|
332
|
+
if Time.now.to_i >= next_retweet_time
|
333
|
+
Twitter.retweet(tweet_id)
|
334
|
+
next_retweet_time=(Time.now.to_i)+rand(rt_wait_min..rt_wait_max)
|
335
|
+
retweeted << tweeter_user_id
|
336
|
+
recently_engaged << tweeter_user_id
|
337
|
+
else
|
338
|
+
puts "To Soon To RT"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
else
|
342
|
+
puts "NOT WORTHY"
|
343
|
+
end
|
344
|
+
end
|
data/lib/tweetganic.rb
ADDED
data/tweetganic
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'require_all'
|
4
|
+
#make program output in real time so errors visible in VR.
|
5
|
+
STDOUT.sync = true
|
6
|
+
STDERR.sync = true
|
7
|
+
|
8
|
+
#everything in these directories will be included
|
9
|
+
my_path = File.expand_path(File.dirname(__FILE__))
|
10
|
+
require_all Dir.glob(my_path + "/bin/**/*.rb")
|
11
|
+
|
12
|
+
MyClass.new
|
data/tweetganic.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tweetganic/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "tweetganic"
|
8
|
+
spec.version = Tweetganic::VERSION
|
9
|
+
spec.authors = ["brianpetro"]
|
10
|
+
spec.email = ["brian@plexm.com"]
|
11
|
+
spec.description = %q{Run Tweetganic}
|
12
|
+
spec.summary = %q{Runs Tweetganic}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "require"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tweetganic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- brianpetro
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: require
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Run Tweetganic
|
63
|
+
email:
|
64
|
+
- brian@plexm.com
|
65
|
+
executables:
|
66
|
+
- MyClass.rb
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE.txt
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- bin/MyClass.rb
|
76
|
+
- lib/tweetganic.rb
|
77
|
+
- lib/tweetganic/version.rb
|
78
|
+
- tweetganic
|
79
|
+
- tweetganic.gemspec
|
80
|
+
homepage: ''
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.25
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Runs Tweetganic
|
105
|
+
test_files: []
|