twog 0.3.0 → 0.3.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/LICENSE +2 -0
- data/README.textile +33 -8
- data/Rakefile +1 -0
- data/VERSION.yml +1 -1
- data/bin/twog +36 -14
- data/lib/twog.rb +31 -21
- data/lib/twog/blog_posts_handler.rb +9 -7
- data/lib/twog/post.rb +31 -0
- data/lib/twog/rss_entry_to_twog_post_mapper.rb +7 -0
- data/lib/twog/rss_parser.rb +11 -9
- data/lib/twog/twitter_handler.rb +32 -44
- data/spec/blog_posts_handler_spec.rb +11 -5
- data/spec/post_spec.rb +74 -0
- data/spec/rss_entry_to_twog_post_mapper_spec.rb +32 -0
- data/spec/rss_parser_spec.rb +4 -4
- data/spec/twitter_handler_spec.rb +3 -3
- data/spec/twog_spec.rb +11 -12
- data/twog.gemspec +11 -2
- metadata +23 -3
data/LICENSE
CHANGED
data/README.textile
CHANGED
@@ -1,25 +1,40 @@
|
|
1
|
-
h1.
|
1
|
+
h1. Twog
|
2
|
+
|
3
|
+
By Jason Meridth
|
4
|
+
|
5
|
+
Twog is a simple application that parses an RSS feed and will tweet any posts it hasn't already tweeted. Once you obtain OAuth access to a twitter account and provide it in the configuration and run Twog, it will tweet a prefix, your blog title, and a URL of the post. There are also options of using Bit.ly for URL shortening and you can install Twog as a cron job for automated polling.
|
2
6
|
|
3
7
|
h2. Install
|
4
8
|
|
5
9
|
sudo gem install twog
|
6
10
|
|
7
|
-
h2. OAuth
|
11
|
+
h2. Writing to Twitter With OAuth
|
12
|
+
|
13
|
+
Please read "this":http://www.lostechies.com/blogs/jason_meridth/archive/2010/04/05/oauth.aspx if you want to know how to get your Twitter OAuth consumer key/secret and access token/secret.
|
8
14
|
|
9
|
-
Please read "this":http://blog.jasonmeridth.com/2010/04/02/oauth.html if you want to know how to get your Twitter OAuth consumer key/secret and access token/secret.
|
10
15
|
One you have those, run the command:
|
11
16
|
|
12
17
|
bq. twog --conf
|
13
18
|
|
14
19
|
and a hidden configuration file will be created in the your home folder (~/.twog/conf.yaml). Once there, please fill it out with the information necessary to use this tool.
|
15
20
|
|
16
|
-
h2.
|
21
|
+
h2. Seeing What Will Be Tweeted
|
22
|
+
|
23
|
+
To see what will be Tweeted before it is, type:
|
24
|
+
|
25
|
+
bq. twog -o
|
26
|
+
|
27
|
+
or
|
28
|
+
|
29
|
+
bq. twog --output
|
30
|
+
|
31
|
+
h2. Shortening Blog Post URLs With Bitly API
|
17
32
|
|
18
33
|
In order to use Bitly for URL shortening, you'll need to go to http://bit.ly and click the "Sign Up":http://bit.ly/account/register?rd=/ link on the top right and get an account. Once you are logged-in you click the "Account":http://bit.ly/account link in the same top right area. You will see your API Key in the middle of the page.
|
19
34
|
|
20
35
|
Put your bit.ly username and api key into the ~/.twog/conf.yaml file to be used in the code.
|
21
36
|
|
22
|
-
h2.
|
37
|
+
h2. Automating Polling With Cron
|
23
38
|
|
24
39
|
To install twog as a crontab job, run the command:
|
25
40
|
|
@@ -33,14 +48,24 @@ bq. twog --cronrm
|
|
33
48
|
|
34
49
|
"Crontab Info":http://www.unixgeeks.org/security/newbie/unix/cron-1.html for all my non-*nix bretheren.
|
35
50
|
|
51
|
+
h2. Runtime Dependencies
|
52
|
+
|
53
|
+
* TwitterOauth: Writes tweets to Twitter (Ruby)
|
54
|
+
* Whenever: Sets up cron jobs (Ruby)
|
55
|
+
* Bitly: Shortens URLs (Ruby)
|
56
|
+
|
57
|
+
h2. Developer Dependencies
|
58
|
+
|
59
|
+
* RSpec: Test and Mocking framework (Ruby)
|
60
|
+
|
36
61
|
h2. TODO
|
37
62
|
|
38
|
-
Please check the
|
63
|
+
Please check the "issues":http://github.com/armmer/twog/issues on Github for future features or bugs that need to be fixed
|
39
64
|
|
40
|
-
h2.
|
65
|
+
h2. Contributors
|
41
66
|
|
67
|
+
Matt Dietz ("cerberus98":http://github.com/cerberus98) special thanks
|
42
68
|
Chris MacGown ("ChristopherMacGown":http://github.com/ChristopherMacGown)
|
43
|
-
Matt Dietz ("cerberus98":http://github.com/cerberus98)
|
44
69
|
Paul Voccio ("pvo":http://github.com/pvo)
|
45
70
|
Joe Ocampo ("agilejoe":http://github.com/agilejoe)
|
46
71
|
|
data/Rakefile
CHANGED
@@ -41,6 +41,7 @@ begin
|
|
41
41
|
s.add_dependency('twitter_oauth', '>= 0.3.3')
|
42
42
|
s.add_dependency('bitly', '>= 0.4.0')
|
43
43
|
s.add_dependency('whenever', '>= 0.4.1')
|
44
|
+
s.add_dependency('activesupport', '>= 2.3.5')
|
44
45
|
end
|
45
46
|
rescue LoadError
|
46
47
|
puts "Jeweler not available. Install it with: sudo gem install jeweler --version '>= 0.11.0'"
|
data/VERSION.yml
CHANGED
data/bin/twog
CHANGED
@@ -8,6 +8,8 @@ require 'optparse'
|
|
8
8
|
require 'whenever'
|
9
9
|
require 'fileutils'
|
10
10
|
|
11
|
+
include Twog::Twog
|
12
|
+
|
11
13
|
twog_dir = "#{ENV['HOME']}/.twog"
|
12
14
|
FileUtils.mkdir_p twog_dir unless File.exists?(twog_dir)
|
13
15
|
twog_cron_schedule_file = "#{twog_dir}/schedule.rb"
|
@@ -16,17 +18,21 @@ twog_cron_identifier = "twog"
|
|
16
18
|
legacy_conf_file_name = "#{ENV['HOME']}/.twog.yaml"
|
17
19
|
twog_conf_file = "#{twog_dir}/conf.yaml"
|
18
20
|
|
21
|
+
def help
|
22
|
+
puts "Invalid options. Run `twog --help` for assistance."
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_conf(conf)
|
26
|
+
raise "please run 'twog --conf' to create the #{conf} file" unless File.exists?(conf)
|
27
|
+
YAML.load_file(conf)
|
28
|
+
end
|
29
|
+
|
19
30
|
options = {}
|
20
31
|
opts = OptionParser.new do |opts|
|
21
32
|
opts.banner = "Twog is a tool to tweet blog posts"
|
22
33
|
|
23
|
-
opts.on_tail("-h","-?","--help", "Display help") do
|
24
|
-
puts opts
|
25
|
-
exit 0
|
26
|
-
end
|
27
|
-
|
28
34
|
opts.on("-v", "--version", "Display current version") do
|
29
|
-
puts "Twog " +
|
35
|
+
puts "Twog " + version
|
30
36
|
exit 0
|
31
37
|
end
|
32
38
|
|
@@ -37,13 +43,14 @@ opts = OptionParser.new do |opts|
|
|
37
43
|
command "twog"
|
38
44
|
end
|
39
45
|
EOS
|
40
|
-
|
46
|
+
|
41
47
|
answer = ""
|
42
48
|
if File.exists?(twog_cron_schedule_file)
|
43
49
|
puts "Cron schedule file (#{twog_cron_schedule_file}) already exists. Overwrite? [Y/n]"
|
44
50
|
answer = gets
|
45
51
|
end
|
46
52
|
|
53
|
+
File.open(twog_cron_schedule_log, 'w') {|f| f.write("") } unless File.exists?(twog_cron_schedule_log)
|
47
54
|
File.open(twog_cron_schedule_file, 'w') {|f| f.write(twog_cron_schedule_content) } if ["Y","y",""].include?(answer.chomp)
|
48
55
|
|
49
56
|
cron_options = {:file => twog_cron_schedule_file, :identifier => twog_cron_identifier, :update => true}
|
@@ -59,7 +66,14 @@ opts = OptionParser.new do |opts|
|
|
59
66
|
exit 0
|
60
67
|
end
|
61
68
|
|
62
|
-
opts.on("--
|
69
|
+
opts.on("-o", "--output", "View the blog posts that will be tweeted") do
|
70
|
+
posts = get_posts_to_tweet(get_conf(twog_conf_file))
|
71
|
+
puts "No posts to tweet" if posts.length == 0
|
72
|
+
posts.each {|post| puts "#{post.title} (#{Time.parse(post.date.to_s)})"; puts "#{post.link}" }
|
73
|
+
exit 0
|
74
|
+
end
|
75
|
+
|
76
|
+
opts.on("-c", "--conf", "Create default conf file") do
|
63
77
|
conf_file_contents = <<-EOS
|
64
78
|
rss_feed: 'http://url.com/feed.rss'
|
65
79
|
consumer_key: 'consumer key'
|
@@ -81,18 +95,26 @@ opts = OptionParser.new do |opts|
|
|
81
95
|
puts "Default configuration file created at #{twog_conf_file}"
|
82
96
|
exit 0
|
83
97
|
end
|
98
|
+
|
99
|
+
opts.on("-h","-?","--help", "Display help") do
|
100
|
+
puts opts
|
101
|
+
exit 0
|
102
|
+
end
|
84
103
|
end
|
85
104
|
|
86
105
|
# Read command line options into `options` hash
|
87
|
-
|
106
|
+
begin
|
107
|
+
opts.parse!
|
108
|
+
rescue OptionParser::MissingArgument => e
|
109
|
+
puts e.message
|
110
|
+
help
|
111
|
+
exit 0
|
112
|
+
end
|
88
113
|
|
89
114
|
# Get args from the command line
|
90
115
|
if ARGV.size > 1
|
91
|
-
|
116
|
+
help
|
92
117
|
exit(1)
|
93
118
|
end
|
94
119
|
|
95
|
-
|
96
|
-
conf = YAML.load_file(twog_conf_file)
|
97
|
-
|
98
|
-
Twog.run(conf)
|
120
|
+
run(get_conf(twog_conf_file))
|
data/lib/twog.rb
CHANGED
@@ -9,32 +9,42 @@ require 'bitly'
|
|
9
9
|
|
10
10
|
# internal requires
|
11
11
|
require 'twog/rss_parser'
|
12
|
+
require 'twog/rss_entry_to_twog_post_mapper'
|
12
13
|
require 'twog/blog_posts_handler'
|
13
14
|
require 'twog/twitter_handler'
|
15
|
+
require 'twog/post'
|
14
16
|
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
module Twog
|
19
|
+
module Twog
|
20
|
+
include RssParser
|
21
|
+
include RssEntryToTwogPostMapper
|
22
|
+
include BlogPostsHandler
|
23
|
+
include TwitterHandler
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
25
|
+
def run(conf)
|
26
|
+
posts = get_posts_to_tweet(conf)
|
27
|
+
return unless posts && posts.length > 0
|
28
|
+
bitly = get_bitly_from(conf)
|
29
|
+
tweet(posts, conf, bitly)
|
30
|
+
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
def get_posts_to_tweet(conf)
|
33
|
+
posts = parse_feed(conf['rss_feed'])
|
34
|
+
posts = map(posts)
|
35
|
+
posts = get_new_blog_posts(posts, conf['last_blog_post_tweeted'])
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_bitly_from(conf)
|
39
|
+
bitly_username = conf['bitly_username']
|
40
|
+
bitly_api_key = conf['bitly_api_key']
|
41
|
+
return nil unless (bitly_username && bitly_api_key)
|
42
|
+
Bitly.new(bitly_username, bitly_api_key)
|
43
|
+
end
|
44
|
+
|
45
|
+
def version
|
46
|
+
yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
|
47
|
+
"#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
|
48
|
+
end
|
39
49
|
end
|
40
50
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module Twog
|
2
|
+
module BlogPostsHandler
|
3
|
+
def get_new_blog_posts(posts, last_blog_post_tweeted)
|
4
|
+
return [] unless posts && posts.length > 0
|
5
|
+
return posts unless last_blog_post_tweeted
|
6
|
+
new_posts = posts.reject do |post|
|
7
|
+
Time.parse(post.date.to_s) <= Time.parse(last_blog_post_tweeted.to_s)
|
8
|
+
end
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
data/lib/twog/post.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Twog
|
2
|
+
class Post
|
3
|
+
def initialize(post)
|
4
|
+
@post = post
|
5
|
+
end
|
6
|
+
|
7
|
+
def link
|
8
|
+
@post.link.respond_to?('href') ? @post.link.href : @post.link
|
9
|
+
end
|
10
|
+
|
11
|
+
def date
|
12
|
+
@post.respond_to?('updated') ? @post.updated.content : @post.pubDate
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
@post.title.respond_to?('content') ? @post.title.content : @post.title
|
17
|
+
end
|
18
|
+
|
19
|
+
def <=>(other_post)
|
20
|
+
this_time = Time.parse(self.date.to_s)
|
21
|
+
other_time = Time.parse(other_post.date.to_s)
|
22
|
+
if this_time < other_time
|
23
|
+
-1
|
24
|
+
elsif this_time > other_time
|
25
|
+
1
|
26
|
+
else
|
27
|
+
0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/twog/rss_parser.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Twog
|
2
|
+
module RssParser
|
3
|
+
def parse_feed(rss_feed_url)
|
4
|
+
raise Exception.new('RSS feed missing') unless rss_feed_url
|
5
|
+
rss = RSS::Parser.parse(get_content(rss_feed_url), false)
|
6
|
+
rss.items
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def get_content(rss_feed_url)
|
10
|
+
open(rss_feed_url) do |f|
|
11
|
+
f.read
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
data/lib/twog/twitter_handler.rb
CHANGED
@@ -1,51 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
module Twog
|
2
|
+
module TwitterHandler
|
3
|
+
def tweet(posts, conf, bitly)
|
4
|
+
return unless posts && posts.length > 0
|
5
|
+
raise Exception.new('OAuth Consumer Key missing') unless conf['consumer_key']
|
6
|
+
raise Exception.new('OAuth Consumer Secret missing') unless conf['consumer_secret']
|
7
|
+
raise Exception.new('OAuth Access Token missing') unless conf['access_token']
|
8
|
+
raise Exception.new('OAuth Access Secret missing') unless conf['access_secret']
|
9
|
+
posts.sort.each do |post|
|
10
|
+
link = bitly ? bitly.shorten(post.link).short_url : item.link
|
11
|
+
use_twitter_oauth(post, link, conf)
|
12
|
+
update_config_file_with_latest_tweet_date(post.date.to_s, conf)
|
13
|
+
end
|
11
14
|
end
|
12
|
-
end
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
update_config_file_with_latest_tweet_date(item.updated.content.to_s, conf)
|
16
|
+
def use_twitter_oauth(post, link, conf)
|
17
|
+
client = TwitterOAuth::Client.new(
|
18
|
+
:consumer_key => conf['consumer_key'],
|
19
|
+
:consumer_secret => conf['consumer_secret'],
|
20
|
+
:token => conf['access_token'],
|
21
|
+
:secret => conf['access_secret']
|
22
|
+
)
|
23
|
+
raise Exception.new('TwitterOAuth unauthorized') unless client.authorized?
|
24
|
+
text = ensure_text_is_of_length(140, post.title, link)
|
25
|
+
client.update(text)
|
26
26
|
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def use_twitter_oauth(item, link, conf)
|
30
|
-
client = TwitterOAuth::Client.new(
|
31
|
-
:consumer_key => conf['consumer_key'],
|
32
|
-
:consumer_secret => conf['consumer_secret'],
|
33
|
-
:token => conf['access_token'],
|
34
|
-
:secret => conf['access_secret']
|
35
|
-
)
|
36
|
-
raise Exception.new('TwitterOAuth unauthorized') unless client.authorized?
|
37
|
-
text = ensure_text_is_of_length(140, item.title.content, link)
|
38
|
-
client.update(text)
|
39
|
-
end
|
40
27
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
28
|
+
def ensure_text_is_of_length(length, title, link)
|
29
|
+
blogged = "blogged:"
|
30
|
+
title = title[0,(length-((" "*2).length+blogged.length+link.length))]
|
31
|
+
[blogged, title, link].join(' ')
|
32
|
+
end
|
46
33
|
|
47
|
-
|
48
|
-
|
49
|
-
|
34
|
+
def update_config_file_with_latest_tweet_date(last_blog_post_tweeted, conf)
|
35
|
+
conf['last_blog_post_tweeted'] = last_blog_post_tweeted
|
36
|
+
File.open("#{ENV['HOME']}/.twog/conf.yaml","w") { |out| out.write(conf.to_yaml) }
|
37
|
+
end
|
50
38
|
end
|
51
39
|
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
2
|
|
3
|
-
describe BlogPostsHandler do
|
3
|
+
describe Twog::BlogPostsHandler do
|
4
4
|
include TwogSpecHelper
|
5
|
-
include BlogPostsHandler
|
5
|
+
include Twog::BlogPostsHandler
|
6
6
|
|
7
7
|
before(:each) do
|
8
|
-
|
9
|
-
|
10
|
-
@posts = [entry]
|
8
|
+
post = Twog::Post.new(stub('', :pubDate => Time.now, :link => 'http://tinyurl.com'))
|
9
|
+
@posts = [post]
|
11
10
|
@last_blog_post_tweeted = test_conf['last_blog_post_tweeted']
|
12
11
|
end
|
13
12
|
|
@@ -30,4 +29,11 @@ describe BlogPostsHandler do
|
|
30
29
|
posts = get_new_blog_posts(@posts, nil)
|
31
30
|
posts.length.should == 1
|
32
31
|
end
|
32
|
+
|
33
|
+
it "should return zero posts if the date is older than the last blog post date tweeted" do
|
34
|
+
post = Twog::Post.new(stub('', :pubDate => (Date.parse(@last_blog_post_tweeted.to_s) - 10).to_s, :link => 'http://tinyurl.com'))
|
35
|
+
@posts = [post]
|
36
|
+
posts = get_new_blog_posts(@posts, @last_blog_post_tweeted)
|
37
|
+
posts.length.should == 0
|
38
|
+
end
|
33
39
|
end
|
data/spec/post_spec.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe Twog::Post do
|
4
|
+
context "when rss entry has updated and link.href" do
|
5
|
+
before(:each) do
|
6
|
+
updated = stub('update', :content => '2010-04-02T01:00:00-06:00')
|
7
|
+
link = stub('link', :href => 'http://tinyurl.com')
|
8
|
+
@post = stub('post', :updated => updated, :link => link)
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return a link" do
|
13
|
+
|
14
|
+
twog_post = Twog::Post.new(@post)
|
15
|
+
|
16
|
+
twog_post.link.should == "http://tinyurl.com"
|
17
|
+
twog_post.date.should == "2010-04-02T01:00:00-06:00"
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
## RE-WRITE TO BE MORE RUBYISH
|
22
|
+
##
|
23
|
+
it "should sort multiple posts" do
|
24
|
+
unsorted = (1..10).sort_by { rand }.collect do |i|
|
25
|
+
updated = stub('update', :content => (Time.now + (60*60*24*i)).to_s)
|
26
|
+
link = stub('link', :href => 'http://tinyurl.com')
|
27
|
+
post = stub('post', :updated => updated, :link => link)
|
28
|
+
Twog::Post.new(post)
|
29
|
+
end
|
30
|
+
sorted = unsorted.sort!
|
31
|
+
sorted.length.should == 10
|
32
|
+
|
33
|
+
time = Time.now
|
34
|
+
sorted.each do |p|
|
35
|
+
p_time = Time.parse(p.date.to_s)
|
36
|
+
p_time.should be > time
|
37
|
+
time = p_time
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when rss entry has pubDate and link" do
|
43
|
+
before(:each) do
|
44
|
+
@post = stub('post', :pubDate => '2010-04-02T01:00:00-06:00', :link => 'http://tinyurl.com')
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return a link" do
|
48
|
+
twog_post = Twog::Post.new(@post)
|
49
|
+
|
50
|
+
twog_post.link.should == "http://tinyurl.com"
|
51
|
+
twog_post.date.should == "2010-04-02T01:00:00-06:00"
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
## RE-WRITE TO BE MORE RUBYISH
|
56
|
+
##
|
57
|
+
it "should sort multiple posts again" do
|
58
|
+
unsorted = (1..10).sort_by { rand }.collect do |i|
|
59
|
+
post = stub('post', :pubDate => (Time.now + (60*60*24*i)).to_s, :link => 'http://tinyurl.com')
|
60
|
+
Twog::Post.new(post)
|
61
|
+
end
|
62
|
+
sorted = unsorted.sort!
|
63
|
+
sorted.length.should == 10
|
64
|
+
|
65
|
+
time = Time.now
|
66
|
+
sorted.each do |p|
|
67
|
+
p_time = Time.parse(p.date.to_s)
|
68
|
+
p_time.should be > time
|
69
|
+
time = p_time
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe Twog::RssEntryToTwogPostMapper do
|
4
|
+
include Twog::RssEntryToTwogPostMapper
|
5
|
+
|
6
|
+
it "should convert rss entries that have updated.content and link.href" do
|
7
|
+
updated = stub('update', :content => '2010-04-02T01:00:00-06:00')
|
8
|
+
link = stub('link', :href => 'http://tinyurl.com')
|
9
|
+
post = stub('post', :updated => updated, :link => link)
|
10
|
+
|
11
|
+
posts = (0..20).collect { |x| post }
|
12
|
+
|
13
|
+
twog_posts = map(posts)
|
14
|
+
twog_posts.length.should == 21
|
15
|
+
twog_posts.each do |p|
|
16
|
+
p.date.should == "2010-04-02T01:00:00-06:00"
|
17
|
+
p.link.should == "http://tinyurl.com"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should convert rss entries that have pubDate and link" do
|
22
|
+
post = stub('post', :pubDate => '2010-04-02T01:00:00-06:00', :link => 'http://tinyurl.com')
|
23
|
+
posts = (0..20).collect { |x| post }
|
24
|
+
|
25
|
+
twog_posts = map(posts)
|
26
|
+
twog_posts.length.should == 21
|
27
|
+
twog_posts.each do |p|
|
28
|
+
p.date.should == "2010-04-02T01:00:00-06:00"
|
29
|
+
p.link.should == "http://tinyurl.com"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/rss_parser_spec.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/spec_helper"
|
2
2
|
|
3
|
-
describe RssParser do
|
3
|
+
describe Twog::RssParser do
|
4
4
|
include TwogSpecHelper
|
5
|
-
include RssParser
|
5
|
+
include Twog::RssParser
|
6
6
|
|
7
7
|
it "should throw exception if rss_feed isn't provided" do
|
8
|
-
lambda {
|
8
|
+
lambda { parse_feed(nil) }.should raise_error('RSS feed missing')
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should read the rss_feed_url and parse the items" do
|
12
12
|
self.stub!(:open).and_return(rss_feed_url_content)
|
13
|
-
items =
|
13
|
+
items = parse_feed(test_conf)
|
14
14
|
items.length.should == 1
|
15
15
|
items[0].title.content.should == "Pair Programming"
|
16
16
|
items[0].link.href.should == "http://blog.jasonmeridth.com/2009/01/29/pair-programming.html"
|
@@ -2,12 +2,12 @@ require File.dirname(__FILE__) + "/spec_helper"
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'rss'
|
4
4
|
|
5
|
-
describe TwitterHandler do
|
5
|
+
describe Twog::TwitterHandler do
|
6
6
|
include TwogSpecHelper
|
7
|
-
include TwitterHandler
|
7
|
+
include Twog::TwitterHandler
|
8
8
|
|
9
9
|
before(:each) do
|
10
|
-
@posts = [
|
10
|
+
@posts = [stub('post', :date => Time.now, :link => 'http://bit.ly/Afr8s9')]
|
11
11
|
@conf = test_conf
|
12
12
|
end
|
13
13
|
|
data/spec/twog_spec.rb
CHANGED
@@ -2,39 +2,38 @@ require File.dirname(__FILE__) + "/spec_helper"
|
|
2
2
|
|
3
3
|
describe Twog do
|
4
4
|
include TwogSpecHelper
|
5
|
+
include Twog::Twog
|
5
6
|
|
6
7
|
it "should not tweet if there are no new blog posts" do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
result = Twog.run(test_conf)
|
8
|
+
stub!(:get_posts_to_tweet).with(test_conf).and_return([])
|
9
|
+
stub!(:tweet).and_return(1)
|
10
|
+
result = run(test_conf)
|
11
11
|
result.should be nil
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should parse the rss feed and tweet new blog posts" do
|
15
15
|
entry = rss_entry
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
result = Twog.run(test_conf)
|
16
|
+
stub!(:get_posts_to_tweet).with(test_conf).and_return([entry])
|
17
|
+
stub!(:get_bitly_from)
|
18
|
+
stub!(:tweet).and_return(1)
|
19
|
+
result = run(test_conf)
|
21
20
|
result.should == 1
|
22
21
|
end
|
23
22
|
|
24
23
|
it "should return nil if bitly username is nil" do
|
25
24
|
conf = test_conf
|
26
25
|
conf['bitly_username'] = nil
|
27
|
-
|
26
|
+
get_bitly_from(conf).should be nil
|
28
27
|
end
|
29
28
|
|
30
29
|
it "should return nil if bitly api key is nil" do
|
31
30
|
conf = test_conf
|
32
31
|
conf['bitly_username'] = nil
|
33
|
-
|
32
|
+
get_bitly_from(conf).should be nil
|
34
33
|
end
|
35
34
|
|
36
35
|
it "should return nil if bitly api key is nil" do
|
37
36
|
Bitly.stub!(:new).and_return("hello")
|
38
|
-
|
37
|
+
get_bitly_from(test_conf).should == "hello"
|
39
38
|
end
|
40
39
|
end
|
data/twog.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{twog}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jason Meridth"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-16}
|
13
13
|
s.default_executable = %q{twog}
|
14
14
|
s.description = %q{Tool to tweet blog posts}
|
15
15
|
s.email = ["jmeridth@gmail.com"]
|
@@ -28,9 +28,13 @@ Gem::Specification.new do |s|
|
|
28
28
|
"bin/twog",
|
29
29
|
"lib/twog.rb",
|
30
30
|
"lib/twog/blog_posts_handler.rb",
|
31
|
+
"lib/twog/post.rb",
|
32
|
+
"lib/twog/rss_entry_to_twog_post_mapper.rb",
|
31
33
|
"lib/twog/rss_parser.rb",
|
32
34
|
"lib/twog/twitter_handler.rb",
|
33
35
|
"spec/blog_posts_handler_spec.rb",
|
36
|
+
"spec/post_spec.rb",
|
37
|
+
"spec/rss_entry_to_twog_post_mapper_spec.rb",
|
34
38
|
"spec/rss_parser_spec.rb",
|
35
39
|
"spec/spec_helper.rb",
|
36
40
|
"spec/twitter_handler_spec.rb",
|
@@ -45,6 +49,8 @@ Gem::Specification.new do |s|
|
|
45
49
|
s.summary = %q{Tool to tweet blog posts}
|
46
50
|
s.test_files = [
|
47
51
|
"spec/blog_posts_handler_spec.rb",
|
52
|
+
"spec/post_spec.rb",
|
53
|
+
"spec/rss_entry_to_twog_post_mapper_spec.rb",
|
48
54
|
"spec/rss_parser_spec.rb",
|
49
55
|
"spec/spec_helper.rb",
|
50
56
|
"spec/twitter_handler_spec.rb",
|
@@ -59,15 +65,18 @@ Gem::Specification.new do |s|
|
|
59
65
|
s.add_runtime_dependency(%q<twitter_oauth>, [">= 0.3.3"])
|
60
66
|
s.add_runtime_dependency(%q<bitly>, [">= 0.4.0"])
|
61
67
|
s.add_runtime_dependency(%q<whenever>, [">= 0.4.1"])
|
68
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
|
62
69
|
else
|
63
70
|
s.add_dependency(%q<twitter_oauth>, [">= 0.3.3"])
|
64
71
|
s.add_dependency(%q<bitly>, [">= 0.4.0"])
|
65
72
|
s.add_dependency(%q<whenever>, [">= 0.4.1"])
|
73
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
66
74
|
end
|
67
75
|
else
|
68
76
|
s.add_dependency(%q<twitter_oauth>, [">= 0.3.3"])
|
69
77
|
s.add_dependency(%q<bitly>, [">= 0.4.0"])
|
70
78
|
s.add_dependency(%q<whenever>, [">= 0.4.1"])
|
79
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
71
80
|
end
|
72
81
|
end
|
73
82
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jason Meridth
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-16 00:00:00 -05:00
|
18
18
|
default_executable: twog
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -59,6 +59,20 @@ dependencies:
|
|
59
59
|
version: 0.4.1
|
60
60
|
type: :runtime
|
61
61
|
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: activesupport
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 2
|
71
|
+
- 3
|
72
|
+
- 5
|
73
|
+
version: 2.3.5
|
74
|
+
type: :runtime
|
75
|
+
version_requirements: *id004
|
62
76
|
description: Tool to tweet blog posts
|
63
77
|
email:
|
64
78
|
- jmeridth@gmail.com
|
@@ -79,9 +93,13 @@ files:
|
|
79
93
|
- bin/twog
|
80
94
|
- lib/twog.rb
|
81
95
|
- lib/twog/blog_posts_handler.rb
|
96
|
+
- lib/twog/post.rb
|
97
|
+
- lib/twog/rss_entry_to_twog_post_mapper.rb
|
82
98
|
- lib/twog/rss_parser.rb
|
83
99
|
- lib/twog/twitter_handler.rb
|
84
100
|
- spec/blog_posts_handler_spec.rb
|
101
|
+
- spec/post_spec.rb
|
102
|
+
- spec/rss_entry_to_twog_post_mapper_spec.rb
|
85
103
|
- spec/rss_parser_spec.rb
|
86
104
|
- spec/spec_helper.rb
|
87
105
|
- spec/twitter_handler_spec.rb
|
@@ -119,6 +137,8 @@ specification_version: 3
|
|
119
137
|
summary: Tool to tweet blog posts
|
120
138
|
test_files:
|
121
139
|
- spec/blog_posts_handler_spec.rb
|
140
|
+
- spec/post_spec.rb
|
141
|
+
- spec/rss_entry_to_twog_post_mapper_spec.rb
|
122
142
|
- spec/rss_parser_spec.rb
|
123
143
|
- spec/spec_helper.rb
|
124
144
|
- spec/twitter_handler_spec.rb
|