twog 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,3 +1,5 @@
1
+ (The MIT License)
2
+
1
3
  Copyright (c) 2010 Jason Meridth
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
@@ -1,25 +1,40 @@
1
- h1. twog
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. Bitly API
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. cron
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 TODO file for items that are to be done in the near future.
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. Technical Reviewers
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'"
@@ -1,5 +1,5 @@
1
1
  ---
2
- :patch: 0
2
+ :patch: 1
3
3
  :major: 0
4
4
  :build:
5
5
  :minor: 3
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 " + Twog.version
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("--conf", "Create default conf file") do
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
- opts.parse!
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
- puts "Invalid options. Run `twog --help` for assistance."
116
+ help
92
117
  exit(1)
93
118
  end
94
119
 
95
- raise "please run 'twog --conf' to create the #{twog_conf_file} file" unless File.exists?(twog_conf_file)
96
- conf = YAML.load_file(twog_conf_file)
97
-
98
- Twog.run(conf)
120
+ run(get_conf(twog_conf_file))
@@ -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
- class Twog
17
- extend RssParser
18
- extend BlogPostsHandler
19
- extend TwitterHandler
18
+ module Twog
19
+ module Twog
20
+ include RssParser
21
+ include RssEntryToTwogPostMapper
22
+ include BlogPostsHandler
23
+ include TwitterHandler
20
24
 
21
- def self.run(conf)
22
- posts = parse(conf['rss_feed'])
23
- posts = get_new_blog_posts(posts, conf['last_blog_post_tweeted'])
24
- return unless posts && posts.length > 0
25
- bitly = get_bitly_from(conf)
26
- tweet(posts, conf, bitly)
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
- def self.get_bitly_from(conf)
30
- bitly_username = conf['bitly_username']
31
- bitly_api_key = conf['bitly_api_key']
32
- return nil unless (bitly_username && bitly_api_key)
33
- Bitly.new(bitly_username, bitly_api_key)
34
- end
35
-
36
- def self.version
37
- yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
38
- "#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
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
- module BlogPostsHandler
4
- def get_new_blog_posts(posts, last_blog_post_tweeted)
5
- return [] unless posts && posts.length > 0
6
- return posts unless last_blog_post_tweeted
7
- new_posts = posts.reject { |post| Time.parse(post.updated.content.to_s) <= Time.parse(last_blog_post_tweeted.to_s) }
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
@@ -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
@@ -0,0 +1,7 @@
1
+ module Twog
2
+ module RssEntryToTwogPostMapper
3
+ def map(rss_entries)
4
+ rss_entries.collect { |x| Post.new(x) }
5
+ end
6
+ end
7
+ end
@@ -1,13 +1,15 @@
1
- module RssParser
2
- def parse(rss_feed_url)
3
- raise Exception.new('RSS feed missing') unless rss_feed_url
4
- rss = RSS::Parser.parse(get_content(rss_feed_url), false)
5
- rss.items
6
- end
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
- def get_content(rss_feed_url)
9
- open(rss_feed_url) do |f|
10
- f.read
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
@@ -1,51 +1,39 @@
1
- class RSS::Atom::Feed::Entry
2
- def <=>(other_entry)
3
- this_time = Time.parse(updated.content.to_s)
4
- other_time = Time.parse(other_entry.updated.content.to_s)
5
- if this_time < other_time
6
- -1
7
- elsif this_time > other_time
8
- 1
9
- else
10
- 0
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
- module TwitterHandler
16
- def tweet(posts, conf, bitly)
17
- return unless posts && posts.length > 0
18
- raise Exception.new('OAuth Consumer Key missing') unless conf['consumer_key']
19
- raise Exception.new('OAuth Consumer Secret missing') unless conf['consumer_secret']
20
- raise Exception.new('OAuth Access Token missing') unless conf['access_token']
21
- raise Exception.new('OAuth Access Secret missing') unless conf['access_secret']
22
- posts.sort.each do |item|
23
- link = bitly ? bitly.shorten(item.link.href).short_url : item.link.href
24
- use_twitter_oauth(item, link, conf)
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
- def ensure_text_is_of_length(length, title, link)
42
- blogged = "blogged:"
43
- title = title[0,(length-((" "*2).length+blogged.length+link.length))]
44
- [blogged, title, link].join(' ')
45
- end
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
- def update_config_file_with_latest_tweet_date(last_blog_post_tweeted, conf)
48
- conf['last_blog_post_tweeted'] = last_blog_post_tweeted
49
- File.open("#{ENV['HOME']}/.twog/conf.yaml","w") { |out| out.write(conf.to_yaml) }
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
- entry = rss_entry
9
- entry.updated.content = Time.new
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
@@ -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
@@ -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 { parse(nil) }.should raise_error('RSS feed missing')
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 = parse(test_conf)
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 = [rss_entry]
10
+ @posts = [stub('post', :date => Time.now, :link => 'http://bit.ly/Afr8s9')]
11
11
  @conf = test_conf
12
12
  end
13
13
 
@@ -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
- Twog.stub!(:parse).with(test_conf['rss_feed']).and_return(1)
8
- Twog.stub!(:get_new_blog_posts).with(1, test_conf['last_blog_post_tweeted']).and_return([])
9
- Twog.stub!(:tweet).and_return(1)
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
- Twog.stub!(:parse).with(test_conf['rss_feed']).and_return(1)
17
- Twog.stub!(:get_new_blog_posts).with(1, test_conf['last_blog_post_tweeted']).and_return([entry])
18
- Twog.stub!(:get_bitly_from)
19
- Twog.stub!(:tweet).and_return(1)
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
- Twog.get_bitly_from(conf).should be nil
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
- Twog.get_bitly_from(conf).should be nil
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
- Twog.get_bitly_from(test_conf).should == "hello"
37
+ get_bitly_from(test_conf).should == "hello"
39
38
  end
40
39
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{twog}
8
- s.version = "0.3.0"
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-10}
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
- - 0
9
- version: 0.3.0
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-10 00:00:00 -05:00
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