Skip to content

Commit

Permalink
Added a bunch of tiny things, should have committed more but I got in…
Browse files Browse the repository at this point in the history
… the groove.
  • Loading branch information
jnunemaker committed Jul 6, 2008
1 parent 868cea5 commit d94b6bd
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 29 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
0.2.7 - June 29, 2008
* added #rate_limit_status (Daniel Morrison)
* added source parameter option to Base#post
* added twittergem as source when posting from command line
* Twitter::RateExceeded raised when you hit your limit (Jim O'Leary)
* Twitter::Unavailable raised when twitter returns 503
* Twitter::CantConnect is now more descriptive as to what is the problem when it is raised during a request
* quoting your message when using twitter post on the command line is now optional (Benoit Caccinolo)
* aliased post to p on command line so it's shorter (Benoit Caccinolo)
* unescaped html and added some color in command line view (Miles Z. Sterrett)
* added gemspec (technoweenie, Miles Z. Sterrett)
* Fixed stack trace error on first command line operation (Matt Rose)
0.2.6 - April 2, 2008
* found a more simple way of doing stdin without any extra gem dependencies
0.2.5 - April 2, 2008
Expand Down
24 changes: 18 additions & 6 deletions Manifest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,31 @@ lib/twitter/base.rb
lib/twitter/command.rb
lib/twitter/direct_message.rb
lib/twitter/easy_class_maker.rb
lib/twitter/rate_limit_status.rb
lib/twitter/status.rb
lib/twitter/user.rb
lib/twitter/version.rb
log/debug.log
script/destroy
script/generate
script/txt2html
setup.rb
spec/base_spec.rb
spec/direct_message_spec.rb
spec/fixtures/followers.xml
spec/fixtures/friends.xml
spec/fixtures/friends_for.xml
spec/fixtures/friends_lite.xml
spec/fixtures/friends_timeline.xml
spec/fixtures/public_timeline.xml
spec/fixtures/rate_limit_status.xml
spec/fixtures/status.xml
spec/fixtures/user.xml
spec/fixtures/user_timeline.xml
spec/spec.opts
spec/spec_helper.rb
spec/status_spec.rb
spec/user_spec.rb
tasks/deployment.rake
tasks/environment.rake
tasks/website.rake
test/test_helper.rb
test/unit/base_test.rb
test/unit/direct_message_test.rb
test/unit/status_test.rb
test/unit/user_test.rb
twitter.gemspec
13 changes: 12 additions & 1 deletion lib/twitter.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
%w(uri cgi net/http yaml rubygems hpricot active_support).each { |f| require f }

$:.unshift(File.join(File.dirname(__FILE__)))
require 'twitter/version'
require 'twitter/easy_class_maker'
require 'twitter/base'
require 'twitter/user'
require 'twitter/status'
require 'twitter/direct_message'
require 'twitter/rate_limit_status'
require 'twitter/rate_limit_status'

module Twitter
class Unavailable < StandardError; end
class CantConnect < StandardError; end
class BadResponse < StandardError; end
class UnknownTimeline < ArgumentError; end
class RateExceeded < StandardError; end

SourceName = 'twittergem'
end
40 changes: 26 additions & 14 deletions lib/twitter/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
#
# The private methods in this one are pretty fun. Be sure to check out users, statuses and call.
module Twitter
class Untwitterable < StandardError; end
class CantConnect < Untwitterable; end
class BadResponse < Untwitterable; end
class UnknownTimeline < ArgumentError; end

class Base
# Twitter's url, duh!
@@api_url = 'twitter.com'
Expand Down Expand Up @@ -130,18 +125,25 @@ def leave(id_or_screenname)
end

# Updates your twitter with whatever status string is passed in
def post(status)
def post(status, o={})
options = {}.merge(o)
form_data = {'status' => status}
form_data['source'] = options[:source] if options[:source]
url = URI.parse("http://#{@@api_url}/statuses/update.xml")
req = Net::HTTP::Post.new(url.path)

req.basic_auth(@config[:email], @config[:password])
req.set_form_data({'status' => status})
req.set_form_data(form_data)

response = Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
Status.new_from_xml(parse(response.body).at('status'))
end
alias :update :post

def verify_credentials
request('account/verify_credentials', :auth => true)
end

private
# Converts an hpricot doc to an array of statuses
def statuses(doc)
Expand Down Expand Up @@ -174,14 +176,24 @@ def request(path, options={})

begin
response = Net::HTTP.start(@@api_url, 80) do |http|
req = Net::HTTP::Get.new('/' + path, options[:headers])
req.basic_auth(@config[:email], @config[:password]) if options[:auth]
http.request(req)
req = Net::HTTP::Get.new('/' + path, options[:headers])
req.basic_auth(@config[:email], @config[:password]) if options[:auth]
http.request(req)
end
raise BadResponse unless response.message == 'OK' || response.message == 'Not Modified'
parse(response.body)
rescue
raise CantConnect
rescue => error
raise CantConnect, error.message
end

if %w[200 304].include?(response.code)
response = parse(response.body)
raise RateExceeded if (response/:hash/:error).text =~ /Rate limit exceeded/
response
elsif response.code == '503'
raise Unavailable, response.message
elsif response.code == '401'
raise CantConnect, 'Authentication failed. Check your username and password'
else
raise CantConnect, "Twitter is returning a #{response.code}: #{response.message}"
end
end

Expand Down
20 changes: 12 additions & 8 deletions lib/twitter/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# It is only used and included in the bin/twitter file.
module Twitter
class Command
@@commands = [:post, :timeline, :friends, :friend, :followers, :follower, :featured, :important, :follow, :leave, :d]
@@commands = [:post, :p, :timeline, :friends, :friend, :followers, :follower, :featured, :important, :follow, :leave, :d]

@@template = <<EOF
# .twitter
Expand Down Expand Up @@ -43,20 +43,26 @@ def post
exit(0)
end

post = ARGV.shift
post = if ARGV.size > 1
ARGV.join " "
else
ARGV.shift
end

print "\nSending twitter update"
finished = false
status = nil
progress_thread = Thread.new { until finished; print "."; $stdout.flush; sleep 0.5; end; }
post_thread = Thread.new(binding()) { |b|
status = Twitter::Base.new(config['email'], config['password']).post(post)
status = Twitter::Base.new(config['email'], config['password']).post(post, :source => Twitter::SourceName)
finished = true
}
post_thread.join
progress_thread.join
puts " OK!"
puts "Got it! New twitter created at: #{status.created_at}\n"
end
alias :p :post

# Shows status, time and user for the specified timeline
def timeline
Expand All @@ -67,8 +73,8 @@ def timeline

puts
Twitter::Base.new(config['email'], config['password']).timeline(timeline).each do |s|
puts "#{s.text}\n-- #{s.user.name} at #{s.created_at}"
puts
puts "#{CGI::unescapeHTML(s.text)}\n --\e[34m #{CGI::unescapeHTML(s.user.name)}\e[32m at #{s.created_at}"
puts "\e[0m"
end
end

Expand Down Expand Up @@ -144,8 +150,6 @@ def follower
end

def featured
puts
puts 'This is all implemented, just waiting for twitter to get the api call working'
config = create_or_find_config

puts
Expand Down Expand Up @@ -234,7 +238,7 @@ def create_or_find_config
config = YAML::load open(home + "/.twitter")
rescue
open(home + '/.twitter','w').write(@@template)
config = YAML::load open(home + "/.twitter")
config = YAML::load(@@template)
end

if config['email'] == nil or config['password'] == nil
Expand Down
23 changes: 23 additions & 0 deletions twitter.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Gem::Specification.new do |s|
s.name = %q{twitter}
s.version = "0.2.7"
s.specification_version = 2 if s.respond_to? :specification_version=
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["John Nunemaker"]
s.date = %q{2008-07-6}
s.default_executable = %q{twitter}
s.description = %q{a command line interface for twitter, also a library which wraps the twitter api}
s.email = %q{[email protected]}
s.executables = ["twitter"]
s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "README.txt"]
s.files = ["CHANGELOG", "History.txt", "License.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/twitter", "config/hoe.rb", "config/requirements.rb", "examples/twitter.rb", "lib/twitter.rb", "lib/twitter/base.rb", "lib/twitter/command.rb", "lib/twitter/direct_message.rb", "lib/twitter/easy_class_maker.rb", "lib/twitter/rate_limit_status.rb", "lib/twitter/status.rb", "lib/twitter/user.rb", "lib/twitter/version.rb", "script/destroy", "script/generate", "script/txt2html", "setup.rb", "spec/base_spec.rb", "spec/direct_message_spec.rb", "spec/fixtures/followers.xml", "spec/fixtures/friends.xml", "spec/fixtures/friends_for.xml", "spec/fixtures/friends_lite.xml", "spec/fixtures/friends_timeline.xml", "spec/fixtures/public_timeline.xml", "spec/fixtures/rate_limit_status.xml", "spec/fixtures/status.xml", "spec/fixtures/user.xml", "spec/fixtures/user_timeline.xml", "spec/spec.opts", "spec/spec_helper.rb", "spec/status_spec.rb", "spec/user_spec.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/website.rake"]
s.has_rdoc = true
s.homepage = %q{http://twitter.rubyforge.org}
s.rdoc_options = ["--main", "README.txt"]
s.require_paths = ["lib"]
s.rubyforge_project = %q{twitter}
s.rubygems_version = %q{1.1.1}
s.summary = %q{a command line interface for twitter, also a library which wraps the twitter api}
s.add_dependency(%q<hpricot>, [">= 0"])
s.add_dependency(%q<activesupport>, [">= 0"])
end

0 comments on commit d94b6bd

Please sign in to comment.