balinterdi-twuckoo 0.2.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/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+ v0.2 Wikipedia TFA module, command line argument decides which file to include
2
+ v0.1.3 Length of sleeping interval settable from config
3
+ v0.1.2 Sleeping interval set with duration-string
4
+ v0.1.1 Removing unnecessary gem requires and config files
5
+ v0.1 Initial release: can tweet from a file.
data/Manifest ADDED
@@ -0,0 +1,18 @@
1
+ bin/twuckoo
2
+ CHANGELOG
3
+ lib/duration_string.rb
4
+ lib/environments.rb
5
+ lib/modules/one_line_from_file.rb
6
+ lib/modules/wikipedia_tfa.rb
7
+ lib/twuckoo.rb
8
+ Manifest
9
+ Rakefile
10
+ README.markdown
11
+ spec/duration_string_spec.rb
12
+ spec/one_line_from_file_spec.rb
13
+ spec/spec.opts
14
+ spec/spec_helper.rb
15
+ spec/twuckoo_spec.rb
16
+ spec/wikipedia_tfa_spec.rb
17
+ tasks/spec.rake
18
+ twuckoo.gemspec
data/README.markdown ADDED
@@ -0,0 +1,4 @@
1
+ # Twuckoo
2
+
3
+ Need to tweet periodically and in an automated fashion? Cuckoo twitterer is for you.
4
+
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('twuckoo', '0.2.1') do |p|
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
+ p.url = "http://github.com/balinterdi/twuckoo"
8
+ p.author = "Bálint Érdi"
9
+ p.email = "balint@bucionrails.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*", "*.txt", "pkg"]
11
+ p.runtime_dependencies = ["twibot >=0.1.7"]
12
+ end
13
+
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
15
+
data/bin/twuckoo ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ dir = File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require File.join(dir, 'twuckoo')
6
+
7
+ Dir.glob(File.join(dir, 'modules', '*.rb')).each do |mod|
8
+ require mod
9
+ end
10
+
11
+ module_to_include = case ARGV.first.downcase
12
+ when "from_file"
13
+ OneLineFromFile
14
+ when "file"
15
+ OneLineFromFile
16
+ when "wikipedia_tfa"
17
+ WikipediaTFA
18
+ else
19
+ raise "No module to include was provided."
20
+ end
21
+
22
+ Twuckoo.send(:include, module_to_include)
23
+ @cuckoo = Twuckoo.new
24
+ # @cuckoo.set_testing
25
+ @cuckoo.run
@@ -0,0 +1,12 @@
1
+ module DurationString
2
+ class << self
3
+ MULTIPLIERS = { "s" => 1, "m" => 60, "h" => 60 * 60, "d" => 60 * 60 * 24, "w" => 60 * 60 * 24 * 7 }
4
+ def to_seconds(duration)
5
+ duration.scan(/(\d+)([smhdw])/).inject(0) do |seconds, match|
6
+ num, dur_chr = match
7
+ multiplier = MULTIPLIERS[dur_chr]
8
+ seconds + num.to_i * multiplier
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ module TwuckooEnvironment
2
+ def set_testing
3
+ ENV["CUCKOO_ENV"] = "testing"
4
+ end
5
+ def testing?
6
+ ENV["CUCKOO_ENV"] == "testing"
7
+ end
8
+ end
@@ -0,0 +1,70 @@
1
+ module OneLineFromFile
2
+ # read all lines from the file that contains the strategies
3
+ # select the strategies that are not used yet
4
+ # pick a random strategy
5
+
6
+ # store used strategies in a file with (store the md5 sum of the strategies' text)
7
+ attr_reader :lines
8
+
9
+ LINES_FILE = 'lines.txt'
10
+ USED_LINES_FILE = 'used_lines.txt'
11
+
12
+ def initialize
13
+ @lines = []
14
+ # load_lines
15
+ end
16
+
17
+ def load_tweets
18
+ load_lines
19
+ end
20
+
21
+ def get_lines_from_file
22
+ begin
23
+ IO::readlines(LINES_FILE).map { |line| line.chomp }
24
+ rescue Errno::ENOENT
25
+ []
26
+ end
27
+ end
28
+
29
+ def get_all_lines
30
+ @fresh_lines ||= get_lines_from_file
31
+ end
32
+
33
+ def get_used_lines_from_file
34
+ begin
35
+ IO::readlines(USED_LINES_FILE).map { |line| line.chomp }
36
+ rescue Errno::ENOENT
37
+ []
38
+ end
39
+ end
40
+
41
+ def get_used_lines
42
+ @used_lines ||= get_used_lines_from_file
43
+ end
44
+
45
+ def load_lines
46
+ used = get_used_lines
47
+ unused_lines = get_all_lines.select { |line| !used.include?(line) }
48
+ add_lines(*unused_lines)
49
+ end
50
+
51
+ def add_lines(*new_lines)
52
+ @lines.concat(new_lines)
53
+ end
54
+
55
+ def pick
56
+ rand(lines.length)
57
+ end
58
+
59
+ def store(line)
60
+ open(USED_LINES_FILE, "a") do |file|
61
+ file.write(line + "\n")
62
+ end
63
+ end
64
+
65
+ def next
66
+ @lines.delete_at(pick)
67
+ end
68
+
69
+ end
70
+
@@ -0,0 +1,24 @@
1
+ require "open-uri"
2
+ require "hpricot"
3
+
4
+ module WikipediaTFA
5
+
6
+ WIKIPEDIA_HOST = "http://en.wikipedia.org"
7
+
8
+ def load_tweets
9
+ end
10
+
11
+ def store(line)
12
+ end
13
+
14
+ def get_wikipedia_main_page
15
+ Hpricot(open("#{WIKIPEDIA_HOST}/wiki/Main_Page"))
16
+ end
17
+
18
+ def next
19
+ doc = get_wikipedia_main_page
20
+ tfa = doc.at("#mp-tfa p b a")
21
+ tfa_link = WIKIPEDIA_HOST + tfa["href"]
22
+ "#{tfa.inner_html}: #{tfa_link}"
23
+ end
24
+ end
data/lib/twuckoo.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require File.join(File.dirname(__FILE__), 'environments')
3
+ require File.join(File.dirname(__FILE__), 'duration_string')
4
+ require 'twibot'
5
+
6
+ class Twuckoo
7
+ include TwuckooEnvironment
8
+ # the idea is to include a module with a well-defined API with three methods:
9
+ # - load_tweets
10
+ # - next
11
+ # - store(tweet)
12
+ attr_accessor :time_to_sleep
13
+
14
+ def initialize
15
+ @time_to_sleep = "1d"
16
+ super
17
+ end
18
+
19
+ def tweet
20
+ next_tweet = self.next
21
+ unless next_tweet.nil?
22
+ store(next_tweet)
23
+ if testing?
24
+ puts "(test) Tweeting #{next_tweet}"
25
+ else
26
+ twitter.status(:post, next_tweet)
27
+ end
28
+ end
29
+ next_tweet
30
+ end
31
+
32
+ def get_config_values_from_file
33
+ begin
34
+ open('config/cuckoo.yml', 'r') do |f|
35
+ YAML.load(f.read)
36
+ end
37
+ rescue
38
+ {}
39
+ end
40
+ end
41
+
42
+ def setup
43
+ get_config_values_from_file.each_pair do |attr, value|
44
+ self.send("#{attr}=".to_sym, value)
45
+ end
46
+ end
47
+
48
+ def relax
49
+ seconds_to_sleep = DurationString.to_seconds(time_to_sleep)
50
+ sleep(seconds_to_sleep)
51
+ end
52
+
53
+ def run
54
+ setup
55
+ load_tweets
56
+ loop do
57
+ tweeted = tweet
58
+ quit if tweeted.nil?
59
+ relax
60
+ end
61
+ end
62
+
63
+ def quit
64
+ exit
65
+ end
66
+ end
@@ -0,0 +1,30 @@
1
+ require "spec"
2
+ dir = File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require File.join(dir, 'duration_string')
4
+
5
+ describe "a string representing a duration" do
6
+ it "gives back the number of seconds for seconds" do
7
+ DurationString.to_seconds("17s").should == 17
8
+ end
9
+
10
+ it "gives back the number of seconds for dur. strings with only minutes defined" do
11
+ DurationString.to_seconds("7m").should == 7 * 60
12
+ end
13
+
14
+ it "gives back the number of seconds for hours for dur. strings with only hours defined" do
15
+ DurationString.to_seconds("4h").should == 60 * 60 * 4
16
+ end
17
+
18
+ it "gives back the number of seconds for hours for dur. strings with only days defined" do
19
+ DurationString.to_seconds("2d").should == 60 * 60 * 24 * 2
20
+ end
21
+
22
+ it "gives back the number of seconds for hours for dur. strings with only weeks defined" do
23
+ DurationString.to_seconds("3w").should == 60 * 60 * 24 * 7 * 3
24
+ end
25
+
26
+ it "gives back the number of seconds for a dur. string that combines several dur. characters" do
27
+ DurationString.to_seconds("1d3h18m22s").should == (60 * 60 * 24 * 1) + (60 * 60 * 3) + (60 * 18) + 22
28
+ end
29
+
30
+ end
@@ -0,0 +1,105 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ dir = File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require File.join(dir, 'modules', 'one_line_from_file')
5
+
6
+ # use mocha for mocking instead of
7
+ # Rspec's own mock framework
8
+ Spec::Runner.configure do |config|
9
+ config.mock_with :mocha
10
+ end
11
+
12
+ class TwuckooWithOneLineFromFileSpec
13
+
14
+ extend TwuckooEnvironment
15
+ set_testing
16
+
17
+ describe "A cuckoo twitterer with one line from a file" do
18
+ before do
19
+ Twuckoo.send(:include, OneLineFromFile)
20
+ @cuckoo = Twuckoo.new
21
+ # just so that no files will be written
22
+ @cuckoo.stubs(:store).returns(nil)
23
+ end
24
+
25
+ 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"]
29
+ end
30
+
31
+ it "loads all the lines in the file when sent the load_tweets message" do
32
+ 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
36
+ end
37
+
38
+ describe "when it tweeted a line already" do
39
+ 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
43
+ end
44
+
45
+ it "it removes it" do
46
+ @cuckoo.lines.should == ["I am sad", "I am thrilled", "I am bored"]
47
+ end
48
+
49
+ it "stores it" do
50
+ @cuckoo.stubs(:pick).returns(0)
51
+ @cuckoo.expects(:store).with("I am sad")
52
+ @cuckoo.tweet
53
+ end
54
+
55
+ it "it picks an unused line to tweet next" do
56
+ next_pick = @cuckoo.next
57
+ ["I am sad", "I am thrilled", "I am bored"].should include(next_pick)
58
+ end
59
+ end
60
+
61
+ it "tweets all the available lines in as many 'rounds' as there are lines" do
62
+ 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
66
+ end
67
+
68
+ it "only reads the file to load lines from the first time around" do
69
+ 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 }
73
+ end
74
+
75
+ it "only reads the file to load used lines from the first time around" do
76
+ 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 }
80
+ end
81
+
82
+ describe "when loading lines to use" do
83
+ 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([])
86
+ end
87
+
88
+ 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"]
91
+ end
92
+
93
+ describe "when having used ones from a previous run" do
94
+ before do
95
+ @cuckoo.stubs(:get_used_lines_from_file).returns(["I am happy", "I am sad"])
96
+ @cuckoo.load_lines
97
+ end
98
+ it "should not pick those used lines" do
99
+ @cuckoo.lines.should == ["I am thrilled", "I am bored"]
100
+ end
101
+ end
102
+ end
103
+
104
+ end
105
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --loadby random
3
+ --format progress
4
+ --backtrace
5
+ --debugger
@@ -0,0 +1,10 @@
1
+ require "spec"
2
+ require "mocha"
3
+
4
+ dir = File.join(File.dirname(__FILE__), '..', 'lib')
5
+ require File.join(dir, 'twuckoo')
6
+ require File.join(dir, 'environments')
7
+
8
+ Spec::Runner.configure do |config|
9
+ config.mock_with :mocha
10
+ end
@@ -0,0 +1,44 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ class TwuckooSpec
4
+ extend TwuckooEnvironment
5
+ set_testing
6
+
7
+ describe "A twuckoo" do
8
+ before do
9
+ @cuckoo = Twuckoo.new
10
+ end
11
+
12
+ it "responds to tweet" do
13
+ @cuckoo.should respond_to(:tweet)
14
+ end
15
+
16
+ it "waits 1 day between tweets by default" do
17
+ @cuckoo.time_to_sleep.should == "1d"
18
+ end
19
+
20
+ describe "loading values from the config file" do
21
+ 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"
25
+ end
26
+ end
27
+
28
+ describe "when there is nothing to tweet" do
29
+ before do
30
+ @cuckoo.stubs(:next).returns(nil)
31
+ @cuckoo.stubs(:load_tweets).returns(nil)
32
+ end
33
+ it "does not call store" do
34
+ @cuckoo.expects(:store).never
35
+ @cuckoo.tweet
36
+ end
37
+ it "quits" do
38
+ pending
39
+ @cuckoo.expects(:quit).once
40
+ @cuckoo.run
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ dir = File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require File.join(dir, 'modules', 'wikipedia_tfa')
5
+
6
+ class TwuckooForWikipediaTfaSpec
7
+
8
+ extend TwuckooEnvironment
9
+ set_testing
10
+
11
+ describe "A cuckoo twitterer for wikipedia featured article" do
12
+ before do
13
+ Twuckoo.send(:include, WikipediaTFA)
14
+ @cuckoo = Twuckoo.new
15
+ end
16
+ it "works" do
17
+ @cuckoo.tweet
18
+ end
19
+ end
20
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,11 @@
1
+ require "rubygems"
2
+ require "rake"
3
+ require "spec/rake/spectask"
4
+
5
+ ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
6
+
7
+ desc "Run all specs"
8
+ Spec::Rake::SpecTask.new(:spec) do |t|
9
+ t.spec_opts << '--options' << ROOT + '/spec/spec.opts'
10
+ t.spec_files = Dir.glob('spec/**/*_spec.rb').map { |f| f.to_s }
11
+ end
data/twuckoo.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{twuckoo}
5
+ s.version = "0.2.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["B\303\241lint \303\211rdi"]
9
+ s.date = %q{2009-06-16}
10
+ s.default_executable = %q{twuckoo}
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
+ s.email = %q{balint@bucionrails.com}
13
+ s.executables = ["twuckoo"]
14
+ s.extra_rdoc_files = ["bin/twuckoo", "CHANGELOG", "lib/duration_string.rb", "lib/environments.rb", "lib/modules/one_line_from_file.rb", "lib/modules/wikipedia_tfa.rb", "lib/twuckoo.rb", "README.markdown", "tasks/spec.rake"]
15
+ s.files = ["bin/twuckoo", "CHANGELOG", "lib/duration_string.rb", "lib/environments.rb", "lib/modules/one_line_from_file.rb", "lib/modules/wikipedia_tfa.rb", "lib/twuckoo.rb", "Manifest", "Rakefile", "README.markdown", "spec/duration_string_spec.rb", "spec/one_line_from_file_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/twuckoo_spec.rb", "spec/wikipedia_tfa_spec.rb", "tasks/spec.rake", "twuckoo.gemspec"]
16
+ s.homepage = %q{http://github.com/balinterdi/twuckoo}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Twuckoo", "--main", "README.markdown"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{twuckoo}
20
+ s.rubygems_version = %q{1.3.3}
21
+ s.summary = %q{A simple yet elegant solution to tweet a message regularly from a file (and in the future: from a webpage, a database, etc.)}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<twibot>, [">= 0.1.7"])
29
+ else
30
+ s.add_dependency(%q<twibot>, [">= 0.1.7"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<twibot>, [">= 0.1.7"])
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: balinterdi-twuckoo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - "B\xC3\xA1lint \xC3\x89rdi"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-16 00:00:00 -07:00
13
+ default_executable: twuckoo
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: twibot
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.7
24
+ version:
25
+ 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
+ email: balint@bucionrails.com
27
+ executables:
28
+ - twuckoo
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - bin/twuckoo
33
+ - CHANGELOG
34
+ - lib/duration_string.rb
35
+ - lib/environments.rb
36
+ - lib/modules/one_line_from_file.rb
37
+ - lib/modules/wikipedia_tfa.rb
38
+ - lib/twuckoo.rb
39
+ - README.markdown
40
+ - tasks/spec.rake
41
+ files:
42
+ - bin/twuckoo
43
+ - CHANGELOG
44
+ - lib/duration_string.rb
45
+ - lib/environments.rb
46
+ - lib/modules/one_line_from_file.rb
47
+ - lib/modules/wikipedia_tfa.rb
48
+ - lib/twuckoo.rb
49
+ - Manifest
50
+ - Rakefile
51
+ - README.markdown
52
+ - spec/duration_string_spec.rb
53
+ - spec/one_line_from_file_spec.rb
54
+ - spec/spec.opts
55
+ - spec/spec_helper.rb
56
+ - spec/twuckoo_spec.rb
57
+ - spec/wikipedia_tfa_spec.rb
58
+ - tasks/spec.rake
59
+ - twuckoo.gemspec
60
+ has_rdoc: false
61
+ homepage: http://github.com/balinterdi/twuckoo
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --line-numbers
65
+ - --inline-source
66
+ - --title
67
+ - Twuckoo
68
+ - --main
69
+ - README.markdown
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "1.2"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project: twuckoo
87
+ rubygems_version: 1.2.0
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: "A simple yet elegant solution to tweet a message regularly from a file (and in the future: from a webpage, a database, etc.)"
91
+ test_files: []
92
+