favebomb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/Gemfile.lock +20 -0
- data/MIT-LICENSE +20 -0
- data/bin/favebomb +13 -0
- data/favebomb.gemspec +23 -0
- data/lib/favebomb.rb +94 -0
- data/lib/favebomb/version.rb +3 -0
- data/readme.md +73 -0
- data/test/unit/favebomb.rb +20 -0
- metadata +104 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Jonathan Vingiano
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/favebomb
ADDED
data/favebomb.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/favebomb/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
|
6
|
+
s.name = "favebomb"
|
7
|
+
s.version = Favebomb::VERSION
|
8
|
+
s.author = "Jonathan Vingiano"
|
9
|
+
s.email = "jgv@jonathanvingiano.com"
|
10
|
+
s.homepage = "http://github.com/jgv/favebomb"
|
11
|
+
s.rubyforge_project = "favebomb"
|
12
|
+
s.summary = "Positive reinforcement"
|
13
|
+
s.description = "Favorite Tweets from the command line"
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_file = 'test/unit/favebomb.rb'
|
16
|
+
s.require_paths = ['lib', 'bin']
|
17
|
+
s.executables = ['favebomb']
|
18
|
+
|
19
|
+
s.add_dependency 'oauth'
|
20
|
+
s.add_dependency 'json'
|
21
|
+
s.add_dependency 'colored'
|
22
|
+
|
23
|
+
end
|
data/lib/favebomb.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'optparse'
|
3
|
+
require 'pp'
|
4
|
+
require 'json'
|
5
|
+
require 'colored'
|
6
|
+
|
7
|
+
class Favebomb
|
8
|
+
|
9
|
+
attr_accessor :results, :faved, :options
|
10
|
+
|
11
|
+
def initialize(opts={})
|
12
|
+
@options = {
|
13
|
+
:lang => nil,
|
14
|
+
:type => nil,
|
15
|
+
:count => nil,
|
16
|
+
:until => nil,
|
17
|
+
:geocode => nil
|
18
|
+
}
|
19
|
+
@faved = []
|
20
|
+
@client = prepare_access_token(ENV["FAVEBOMB_ACCESS_TOKEN"], ENV["FAVEBOMB_ACCESS_SECRET"])
|
21
|
+
end
|
22
|
+
|
23
|
+
def bomb term
|
24
|
+
parse_options!
|
25
|
+
puts "looking for #{term}".bold.blue
|
26
|
+
query = generate_params term
|
27
|
+
|
28
|
+
search = @client.request(:get, "http://api.twitter.com/1.1/search/tweets.json?#{query}")
|
29
|
+
@results = JSON.parse(search.read_body)["statuses"]
|
30
|
+
puts "found #{@results.count} tweets"
|
31
|
+
results.each {|tweet| fave! tweet if tweet["favorited"] == false }
|
32
|
+
puts
|
33
|
+
puts "faved #{@faved.count} tweets"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def parse_options!
|
39
|
+
OptionParser.new do |opts|
|
40
|
+
opts.banner = "Usage: favebomb [command] [options]"
|
41
|
+
opts.on("-l", "--lang lang", "Restricts tweets to the given language, given by an ISO 639-1 code. Language detection is best-effort.") {|lang| @options[:lang] = lang }
|
42
|
+
opts.on("-t", "--type type", "Restrict tweets to a specific type. Choose between popular, recent, or mixed (the default).") {|type| @options[:type] = type }
|
43
|
+
opts.on("-c", "--count count", "Control the number of tweets to fave. Maximum is 100, default is 15.") {|count| @options[:count] = count }
|
44
|
+
opts.on("-u", "--until date", "Returns tweets generated before the given date. Date should be formatted as YYYY-MM-DD. Keep in mind that the search index may not go back as far as the date you specify here.") {|date| @options[:until] = date }
|
45
|
+
opts.on("-g", "--geocode code", "Returns tweets by users located within a given radius of the given latitude/longitude. The location is preferentially taking from the Geotagging API, but will fall back to their Twitter profile. The parameter value is specified by 'latitude,longitude,radius', where radius units must be specified as either 'mi' (miles) or 'km' (kilometers). Note that you cannot use the near operator via the API to geocode arbitrary locations; however you can use this geocode parameter to search near geocodes directly. A maximum of 1,000 distinct 'sub-regions' will be considered when using the radius modifier.") {|code|
|
46
|
+
@options[:geocode] = code }
|
47
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
48
|
+
puts opts
|
49
|
+
Kernel.exit!
|
50
|
+
end
|
51
|
+
end.parse!
|
52
|
+
end
|
53
|
+
|
54
|
+
def generate_params term
|
55
|
+
params = ""
|
56
|
+
@options.each {|k,v| params += "&#{k}=#{URI.encode(v)}" if v != nil }
|
57
|
+
query = "q=#{URI.encode(term)}" + params
|
58
|
+
return query
|
59
|
+
end
|
60
|
+
|
61
|
+
def fave! tweet
|
62
|
+
puts
|
63
|
+
puts "faving..".yellow
|
64
|
+
puts tweet["text"]
|
65
|
+
fave = @client.request(:post, "https://api.twitter.com/1.1/favorites/create.json?id=#{tweet["id"]}")
|
66
|
+
if fave.response.code.to_i == 200
|
67
|
+
puts "faved!".bold.green
|
68
|
+
@faved << tweet
|
69
|
+
else
|
70
|
+
begin
|
71
|
+
json = JSON.parse(fave.read_body)["errors"]
|
72
|
+
puts json ["errors"]["message"].bold.red if json["errors"]
|
73
|
+
rescue Exception => e
|
74
|
+
puts "Error: ".bold.red + e.to_s.bold.red
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def prepare_access_token oauth_token, oauth_token_secret
|
80
|
+
consumer = OAuth::Consumer.new(ENV["FAVEBOMB_CONSUMER_KEY"], ENV["FAVEBOMB_CONSUMER_SECRET"],
|
81
|
+
{ :site => "http://api.twitter.com",
|
82
|
+
:scheme => :header
|
83
|
+
})
|
84
|
+
|
85
|
+
token_hash = {
|
86
|
+
:oauth_token => oauth_token,
|
87
|
+
:oauth_token_secret => oauth_token_secret
|
88
|
+
}
|
89
|
+
|
90
|
+
access_token = OAuth::AccessToken.from_hash(consumer, token_hash )
|
91
|
+
return access_token
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/readme.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Favebomb
|
2
|
+
|
3
|
+
Hello! Have you ever released a project on the "internet" and wanted to high five people who are tweeting about it. It's super annoying to fave each and every tweet. **Enter Favebomb** This little Ruby gem will take care of all your faving for you!
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Currently Favebomb requires that you [create a Twitter app](https://dev.twitter.com/apps/new) and have environment variables for the consumer and OAuth tokens. Add something like this to your config:
|
8
|
+
|
9
|
+
``` bash
|
10
|
+
export FAVEBOMB_CONSUMER_KEY=12345
|
11
|
+
export FAVEBOMB_CONSUMER_SECRET=12345
|
12
|
+
export FAVEBOMB_ACCESS_TOKEN=12345
|
13
|
+
export FAVEBOMB_ACCESS_SECRET=12345
|
14
|
+
```
|
15
|
+
|
16
|
+
Then actually install Favebomb like so:
|
17
|
+
|
18
|
+
``` bash
|
19
|
+
$ gem install favebomb
|
20
|
+
```
|
21
|
+
or in your Gemfile: `gem 'favebomb'`
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
```
|
26
|
+
$ favebomb --help
|
27
|
+
|
28
|
+
Usage: favebomb [command] [options]
|
29
|
+
-l, --lang lang Restricts tweets to the given language, given by an ISO 639-1 code.
|
30
|
+
Language detection is best-effort.
|
31
|
+
-t, --type type Restrict tweets to a specific type. Choose between popular, recent,
|
32
|
+
or mixed (the default).
|
33
|
+
-c, --count count Control the number of tweets to fave. Maximum is 100, default is 15.
|
34
|
+
-u, --until date Returns tweets generated before the given date. Date should be
|
35
|
+
formatted as YYYY-MM-DD. Keep in mind that the search index may not
|
36
|
+
go back as far as the date you specify here.
|
37
|
+
-g, --geocode code Returns tweets by users located within a given radius of the given
|
38
|
+
latitude/longitude. The location is preferentially taking from the
|
39
|
+
Geotagging API, but will fall back to their Twitter profile. The
|
40
|
+
parameter value is specified by 'latitude,longitude,radius', where
|
41
|
+
radius units must be specified as either 'mi' (miles) or 'km'
|
42
|
+
(kilometers). Note that you cannot use the near operator via the API
|
43
|
+
to geocode arbitrary locations; however you can use this geocode
|
44
|
+
parameter to search near geocodes directly. A maximum of 1,000
|
45
|
+
distinct 'sub-regions' will be considered when using the radius
|
46
|
+
modifier.
|
47
|
+
-h, --help Show this message
|
48
|
+
|
49
|
+
```
|
50
|
+
|
51
|
+
The [Twitter search docs](https://dev.twitter.com/docs/api/1.1/get/search/tweets) are also a good resource for option usage.
|
52
|
+
|
53
|
+
Let's search Twitter for the term "bieber" and fave a bunch of Tweets.
|
54
|
+
|
55
|
+
``` bash
|
56
|
+
$ favebomb bieber
|
57
|
+
```
|
58
|
+
|
59
|
+
Or what about searching Twitter for "kawaii" from users located in Japan.
|
60
|
+
|
61
|
+
``` bash
|
62
|
+
$ favebomb --lang ja kawaii
|
63
|
+
```
|
64
|
+
|
65
|
+
## Tests
|
66
|
+
|
67
|
+
Run tests with minitest.
|
68
|
+
|
69
|
+
```
|
70
|
+
$ ruby test/unit/favebomb.rb
|
71
|
+
```
|
72
|
+
|
73
|
+
**License: MIT**
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/unit'
|
3
|
+
require 'minitest/pride'
|
4
|
+
|
5
|
+
$:.unshift File.dirname(__FILE__) + '/../../lib'
|
6
|
+
require 'favebomb'
|
7
|
+
|
8
|
+
class TestFavebomb < MiniTest::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@favebomb = Favebomb.new
|
12
|
+
@favebomb.bomb "bieber"
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_that_it_can_bomb_a_term
|
16
|
+
@favebomb.instance_variable_get("@faved").count.must_be_close_to @favebomb.instance_variable_get("@results").count, 1
|
17
|
+
@favebomb.instance_variable_get("@faved").must_be_kind_of Array
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: favebomb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonathan Vingiano
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: oauth
|
16
|
+
requirement: !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: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '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: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: colored
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
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: Favorite Tweets from the command line
|
63
|
+
email: jgv@jonathanvingiano.com
|
64
|
+
executables:
|
65
|
+
- favebomb
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- Gemfile
|
70
|
+
- Gemfile.lock
|
71
|
+
- MIT-LICENSE
|
72
|
+
- bin/favebomb
|
73
|
+
- favebomb.gemspec
|
74
|
+
- lib/favebomb.rb
|
75
|
+
- lib/favebomb/version.rb
|
76
|
+
- readme.md
|
77
|
+
- test/unit/favebomb.rb
|
78
|
+
homepage: http://github.com/jgv/favebomb
|
79
|
+
licenses: []
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
- bin
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project: favebomb
|
99
|
+
rubygems_version: 1.8.23
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: Positive reinforcement
|
103
|
+
test_files:
|
104
|
+
- test/unit/favebomb.rb
|