PerfectlyNormal-Twitorious 0.2.9 → 0.3.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/TODO CHANGED
@@ -12,5 +12,9 @@
12
12
  * Daemon that runs in the background
13
13
  * Let the app run in a loop where it constantly prompts for new tweets
14
14
  * Make more of a CLI
15
+ * Display how many more characters there's room for
15
16
  * Update the timeline and get text-tweets in the app
16
17
  * Open profile pages if there's a username in the tweet
18
+ * Support subscribing and unsubscribing to people
19
+ * Create the ~/twit-file if it doesn't exist
20
+ * Tab-complete followers
data/bin/twit CHANGED
@@ -16,7 +16,39 @@ module Twitorious
16
16
 
17
17
  while true
18
18
  begin
19
+ Readline.completion_append_character = " "
20
+ Readline.completion_proc = Proc.new do |url|
21
+ if !url.match(/^(ftp|http|https):\/\//)
22
+ print "\a"
23
+ []
24
+ elsif !@config[:url_shortening]
25
+ print "\a"
26
+ []
27
+ else
28
+ # FIXME: Maybe add some magic here, so we don't need a 'case'
29
+ case @config.url_shortening[:service].downcase
30
+ when "bitly":
31
+ if(!@config.url_shortening[:user] || !@config.url_shortening[:pass])
32
+ puts "Invalid configuration for Bit.ly"
33
+ []
34
+ else
35
+ bitly = Twitorious::URL::Bitly.new(@config.url_shortening[:user], @config.url_shortening[:pass])
36
+ [bitly.shorten(url)]
37
+ end
38
+ when "isgd":
39
+ [Twitorious::URL::Isgd.new.shorten(url)]
40
+ else
41
+ []
42
+ end
43
+ end
44
+ end
19
45
  status = Readline.readline("> ", true)
46
+
47
+ unless status # So we quit with a ^D
48
+ puts # And I hate that there's no newline before the prompt by default
49
+ exit
50
+ end
51
+
20
52
  raise Twitorious::TooLongUpdate.new(status) if status.length > 140
21
53
 
22
54
  cmd, *args = status.split(" ")
data/lib/twitorious.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Twitorious
2
- VERSION = '0.2.9'
2
+ VERSION = '0.3.1'
3
3
 
4
4
  class TooLongUpdate < StandardError; end
5
5
 
@@ -42,4 +42,8 @@ require 'twitorious/timeline'
42
42
  require 'twitorious/update'
43
43
  require 'twitorious/image'
44
44
  require 'twitorious/notifier'
45
- require 'twitorious/api/twitter'
45
+ require 'twitorious/api/twitter'
46
+ require 'twitorious/auth/basic'
47
+ require 'twitorious/auth/oauth'
48
+ require 'twitorious/url/bitly'
49
+ require 'twitorious/url/isgd'
@@ -10,14 +10,30 @@ module Twitorious
10
10
  @config = config
11
11
  @site = site
12
12
  @notifier = Twitorious::Notifier.new
13
+ @auth = @site[:oauth_enabled] ?
14
+ Twitorious::Auth::OAuth.new :
15
+ Twitorious::Auth::Basic.new(@site[:user], @site[:pass])
16
+
17
+ if(@site[:oauth_enabled] && !@site[:oauth_authorized])
18
+ rt = @auth.get_request_token
19
+ puts "You need to authorize first"
20
+ %x{open #{@auth.authorize_url}}
21
+ puts "Press enter when done"
22
+ gets
23
+ at = rt.get_access_token
24
+ @site[:oauth_authorized] = true
25
+ @site[:oauth_token] = at.token
26
+ @site[:oauth_secret] = at.secret
27
+ end
28
+
29
+ if @site[:oauth_enabled] && @site[:oauth_authorized]
30
+ @auth.set_token(@site[:oauth_token], @site[:oauth_secret])
31
+ end
13
32
  end
14
33
 
15
34
  def update(status)
16
35
  puts "Updating #{@site[:name]}"
17
- req = Net::HTTP::Post.new(@site[:url].path + "/statuses/update.json", { "User-Agent" => "Twitorious/#{Twitorious::VERSION}"})
18
- req.basic_auth @site[:user], @site[:pass]
19
- req.set_form_data({'status' => status}, ';')
20
- res = Net::HTTP.new(@site[:url].host, @site[:url].port).start { |http| http.request(req) }
36
+ res = @auth.post(@site[:url], @site[:url].path + "/statuses/update.json", {"status" => status})
21
37
  end
22
38
 
23
39
  def fetch_timeline
@@ -25,9 +41,9 @@ module Twitorious
25
41
 
26
42
  path = @site[:url].path + "/statuses/friends_timeline.json"
27
43
  path += "?count=200&since_id=#{@site[:timeline_since_id]}" if @site[:timeline_since_id]
28
- res = fetch_body(@site[:url].host, @site[:url].port, path, @site[:user], @site[:pass])
44
+ body = @auth.get(@site[:url], path)
29
45
 
30
- updates = JSON.parse(res)
46
+ updates = JSON.parse(body)
31
47
  puts " No updates" if updates.empty?
32
48
  return if updates.empty?
33
49
 
@@ -42,10 +58,11 @@ module Twitorious
42
58
  puts "Fetching mentions from #{@site[:name]}"
43
59
 
44
60
  path = @site[:url].path + "/statuses/mentions.json"
61
+ path = @site[:url].path + "/statuses/replies.json" if @site[:name] == "Identi.ca"
45
62
  path += "?since_id=#{@site[:mentions_since_id]}" if @site[:mentions_since_id]
46
- res = fetch_body(@site[:url].host, @site[:url].port, path, @site[:user], @site[:pass])
63
+ body = @auth.get(@site[:url], path)
47
64
 
48
- updates = JSON.parse(res)
65
+ updates = JSON.parse(body)
49
66
  puts " No new mentions" if updates.empty?
50
67
  return if updates.empty?
51
68
 
@@ -60,30 +77,6 @@ module Twitorious
60
77
 
61
78
  private
62
79
 
63
- def fetch_body(host, port, path, username = nil, password = nil)
64
- res = nil
65
- begin
66
- Net::HTTP.start(host, port) do |http|
67
- req = Net::HTTP::Get.new(path, { "User-Agent" => "Twitorious/#{Twitorious::VERSION}"})
68
- req.basic_auth username, password if username
69
- res = http.request(req)
70
- end
71
- rescue => e
72
- $stderr.puts "Unhandled exception! #{e.message}"
73
- rescue Timeout::Error
74
- $stderr.puts "Request to #{host} timed out. Retrying in five seconds"
75
- sleep 5
76
- retry
77
- end
78
-
79
- if res.kind_of?(Net::HTTPNotFound)
80
- $stderr.puts "404 Not Found! #{host}:#{port}/#{path}"
81
- return "{}"
82
- elsif res.kind_of?(Net::HTTPOK)
83
- return res.body
84
- end
85
- end
86
-
87
80
  def show_notifications(updates)
88
81
  updates.each do |update|
89
82
  image = Twitorious::Image.from_url(update["user"]["profile_image_url"], @config.image_store)
@@ -0,0 +1,60 @@
1
+ module Twitorious
2
+ module Auth
3
+ class Basic
4
+ def initialize(username, password)
5
+ @username = username
6
+ @password = password
7
+ end
8
+
9
+ def get(url, path)
10
+ res = nil
11
+ begin
12
+ Net::HTTP.start(url.host, url.port) do |http|
13
+ req = Net::HTTP::Get.new(path, { "User-Agent" => "Twitorious/#{Twitorious::VERSION}"})
14
+ req.basic_auth @username, @password
15
+ res = http.request(req)
16
+ end
17
+ rescue => e
18
+ $stderr.puts "Unhandled exception! #{e.message}"
19
+ rescue Timeout::Error
20
+ $stderr.puts "Request to #{url.host} timed out. Retrying in five seconds"
21
+ sleep 5
22
+ retry
23
+ end
24
+
25
+ case res.code.to_i
26
+ when 400:
27
+ $stderr.puts "400 Rate Limited!"
28
+ return "{}"
29
+ when 401:
30
+ $stderr.puts "401 Unauthorized"
31
+ return "{}"
32
+ when 403:
33
+ $stderr.puts "403: #{res.message}!"
34
+ $stderr.puts res.body
35
+ return "{}"
36
+ when 404:
37
+ $stderr.puts "404 Not Found! #{url.host}:#{url.port}#{path}"
38
+ return "{}"
39
+ when 500:
40
+ $stderr.puts "An internal server error occured. (#{res.code}): #{res.message}"
41
+ return "{}"
42
+ when 502..503:
43
+ $stderr.puts "Unavailable!"
44
+ return "{}"
45
+ end
46
+
47
+ return res.body
48
+ end
49
+
50
+ def post(url, path, form_data)
51
+ req = Net::HTTP::Post.new(path, { "User-Agent" => "Twitorious/#{Twitorious::VERSION}"})
52
+ req.basic_auth @username, @password
53
+ req.set_form_data(form_data, ';')
54
+ res = Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
55
+
56
+ return res.body
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,44 @@
1
+ require 'oauth'
2
+ require 'oauth/consumer'
3
+
4
+ module Twitorious
5
+ module Auth
6
+ class OAuth
7
+ def initialize
8
+ @consumer = ::OAuth::Consumer.new(
9
+ "oZglZozO6F3p1Ed8n9F6fw",
10
+ "onR6S9HS54D40Qg1KfI16c9A72KRoJKJwaXe73Tv0",
11
+ { :site => "http://twitter.com" })
12
+ end
13
+
14
+ def get_request_token
15
+ @request_token = @consumer.get_request_token
16
+ @request_token
17
+ end
18
+
19
+ def authorize_url
20
+ @request_token.authorize_url
21
+ end
22
+
23
+ def set_token(token, secret)
24
+ @token, @secret = token, secret
25
+ get_access_token
26
+ end
27
+
28
+ def get_access_token
29
+ @access_token ||= ::OAuth::AccessToken.new(@consumer, @token, @secret)
30
+ @access_token
31
+ end
32
+
33
+ def get(url, path)
34
+ res = @access_token.get path
35
+ return res.body
36
+ end
37
+
38
+ def post(url, path, form_data)
39
+ res = @access_token.post path, form_data
40
+ return res.body
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ require 'cgi'
2
+
3
+ module Twitorious
4
+ module URL
5
+ class Bitly
6
+ def initialize(user, pass)
7
+ @auth = Twitorious::Auth::Basic.new(user, pass)
8
+ @host = URI.parse("http://api.bit.ly")
9
+ end
10
+
11
+ def shorten(url)
12
+ path = "/shorten?version=2.0.1&longUrl=#{CGI.escape(url)}"
13
+ body = @auth.get(@host, path)
14
+ json = JSON.parse(body)
15
+ return json["results"][url]["shortUrl"]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require 'cgi'
2
+
3
+ module Twitorious
4
+ module URL
5
+ class Isgd
6
+ def initialize
7
+ @auth = Twitorious::Auth::Basic.new("not", "needed")
8
+ @host = URI.parse("http://is.gd")
9
+ end
10
+
11
+ def shorten(url)
12
+ body = @auth.get @host, "/api.php?longurl=#{CGI.escape(url)}"
13
+ return nil if body == "{}"
14
+ return body
15
+ end
16
+ end
17
+ end
18
+ end
data/twitorious.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "Twitorious"
3
- s.version = "0.2.9"
4
- s.date = "2009-04-16"
3
+ s.version = "0.3.1"
4
+ s.date = "2009-04-20"
5
5
  s.author = "Per Christian B. Viken"
6
6
  s.email = "perchr@northblue.org"
7
7
  s.homepage = "http://eastblue.org/projects/twitorious/"
@@ -15,10 +15,15 @@ Gem::Specification.new do |s|
15
15
  "lib/twitorious/update.rb",
16
16
  "lib/twitorious/notifier.rb",
17
17
  "lib/twitorious/api/twitter.rb",
18
+ "lib/twitorious/auth/basic.rb",
19
+ "lib/twitorious/auth/oauth.rb",
20
+ "lib/twitorious/url/isgd.rb",
21
+ "lib/twitorious/url/bitly.rb",
18
22
  "TODO"]
19
23
  s.executables << 'twit'
20
24
  s.executables << 'twit-notifier'
21
25
  s.add_dependency("meow", ">= 2.1.0")
22
26
  s.add_dependency("json", ">= 1.1.0")
27
+ s.add_dependency("oauth", ">= 0.3.2")
23
28
  s.has_rdoc = true
24
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: PerfectlyNormal-Twitorious
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Per Christian B. Viken
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-16 00:00:00 -07:00
12
+ date: 2009-04-20 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,16 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.1.0
34
34
  version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: oauth
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.3.2
44
+ version:
35
45
  description:
36
46
  email: perchr@northblue.org
37
47
  executables:
@@ -50,6 +60,10 @@ files:
50
60
  - lib/twitorious/update.rb
51
61
  - lib/twitorious/notifier.rb
52
62
  - lib/twitorious/api/twitter.rb
63
+ - lib/twitorious/auth/basic.rb
64
+ - lib/twitorious/auth/oauth.rb
65
+ - lib/twitorious/url/isgd.rb
66
+ - lib/twitorious/url/bitly.rb
53
67
  - TODO
54
68
  has_rdoc: true
55
69
  homepage: http://eastblue.org/projects/twitorious/