phillipoertel-all_tweets_must_die 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/README +3 -0
- data/Rakefile +31 -0
- data/VERSION.yml +4 -0
- data/all_tweets_must_die.gemspec +53 -0
- data/examples/crontab +1 -0
- data/lib/argument_validator.rb +20 -0
- data/lib/hitman.rb +40 -0
- data/lib/tweet.rb +31 -0
- data/test/argument_validator_test.rb +43 -0
- data/test/fixtures/user_timeline_noradio.json +1 -0
- data/test/hitman_test.rb +51 -0
- data/test/test_helper.rb +22 -0
- data/test/tweet_test.rb +45 -0
- metadata +69 -0
data/.gitignore
ADDED
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
# for gem packaging etc. see http://github.com/technicalpickles/jeweler
|
4
|
+
require 'jeweler'
|
5
|
+
Jeweler::Tasks.new do |gemspec|
|
6
|
+
gemspec.name = "all_tweets_must_die"
|
7
|
+
gemspec.summary = "Deletes all your tweets older than a certain age"
|
8
|
+
gemspec.email = "me AT phillipoertel DOHT com"
|
9
|
+
gemspec.homepage = "https://github.com/phillipoertel/all_tweets_must_die"
|
10
|
+
gemspec.description = "Deletes all your tweets older than a certain age"
|
11
|
+
gemspec.authors = ["Phillip Oertel"]
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => [:test]
|
15
|
+
|
16
|
+
Rake::TestTask.new(:test) do |t|
|
17
|
+
t.test_files = FileList['test/**/*_test.rb']
|
18
|
+
t.verbose = true
|
19
|
+
end
|
20
|
+
|
21
|
+
task :rcov do
|
22
|
+
sh "rcov test/*test.rb --sort=coverage"
|
23
|
+
end
|
24
|
+
|
25
|
+
task :run do
|
26
|
+
require 'rubygems'
|
27
|
+
require 'login'
|
28
|
+
Dir.glob('lib/*.rb').each { |file| require file }
|
29
|
+
hitman = AllTweetsMustDie::Hitman.new(:username => @login[:user], :password => @login[:password])
|
30
|
+
hitman.run!
|
31
|
+
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{all_tweets_must_die}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Phillip Oertel"]
|
9
|
+
s.date = %q{2009-06-19}
|
10
|
+
s.description = %q{Deletes all your tweets older than a certain age}
|
11
|
+
s.email = %q{me AT phillipoertel DOHT com}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"README"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".gitignore",
|
17
|
+
"README",
|
18
|
+
"Rakefile",
|
19
|
+
"VERSION.yml",
|
20
|
+
"all_tweets_must_die.gemspec",
|
21
|
+
"examples/crontab",
|
22
|
+
"lib/argument_validator.rb",
|
23
|
+
"lib/hitman.rb",
|
24
|
+
"lib/tweet.rb",
|
25
|
+
"test/argument_validator_test.rb",
|
26
|
+
"test/fixtures/user_timeline_noradio.json",
|
27
|
+
"test/hitman_test.rb",
|
28
|
+
"test/test_helper.rb",
|
29
|
+
"test/tweet_test.rb"
|
30
|
+
]
|
31
|
+
s.has_rdoc = true
|
32
|
+
s.homepage = %q{https://github.com/phillipoertel/all_tweets_must_die}
|
33
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubygems_version = %q{1.3.2}
|
36
|
+
s.summary = %q{Deletes all your tweets older than a certain age}
|
37
|
+
s.test_files = [
|
38
|
+
"test/argument_validator_test.rb",
|
39
|
+
"test/hitman_test.rb",
|
40
|
+
"test/test_helper.rb",
|
41
|
+
"test/tweet_test.rb"
|
42
|
+
]
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
else
|
50
|
+
end
|
51
|
+
else
|
52
|
+
end
|
53
|
+
end
|
data/examples/crontab
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*/5 * * * * cd /path/to/all_tweets_must_die && rake run &> /tmp/all_tweets_must_die.log
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module AllTweetsMustDie
|
2
|
+
module ArgumentValidator
|
3
|
+
|
4
|
+
private
|
5
|
+
|
6
|
+
# fail early, don't swallow unknown arguments.
|
7
|
+
# especially useful for named parameter style argument passing
|
8
|
+
def validate_args!(valid_args, actual_args)
|
9
|
+
invalid_args = actual_args.keys - valid_args
|
10
|
+
unless invalid_args.empty?
|
11
|
+
msg = "Invalid argument(s) %s. Valid are: %s" % [format_args(invalid_args), format_args(valid_args)]
|
12
|
+
raise ArgumentError.new(msg)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def format_args(args)
|
17
|
+
args.sort { |a1, a2| a1.to_s <=> a2.to_s }.map { |a| %("#{a}") }.join(', ')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/hitman.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rest_client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require File.join(File.dirname(__FILE__), 'argument_validator')
|
6
|
+
|
7
|
+
#
|
8
|
+
# appropriate soundtracks: Miss Kittin -- Rippin Kittin; Kill Bill Vol. 1 & 2
|
9
|
+
#
|
10
|
+
module AllTweetsMustDie
|
11
|
+
class Hitman
|
12
|
+
|
13
|
+
include ArgumentValidator
|
14
|
+
|
15
|
+
attr_reader :default_tweet_lifetime, :username, :password
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
validate_args!([:lifetime, :username, :password], options)
|
19
|
+
@default_tweet_lifetime = options[:lifetime] || 12 # maximum allowed age in hours
|
20
|
+
@username = options[:username]
|
21
|
+
@password = options[:password]
|
22
|
+
end
|
23
|
+
|
24
|
+
def run!
|
25
|
+
fetch_victim_tweets.each do |tweet|
|
26
|
+
tweet.kill!(@password) unless tweet.should_live?(@default_tweet_lifetime)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def fetch_victim_tweets
|
33
|
+
auth = @password ? "#{@username}:#{@password}@" : ''
|
34
|
+
url = "http://%stwitter.com/statuses/user_timeline/%s.json" % [auth, @username]
|
35
|
+
response = RestClient.get(url)
|
36
|
+
JSON.parse(response).map { |tweet_data| Tweet.new(tweet_data) }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/lib/tweet.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module AllTweetsMustDie
|
5
|
+
class Tweet
|
6
|
+
|
7
|
+
def initialize(data)
|
8
|
+
@data = data
|
9
|
+
@data['created_at'] = Time.parse(@data['created_at'])
|
10
|
+
end
|
11
|
+
|
12
|
+
def kill!(password)
|
13
|
+
http_auth_string = "#{@data['user']['screen_name']}:#{password}@"
|
14
|
+
url = "http://%stwitter.com/statuses/destroy/%d.xml" % [http_auth_string, @data['id']]
|
15
|
+
RestClient.delete(url)
|
16
|
+
end
|
17
|
+
|
18
|
+
def should_live?(default_lifetime)
|
19
|
+
keep_hashtag = @data['text'].match(/#keep(\d+)h$/)
|
20
|
+
hours_to_live = keep_hashtag ? keep_hashtag[1].to_i : default_lifetime
|
21
|
+
maximum_age = (hours_to_live * 60 * 60)
|
22
|
+
age <= maximum_age
|
23
|
+
end
|
24
|
+
|
25
|
+
# in seconds
|
26
|
+
def age
|
27
|
+
Time.now.utc - @data['created_at']
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test/test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/argument_validator')
|
3
|
+
|
4
|
+
class MyClass
|
5
|
+
|
6
|
+
include AllTweetsMustDie::ArgumentValidator
|
7
|
+
|
8
|
+
def foo(args = {})
|
9
|
+
validate_args!([:foo, :bar], args)
|
10
|
+
"NOTHING RAISED"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
class ArgumentValidatorTest < Test::Unit::TestCase
|
16
|
+
|
17
|
+
def test_with_zero_args
|
18
|
+
assert_equal "NOTHING RAISED", MyClass.new.foo
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_with_one_valid_arg
|
22
|
+
assert_equal "NOTHING RAISED", MyClass.new.foo(:foo => 1)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_with_two_valid_args
|
26
|
+
assert_equal "NOTHING RAISED", MyClass.new.foo(:foo => 1, :bar => 'bar')
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_with_invalid_arg
|
30
|
+
ex = assert_raises(ArgumentError) { MyClass.new.foo(:baz => 1) }
|
31
|
+
assert_equal 'Invalid argument(s) "baz". Valid are: "bar", "foo"', ex.message
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_with_two_invalid_arg
|
35
|
+
ex = assert_raises(ArgumentError) { MyClass.new.foo(:baz => 1, :zed => 'dead') }
|
36
|
+
assert_equal 'Invalid argument(s) "baz", "zed". Valid are: "bar", "foo"', ex.message
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_with_valid_and_invalid_arg
|
40
|
+
ex = assert_raises(ArgumentError) { MyClass.new.foo(:foo => 1, :bar => 'bar', :baz => 1) }
|
41
|
+
assert_equal 'Invalid argument(s) "baz". Valid are: "bar", "foo"', ex.message
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
[{"text":"Ubiquitous support for landscape mode in iPhone 3.0 means bigger keyboard keys means thumb typing means I can FINALLY type quickly.","in_reply_to_status_id":null,"user":{"profile_background_color":"9AE4E8","followers_count":1769,"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"statuses_count":3220,"friends_count":272,"profile_sidebar_fill_color":"DDFFCC","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_sidebar_border_color":"BDDCAD","url":"http:\/\/project.ioni.st","screen_name":"noradio","name":"Marcel Molina","notifications":null,"favourites_count":73,"created_at":"Mon Apr 02 07:47:28 +0000 2007","protected":false,"verified":false,"profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/18156348\/jessica_tiled.jpg.jpeg","following":null,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","location":"San Francisco, CA","id":3191321,"profile_background_tile":true},"in_reply_to_user_id":null,"favorited":false,"created_at":"Fri Jun 19 06:31:54 +0000 2009","in_reply_to_screen_name":null,"id":2234681759,"truncated":false,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"text":"@rael How else would he be able to see 10 patients at once though? ;-)","in_reply_to_user_id":257,"user":{"profile_sidebar_fill_color":"DDFFCC","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","screen_name":"noradio","utc_offset":-28800,"verified":false,"profile_sidebar_border_color":"BDDCAD","notifications":null,"url":"http:\/\/project.ioni.st","name":"Marcel Molina","created_at":"Mon Apr 02 07:47:28 +0000 2007","profile_text_color":"333333","followers_count":1765,"protected":false,"statuses_count":3219,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/18156348\/jessica_tiled.jpg.jpeg","time_zone":"Pacific Time (US & Canada)","friends_count":272,"profile_link_color":"0084B4","profile_background_tile":true,"following":null,"favourites_count":73,"profile_background_color":"9AE4E8","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","location":"San Francisco, CA","id":3191321},"favorited":false,"in_reply_to_screen_name":"rael","created_at":"Thu Jun 18 23:18:04 +0000 2009","truncated":false,"id":2229855057,"in_reply_to_status_id":2229770002,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"in_reply_to_screen_name":null,"text":"Realizing that the Ying Yang Twins' Whisper Song is basically a rip of the end of Don Cherry's Brown Rice modulo raunch: http:\/\/bit.ly\/wPybS","user":{"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","screen_name":"noradio","utc_offset":-28800,"profile_sidebar_fill_color":"DDFFCC","notifications":null,"followers_count":1762,"profile_sidebar_border_color":"BDDCAD","friends_count":272,"url":"http:\/\/project.ioni.st","name":"Marcel Molina","created_at":"Mon Apr 02 07:47:28 +0000 2007","protected":false,"verified":false,"favourites_count":72,"profile_text_color":"333333","statuses_count":3218,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/18156348\/jessica_tiled.jpg.jpeg","time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","following":null,"profile_background_tile":true,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","location":"San Francisco, CA","id":3191321,"profile_background_color":"9AE4E8"},"truncated":false,"in_reply_to_status_id":null,"created_at":"Thu Jun 18 17:41:46 +0000 2009","in_reply_to_user_id":null,"favorited":false,"id":2225418746,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"text":"@bil_kleb I'm sad for your lose. It's a comfort that he passed quietly. Camping sounds, all things considered, like a calming diversion.","user":{"following":0,"statuses_count":3217,"profile_background_color":"9AE4E8","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"followers_count":1741,"profile_sidebar_fill_color":"DDFFCC","friends_count":271,"created_at":"Mon Apr 02 07:47:28 +0000 2007","profile_sidebar_border_color":"BDDCAD","url":"http:\/\/project.ioni.st","name":"Marcel Molina","verified_profile":false,"protected":false,"profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/18156348\/jessica_tiled.jpg.jpeg","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","notifications":false,"time_zone":"Pacific Time (US & Canada)","favourites_count":72,"profile_link_color":"0084B4","location":"San Francisco, CA","id":3191321,"profile_background_tile":true,"screen_name":"noradio"},"truncated":false,"in_reply_to_status_id":2210543360,"created_at":"Wed Jun 17 18:46:39 +0000 2009","in_reply_to_user_id":9579412,"favorited":false,"id":2210593900,"in_reply_to_screen_name":"bil_kleb","source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"text":"OH: \"If there is sufficient interest, I'd be pleased to lead a morning group practice whose ingredients include...tantra\" @gregpass","in_reply_to_screen_name":null,"user":{"following":null,"time_zone":"Pacific Time (US & Canada)","favourites_count":71,"profile_link_color":"0084B4","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","profile_background_tile":true,"utc_offset":-28800,"profile_background_color":"9AE4E8","verified_profile":false,"created_at":"Mon Apr 02 07:47:28 +0000 2007","profile_sidebar_fill_color":"DDFFCC","url":"http:\/\/project.ioni.st","name":"Marcel Molina","notifications":null,"protected":false,"profile_sidebar_border_color":"BDDCAD","followers_count":1732,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","friends_count":267,"profile_text_color":"333333","location":"San Francisco, CA","id":3191321,"statuses_count":3216,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/18156348\/jessica_tiled.jpg.jpeg","screen_name":"noradio"},"truncated":false,"created_at":"Tue Jun 16 22:43:25 +0000 2009","in_reply_to_status_id":null,"in_reply_to_user_id":null,"id":2198187320,"favorited":false,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"truncated":false,"text":"@atduskgreg You might not even get one if you pre-order. It's still first come first serve. Though they said they might have separate lines.","user":{"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/18156348\/jessica_tiled.jpg.jpeg","created_at":"Mon Apr 02 07:47:28 +0000 2007","notifications":null,"time_zone":"Pacific Time (US & Canada)","favourites_count":71,"profile_link_color":"0084B4","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_background_tile":true,"url":"http:\/\/project.ioni.st","name":"Marcel Molina","statuses_count":3215,"profile_background_color":"9AE4E8","protected":false,"screen_name":"noradio","followers_count":1710,"profile_sidebar_fill_color":"DDFFCC","friends_count":267,"following":null,"profile_sidebar_border_color":"BDDCAD","location":"San Francisco, CA","id":3191321,"verified_profile":false},"in_reply_to_status_id":2183644637,"created_at":"Mon Jun 15 21:56:00 +0000 2009","in_reply_to_user_id":26853,"favorited":false,"in_reply_to_screen_name":"atduskgreg","id":2183748561,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"text":"Lately, the most effective GTD apps for me are command-H and option-command-H.","user":{"following":0,"profile_sidebar_border_color":"BDDCAD","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"favourites_count":70,"followers_count":1711,"friends_count":267,"profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/18156348\/jessica_tiled.jpg.jpeg","created_at":"Mon Apr 02 07:47:28 +0000 2007","url":"http:\/\/project.ioni.st","name":"Marcel Molina","statuses_count":3214,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","protected":false,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_background_tile":true,"profile_background_color":"9AE4E8","screen_name":"noradio","verified_profile":false,"profile_sidebar_fill_color":"DDFFCC","location":"San Francisco, CA","id":3191321,"notifications":false},"truncated":false,"in_reply_to_status_id":null,"created_at":"Mon Jun 15 17:37:22 +0000 2009","in_reply_to_user_id":null,"favorited":false,"id":2180550348,"in_reply_to_screen_name":null,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"truncated":false,"in_reply_to_status_id":null,"in_reply_to_user_id":null,"user":{"utc_offset":-28800,"followers_count":1687,"screen_name":"noradio","profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","friends_count":266,"protected":false,"location":"San Francisco, CA","notifications":0,"time_zone":"Pacific Time (US & Canada)","favourites_count":69,"profile_link_color":"0084B4","name":"Marcel Molina","following":0,"profile_background_tile":false,"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","statuses_count":3213,"profile_background_color":"9AE4E8","verified_profile":false,"profile_sidebar_fill_color":"DDFFCC","created_at":"Mon Apr 02 07:47:28 +0000 2007","url":"http:\/\/project.ioni.st","id":3191321,"profile_sidebar_border_color":"BDDCAD","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg"},"favorited":false,"text":"via @netik \"This is the coolest site, ever. Real people telling their life stories. http:\/\/www.peoplesarchive.com\/ I'm watching Donald K...\"","in_reply_to_screen_name":null,"id":2159490339,"created_at":"Sun Jun 14 00:14:10 +0000 2009","source":"web"},{"text":"That a throng of completely naked cyclists just rolled by would be remarkable were this not San Francisco.","user":{"following":null,"profile_sidebar_border_color":"BDDCAD","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"favourites_count":69,"followers_count":1687,"friends_count":266,"profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","created_at":"Mon Apr 02 07:47:28 +0000 2007","url":"http:\/\/project.ioni.st","name":"Marcel Molina","statuses_count":3212,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","protected":false,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_background_tile":false,"profile_background_color":"9AE4E8","screen_name":"noradio","verified_profile":false,"profile_sidebar_fill_color":"DDFFCC","location":"San Francisco, CA","id":3191321,"notifications":null},"truncated":false,"in_reply_to_status_id":null,"created_at":"Sat Jun 13 23:44:35 +0000 2009","in_reply_to_user_id":null,"favorited":false,"id":2159223054,"in_reply_to_screen_name":null,"source":"web"},{"in_reply_to_screen_name":"liquidgecka","text":"@liquidgecka Welcome to Twitter. You've made the right choice ;-)","user":{"notifications":false,"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"profile_sidebar_border_color":"BDDCAD","favourites_count":69,"created_at":"Mon Apr 02 07:47:28 +0000 2007","followers_count":1687,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","friends_count":266,"profile_text_color":"333333","url":"http:\/\/project.ioni.st","name":"Marcel Molina","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","protected":false,"screen_name":"noradio","statuses_count":3212,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","profile_background_tile":false,"profile_background_color":"9AE4E8","following":false,"location":"San Francisco, CA","id":3191321,"verified_profile":false,"profile_sidebar_fill_color":"DDFFCC"},"created_at":"Sat Jun 13 23:42:31 +0000 2009","truncated":false,"in_reply_to_status_id":null,"in_reply_to_user_id":34270047,"favorited":false,"id":2159204798,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"truncated":false,"text":"Be aprised: The frittata at Serpentine is the best brunch I've had since moving to SF. Better than e.g. Universal. What's your best brunch?","user":{"followers_count":1684,"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","created_at":"Mon Apr 02 07:47:28 +0000 2007","friends_count":265,"notifications":false,"time_zone":"Pacific Time (US & Canada)","favourites_count":69,"profile_link_color":"0084B4","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_background_tile":false,"url":"http:\/\/project.ioni.st","name":"Marcel Molina","statuses_count":3210,"profile_background_color":"9AE4E8","protected":false,"screen_name":"noradio","verified_profile":false,"profile_sidebar_fill_color":"DDFFCC","following":0,"profile_sidebar_border_color":"BDDCAD","location":"San Francisco, CA","id":3191321},"in_reply_to_status_id":null,"created_at":"Sat Jun 13 21:03:38 +0000 2009","in_reply_to_user_id":null,"favorited":false,"in_reply_to_screen_name":null,"id":2157728641,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"in_reply_to_screen_name":"nodler","text":"@nodler when I was seven I literally day dreamed of living in a bathysphere though I didn't know it had a name.","user":{"notifications":null,"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"profile_sidebar_border_color":"BDDCAD","favourites_count":69,"followers_count":1676,"friends_count":265,"profile_text_color":"333333","url":"http:\/\/project.ioni.st","name":"Marcel Molina","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","created_at":"Mon Apr 02 07:47:28 +0000 2007","protected":false,"statuses_count":3209,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_background_tile":false,"profile_background_color":"9AE4E8","screen_name":"noradio","following":null,"location":"San Francisco, CA","id":3191321,"verified_profile":false,"profile_sidebar_fill_color":"DDFFCC"},"truncated":false,"in_reply_to_status_id":2149720133,"created_at":"Sat Jun 13 03:34:24 +0000 2009","in_reply_to_user_id":10171902,"favorited":false,"id":2149748525,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"in_reply_to_user_id":null,"text":"OH: \"Follow these rules and you'll find success not only in the job market, but also the meat market.\"","user":{"profile_background_tile":false,"friends_count":265,"description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"profile_background_color":"9AE4E8","favourites_count":69,"created_at":"Mon Apr 02 07:47:28 +0000 2007","profile_sidebar_fill_color":"DDFFCC","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","url":"http:\/\/project.ioni.st","name":"Marcel Molina","statuses_count":3208,"profile_sidebar_border_color":"BDDCAD","protected":false,"screen_name":"noradio","profile_text_color":"333333","following":null,"verified_profile":false,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","followers_count":1659,"location":"San Francisco, CA","id":3191321,"notifications":null,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4"},"favorited":false,"created_at":"Fri Jun 12 20:27:09 +0000 2009","in_reply_to_screen_name":null,"truncated":false,"in_reply_to_status_id":null,"id":2136227015,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"text":"How to butcher a pig: http:\/\/bit.ly\/QJVCd\n. The Boston Butt!!!","user":{"profile_sidebar_border_color":"BDDCAD","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","verified_profile":false,"utc_offset":-28800,"profile_text_color":"333333","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","url":"http:\/\/project.ioni.st","name":"Marcel Molina","notifications":false,"time_zone":"Pacific Time (US & Canada)","favourites_count":69,"created_at":"Mon Apr 02 07:47:28 +0000 2007","profile_link_color":"0084B4","protected":false,"screen_name":"noradio","profile_background_tile":false,"statuses_count":3207,"profile_background_color":"9AE4E8","followers_count":1650,"following":0,"friends_count":265,"profile_sidebar_fill_color":"DDFFCC","location":"San Francisco, CA","id":3191321},"truncated":false,"in_reply_to_status_id":null,"created_at":"Fri Jun 12 07:20:25 +0000 2009","in_reply_to_user_id":null,"favorited":false,"id":2128646883,"in_reply_to_screen_name":null,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"text":"@stop What a precious child. Her gaze has the intensity of someone fated for greatness.","user":{"profile_sidebar_border_color":"BDDCAD","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"favourites_count":69,"verified_profile":false,"created_at":"Mon Apr 02 07:47:28 +0000 2007","screen_name":"noradio","notifications":null,"profile_text_color":"333333","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","url":"http:\/\/project.ioni.st","name":"Marcel Molina","time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","protected":false,"profile_background_tile":false,"followers_count":1650,"profile_background_color":"9AE4E8","friends_count":265,"following":null,"statuses_count":3206,"profile_sidebar_fill_color":"DDFFCC","location":"San Francisco, CA","id":3191321},"truncated":false,"created_at":"Fri Jun 12 07:12:44 +0000 2009","in_reply_to_status_id":2127317239,"in_reply_to_user_id":949521,"favorited":false,"id":2128596354,"in_reply_to_screen_name":"stop","source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"text":"@drawohara At first I read 'homomorphic encryption' as 'homoerotic encryption'. Was confused.","in_reply_to_user_id":17058191,"user":{"favourites_count":69,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"profile_sidebar_fill_color":"DDFFCC","created_at":"Mon Apr 02 07:47:28 +0000 2007","screen_name":"noradio","profile_sidebar_border_color":"BDDCAD","url":"http:\/\/project.ioni.st","name":"Marcel Molina","verified_profile":false,"protected":false,"profile_text_color":"333333","statuses_count":3205,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","followers_count":1644,"notifications":null,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","following":null,"profile_background_tile":false,"friends_count":265,"location":"San Francisco, CA","id":3191321,"profile_background_color":"9AE4E8"},"created_at":"Fri Jun 12 00:12:53 +0000 2009","favorited":false,"in_reply_to_screen_name":"drawohara","truncated":false,"id":2124216812,"in_reply_to_status_id":2124151749,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"truncated":false,"text":"@vl You are an \"extraordinary alien\" ;-)","user":{"verified_profile":false,"notifications":null,"time_zone":"Pacific Time (US & Canada)","favourites_count":68,"profile_link_color":"0084B4","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","profile_background_tile":false,"utc_offset":-28800,"statuses_count":3204,"profile_background_color":"9AE4E8","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","profile_sidebar_fill_color":"DDFFCC","url":"http:\/\/project.ioni.st","name":"Marcel Molina","created_at":"Mon Apr 02 07:47:28 +0000 2007","protected":false,"screen_name":"noradio","profile_sidebar_border_color":"BDDCAD","followers_count":1643,"friends_count":265,"following":null,"profile_text_color":"333333","location":"San Francisco, CA","id":3191321,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg"},"in_reply_to_status_id":2122988543,"in_reply_to_user_id":760892,"created_at":"Thu Jun 11 22:51:54 +0000 2009","favorited":false,"in_reply_to_screen_name":"vl","id":2123331673,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"truncated":false,"text":"@objo Anything written by @sstephenson (http:\/\/github.com\/sstephenson).","user":{"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0084B4","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","profile_background_tile":false,"utc_offset":-28800,"profile_background_color":"9AE4E8","verified_profile":false,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","notifications":null,"profile_sidebar_fill_color":"DDFFCC","url":"http:\/\/project.ioni.st","name":"Marcel Molina","created_at":"Mon Apr 02 07:47:28 +0000 2007","protected":false,"screen_name":"noradio","profile_sidebar_border_color":"BDDCAD","followers_count":1631,"friends_count":264,"following":null,"profile_text_color":"333333","location":"San Francisco, CA","id":3191321,"statuses_count":3203,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/17589558\/512719047_83c871d09e_b.jpg.jpeg","favourites_count":68},"in_reply_to_status_id":2118859040,"in_reply_to_user_id":1315011,"created_at":"Thu Jun 11 17:06:09 +0000 2009","favorited":false,"in_reply_to_screen_name":"objo","id":2119253001,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"in_reply_to_status_id":null,"text":"I'm trilingual and often times borderline incoherent in conversation. It all makes sense now: http:\/\/bit.ly\/18yTtZ","user":{"profile_background_color":"9ae4e8","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"followers_count":1629,"created_at":"Mon Apr 02 07:47:28 +0000 2007","profile_sidebar_fill_color":"e0ff92","screen_name":"noradio","friends_count":264,"statuses_count":3202,"profile_sidebar_border_color":"87bc44","url":"http:\/\/project.ioni.st","name":"Marcel Molina","favourites_count":68,"protected":false,"profile_text_color":"000000","verified_profile":false,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/2467381\/elephants.jpg","following":null,"notifications":null,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0000ff","location":"San Francisco, CA","id":3191321,"profile_background_tile":false},"in_reply_to_user_id":null,"created_at":"Thu Jun 11 05:53:02 +0000 2009","favorited":false,"in_reply_to_screen_name":null,"truncated":false,"id":2113864022,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"},{"in_reply_to_status_id":2112786531,"text":"@rsarver Man that's terrible. I've gotten 2 windows smashed in the last few months over in Oakland. Have fully learned my lesson...","user":{"profile_background_color":"9ae4e8","description":"Engineer at Twitter, retired Rails Core member, co-author of iPhone SDK Development and burgeoning Scala enthusiast.","utc_offset":-28800,"followers_count":1627,"profile_sidebar_fill_color":"e0ff92","friends_count":263,"profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53473799\/marcel-euro-rails-conf_normal.jpg","statuses_count":3201,"profile_sidebar_border_color":"87bc44","url":"http:\/\/project.ioni.st","name":"Marcel Molina","favourites_count":68,"created_at":"Mon Apr 02 07:47:28 +0000 2007","protected":false,"screen_name":"noradio","profile_text_color":"000000","verified_profile":false,"profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/2467381\/elephants.jpg","following":null,"notifications":null,"time_zone":"Pacific Time (US & Canada)","profile_link_color":"0000ff","location":"San Francisco, CA","id":3191321,"profile_background_tile":false},"in_reply_to_user_id":795649,"favorited":false,"created_at":"Thu Jun 11 04:02:40 +0000 2009","in_reply_to_screen_name":"rsarver","truncated":false,"id":2112873019,"source":"<a href=\"http:\/\/www.atebits.com\/\">Tweetie<\/a>"}]
|
data/test/hitman_test.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test/test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/hitman')
|
3
|
+
|
4
|
+
class InitializationTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include AllTweetsMustDie
|
7
|
+
|
8
|
+
def test_should_initialize_tweet_lifetime_to_12h_if_none_given
|
9
|
+
killer = Hitman.new
|
10
|
+
assert_equal 12, killer.default_tweet_lifetime
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_accept_different_tweet_lifetime
|
14
|
+
killer = Hitman.new(:lifetime => 42)
|
15
|
+
assert_equal 42, killer.default_tweet_lifetime
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_should_accept_and_store_username_and_password
|
19
|
+
killer = Hitman.new(:username => 'phil76', :password => 'foo')
|
20
|
+
assert_equal 'phil76', killer.username
|
21
|
+
assert_equal 'foo', killer.password
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
class RunTest < Test::Unit::TestCase
|
27
|
+
|
28
|
+
include AllTweetsMustDie
|
29
|
+
include TweetFixtureProvider
|
30
|
+
|
31
|
+
def test_request_the_correct_users_timeline_when_updates_are_public
|
32
|
+
url = "http://noradio:foo@twitter.com/statuses/user_timeline/noradio.json"
|
33
|
+
RestClient.expects(:get).with(url).returns("{}")
|
34
|
+
Hitman.new(:username => 'noradio', :password => 'foo').run!
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_request_the_correct_users_timeline_when_updates_are_protected
|
38
|
+
url = "http://twitter.com/statuses/user_timeline/noradio.json"
|
39
|
+
RestClient.expects(:get).with(url).returns("{}")
|
40
|
+
Hitman.new(:username => 'noradio').run!
|
41
|
+
end
|
42
|
+
|
43
|
+
# TODO decouple from implementation and make more specific
|
44
|
+
def test_should_kill_tweets_older_than_allowed
|
45
|
+
# fix the current time so we can operate on the canned tweets in the fixture
|
46
|
+
Time.stubs(:now).returns(Time.parse("Fri Jun 19 14:23:07 +0200 2009"))
|
47
|
+
RestClient.stubs(:get).returns(noradios_tweets_as_json)
|
48
|
+
Tweet.any_instance.expects(:kill!).times(19) # 20 tweets in fixture. all but the latest tweets are older than 12h.
|
49
|
+
Hitman.new(:username => 'noradio').run!
|
50
|
+
end
|
51
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'mocha'
|
4
|
+
require 'redgreen' unless ENV['TM_FILENAME']
|
5
|
+
|
6
|
+
require 'rest_client'
|
7
|
+
require 'json'
|
8
|
+
require 'time'
|
9
|
+
|
10
|
+
module TweetFixtureProvider
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def valid_tweet_data(attributes = {})
|
15
|
+
tweets = JSON.parse(noradios_tweets_as_json)
|
16
|
+
tweets[0].merge(attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
def noradios_tweets_as_json
|
20
|
+
File.read(File.join(File.dirname(__FILE__), '../test/fixtures/user_timeline_noradio.json'))
|
21
|
+
end
|
22
|
+
end
|
data/test/tweet_test.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test/test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/tweet')
|
3
|
+
|
4
|
+
class ShouldLiveTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include AllTweetsMustDie
|
7
|
+
include TweetFixtureProvider
|
8
|
+
|
9
|
+
def test_should_live_if_tweet_is_6h_old_and_default_lifetime_is_12h
|
10
|
+
data = valid_tweet_data('created_at' => (Time.now - (6 * (60 * 60))).to_s, 'text' => 'Hello World')
|
11
|
+
default_lifetime = 12
|
12
|
+
assert_equal true, Tweet.new(data).should_live?(default_lifetime)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_die_if_tweet_is_24h_old_and_default_lifetime_is_12h
|
16
|
+
data = valid_tweet_data('created_at' => (Time.now - (24 * (60 * 60))).to_s, 'text' => 'Hello World')
|
17
|
+
default_lifetime = 12
|
18
|
+
assert_equal false, Tweet.new(data).should_live?(default_lifetime)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_live_if_tweet_is_20h_old_and_has_hashtag_with_keep24h
|
22
|
+
data = valid_tweet_data('created_at' => (Time.now - (20 * (60 * 60))).to_s, 'text' => 'Hello World #keep24h')
|
23
|
+
default_lifetime = 12
|
24
|
+
assert_equal true, Tweet.new(data).should_live?(default_lifetime)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_die_if_tweet_is_8h_old_and_has_hashtag_with_keep6h
|
28
|
+
data = valid_tweet_data('created_at' => (Time.now - (8 * (60 * 60))).to_s, 'text' => 'Hello World #keep6h')
|
29
|
+
default_lifetime = 12
|
30
|
+
assert_equal false, Tweet.new(data).should_live?(default_lifetime)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
class KillTest < Test::Unit::TestCase
|
37
|
+
|
38
|
+
include AllTweetsMustDie
|
39
|
+
include TweetFixtureProvider
|
40
|
+
|
41
|
+
def test_should_call_the_correct_url
|
42
|
+
RestClient.expects(:delete).with('http://noradio:noradios_password@twitter.com/statuses/destroy/42.xml')
|
43
|
+
Tweet.new(valid_tweet_data('id' => 42)).kill!('noradios_password')
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: phillipoertel-all_tweets_must_die
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Phillip Oertel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-19 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Deletes all your tweets older than a certain age
|
17
|
+
email: me AT phillipoertel DOHT com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- README
|
27
|
+
- Rakefile
|
28
|
+
- VERSION.yml
|
29
|
+
- all_tweets_must_die.gemspec
|
30
|
+
- examples/crontab
|
31
|
+
- lib/argument_validator.rb
|
32
|
+
- lib/hitman.rb
|
33
|
+
- lib/tweet.rb
|
34
|
+
- test/argument_validator_test.rb
|
35
|
+
- test/fixtures/user_timeline_noradio.json
|
36
|
+
- test/hitman_test.rb
|
37
|
+
- test/test_helper.rb
|
38
|
+
- test/tweet_test.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: https://github.com/phillipoertel/all_tweets_must_die
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.2.0
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Deletes all your tweets older than a certain age
|
65
|
+
test_files:
|
66
|
+
- test/argument_validator_test.rb
|
67
|
+
- test/hitman_test.rb
|
68
|
+
- test/test_helper.rb
|
69
|
+
- test/tweet_test.rb
|