hackershout 0.1.0

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use ruby-1.9.2@hackershout
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in hackershout.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(/^spec\/(.*)_spec.rb/)
6
+ watch(/^lib\/(.*)\.rb/) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch(/^spec\/spec_helper.rb/) { "spec" }
8
+ end
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task :default => :spec
11
+ task :test => [:spec]
data/Readme.md ADDED
@@ -0,0 +1,92 @@
1
+ #Hackershout
2
+
3
+ Shout your hackerness to the world!
4
+
5
+ Hackershout lets you promote your open-source work on the major Ruby (and geek
6
+ related) community blogs (Reddit, Hackernews and RubyFlow) via a nice command
7
+ line interface.
8
+
9
+ ##Install
10
+
11
+ $ gem install hackershout
12
+
13
+ ##Known caveats
14
+
15
+ Publishing to Reddit is not available yet.
16
+
17
+ ##Notes
18
+
19
+ Through hackershout you publish an **URL** and a **text**. To link the URL from
20
+ the text you just have to use the special `<link>` tag. Note that for certain
21
+ sites, such as RubyFlow, you _have to link_ the URL from the text, since there
22
+ is no separate URL field. Hackershout will omit the special tag where it
23
+ doesn't need it (for example, in Reddit).
24
+
25
+ You can add additional links with normal HTML `<a>` tags.
26
+
27
+ Given `http://rubygems.org/gems/my_gem` as an URL, an example of a message
28
+ would be:
29
+
30
+ Hey! I have released <link>some awesome open-source gem</link> that is
31
+ going to save the world. Check it out! You can also grab the source code on
32
+ <a href="http://github.com/me/my_gem">Github</a> if you want.
33
+
34
+ This will publish in Reddit like this:
35
+
36
+ URL: http://rubygems.org/gems/my_gem
37
+ TEXT: Hey! I have released some awesome open-source gem that is going to
38
+ save the world. Check it out! You can also grab the source code on
39
+ <a href="http://github.com/me/my_gem">Github</a> if you want.
40
+
41
+ And on RubyFlow (where there is no separate URL field) like this:
42
+
43
+ TEXT: Hey! I have released <a href="http://rubygems.org/gems/my_gem">some
44
+ awesome open-source gem</a> that is going to save the world. Check it out!
45
+ You can also grab the source code on <a href="http://github.com/me/my_gem">
46
+ Github</a> if you want.
47
+
48
+ ##Usage
49
+
50
+ $ hackershout
51
+
52
+ :: Welcome to hackershout! ::
53
+
54
+ Type the URL you want to share: http://rubygems.com/gems/my_gem
55
+ Enter a brief, descriptive title: Released MyGem 1.0!
56
+
57
+ Bear in mind that some services may require a more extended text aside from the title.
58
+ Type your message (two ENTERs to finish):
59
+ Hey! I have released <link>some awesome open-source gem</link> that is
60
+ going to save the world. Check it out! You can also grab the source code
61
+ on <a href="http://github.com/me/my_gem">Github</a> if you want.(enter)
62
+ (enter)
63
+ Type some tags separated by comma (i.e. ruby, rails, bdd): ruby, parsing
64
+
65
+ ...Got it! Now where would you want to spread the word?
66
+ Ruby Reddit (y/n)? y
67
+ Sorry, I don't have your Ruby Reddit credentials.
68
+ E-mail: my.email@gmail.com
69
+ Password: ********
70
+ Saved! You won't have to enter your credentials for Ruby Reddit again.
71
+ Hackernews (y/n)? y
72
+ RubyFlow (y/n)? n
73
+ Fine.
74
+ Posting to Ruby Reddit...........ok
75
+ Posting to Hackernews............ok
76
+
77
+ Done. Happy hacking! :)
78
+
79
+ ##Contribute!
80
+
81
+ * Fork the project.
82
+ * Make your feature addition or bug fix.
83
+ * Add specs for it. This is important so I don't break it in a future
84
+ version unintentionally.
85
+ * Commit, do not mess with rakefile, version, or history.
86
+ If you want to have your own version, that is fine but bump version
87
+ in a commit by itself I can ignore when I pull.
88
+ * Send me a pull request. Bonus points for topic branches.
89
+
90
+ ## Copyright
91
+
92
+ Copyright (c) 2011 Codegram. See LICENSE for details.
data/bin/hackershout ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $: << 'lib'
3
+ require 'hackershout'
4
+
5
+ Hackershout.run
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "hackershout/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "hackershout"
7
+ s.version = Hackershout::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Josep M. Bach", "Josep Jaume Rey", "Oriol Gual"]
10
+ s.email = ["info@codegram.com"]
11
+ s.homepage = "http://github.com/codegram/hackershout"
12
+ s.summary = %q{Shout your hackerness! Promote your work on Reddit, Hackernews and Ruby Flow.}
13
+ s.description = %q{Shout your hackerness! Promote your work on Reddit, Hackernews and Ruby Flow.}
14
+
15
+ s.rubyforge_project = "hackershout"
16
+
17
+ s.add_runtime_dependency 'nokogiri'
18
+ s.add_runtime_dependency 'mechanize'
19
+
20
+ s.add_development_dependency 'rspec', '~> 2.5.0'
21
+ s.add_development_dependency 'guard'
22
+ s.add_development_dependency 'guard-rspec'
23
+ s.add_development_dependency 'rb-fsevent'
24
+ s.add_development_dependency 'vcr'
25
+
26
+ s.files = `git ls-files`.split("\n")
27
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
28
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
29
+ s.require_paths = ["lib"]
30
+ end
@@ -0,0 +1,83 @@
1
+ require 'hackershout/output'
2
+
3
+ module Hackershout
4
+ class Base
5
+ include Output
6
+
7
+ def initialize(options = {})
8
+ @url = options[:url]
9
+ @title = options[:title]
10
+ @message = options[:message]
11
+ @tags = options[:tags] || []
12
+ @providers = options[:providers] || []
13
+ end
14
+
15
+ def run
16
+ welcome_banner
17
+ @url = ask_for_url
18
+ @title = ask_for_title
19
+ @message = ask_for_message
20
+ @tags = ask_for_tags
21
+ providers_banner
22
+
23
+ @providers = ask_for_providers
24
+ post_to_providers
25
+ end
26
+
27
+ def welcome_banner
28
+ print ":: Welcome to hackershout! ::"
29
+ blank
30
+ end
31
+
32
+ def ask_for_url
33
+ print "Type the URL you want to share: "
34
+ gets.chomp.strip
35
+ end
36
+
37
+ def ask_for_title
38
+ print "Enter a brief, descriptive title: "
39
+ gets.chomp.strip
40
+ end
41
+
42
+ def ask_for_message
43
+ print "Bear in mind that some services may require a more extended text aside from the title."
44
+ print "Type your message (two ENTERs to finish): "
45
+ $/ = "\n\n"
46
+ gets.chomp.strip.tap do
47
+ # Restore EOM char
48
+ $/ = "\n"
49
+ end
50
+ end
51
+
52
+ def ask_for_tags
53
+ print "Type some tags separated by comma (i.e. ruby, rails, bdd): "
54
+ gets.chomp.strip.split(',').map(&:strip)
55
+ end
56
+
57
+ def providers_banner
58
+ print "...Got it! Now where would you want to spread the word?"
59
+ end
60
+
61
+ def ask_for_providers
62
+ Provider.list.keys.select do |provider|
63
+ Provider.wants?(provider)
64
+ end
65
+ end
66
+
67
+ def post_to_providers
68
+ print "Fine."
69
+ @providers.map do |provider|
70
+ eval("Provider::#{provider.capitalize}").new({
71
+ url: @url,
72
+ title: @title,
73
+ message: @message,
74
+ tags: @tags,
75
+ })
76
+ end.each do |provider|
77
+ provider.publish
78
+ end
79
+ puts "Done. Happy hacking! :)\n"
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,13 @@
1
+ module Hackershout
2
+ module Output
3
+
4
+ def print(str)
5
+ $stdout.print "\n" + str
6
+ end
7
+
8
+ def blank
9
+ print "\n"
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ require 'mechanize'
2
+ require 'nokogiri'
3
+
4
+ Mechanize.html_parser = Nokogiri::HTML
5
+
6
+ module Hackershout
7
+ module Provider
8
+ class Base
9
+ attr_reader :agent
10
+
11
+ include Output
12
+
13
+ def initialize(options = {})
14
+ @name = self.class.name.split("::").last
15
+ @url = options[:url]
16
+ @title = options[:title]
17
+ @tags = options[:tags]
18
+ @message = options[:message]
19
+
20
+ creds = YAML.load(File.read(File.join(File.expand_path('~'), '.hackershoutrc')))[@name.downcase]
21
+ raise "Can't find credentials on ~/.hackershoutrc for #{@name}" unless creds
22
+
23
+ @login = creds["login"]
24
+ @password = creds["password"]
25
+ @agent = Mechanize.new
26
+ end
27
+
28
+ def publish
29
+ print "Posting to #{@name}..."
30
+ post unless ENV['NOSEND']
31
+ print "Posted to #{@name}!"
32
+ end
33
+
34
+ def post
35
+ raise NotImplementedError
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ module Hackershout
2
+ module Provider
3
+ class Hackernews < Base
4
+
5
+ URL = {
6
+ :login => 'http://news.ycombinator.com/submit'
7
+ }
8
+
9
+ def post
10
+ page = agent.get(URL[:login])
11
+ login_form = page.forms.first
12
+ login_form.u = @login
13
+ login_form.p = @password
14
+ page = login_form.submit
15
+ submit(page)
16
+ end
17
+
18
+ private
19
+
20
+ def submit(submit_page)
21
+ form = submit_page.forms.first
22
+ form.t = @title
23
+ form.u = @url
24
+ form.submit
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module Hackershout
2
+ module Provider
3
+ class Reddit < Base
4
+
5
+ URL = {
6
+ :login => 'http://www.reddit.com/r/ruby/',
7
+ :submit => 'http://www.reddit.com/r/ruby/submit',
8
+ }
9
+
10
+ # Not logging in! :(
11
+ def post
12
+ raise NotImplementedError
13
+ page = agent.get(URL[:login])
14
+ login_form = page.forms_with(:action => 'http://www.reddit.com/r/ruby/post/login').first
15
+ login_form.user = @login
16
+ login_form.passwd = @password
17
+ page = login_form.submit
18
+ puts page.links_with(:text => 'logout').inspect
19
+ page = page.links_with(:text => 'Submit a link').first.click
20
+ puts page.inspect
21
+
22
+ rescue Mechanize::ResponseCodeError=>e
23
+ puts "#{@name} is unavailable for now. Please try in a few minutes. The server gave the following reason:"
24
+ puts e.inspect
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ module Hackershout
2
+ module Provider
3
+ class Rubyflow < Base
4
+
5
+ URL = {
6
+ :login => 'http://www.rubyflow.com/login'
7
+ }
8
+
9
+ def post
10
+ page = agent.get(URL[:login])
11
+ login_form = page.form_with(:action => '/session')
12
+ login_form.login = @login
13
+ login_form.password = @password
14
+ page = login_form.submit
15
+ page = page.link_with(:href => /items\/new/).click
16
+ submit(page)
17
+ end
18
+
19
+ private
20
+
21
+ def submit(submit_page)
22
+ form = submit_page.form_with(:action => '/items')
23
+ form['item[title]'] = @title
24
+ form['item[content]'] = process(@message)
25
+ form.submit
26
+ end
27
+
28
+ def process(message)
29
+ message.gsub!('<link>', "<a href=\"#{@url}\">")
30
+ message.gsub!('</link>', "</a>")
31
+ message
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,67 @@
1
+ module Hackershout
2
+ module Provider
3
+ class << self
4
+
5
+ include Output
6
+
7
+ def list
8
+ {
9
+ # :reddit => 'Ruby Reddit',
10
+ :hackernews => 'Hackernews',
11
+ :rubyflow => 'RubyFlow',
12
+ }
13
+ end
14
+
15
+ def wants?(provider)
16
+ name = list[provider]
17
+ print "\t#{name} (y/n)? "
18
+ return case gets.chomp
19
+ when 'y'
20
+ check_credentials_for(provider)
21
+ when 'n'
22
+ false
23
+ else
24
+ blank
25
+ print "I don't understand. Just type y for yes and n for no :)"
26
+ wants?(provider)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def check_credentials_for(provider)
33
+ credentials = if File.exists?(File.join(File.expand_path('~'), '.hackershoutrc'))
34
+ YAML.load(File.read(File.join(File.expand_path('~'), '.hackershoutrc')))
35
+ else
36
+ ask_for_credentials(provider)
37
+ end
38
+
39
+ if credentials[provider.to_s] &&
40
+ credentials[provider.to_s]["login"] &&
41
+ credentials[provider.to_s]["password"]
42
+ true
43
+ else
44
+ ask_for_credentials(provider)
45
+ end
46
+ end
47
+
48
+ def ask_for_credentials(provider)
49
+ print "Sorry, I don't have your #{list[provider]} credentials."
50
+ print "\tLogin: "
51
+ login = gets.chomp.strip
52
+ system('stty -echo')
53
+ print "\tPassword: "
54
+ password = gets.chomp.strip
55
+ system('stty echo')
56
+ File.open(File.join(File.expand_path('~'), '.hackershoutrc'), 'a') do |file|
57
+ file.write "\n#{provider}:"
58
+ file.write "\n login: #{login}"
59
+ file.write "\n password: #{password}"
60
+ file.write "\n"
61
+ end
62
+ { provider => { "login" => login, "password" => password } }
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module Hackershout
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,15 @@
1
+ require 'hackershout/output'
2
+ require 'hackershout/provider'
3
+ require 'hackershout/provider/base'
4
+ require 'hackershout/provider/reddit'
5
+ require 'hackershout/provider/hackernews'
6
+ require 'hackershout/provider/rubyflow'
7
+ require 'hackershout/base'
8
+
9
+ module Hackershout
10
+ class << self
11
+ def run
12
+ Base.new.run
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,137 @@
1
+ require 'spec_helper'
2
+
3
+ module Hackershout
4
+ describe Base do
5
+
6
+ describe ".run" do
7
+ before do
8
+ subject.stub(:welcome_banner)
9
+ subject.stub(:ask_for_url)
10
+ subject.stub(:ask_for_message)
11
+ subject.stub(:ask_for_title)
12
+ subject.stub(:ask_for_tags)
13
+ subject.stub(:providers_banner)
14
+ subject.stub(:ask_for_providers)
15
+ subject.stub(:post_to_providers)
16
+ end
17
+ it 'calls welcome banner' do
18
+ subject.should_receive(:welcome_banner)
19
+ subject.run
20
+ end
21
+ it 'calls ask_for_url' do
22
+ subject.should_receive(:ask_for_url)
23
+ subject.run
24
+ end
25
+ it 'calls ask_for_title' do
26
+ subject.should_receive(:ask_for_title)
27
+ subject.run
28
+ end
29
+ it 'calls ask_for_message' do
30
+ subject.should_receive(:ask_for_message)
31
+ subject.run
32
+ end
33
+ it 'calls ask_for_tags' do
34
+ subject.should_receive(:ask_for_tags)
35
+ subject.run
36
+ end
37
+ it 'calls providers_banner' do
38
+ subject.should_receive(:providers_banner)
39
+ subject.run
40
+ end
41
+ it 'calls ask_for_providers' do
42
+ subject.should_receive(:ask_for_providers)
43
+ subject.run
44
+ end
45
+ end
46
+
47
+ describe "#welcome_banner" do
48
+ it 'prints the welcome banner' do
49
+ subject.should_receive(:blank).any_number_of_times
50
+ subject.should_receive(:print).with(":: Welcome to hackershout! ::")
51
+ subject.welcome_banner
52
+ end
53
+ end
54
+
55
+ describe "#ask_for_url" do
56
+ it 'asks for the url and returns it' do
57
+ subject.should_receive(:print).with("Type the URL you want to share: ")
58
+ subject.should_receive(:gets).and_return ' http://rubygems.org/gems/my_gem '
59
+ subject.ask_for_url.should == 'http://rubygems.org/gems/my_gem'
60
+ end
61
+ end
62
+
63
+ describe "#ask_for_title" do
64
+ it 'asks for the title and returns it' do
65
+ subject.should_receive(:print).with("Enter a brief, descriptive title: ")
66
+ subject.should_receive(:gets).and_return ' Released my gem: a nifty gem to eradicate hunger! '
67
+ subject.ask_for_title.should == 'Released my gem: a nifty gem to eradicate hunger!'
68
+ end
69
+ end
70
+
71
+ describe "#ask_for_message" do
72
+ it 'asks for the message and returns it' do
73
+ subject.should_receive(:print).with("Bear in mind that some services may require a more extended text aside from the title.")
74
+ subject.should_receive(:print).with("Type your message (two ENTERs to finish): ")
75
+ subject.should_receive(:gets).and_return("""
76
+ Hey! I have released <link>some awesome open-source gem</link> that is
77
+ going to save the world.\nCheck it out! You can also grab the source code
78
+ on <a href=\"http://github.com/me/my_gem\">Github</a> if you want.
79
+
80
+ """)
81
+ subject.ask_for_message
82
+ end
83
+ end
84
+
85
+ describe "#ask_for_tags" do
86
+ it 'asks for the tags and returns them' do
87
+ subject.should_receive(:print).with("Type some tags separated by comma (i.e. ruby, rails, bdd): ")
88
+ subject.should_receive(:gets).and_return ' ruby , bdd, rails, parsing '
89
+ subject.ask_for_tags.should == %w( ruby bdd rails parsing )
90
+ end
91
+ end
92
+
93
+ describe "#providers_banner" do
94
+ it 'prints the providers banner' do
95
+ subject.should_receive(:print).with("...Got it! Now where would you want to spread the word?")
96
+ subject.providers_banner
97
+ end
98
+ end
99
+
100
+ describe "#ask_for_providers" do
101
+ it 'asks for providers' do
102
+ providers = [:reddit, :hackernews, :rubyflow]
103
+ Provider.stub_chain('list.keys').and_return providers
104
+ Provider.should_receive(:wants?).with(:reddit).and_return true
105
+ Provider.should_receive(:wants?).with(:hackernews).and_return false
106
+ Provider.should_receive(:wants?).with(:rubyflow).and_return true
107
+
108
+ subject.ask_for_providers.should == [:reddit, :rubyflow]
109
+ end
110
+ end
111
+
112
+ describe "#post_to_providers" do
113
+ it 'instantiates each provider and calls #publish on it' do
114
+ args = {
115
+ :url => 'http://rubygems.org/gems/my_gem',
116
+ :title => 'Released MyGem!',
117
+ :tags => ['ruby', 'bdd'],
118
+ :message => 'Hello!',
119
+ }
120
+ base = Base.new({:providers => [:reddit, :hackernews]}.update(args))
121
+ base.stub(:print)
122
+
123
+ hackernews = double :provider
124
+ reddit = double :provider
125
+
126
+ Provider::Hackernews.should_receive(:new).with(args).and_return hackernews
127
+ Provider::Reddit.should_receive(:new).with(args).and_return reddit
128
+
129
+ hackernews.should_receive(:publish)
130
+ reddit.should_receive(:publish)
131
+
132
+ base.post_to_providers
133
+ end
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ module Hackershout
4
+ module Provider
5
+ describe Base do
6
+
7
+ # Test only base class. Each provider only implements #post with pure Mechanize logic.
8
+
9
+ before do
10
+ File.stub(:read).and_return """
11
+ base:
12
+ login: my.email@gmail.com
13
+ password: mypassword
14
+ """
15
+ end
16
+
17
+ describe "#initialize" do
18
+ it 'reads the credentials and stores them' do
19
+ base = Base.new(:url => 'url',
20
+ :tags => ['my', 'tags'],
21
+ :message => 'message')
22
+
23
+ base.instance_variable_get(:@login).should eq('my.email@gmail.com')
24
+ base.instance_variable_get(:@password).should eq('mypassword')
25
+ base.instance_variable_get(:@agent).should be_a(Mechanize)
26
+ end
27
+ end
28
+
29
+ describe "#publish" do
30
+ it 'logs in and posts' do
31
+ base = Base.new(:url => 'url',
32
+ :tags => ['my', 'tags'],
33
+ :message => 'message')
34
+
35
+ base.should_receive(:post)
36
+
37
+ base.publish
38
+ end
39
+ end
40
+
41
+ it 'crap' do
42
+ File.stub(:read).and_return """
43
+ hackernews:
44
+ login: codegram
45
+ password: codgamerP90
46
+ """
47
+ Hackernews.new(:title => 'my title', :message => 'my message', :url => 'http://google.com').post
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ module Hackershout
4
+ describe Provider do
5
+
6
+ describe "#list" do
7
+ it 'returns a hash' do
8
+ subject.list.should == {
9
+ :reddit => 'Ruby Reddit',
10
+ :hackernews => 'Hackernews',
11
+ :rubyflow => 'RubyFlow',
12
+ }
13
+ end
14
+ end
15
+
16
+ describe "#wants?(provider)" do
17
+ before do
18
+ subject.should_receive(:print).with("\tRuby Reddit (y/n)? ")
19
+ end
20
+ context 'if the user wants to publish on a provider' do
21
+ it 'checks the credentials' do
22
+ subject.should_receive(:gets).and_return 'y'
23
+ subject.should_receive(:check_credentials_for).with(:reddit)
24
+ subject.wants?(:reddit)
25
+ end
26
+ end
27
+ context 'if the user doesn\'t want' do
28
+ it 'returns false' do
29
+ subject.should_receive(:gets).and_return 'n'
30
+ subject.wants?(:reddit).should be_false
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "#check_credentials_for(provider)" do
36
+
37
+ context 'if the credentials exist' do
38
+ it 'returns true' do
39
+ File.stub(:read).and_return "reddit:\n login: my.email@gmail.com\n password: mypassword"
40
+ subject.should_not_receive(:ask_for_credentials)
41
+ subject.send(:check_credentials_for, :reddit).should be_true
42
+ end
43
+ end
44
+
45
+ context 'otherwise' do
46
+ it 'asks for them' do
47
+ File.stub(:read).and_return "hackernews:\n login: my.email@gmail.com\n password: mypassword"
48
+ subject.should_receive(:ask_for_credentials).with(:reddit)
49
+ subject.send(:check_credentials_for, :reddit)
50
+ end
51
+ end
52
+
53
+ context "if the file doesn't even exist" do
54
+ it 'asks for the credentials as well' do
55
+ File.stub(:read).and_raise Errno::ENOENT
56
+ subject.should_receive(:ask_for_credentials).with(:reddit)
57
+ subject.send(:check_credentials_for, :reddit)
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ describe "#ask_for_credentials(provider)" do
64
+ it 'asks for the credentials and saves them into ~/.hackershoutrc' do
65
+ subject.stub(:print)
66
+ file = double :file
67
+ subject.should_receive(:gets).and_return 'my.email@gmail.com'
68
+ subject.should_receive(:gets).and_return 'mypassword'
69
+ File.should_receive(:open).and_yield file
70
+
71
+ file.should_receive(:write).with "\nreddit:"
72
+ file.should_receive(:write).with "\n login: my.email@gmail.com"
73
+ file.should_receive(:write).with "\n password: mypassword"
74
+
75
+ subject.send(:ask_for_credentials, :reddit)
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hackershout do
4
+
5
+ describe ".run" do
6
+ it 'calls run on a new Base instance' do
7
+ Hackershout::Base.should_receive(:new).and_return(double(:base).tap { |b|
8
+ b.should_receive(:run)
9
+ })
10
+ subject.run
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require 'hackershout'
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hackershout
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Josep M. Bach
13
+ - Josep Jaume Rey
14
+ - Oriol Gual
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-02-17 00:00:00 +01:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: nokogiri
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: mechanize
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 2
58
+ - 5
59
+ - 0
60
+ version: 2.5.0
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: guard
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ type: :development
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: guard-rspec
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ type: :development
88
+ version_requirements: *id005
89
+ - !ruby/object:Gem::Dependency
90
+ name: rb-fsevent
91
+ prerelease: false
92
+ requirement: &id006 !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ type: :development
101
+ version_requirements: *id006
102
+ - !ruby/object:Gem::Dependency
103
+ name: vcr
104
+ prerelease: false
105
+ requirement: &id007 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ segments:
111
+ - 0
112
+ version: "0"
113
+ type: :development
114
+ version_requirements: *id007
115
+ description: Shout your hackerness! Promote your work on Reddit, Hackernews and Ruby Flow.
116
+ email:
117
+ - info@codegram.com
118
+ executables:
119
+ - hackershout
120
+ extensions: []
121
+
122
+ extra_rdoc_files: []
123
+
124
+ files:
125
+ - .gitignore
126
+ - .rspec
127
+ - .rvmrc
128
+ - Gemfile
129
+ - Guardfile
130
+ - Rakefile
131
+ - Readme.md
132
+ - bin/hackershout
133
+ - hackershout.gemspec
134
+ - lib/hackershout.rb
135
+ - lib/hackershout/base.rb
136
+ - lib/hackershout/output.rb
137
+ - lib/hackershout/provider.rb
138
+ - lib/hackershout/provider/base.rb
139
+ - lib/hackershout/provider/hackernews.rb
140
+ - lib/hackershout/provider/reddit.rb
141
+ - lib/hackershout/provider/rubyflow.rb
142
+ - lib/hackershout/version.rb
143
+ - spec/hackershout/base_spec.rb
144
+ - spec/hackershout/provider/base_spec.rb
145
+ - spec/hackershout/provider_spec.rb
146
+ - spec/hackershout_spec.rb
147
+ - spec/spec_helper.rb
148
+ has_rdoc: true
149
+ homepage: http://github.com/codegram/hackershout
150
+ licenses: []
151
+
152
+ post_install_message:
153
+ rdoc_options: []
154
+
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ segments:
163
+ - 0
164
+ version: "0"
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ segments:
171
+ - 0
172
+ version: "0"
173
+ requirements: []
174
+
175
+ rubyforge_project: hackershout
176
+ rubygems_version: 1.3.7
177
+ signing_key:
178
+ specification_version: 3
179
+ summary: Shout your hackerness! Promote your work on Reddit, Hackernews and Ruby Flow.
180
+ test_files:
181
+ - spec/hackershout/base_spec.rb
182
+ - spec/hackershout/provider/base_spec.rb
183
+ - spec/hackershout/provider_spec.rb
184
+ - spec/hackershout_spec.rb
185
+ - spec/spec_helper.rb