balinterdi-twuckoo 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ v0.2.2 Minor modification because of changed Wikipedia TFA markup
1
2
  v0.2 Wikipedia TFA module, command line argument decides which file to include
2
3
  v0.1.3 Length of sleeping interval settable from config
3
4
  v0.1.2 Sleeping interval set with duration-string
data/README.markdown CHANGED
@@ -1,4 +1,102 @@
1
1
  # Twuckoo
2
2
 
3
- Need to tweet periodically and in an automated fashion? Cuckoo twitterer is for you.
3
+ Need to tweet periodically and in an automated fashion? Then Twuckoo is for you. Still not convinced? :) Read on.
4
4
 
5
+ ## Abstract
6
+
7
+ Twuckoo fulfills the task of periodically fetching a message and tweeting it (Twuckoo = Twitter + Cuckoo). Since we all prefer code to words, I'll show you its main loop:
8
+
9
+ def run
10
+ setup
11
+ load_tweets
12
+ loop do
13
+ tweeted = tweet
14
+ quit if tweeted.nil?
15
+ relax
16
+ end
17
+ end
18
+
19
+ It is very simple in its design but opens vast possibilities due to its modular approach.
20
+
21
+ ## A simple API
22
+
23
+ Twuckoo takes a modular approach. It defines a very simple API and expects modules to implement these API methods. The methods are:
24
+
25
+ * load_tweets
26
+
27
+ Loads the possible tweets that twuckoo will use when selecting the next one. This could be reading all lines from a file, for example.
28
+
29
+ * next
30
+
31
+ Fetches the next message to be tweeted. Usually the bulk of the "business logic" is implemented here. This could be scraping a web page and extracting a specific snippet of html.
32
+
33
+ * store(tweet)
34
+
35
+ Hands the last tweeted message to be stored. In the case of the one\_line\_from_file module, this stores the tweet in a file so that no message is used multiple times.
36
+
37
+ Twuckoo needs to be passed the name of the module to be used. At the moment there are two provided modules:
38
+
39
+ * one\_line\_from\_file
40
+
41
+ Loads all the lines from a file (lines.txt) and tweets one line randomly each time.
42
+
43
+ * wikipedia_tfa
44
+
45
+ Scraps Wikipedia's main page and extracts the name and link of Today's Featured Article. This is not as general a module as one\_line\_from_file. I am thinking about how to best make a "web" module out of this.
46
+
47
+ ## Installation
48
+
49
+ gem install balinterdi-twuckoo --source http://gems.github.com
50
+
51
+ Twuckoo depends on twibot which will also get installed with the above command.
52
+
53
+ In order for twibot to be able to connect to your twitter account, a config/bot.yml file need to be present at where you launch twuckoo from. It has to contain the following lines at least:
54
+
55
+ login: my_login
56
+ password: my_password
57
+
58
+ For more options, see [twibot's README](http://github.com/cjohansen/twibot/tree/master "twibot's README")
59
+
60
+ ## Configuration
61
+
62
+ Currently the only thing you can set is the time to wait between tweets. By default, it is "1d", so the script will "relax" for 24 hours after tweeting. If you wish to change this value, just place the following in a config/cuckoo.yml:
63
+
64
+ time_to_sleep: 1h
65
+
66
+ The value should be given in a human-comprehensible form. You can use any combination of weeks, days, hours, minutes and seconds, so 1w3d13h27m19s will work, too, although you probably do not want to be this precise :)
67
+
68
+ ## Running
69
+
70
+ You have to indicate the module you wish to use:
71
+
72
+ $ twuckoo file
73
+
74
+ Will make use of the one_line_from_file module. There has to be a lines.txt file in the directory where you run twuckoo from that contains the possible tweets, one tweet per line. The tweeted lines will be stored in a file called used\_lines.txt so you should have write permission to the directory.
75
+
76
+ or
77
+
78
+ $ twuckoo wikipedia_tfa
79
+
80
+ (see above)
81
+
82
+ ## Examples out there
83
+
84
+ In the course of the development of this gem I "ate my own dogfood" so you'll find one twitter account for each of the modules:
85
+
86
+ * [Daily Oblique](http://twitter.com/daily_oblique)
87
+
88
+ Serves you an [Oblique Strategy](http://www.rtqe.net/ObliqueStrategies/) per day.
89
+
90
+ * [Wikipedia Today's Featured Article](http://twitter.com/wikipedia_tfa)
91
+
92
+ An interesting article from the English Wikipedia delivered right to your twitter feed.
93
+
94
+ If you set up something with twuckoo, I would like to know about it, so that I might include it here.
95
+
96
+ ## Credits & License
97
+
98
+ You can go ahead and play with the software as well as modify it, release it under another name, charge for someone that uses your service, etc. A link back to [this page](http://github.com/balinterdi/twuckoo/tree/master) would be appreciated if you release something based on it.
99
+
100
+ Any feedback (especially bug reports!) is highly appreciated, so please do not hesitate to contact me at <balint@bucionrails.com>
101
+
102
+ Original idea and development: [Balint Erdi](http://bucionrails.com)
data/Rakefile CHANGED
@@ -2,13 +2,13 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('twuckoo', '0.2.1') do |p|
5
+ Echoe.new('twuckoo', '0.2.2') do |p|
6
6
  p.description = "A simple yet elegant solution to tweet a message regularly from a file (and in the future: from a webpage, a database, etc.)"
7
7
  p.url = "http://github.com/balinterdi/twuckoo"
8
8
  p.author = "Bálint Érdi"
9
9
  p.email = "balint@bucionrails.com"
10
10
  p.ignore_pattern = ["tmp/*", "script/*", "*.txt", "pkg"]
11
- p.runtime_dependencies = ["twibot >=0.1.7"]
11
+ p.runtime_dependencies = ["twibot >=0.1.7", "hpricot >= 0.6.164", "mocha >= 0.9.5"]
12
12
  end
13
13
 
14
14
  Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
@@ -1,24 +1,37 @@
1
1
  require "open-uri"
2
2
  require "hpricot"
3
3
 
4
+ # Grabs the headline of Wikipedia's Today's Featured Article (TFA)
4
5
  module WikipediaTFA
5
-
6
+
6
7
  WIKIPEDIA_HOST = "http://en.wikipedia.org"
7
-
8
+
8
9
  def load_tweets
9
10
  end
10
11
 
11
12
  def store(line)
12
13
  end
13
14
 
14
- def get_wikipedia_main_page
15
+ def fetch_main_page
15
16
  Hpricot(open("#{WIKIPEDIA_HOST}/wiki/Main_Page"))
16
17
  end
17
-
18
- def next
19
- doc = get_wikipedia_main_page
20
- tfa = doc.at("#mp-tfa p b a")
18
+
19
+ def fetch_tfa
20
+ doc = fetch_main_page
21
+ tfa = doc.at("#mp-tfa b a")
21
22
  tfa_link = WIKIPEDIA_HOST + tfa["href"]
22
23
  "#{tfa.inner_html}: #{tfa_link}"
23
24
  end
25
+
26
+ def next
27
+ prev_tweet = get_last_tweet
28
+ next_tweet = fetch_tfa
29
+ return prev_tweet == next_tweet ? '' : next_tweet
30
+ end
31
+
32
+ private
33
+ def get_last_tweet
34
+ last_tweet = twitter.timeline_for(:me).first
35
+ last_tweet.text if last_tweet
36
+ end
24
37
  end
data/lib/twuckoo.rb CHANGED
@@ -4,7 +4,6 @@ require File.join(File.dirname(__FILE__), 'duration_string')
4
4
  require 'twibot'
5
5
 
6
6
  class Twuckoo
7
- include TwuckooEnvironment
8
7
  # the idea is to include a module with a well-defined API with three methods:
9
8
  # - load_tweets
10
9
  # - next
@@ -18,13 +17,9 @@ class Twuckoo
18
17
 
19
18
  def tweet
20
19
  next_tweet = self.next
21
- unless next_tweet.nil?
20
+ unless next_tweet.nil? or next_tweet.empty?
22
21
  store(next_tweet)
23
- if testing?
24
- puts "(test) Tweeting #{next_tweet}"
25
- else
26
- twitter.status(:post, next_tweet)
27
- end
22
+ send_tweet(next_tweet)
28
23
  end
29
24
  next_tweet
30
25
  end
@@ -63,4 +58,9 @@ class Twuckoo
63
58
  def quit
64
59
  exit
65
60
  end
61
+
62
+ private
63
+ def send_tweet(next_tweet)
64
+ twitter.status(:post, next_tweet)
65
+ end
66
66
  end
@@ -11,92 +11,91 @@ end
11
11
 
12
12
  class TwuckooWithOneLineFromFileSpec
13
13
 
14
- extend TwuckooEnvironment
15
- set_testing
16
-
17
14
  describe "A cuckoo twitterer with one line from a file" do
18
15
  before do
19
16
  Twuckoo.send(:include, OneLineFromFile)
20
- @cuckoo = Twuckoo.new
17
+ @twuckoo = Twuckoo.new
21
18
  # just so that no files will be written
22
- @cuckoo.stubs(:store).returns(nil)
19
+ @twuckoo.stubs(:store).returns(nil)
20
+ # and the actual text tweets are not tweeted (twittered?)
21
+ @twuckoo.stubs(:send_tweet).returns(true)
23
22
  end
24
23
 
25
24
  it "stores a line that was sent to it correctly" do
26
- @cuckoo.lines.should be_empty
27
- @cuckoo.add_lines("I am happy", "I am sad")
28
- @cuckoo.lines.should == ["I am happy", "I am sad"]
25
+ @twuckoo.lines.should be_empty
26
+ @twuckoo.add_lines("I am happy", "I am sad")
27
+ @twuckoo.lines.should == ["I am happy", "I am sad"]
29
28
  end
30
29
 
31
30
  it "loads all the lines in the file when sent the load_tweets message" do
32
31
  lines = ["I am happy", "I am sad", "I am thrilled", "I am bored"]
33
- @cuckoo.expects(:get_lines_from_file).returns(lines)
34
- @cuckoo.load_tweets
35
- @cuckoo.lines.should == lines
32
+ @twuckoo.expects(:get_lines_from_file).returns(lines)
33
+ @twuckoo.load_tweets
34
+ @twuckoo.lines.should == lines
36
35
  end
37
36
 
38
37
  describe "when it tweeted a line already" do
39
38
  before do
40
- @cuckoo.add_lines("I am happy", "I am sad", "I am thrilled", "I am bored")
41
- @cuckoo.stubs(:pick).returns(0)
42
- @cuckoo.tweet
39
+ @twuckoo.add_lines("I am happy", "I am sad", "I am thrilled", "I am bored")
40
+ @twuckoo.stubs(:pick).returns(0)
41
+ @twuckoo.tweet
43
42
  end
44
43
 
45
44
  it "it removes it" do
46
- @cuckoo.lines.should == ["I am sad", "I am thrilled", "I am bored"]
45
+ @twuckoo.lines.should == ["I am sad", "I am thrilled", "I am bored"]
47
46
  end
48
47
 
49
48
  it "stores it" do
50
- @cuckoo.stubs(:pick).returns(0)
51
- @cuckoo.expects(:store).with("I am sad")
52
- @cuckoo.tweet
49
+ @twuckoo.stubs(:pick).returns(0)
50
+ @twuckoo.expects(:store).with("I am sad")
51
+ @twuckoo.tweet
53
52
  end
54
53
 
55
54
  it "it picks an unused line to tweet next" do
56
- next_pick = @cuckoo.next
55
+ next_pick = @twuckoo.next
57
56
  ["I am sad", "I am thrilled", "I am bored"].should include(next_pick)
58
57
  end
59
58
  end
60
59
 
61
60
  it "tweets all the available lines in as many 'rounds' as there are lines" do
62
61
  lines = ["I am happy", "I am sad", "I am thrilled", "I am bored"]
63
- @cuckoo.add_lines(*lines)
64
- lines.length.times { @cuckoo.tweet }
65
- @cuckoo.lines.should be_empty
62
+ @twuckoo.add_lines(*lines)
63
+ lines.length.times { @twuckoo.tweet }
64
+ @twuckoo.lines.should be_empty
66
65
  end
67
66
 
68
67
  it "only reads the file to load lines from the first time around" do
69
68
  pending
70
- @cuckoo.stubs(:get_used_lines_from_file).returns([])
71
- @cuckoo.expects(:get_lines_from_file).returns(["I am happy", "I am sad", "I am thrilled", "I am bored"])
72
- 2.times { @cuckoo.load_lines }
69
+ @twuckoo.stubs(:get_used_lines_from_file).returns([])
70
+ @twuckoo.expects(:get_lines_from_file).returns(["I am happy", "I am sad", "I am thrilled", "I am bored"])
71
+ 2.times { @twuckoo.load_lines }
73
72
  end
74
73
 
75
74
  it "only reads the file to load used lines from the first time around" do
76
75
  pending
77
- @cuckoo.stubs(:get_lines_from_file).returns(["I am happy", "I am sad", "I am thrilled", "I am bored"])
78
- @cuckoo.expects(:get_used_lines_from_file).returns([])
79
- 2.times { @cuckoo.load_lines }
76
+ @twuckoo.stubs(:get_lines_from_file).returns(["I am happy", "I am sad", "I am thrilled", "I am bored"])
77
+ @twuckoo.expects(:get_used_lines_from_file).returns([])
78
+ 2.times { @twuckoo.load_lines }
80
79
  end
81
80
 
82
81
  describe "when loading lines to use" do
83
82
  before do
84
- @cuckoo.stubs(:get_lines_from_file).returns(["I am happy", "I am sad", "I am thrilled", "I am bored"])
85
- @cuckoo.stubs(:get_used_lines_from_file).returns([])
83
+ @twuckoo.stubs(:get_lines_from_file).returns(["I am happy", "I am sad", "I am thrilled", "I am bored"])
84
+ @twuckoo.stubs(:get_used_lines_from_file).returns([])
86
85
  end
87
86
 
88
87
  it "loads the available ones" do
89
- @cuckoo.load_lines
90
- @cuckoo.lines.should == ["I am happy", "I am sad", "I am thrilled", "I am bored"]
88
+ @twuckoo.load_lines
89
+ @twuckoo.lines.should == ["I am happy", "I am sad", "I am thrilled", "I am bored"]
91
90
  end
92
91
 
93
92
  describe "when having used ones from a previous run" do
94
93
  before do
95
- @cuckoo.stubs(:get_used_lines_from_file).returns(["I am happy", "I am sad"])
96
- @cuckoo.load_lines
94
+ @twuckoo.stubs(:get_used_lines_from_file).returns(["I am happy", "I am sad"])
95
+ @twuckoo.load_lines
97
96
  end
98
97
  it "should not pick those used lines" do
99
- @cuckoo.lines.should == ["I am thrilled", "I am bored"]
98
+ @twuckoo.lines.should == ["I am thrilled", "I am bored"]
100
99
  end
101
100
  end
102
101
  end
data/spec/spec.opts CHANGED
@@ -2,4 +2,3 @@
2
2
  --loadby random
3
3
  --format progress
4
4
  --backtrace
5
- --debugger
data/spec/twuckoo_spec.rb CHANGED
@@ -1,44 +1,44 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper')
2
2
 
3
3
  class TwuckooSpec
4
- extend TwuckooEnvironment
5
- set_testing
6
-
7
4
  describe "A twuckoo" do
8
5
  before do
9
- @cuckoo = Twuckoo.new
6
+ @twuckoo = Twuckoo.new
7
+ # actual text tweets should not be tweeted (twittered?)
8
+ @twuckoo.stubs(:send_tweet).returns(true)
10
9
  end
11
10
 
12
11
  it "responds to tweet" do
13
- @cuckoo.should respond_to(:tweet)
12
+ @twuckoo.should respond_to(:tweet)
14
13
  end
15
14
 
16
15
  it "waits 1 day between tweets by default" do
17
- @cuckoo.time_to_sleep.should == "1d"
16
+ @twuckoo.time_to_sleep.should == "1d"
18
17
  end
19
18
 
20
19
  describe "loading values from the config file" do
21
20
  it "sets the time interval to wait b/w tweets correctly" do
22
- @cuckoo.expects(:get_config_values_from_file).returns({ :time_to_sleep => "3m" })
23
- @cuckoo.setup
24
- @cuckoo.time_to_sleep.should == "3m"
21
+ @twuckoo.expects(:get_config_values_from_file).returns({ :time_to_sleep => "3m" })
22
+ @twuckoo.setup
23
+ @twuckoo.time_to_sleep.should == "3m"
25
24
  end
26
25
  end
27
26
 
28
27
  describe "when there is nothing to tweet" do
29
28
  before do
30
- @cuckoo.stubs(:next).returns(nil)
31
- @cuckoo.stubs(:load_tweets).returns(nil)
29
+ @twuckoo.stubs(:next).returns(nil)
30
+ @twuckoo.stubs(:load_tweets).returns(nil)
32
31
  end
33
32
  it "does not call store" do
34
- @cuckoo.expects(:store).never
35
- @cuckoo.tweet
33
+ @twuckoo.expects(:store).never
34
+ @twuckoo.tweet
36
35
  end
37
36
  it "quits" do
38
37
  pending
39
- @cuckoo.expects(:quit).once
40
- @cuckoo.run
38
+ @twuckoo.expects(:quit).once
39
+ @twuckoo.run
41
40
  end
42
41
  end
42
+
43
43
  end
44
44
  end
@@ -5,16 +5,19 @@ require File.join(dir, 'modules', 'wikipedia_tfa')
5
5
 
6
6
  class TwuckooForWikipediaTfaSpec
7
7
 
8
- extend TwuckooEnvironment
9
- set_testing
10
-
11
8
  describe "A cuckoo twitterer for wikipedia featured article" do
12
9
  before do
13
10
  Twuckoo.send(:include, WikipediaTFA)
14
- @cuckoo = Twuckoo.new
15
- end
16
- it "works" do
17
- @cuckoo.tweet
11
+ # actual text tweets should not be tweeted (twittered?)
12
+ @twuckoo.stubs(:send_tweet).returns(true)
13
+ @twuckoo = Twuckoo.new
18
14
  end
15
+
16
+ it "should not tweet the same thing twice subsequently" do
17
+ @twuckoo.expects(:get_last_tweet).returns("Twitter: http://en.wikipedia.org/wiki/Twitter")
18
+ @twuckoo.expects(:fetch_tfa).returns("Twitter: http://en.wikipedia.org/wiki/Twitter")
19
+ @twuckoo.expects(:send_tweet).never
20
+ @twuckoo.tweet
21
+ end
19
22
  end
20
23
  end
data/twuckoo.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{twuckoo}
5
- s.version = "0.2.1"
5
+ s.version = "0.2.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["B\303\241lint \303\211rdi"]
9
- s.date = %q{2009-06-16}
9
+ s.date = %q{2009-08-07}
10
10
  s.default_executable = %q{twuckoo}
11
11
  s.description = %q{A simple yet elegant solution to tweet a message regularly from a file (and in the future: from a webpage, a database, etc.)}
12
12
  s.email = %q{balint@bucionrails.com}
@@ -26,10 +26,16 @@ Gem::Specification.new do |s|
26
26
 
27
27
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
28
  s.add_runtime_dependency(%q<twibot>, [">= 0.1.7"])
29
+ s.add_runtime_dependency(%q<hpricot>, [">= 0", "= 0.6.164"])
30
+ s.add_runtime_dependency(%q<mocha>, [">= 0", "= 0.9.5"])
29
31
  else
30
32
  s.add_dependency(%q<twibot>, [">= 0.1.7"])
33
+ s.add_dependency(%q<hpricot>, [">= 0", "= 0.6.164"])
34
+ s.add_dependency(%q<mocha>, [">= 0", "= 0.9.5"])
31
35
  end
32
36
  else
33
37
  s.add_dependency(%q<twibot>, [">= 0.1.7"])
38
+ s.add_dependency(%q<hpricot>, [">= 0", "= 0.6.164"])
39
+ s.add_dependency(%q<mocha>, [">= 0", "= 0.9.5"])
34
40
  end
35
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: balinterdi-twuckoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - "B\xC3\xA1lint \xC3\x89rdi"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-16 00:00:00 -07:00
12
+ date: 2009-08-07 00:00:00 -07:00
13
13
  default_executable: twuckoo
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,6 +22,32 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 0.1.7
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hpricot
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ - - "="
35
+ - !ruby/object:Gem::Version
36
+ version: 0.6.164
37
+ version:
38
+ - !ruby/object:Gem::Dependency
39
+ name: mocha
40
+ type: :runtime
41
+ version_requirement:
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ - - "="
48
+ - !ruby/object:Gem::Version
49
+ version: 0.9.5
50
+ version:
25
51
  description: "A simple yet elegant solution to tweet a message regularly from a file (and in the future: from a webpage, a database, etc.)"
26
52
  email: balint@bucionrails.com
27
53
  executables:
@@ -59,6 +85,7 @@ files:
59
85
  - twuckoo.gemspec
60
86
  has_rdoc: false
61
87
  homepage: http://github.com/balinterdi/twuckoo
88
+ licenses:
62
89
  post_install_message:
63
90
  rdoc_options:
64
91
  - --line-numbers
@@ -84,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
111
  requirements: []
85
112
 
86
113
  rubyforge_project: twuckoo
87
- rubygems_version: 1.2.0
114
+ rubygems_version: 1.3.5
88
115
  signing_key:
89
116
  specification_version: 3
90
117
  summary: "A simple yet elegant solution to tweet a message regularly from a file (and in the future: from a webpage, a database, etc.)"