tuiter 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS CHANGED
@@ -7,8 +7,11 @@ Both projects were latter adopted by WebCo Internet (http://webcointernet.com).
7
7
 
8
8
  The authors and contributors of Tuiter are:
9
9
 
10
- * Manoel Lemos (manoel@lemos.net)
11
- * Luiz Rocha (lsdr@lsdr.net)
12
- * Luis Cipriani (lfcipriani@talleye.com)
13
- * Lucas Húngaro (lucashungaro@gmail.com)
10
+ * Manoel Lemos (manoel@lemos.net) - initial work
11
+ * Celestino Gomes (tinorj@gmail.com)
12
+ * Leandro Silva (leandrodoze@gmail.com)
13
+ * Lucas Fais (lfais@webcointernet.com)
14
+ * Lucas Húngaro (lucashungaro@gmail.com)
15
+ * Luis Cipriani (lfcipriani@talleye.com)
16
+ * Luiz Rocha (lsdr@lsdr.net)
14
17
 
data/README.rdoc CHANGED
@@ -1,16 +1,31 @@
1
1
  = Tuiter
2
2
 
3
- Tuiter was design and developed by {Manoel Lemos}[http://manoellemos.com] to provide access to the Twitter API. It was developed for the experimental project called {Tuitersfera Brasil}[http://tuitersfera.com.br], an application to monitor the Twitter usage in Brazil.
3
+ Tuiter was design and developed by {Manoel Lemos}[http://manoellemos.com] to
4
+ provide access to the Twitter API. It was developed for the experimental
5
+ project called {Tuitersfera Brasil}[http://tuitersfera.com.br], an application
6
+ to monitor the Twitter usage in Brazil.
4
7
 
5
- Both Tuiter and Tuitersfera were adopted, further developed and maintained by {Webco Internet}[http://webcointernet.com].
8
+ Both Tuiter and Tuitersfera were adopted, further developed and maintained by
9
+ {Webco Internet}[http://webcointernet.com].
6
10
 
7
11
  == Instalation
8
12
 
9
- A tuiter gem is avaliable in Github. To install simply run on a console:
13
+ Tuiter is avaliable as a gem on
14
+ {Rubyforge}[http://rubyforge.org/projects/tuiter/], so you can easily install
15
+ using rubygems:
10
16
 
11
- gem install webco-utils --source=http://gems.github.com
17
+ gem install tuiter
12
18
 
13
- If you already have Github gem repository on you gem source, you can leave the source part out.
19
+ Although it is recommended to use the gem published on Rubyforge, tuiter is also
20
+ avaliable at Github. This might be useful if you want to experiment with forks
21
+ or live on the bleeding edge.
22
+
23
+ To install the Github version, simply run on a console:
24
+
25
+ gem install webco-tuiter --source=http://gems.github.com
26
+
27
+ If you already have Github gem repository on you gem source, you can leave the
28
+ source part out.
14
29
 
15
30
  == Basic Usage
16
31
 
@@ -19,9 +34,11 @@ If you already have Github gem repository on you gem source, you can leave the s
19
34
 
20
35
  client.update('Hey Ho, Twitters!')
21
36
 
22
- There are (or at least we pretend to add :-) another examples in the examples/ folder.
37
+ There are (or at least we want to add :-) another examples in the examples/
38
+ folder.
23
39
 
24
40
  == Roadmap and TO-DO list
25
41
 
26
- Check out the library roadmap and to-do list {in the wiki}[http://wiki.github.com/webco/tuiter]
42
+ Check out the library roadmap and to-do list
43
+ {in the project wiki}[http://wiki.github.com/webco/tuiter]
27
44
 
data/Rakefile CHANGED
@@ -4,6 +4,10 @@ require "rake"
4
4
  require "rake/testtask"
5
5
  require "rake/rdoctask"
6
6
 
7
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].each do |req|
8
+ load req
9
+ end
10
+
7
11
  require "lib/tuiter/version"
8
12
 
9
13
  desc "Run test suite"
@@ -112,14 +116,14 @@ task "install" => "build" do
112
116
  end
113
117
 
114
118
  desc "Publish the gem to Rubyforge"
115
- task "rubyforge" => "build" do
119
+ task "publish" => "build" do
116
120
  require 'rubyforge'
117
121
  rubyforge_config_path = File.expand_path(File.join('~', '.rubyforge'))
118
122
  user_config = YAML::load(File.open(rubyforge_config_path + '/user-config.yml'))
119
123
  auto_config = YAML::load(File.open(rubyforge_config_path + '/auto-config.yml'))
120
124
 
121
- @rubyforge = RubyForge.new(user_config, auto_config)
122
-
125
+ @rubyforge = RubyForge::Client.new(user_config, auto_config)
126
+
123
127
  @rubyforge.login
124
128
  @rubyforge.add_release('tuiter', 'tuiter', "#{spec.version}", "#{spec.name}-#{spec.version}.gem")
125
129
  end
data/lib/tuiter.log ADDED
@@ -0,0 +1,68 @@
1
+ # Logfile created on Sat Mar 21 16:21:26 -0300 2009 by /
2
+ I, [2009-03-21T16:21:26.630191 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:21:26 -0300 2009 : initialize()
3
+ I, [2009-03-21T16:21:54.173399 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:21:54 -0300 2009 : request() query: http://twitter.com/account/rate_limit_status.json
4
+ I, [2009-03-21T16:21:55.040625 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:21:55 -0300 2009 : request() debug: http status is 200 OK
5
+ I, [2009-03-21T16:25:50.347735 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:25:50 -0300 2009 : request() query: http://twitter.com/statuses/show/lsdr.json
6
+ I, [2009-03-21T16:25:50.818158 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:25:50 -0300 2009 : request() http error: 404 Not Found in /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/open-uri.rb:278:in `open_http'
7
+ I, [2009-03-21T16:25:57.859336 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:25:57 -0300 2009 : request() query: http://twitter.com/statuses/show/34751.json
8
+ I, [2009-03-21T16:25:58.344673 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:25:58 -0300 2009 : request() debug: http status is 200 OK
9
+ I, [2009-03-21T16:26:18.827014 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:26:18 -0300 2009 : request() query: http://twitter.com/users/show/lucasfais.json
10
+ I, [2009-03-21T16:26:19.573533 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:26:19 -0300 2009 : request() debug: http status is 200 OK
11
+ I, [2009-03-21T16:26:28.962982 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:26:28 -0300 2009 : request() query: http://twitter.com/users/show/jacktorrance.json
12
+ I, [2009-03-21T16:26:29.498437 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:26:29 -0300 2009 : request() debug: http status is 200 OK
13
+ I, [2009-03-21T16:30:43.347043 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:30:43 -0300 2009 : request() query: http://twitter.com/statuses/followers.json
14
+ I, [2009-03-21T16:30:43.862539 #2112] INFO -- : [Tuiter:2112] Sat Mar 21 16:30:43 -0300 2009 : request() debug: http status is 200 OK
15
+ I, [2009-03-21T20:08:51.185245 #2265] INFO -- : [Tuiter:2265] Sat Mar 21 20:08:51 -0300 2009 : initialize()
16
+ I, [2009-03-21T20:08:54.287965 #2265] INFO -- : [Tuiter:2265] Sat Mar 21 20:08:54 -0300 2009 : request() query: http://twitter.com/users/show/jacktorrance.json
17
+ I, [2009-03-21T20:09:09.302025 #2265] INFO -- : [Tuiter:2265] Sat Mar 21 20:09:09 -0300 2009 : request() error: timeout error
18
+ I, [2009-03-21T20:09:46.075840 #2265] INFO -- : [Tuiter:2265] Sat Mar 21 20:09:46 -0300 2009 : request() query: http://twitter.com/statuses/show/34751.json
19
+ I, [2009-03-21T20:10:01.095919 #2265] INFO -- : [Tuiter:2265] Sat Mar 21 20:10:01 -0300 2009 : request() error: timeout error
20
+ I, [2009-03-21T20:10:15.372542 #2457] INFO -- : [Tuiter:2457] Sat Mar 21 20:10:15 -0300 2009 : initialize()
21
+ I, [2009-03-21T20:10:22.107576 #2457] INFO -- : [Tuiter:2457] Sat Mar 21 20:10:22 -0300 2009 : request() query: http://twitter.com/account/rate_limit_status.json
22
+ I, [2009-03-21T20:10:22.771328 #2457] INFO -- : [Tuiter:2457] Sat Mar 21 20:10:22 -0300 2009 : request() debug: http status is 200 OK
23
+ I, [2009-03-21T20:11:40.731980 #2457] INFO -- : [Tuiter:2457] Sat Mar 21 20:11:40 -0300 2009 : update() sending: #<Tuiter::Status:0x57f710>
24
+ I, [2009-03-21T20:11:56.729236 #2457] INFO -- : [Tuiter:2457] Sat Mar 21 20:11:56 -0300 2009 : update() success: OK
25
+ I, [2009-04-03T08:53:43.427986 #4321] INFO -- : [Tuiter:4321] Fri Apr 03 08:53:43 -0300 2009 : initialize()
26
+ I, [2009-04-03T09:10:50.463761 #4321] INFO -- : [Tuiter:4321] Fri Apr 03 09:10:50 -0300 2009 : request() query: http://twitter.com/account/rate_limit_status.json
27
+ I, [2009-04-03T09:10:51.298101 #4321] INFO -- : [Tuiter:4321] Fri Apr 03 09:10:51 -0300 2009 : request() debug: http status is 200 OK
28
+ I, [2009-04-03T10:02:23.578571 #8903] INFO -- : [Tuiter:8903] Fri Apr 03 10:02:23 -0300 2009 : initialize()
29
+ I, [2009-04-03T10:02:28.009525 #8903] INFO -- : [Tuiter:8903] Fri Apr 03 10:02:28 -0300 2009 : request() query: http://twitter.com/direct_messages.json
30
+ I, [2009-04-03T10:02:31.793239 #8903] INFO -- : [Tuiter:8903] Fri Apr 03 10:02:31 -0300 2009 : request() debug: http status is 200 OK
31
+ I, [2009-04-04T10:46:52.065881 #652] INFO -- : [Tuiter:652] Sat Apr 04 10:46:52 -0300 2009 : initialize()
32
+ I, [2009-04-04T10:46:56.967758 #652] INFO -- : [Tuiter:652] Sat Apr 04 10:46:56 -0300 2009 : request() query: http://twitter.com/account/rate_limit_status.json
33
+ I, [2009-04-04T10:46:57.442538 #652] INFO -- : [Tuiter:652] Sat Apr 04 10:46:57 -0300 2009 : request() debug: http status is 200 OK
34
+ I, [2009-04-04T10:48:17.721315 #720] INFO -- : [Tuiter:720] Sat Apr 04 10:48:17 -0300 2009 : initialize()
35
+ I, [2009-04-04T10:48:21.166143 #720] INFO -- : [Tuiter:720] Sat Apr 04 10:48:21 -0300 2009 : request() query: http://twitter.com/account/rate_limit_status.json
36
+ I, [2009-04-04T10:48:21.765680 #720] INFO -- : [Tuiter:720] Sat Apr 04 10:48:21 -0300 2009 : request() debug: http status is 200 OK
37
+ I, [2009-04-04T10:48:33.733567 #720] INFO -- : [Tuiter:720] Sat Apr 04 10:48:33 -0300 2009 : request() query: http://twitter.com/direct_messages.json
38
+ I, [2009-04-04T10:48:34.636358 #720] INFO -- : [Tuiter:720] Sat Apr 04 10:48:34 -0300 2009 : request() debug: http status is 200 OK
39
+ I, [2009-04-04T10:59:19.665326 #652] INFO -- : [Tuiter:652] Sat Apr 04 10:59:19 -0300 2009 : request() query: http://twitter.com/direct_messages.json
40
+ I, [2009-04-04T10:59:20.229616 #652] INFO -- : [Tuiter:652] Sat Apr 04 10:59:20 -0300 2009 : request() debug: http status is 200 OK
41
+ I, [2009-04-04T11:06:28.427837 #652] INFO -- : [Tuiter:652] Sat Apr 04 11:06:28 -0300 2009 : request() query: http://twitter.com/direct_messages.json
42
+ I, [2009-04-04T11:06:29.077480 #652] INFO -- : [Tuiter:652] Sat Apr 04 11:06:29 -0300 2009 : request() debug: http status is 200 OK
43
+ I, [2009-04-04T11:06:51.125856 #754] INFO -- : [Tuiter:754] Sat Apr 04 11:06:51 -0300 2009 : initialize()
44
+ I, [2009-04-04T11:06:54.684243 #754] INFO -- : [Tuiter:754] Sat Apr 04 11:06:54 -0300 2009 : request() query: http://twitter.com/direct_messages.json
45
+ I, [2009-04-04T11:06:55.296060 #754] INFO -- : [Tuiter:754] Sat Apr 04 11:06:55 -0300 2009 : request() debug: http status is 200 OK
46
+ I, [2009-04-04T11:08:29.059308 #766] INFO -- : [Tuiter:766] Sat Apr 04 11:08:29 -0300 2009 : initialize()
47
+ I, [2009-04-04T11:08:32.425009 #766] INFO -- : [Tuiter:766] Sat Apr 04 11:08:32 -0300 2009 : request() query: http://twitter.com/direct_messages.json
48
+ I, [2009-04-04T11:08:33.088710 #766] INFO -- : [Tuiter:766] Sat Apr 04 11:08:33 -0300 2009 : request() debug: http status is 200 OK
49
+ I, [2009-04-04T11:10:22.162594 #777] INFO -- : [Tuiter:777] Sat Apr 04 11:10:22 -0300 2009 : initialize()
50
+ I, [2009-04-04T11:10:24.984837 #777] INFO -- : [Tuiter:777] Sat Apr 04 11:10:24 -0300 2009 : request() query: http://twitter.com/direct_messages.json
51
+ I, [2009-04-04T11:10:25.459088 #777] INFO -- : [Tuiter:777] Sat Apr 04 11:10:25 -0300 2009 : request() debug: http status is 200 OK
52
+ I, [2009-04-04T11:10:33.344786 #777] INFO -- : [Tuiter:777] Sat Apr 04 11:10:33 -0300 2009 : request() query: http://twitter.com/direct_messages.json
53
+ I, [2009-04-04T11:10:33.954567 #777] INFO -- : [Tuiter:777] Sat Apr 04 11:10:33 -0300 2009 : request() debug: http status is 200 OK
54
+ I, [2009-04-04T11:13:45.335715 #789] INFO -- : [Tuiter:789] Sat Apr 04 11:13:45 -0300 2009 : initialize()
55
+ I, [2009-04-04T11:13:50.022233 #789] INFO -- : [Tuiter:789] Sat Apr 04 11:13:50 -0300 2009 : request() query: http://twitter.com/direct_messages.json
56
+ I, [2009-04-04T11:13:51.264725 #789] INFO -- : [Tuiter:789] Sat Apr 04 11:13:51 -0300 2009 : request() debug: http status is 200 OK
57
+ I, [2009-04-04T11:13:57.622508 #789] INFO -- : [Tuiter:789] Sat Apr 04 11:13:57 -0300 2009 : request() query: http://twitter.com/direct_messages.json
58
+ I, [2009-04-04T11:13:58.246439 #789] INFO -- : [Tuiter:789] Sat Apr 04 11:13:58 -0300 2009 : request() debug: http status is 200 OK
59
+ I, [2009-04-04T11:22:32.286894 #817] INFO -- : [Tuiter:817] Sat Apr 04 11:22:32 -0300 2009 : initialize()
60
+ I, [2009-04-04T11:22:42.397339 #817] INFO -- : [Tuiter:817] Sat Apr 04 11:22:42 -0300 2009 : request() query: http://twitter.com/direct_messages.json
61
+ I, [2009-04-04T11:22:43.736985 #817] INFO -- : [Tuiter:817] Sat Apr 04 11:22:43 -0300 2009 : request() debug: http status is 200 OK
62
+ I, [2009-04-04T11:24:51.155070 #877] INFO -- : [Tuiter:877] Sat Apr 04 11:24:51 -0300 2009 : initialize()
63
+ I, [2009-04-04T11:27:05.763596 #877] INFO -- : [Tuiter:877] Sat Apr 04 11:27:05 -0300 2009 : request() query: http://twitter.com/direct_messages.json
64
+ I, [2009-04-04T11:27:06.886668 #877] INFO -- : [Tuiter:877] Sat Apr 04 11:27:06 -0300 2009 : request() debug: http status is 200 OK
65
+ I, [2009-04-04T11:27:16.028439 #877] INFO -- : [Tuiter:877] Sat Apr 04 11:27:16 -0300 2009 : request() query: http://twitter.com/direct_messages.json
66
+ I, [2009-04-04T11:27:16.798857 #877] INFO -- : [Tuiter:877] Sat Apr 04 11:27:16 -0300 2009 : request() debug: http status is 200 OK
67
+ I, [2009-04-04T11:27:32.333157 #877] INFO -- : [Tuiter:877] Sat Apr 04 11:27:32 -0300 2009 : request() query: http://twitter.com/direct_messages.json?page=2
68
+ I, [2009-04-04T11:27:33.356890 #877] INFO -- : [Tuiter:877] Sat Apr 04 11:27:33 -0300 2009 : request() debug: http status is 200 OK
data/lib/tuiter.rb CHANGED
@@ -5,7 +5,15 @@ require 'logger'
5
5
 
6
6
  require 'json'
7
7
 
8
+ libdir = File.dirname(__FILE__)
9
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
10
+
11
+ # Tuiter client and end points
8
12
  require 'tuiter/client'
13
+
14
+ # Tuiter data structures
9
15
  require 'tuiter/data/user'
10
16
  require 'tuiter/data/status'
11
17
  require 'tuiter/data/rate_limit'
18
+ require 'tuiter/data/direct_message'
19
+
data/lib/tuiter.rb~ ADDED
@@ -0,0 +1,19 @@
1
+ require 'open-uri'
2
+ require 'uri'
3
+ require 'net/http'
4
+ require 'logger'
5
+
6
+ require 'json'
7
+
8
+ libdir = File.dirname(__FILE__)
9
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
10
+
11
+ # Tuiter client and end points
12
+ require 'tuiter/client'
13
+
14
+ # Tuiter data structures
15
+ require 'tuiter/data/user'
16
+ require 'tuiter/data/status'
17
+ require 'tuiter/data/rate_limit'
18
+ require 'tuiter/data/direct_message'
19
+
data/lib/tuiter/client.rb CHANGED
@@ -8,6 +8,7 @@ module Tuiter
8
8
  @logger = options[:logger] || Logger.new('tuiter.log')
9
9
  @username = options[:username]
10
10
  @password = options[:password]
11
+ @use_proxy = setup_a_proxy?
11
12
  log("initialize()")
12
13
  end
13
14
 
@@ -17,7 +18,7 @@ module Tuiter
17
18
  req = Net::HTTP::Post.new(url.path)
18
19
  req.basic_auth @username, @password
19
20
  req.set_form_data({'status'=>status, 'in_reply_to_status_id'=>in_reply_to_status_id })
20
- res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
21
+ res = new_http_for(url).start {|http| http.request(req) }
21
22
  case res
22
23
  when Net::HTTPSuccess, Net::HTTPRedirection
23
24
  log("update() success: OK")
@@ -34,7 +35,7 @@ module Tuiter
34
35
  req = Net::HTTP::Post.new(url.path)
35
36
  req.basic_auth @username, @password
36
37
  req.set_form_data({'user'=>user, 'text'=>text })
37
- res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
38
+ res = new_http_for(url).start {|http| http.request(req) }
38
39
  case res
39
40
  when Net::HTTPSuccess, Net::HTTPRedirection
40
41
  log("direct_new() success: OK")
@@ -44,14 +45,26 @@ module Tuiter
44
45
  res.error!
45
46
  end
46
47
  end
47
-
48
+
49
+ def direct_list(options = {})
50
+ url = 'http://twitter.com/direct_messages.json'
51
+ params = parse_options(options) || ""
52
+
53
+ if res = request(url+params)
54
+ data = JSON.parse(res)
55
+ return data.map { |d| DirectMessage.new(d) }
56
+ else
57
+ return nil
58
+ end
59
+ end
60
+
48
61
  def friendship_new(user, follow = nil)
49
62
  log("friendship_new() following: #{user}")
50
63
  url = URI.parse("http://twitter.com/friendships/create/#{user}.json")
51
64
  req = Net::HTTP::Post.new(url.path)
52
65
  req.basic_auth @username, @password
53
66
  req.set_form_data({'follow'=>"true"}) if follow
54
- res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
67
+ res = new_http_for(url).start {|http| http.request(req) }
55
68
  case res
56
69
  when Net::HTTPSuccess, Net::HTTPRedirection
57
70
  log("friendship_new() success: OK")
@@ -177,7 +190,49 @@ module Tuiter
177
190
  rescue Exception => e
178
191
  log("request() error: #{e.message} in #{e.backtrace.first.to_s}")
179
192
  return nil
180
- end
193
+ end
194
+
195
+ def parse_options(options)
196
+ if options[:since]
197
+ params = "?since=#{options[:since]}"
198
+ elsif options[:since_id]
199
+ params = "?since_id=#{options[:since_id]}"
200
+ else
201
+ params = ""
202
+ end
203
+
204
+ if options[:page]
205
+ if params == ""
206
+ params = "?page=#{options[:page]}"
207
+ else
208
+ params = params + "&" + "page=#{options[:page]}"
209
+ end
210
+ end
211
+
212
+ return params
213
+ end
214
+
215
+ def setup_a_proxy?
216
+ http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] || nil
217
+
218
+ if http_proxy
219
+ proxy = URI.parse(http_proxy)
220
+
221
+ @proxy_host = proxy.host
222
+ @proxy_port = proxy.port
223
+ @proxy_user, @proxy_pass = proxy.userinfo.split(/:/) if proxy.userinfo
224
+ end
225
+
226
+ http_proxy != nil
227
+ end
228
+
229
+ def new_http_for(url)
230
+ if @use_proxy
231
+ http = Net::HTTP.new(url.host, url.port, @proxy_host, @proxy_port, @proxy_user, @proxy_pass)
232
+ else
233
+ http = Net::HTTP.new(url.host, url.port)
234
+ end
235
+ end
181
236
 
182
237
  def log(message)
183
238
  @logger.info "[Tuiter:#{@pid}] #{Time.now.to_s} : #{message}"
@@ -0,0 +1,244 @@
1
+ module Tuiter
2
+
3
+ class Client
4
+ attr_accessor :username, :password
5
+
6
+ def initialize(options = {})
7
+ @pid = Process.pid
8
+ @logger = options[:logger] || Logger.new('tuiter.log')
9
+ @username = options[:username]
10
+ @password = options[:password]
11
+ @use_proxy = setup_a_proxy?
12
+ log("initialize()")
13
+ end
14
+
15
+ def update(status, in_reply_to_status_id = nil)
16
+ log("update() sending: #{status}")
17
+ url = URI.parse('http://twitter.com/statuses/update.json')
18
+ req = Net::HTTP::Post.new(url.path)
19
+ req.basic_auth @username, @password
20
+ req.set_form_data({'status'=>status, 'in_reply_to_status_id'=>in_reply_to_status_id })
21
+ res = new_http_for(url).start {|http| http.request(req) }
22
+ case res
23
+ when Net::HTTPSuccess, Net::HTTPRedirection
24
+ log("update() success: OK")
25
+ return res # OK
26
+ else
27
+ log("update() error: #{res.error!}")
28
+ res.error!
29
+ end
30
+ end
31
+
32
+ def direct_new(user, text)
33
+ log("direct_new() sending: #{text} to #{user}")
34
+ url = URI.parse('http://twitter.com/direct_messages/new.json')
35
+ req = Net::HTTP::Post.new(url.path)
36
+ req.basic_auth @username, @password
37
+ req.set_form_data({'user'=>user, 'text'=>text })
38
+ res = new_http_for(url).start {|http| http.request(req) }
39
+ case res
40
+ when Net::HTTPSuccess, Net::HTTPRedirection
41
+ log("direct_new() success: OK")
42
+ return res # OK
43
+ else
44
+ log("direct_new() error: #{res.error!}")
45
+ res.error!
46
+ end
47
+ end
48
+
49
+ def direct_list(options = {})
50
+ url = 'http://twitter.com/direct_messages.json')
51
+ params = parse_options(options) || ""
52
+
53
+ if res = request(url+params)
54
+ data = JSON.parse(res)
55
+ return data.map { |d| DirectMessage.new(d) }
56
+ else
57
+ return nil
58
+ end
59
+ end
60
+
61
+ def friendship_new(user, follow = nil)
62
+ log("friendship_new() following: #{user}")
63
+ url = URI.parse("http://twitter.com/friendships/create/#{user}.json")
64
+ req = Net::HTTP::Post.new(url.path)
65
+ req.basic_auth @username, @password
66
+ req.set_form_data({'follow'=>"true"}) if follow
67
+ res = new_http_for(url).start {|http| http.request(req) }
68
+ case res
69
+ when Net::HTTPSuccess, Net::HTTPRedirection
70
+ log("friendship_new() success: OK")
71
+ return res # OK
72
+ else
73
+ log("friendship_new() error: #{res.error!}")
74
+ res.error!
75
+ end
76
+ end
77
+
78
+ def verify_credentials?
79
+ if res = request("http://twitter.com/account/verify_credentials.json")
80
+ return UserExtended.new(JSON.parse(res))
81
+ else
82
+ return nil
83
+ end
84
+ end
85
+
86
+ def get_followers(options = {})
87
+ if options[:id]
88
+ query = "http://twitter.com/statuses/followers/#{options[:id]}.json"
89
+ else
90
+ query = "http://twitter.com/statuses/followers.json"
91
+ end
92
+ if options[:page]
93
+ params = "?page=#{options[:page]}"
94
+ else
95
+ params = ""
96
+ end
97
+ if res = request(query+params)
98
+ data = JSON.parse(res)
99
+ return data.map { |d| User.new(d) }
100
+ else
101
+ return nil
102
+ end
103
+ end
104
+
105
+ def get_replies(options = {})
106
+ query = "http://twitter.com/statuses/replies.json"
107
+ if options[:since]
108
+ params = "?since=#{options[:since]}"
109
+ elsif options[:since_id]
110
+ params = "?since_id=#{options[:since_id]}"
111
+ else
112
+ params = ""
113
+ end
114
+ if options[:page]
115
+ if params == ""
116
+ params = "?page=#{options[:page]}"
117
+ else
118
+ params = params + "&" + "page=#{options[:page]}"
119
+ end
120
+ end
121
+ if res = request(query+params)
122
+ data = JSON.parse(res)
123
+ return data.map { |d| Status.new(d) }
124
+ else
125
+ return nil
126
+ end
127
+ end
128
+
129
+ def get_client
130
+ if res = request("http://twitter.com/users/show/#{@username}.json")
131
+ return UserExtended.new(JSON.parse(res))
132
+ else
133
+ return nil
134
+ end
135
+ end
136
+
137
+ def get_user(id)
138
+ if res = request("http://twitter.com/users/show/#{id}.json")
139
+ return UserExtended.new(JSON.parse(res))
140
+ else
141
+ return nil
142
+ end
143
+ end
144
+
145
+ def get_status(id)
146
+ if res = request("http://twitter.com/statuses/show/#{id}.json")
147
+ return Status.new(JSON.parse(res))
148
+ else
149
+ return nil
150
+ end
151
+ end
152
+
153
+ def rate_limit
154
+ if res = request("http://twitter.com/account/rate_limit_status.json")
155
+ return RateLimit.new(JSON.parse(res))
156
+ else
157
+ return nil
158
+ end
159
+ end
160
+
161
+ def follows_me?(id)
162
+ if res = request("http://twitter.com/friendships/exists.json?user_a=#{id}&user_b=#{@username}")
163
+ return true if res == "true"
164
+ return false
165
+ else
166
+ return nil
167
+ end
168
+ end
169
+
170
+ private
171
+
172
+ def request(url)
173
+ http = nil
174
+ status = Timeout::timeout(10) do
175
+ log("request() query: #{url}")
176
+ http = open(url, :http_basic_authentication=>[@username, @password])
177
+ log("request() debug: http status is #{http.status.join(' ')}")
178
+ if http.status == ["200", "OK"]
179
+ res = http.read
180
+ return res
181
+ end
182
+ return nil
183
+ end
184
+ rescue Timeout::Error
185
+ log("request() error: timeout error")
186
+ return nil
187
+ rescue OpenURI::HTTPError => e
188
+ log("request() http error: #{e.message} in #{e.backtrace.first.to_s}")
189
+ return nil
190
+ rescue Exception => e
191
+ log("request() error: #{e.message} in #{e.backtrace.first.to_s}")
192
+ return nil
193
+ end
194
+
195
+ def parse_options(options)
196
+ if options[:since]
197
+ params = "?since=#{options[:since]}"
198
+ elsif options[:since_id]
199
+ params = "?since_id=#{options[:since_id]}"
200
+ else
201
+ params = ""
202
+ end
203
+
204
+ if options[:page]
205
+ if params == ""
206
+ params = "?page=#{options[:page]}"
207
+ else
208
+ params = params + "&" + "page=#{options[:page]}"
209
+ end
210
+ end
211
+
212
+ return params
213
+ end
214
+
215
+ def setup_a_proxy?
216
+ http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] || nil
217
+
218
+ if http_proxy
219
+ proxy = URI.parse(http_proxy)
220
+
221
+ @proxy_host = proxy.host
222
+ @proxy_port = proxy.port
223
+ @proxy_user, @proxy_pass = proxy.userinfo.split(/:/) if proxy.userinfo
224
+ end
225
+
226
+ http_proxy != nil
227
+ end
228
+
229
+ def new_http_for(url)
230
+ if @use_proxy
231
+ http = Net::HTTP.new(url.host, url.port, @proxy_host, @proxy_port, @proxy_user, @proxy_pass)
232
+ else
233
+ http = Net::HTTP.new(url.host, url.port)
234
+ end
235
+ end
236
+
237
+ def log(message)
238
+ @logger.info "[Tuiter:#{@pid}] #{Time.now.to_s} : #{message}"
239
+ end
240
+
241
+ end
242
+
243
+ end
244
+
@@ -0,0 +1,44 @@
1
+ module Tuiter
2
+
3
+ class DirectMessageBasic
4
+ attr_accessor :id
5
+ attr_accessor :text
6
+ attr_accessor :created_at
7
+ attr_accessor :sender_id
8
+ attr_accessor :sender_screen_name
9
+ attr_accessor :recipient_id
10
+ attr_accessor :recipient_screen_name
11
+
12
+ def initialize(data = nil)
13
+ unless data.nil?
14
+ @id = data['id']
15
+ @text = data['text']
16
+ @created_at = (data['created_at'] ? DateTime.parse(data['created_at']) : DateTime.now)
17
+ @sender_id = data['sender_id']
18
+ @sender_screen_name = data['sender_screen_name']
19
+ @recipient_id = data['recipient_id']
20
+ @recipient_screen_name = data['recipient_screen_name']
21
+ else
22
+ @created_at = DateTime.now
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+
29
+ class DirectMessage < DirectMessageBasic
30
+ attr_accessor :sender
31
+ attr_accessor :recipient
32
+
33
+ def initialize(data = nil)
34
+ unless data.nil?
35
+ super(data)
36
+ @sender = UserBasic.new(data['sender'])
37
+ @recipient = UserBasic.new(data['recipient'])
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
@@ -0,0 +1,44 @@
1
+ module Tuiter
2
+
3
+ class DirectMessageBasic
4
+ attr_accessor :id
5
+ attr_accessor :text
6
+ attr_accessor :created_at
7
+ attr_accessor :sender_id
8
+ attr_accessor :sender_screen_name
9
+ attr_accessor :recipient_id
10
+ attr_accessor :recipient_screen_name
11
+
12
+ def initialize(data = nil)
13
+ unless data.nil?
14
+ @id = data['id']
15
+ @text = data['text']
16
+ @created_at = (data['created_at'] ? DateTime.parse(data['created_at']) : DateTime.now)
17
+ @sender_id = data['sender_id']
18
+ @sender_screen_name = data['sender_screen_name']
19
+ @recipient_id = data['recipient_id']
20
+ @recipient_screen_name = data['recipient_screen_name']
21
+ else
22
+ @created_at = DateTime.now
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+
29
+ class DirectMessage < DirectMessageBasic
30
+ attr_accessor :sender
31
+ attr_accessor :recipient
32
+
33
+ def initialize(data = nil)
34
+ unless data.nil?
35
+ super(data)
36
+ @sender = UserBasic.new(data['sender'])
37
+ @recipient = UserBasic.new(data['recipient'])
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
@@ -13,7 +13,7 @@ module Tuiter
13
13
 
14
14
  def initialize(data = nil)
15
15
  unless data.nil?
16
- @created_at = Time.parse(data["created_at"])
16
+ @created_at = (data["created_at"] ? DateTime.parse(data["created_at"]) : DateTime.now)
17
17
  @id = data["id"]
18
18
  @text = data["text"]
19
19
  @source = data["source"]
@@ -22,6 +22,8 @@ module Tuiter
22
22
  @in_reply_to_user_id = data["in_reply_to_user_id"]
23
23
  @favorited = data["favorited"]
24
24
  @in_reply_to_screen_name = data["in_reply_to_screen_name"]
25
+ else
26
+ @created_at = DateTime.now
25
27
  end
26
28
  end
27
29
 
@@ -53,7 +53,7 @@ module Tuiter
53
53
  @profile_sidebar_fill_color = data["profile_sidebar_fill_color"]
54
54
  @profile_sidebar_border_color = data["profile_sidebar_border_color"]
55
55
  @friends_count = data["friends_count"].to_i
56
- @created_at = Time.parse(data["created_at"])
56
+ @created_at = (data["created_at"] ? DateTime.parse(data["created_at"]) : DateTime.now)
57
57
  @favourites_count = data["favourites_count"].to_i
58
58
  @utc_offset = data["utc_offset"]
59
59
  @time_zone = data["time_zone"]
@@ -62,6 +62,8 @@ module Tuiter
62
62
  @following = data["following"]
63
63
  @notifications = data["notifications"]
64
64
  @statuses_count = data["statuses_count"].to_i
65
+ else
66
+ @created_at = DateTime.now
65
67
  end
66
68
  end
67
69
 
@@ -0,0 +1,9 @@
1
+ module Tuiter
2
+
3
+ DIRECT_MESSAGES = { :list => 'http://twitter.com/direct_messages',
4
+ :sent => 'http://twitter.com/direct_messages/sent',
5
+ :new => 'http://twitter.com/direct_messages/new',
6
+ :destroy => "http://twitter.com/direct_messages/destroy/#{id}" }
7
+
8
+ end
9
+
@@ -7,7 +7,7 @@ unless defined? Tuiter::VERSION
7
7
  module VERSION
8
8
  MAJOR = 0
9
9
  MINOR = 0
10
- TINY = 1
10
+ TINY = 2
11
11
 
12
12
  STRING = [MAJOR, MINOR, TINY].join('.')
13
13
  end
@@ -0,0 +1,16 @@
1
+ #
2
+ # Tuiter, Copyright (c) 2009 Manoel Lemos & WebCo Internet
3
+ #
4
+
5
+ unless defined? Tuiter::VERSION
6
+ module Tuiter
7
+ module VERSION
8
+ MAJOR = 0
9
+ MINOR = 0
10
+ TINY = 1
11
+
12
+ STRING = [MAJOR, MINOR, TINY].join('.')
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,68 @@
1
+ [
2
+ {
3
+ "description":"Follower #1",
4
+ "followers_count":300,
5
+ "url":"http:\/\/tuitersfera.com.br\/",
6
+ "name":"Joe Doe",
7
+ "protected":false,
8
+ "status":
9
+ {
10
+ "in_reply_to_status_id":null,
11
+ "truncated":false,
12
+ "text":"I am fine",
13
+ "created_at":"Mon Mar 23 18:25:41 +0000 2009",
14
+ "favorited":false,
15
+ "id":1203219398,
16
+ "in_reply_to_user_id":null,
17
+ "source":"web"
18
+ },
19
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
20
+ "location":"S\u00e3o Paulo",
21
+ "id":11111111,
22
+ "screen_name":"follower#1"
23
+ },
24
+ {
25
+ "description":"Follower #2",
26
+ "followers_count":15,
27
+ "url":"http:\/\/tuitersfera.com.br\/",
28
+ "name":"Mark Knoffler",
29
+ "protected":false,
30
+ "status":
31
+ {
32
+ "in_reply_to_status_id":null,
33
+ "truncated":false,
34
+ "text":"Playing the blues",
35
+ "created_at":"Mon Mar 23 09:30:10 +0000 2009",
36
+ "favorited":false,
37
+ "id":1203219398,
38
+ "in_reply_to_user_id":null,
39
+ "source":"web"
40
+ },
41
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
42
+ "location":"S\u00e3o Paulo",
43
+ "id":22222222,
44
+ "screen_name":"follower#2"
45
+ },
46
+ {
47
+ "description":"Follower #3",
48
+ "followers_count":200,
49
+ "url":"http:\/\/tuitersfera.com.br\/",
50
+ "name":"Iron Man",
51
+ "protected":false,
52
+ "status":
53
+ {
54
+ "in_reply_to_status_id":null,
55
+ "truncated":false,
56
+ "text":"Saving the world",
57
+ "created_at":"Mon Mar 23 09:30:10 +0000 2009",
58
+ "favorited":false,
59
+ "id":1203219398,
60
+ "in_reply_to_user_id":null,
61
+ "source":"web"
62
+ },
63
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
64
+ "location":"San Francisco",
65
+ "id":33333333,
66
+ "screen_name":"follower#3"
67
+ }
68
+ ]
@@ -0,0 +1,48 @@
1
+ [
2
+ {
3
+ "in_reply_to_user_id":19815179,
4
+ "truncated":false,
5
+ "user":
6
+ {
7
+ "description":"I am cool",
8
+ "followers_count":50,
9
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
10
+ "url":"http:\/\/tuitersfera.com.br\/",
11
+ "name":"Morgan Freeman",
12
+ "protected":false,
13
+ "screen_name":"morgan",
14
+ "location":"Hollywood, CA, USA",
15
+ "id":99999999
16
+ },
17
+ "favorited":false,
18
+ "text":"@tuitersfera hello?",
19
+ "created_at":"Sun Mar 22 18:56:38 +0000 2009",
20
+ "id":3333,
21
+ "in_reply_to_screen_name":"tuitersfera",
22
+ "in_reply_to_status_id":null,
23
+ "source":"web"
24
+ },
25
+ {
26
+ "in_reply_to_user_id":19815179,
27
+ "truncated":false,
28
+ "user":
29
+ {
30
+ "description":"Just relaxing",
31
+ "followers_count":300,
32
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
33
+ "url":"http:\/\/tuitersfera.com.br\/",
34
+ "name":"Carla Gugino",
35
+ "protected":false,
36
+ "screen_name":"HotCarla",
37
+ "location":"Hollywood, CA, USA",
38
+ "id":88888888
39
+ },
40
+ "favorited":false,
41
+ "text":"@tuitersfera I am fine, thanks.",
42
+ "created_at":"Sun Mar 22 13:50:38 +0000 2009",
43
+ "id":2222,
44
+ "in_reply_to_screen_name":"tuitersfera",
45
+ "in_reply_to_status_id":1,
46
+ "source":"web"
47
+ }
48
+ ]
@@ -0,0 +1,37 @@
1
+ {
2
+ "profile_background_image_url":"http:\/\/static.twitter.com\/images\/themes\/theme1\/bg.gif",
3
+ "description":"Projeto focado em medir a twittersfera brasileira.",
4
+ "utc_offset":-10800,
5
+ "profile_sidebar_fill_color":"e0ff92",
6
+ "following":false,
7
+ "friends_count":2053,
8
+ "notifications":false,
9
+ "profile_sidebar_border_color":"87bc44",
10
+ "profile_background_tile":false,
11
+ "time_zone":"Brasilia",
12
+ "favourites_count":0,
13
+ "profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/102032546\/tuit_normal.jpg",
14
+ "url":"http:\/\/tuitersfera.com.br\/",
15
+ "name":"Tuitersfera Brasil",
16
+ "protected":false,
17
+ "status":
18
+ {
19
+ "text":"Yesbaaaaaaa.... Completamos 1.000 usu\u00e1rios no Tuitersfera. http:\/\/tuitersfera.com.br\/",
20
+ "favorited":false,
21
+ "in_reply_to_user_id":null,
22
+ "in_reply_to_status_id":null,
23
+ "truncated":false,
24
+ "created_at":"Thu Feb 12 16:53:55 +0000 2009",
25
+ "id":1203219398,
26
+ "source":"<a href=\"http:\/\/www.twhirl.org\/\">twhirl<\/a>"
27
+ },
28
+ "profile_background_color":"9ae4e8",
29
+ "followers_count":1946,
30
+ "screen_name":"tuitersfera",
31
+ "profile_text_color":"000000",
32
+ "statuses_count":122,
33
+ "created_at":"Sat Jan 31 13:39:45 +0000 2009",
34
+ "location":"S\u00e3o Paulo, Brasil",
35
+ "id":19815179,
36
+ "profile_link_color":"0000ff"
37
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "id":11111111,
3
+ "name":"Joe Doe",
4
+ "screen_name":"follower#1"
5
+ "description":"Follower #1",
6
+ "location":"S\u00e3o Paulo",
7
+ "profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png",
8
+ "url":"http:\/\/tuitersfera.com.br\/",
9
+ "protected":false,
10
+ "followers_count":300,
11
+ "status":
12
+ {
13
+ "in_reply_to_status_id":null,
14
+ "truncated":false,
15
+ "text":"I am fine",
16
+ "created_at":"Mon Mar 23 18:25:41 +0000 2009",
17
+ "favorited":false,
18
+ "id":1203219398,
19
+ "in_reply_to_user_id":null,
20
+ "source":"web"
21
+ },
22
+ }
@@ -0,0 +1,48 @@
1
+ [
2
+ {
3
+ "user":
4
+ {
5
+ "description":"Projeto focado em medir a twittersfera brasileira.",
6
+ "profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/102032546\/tuit_normal.jpg",
7
+ "url":"http:\/\/tuitersfera.com.br\/",
8
+ "name":"Tuitersfera Brasil",
9
+ "protected":false,
10
+ "followers_count":1946,
11
+ "screen_name":"tuitersfera",
12
+ "location":"S\u00e3o Paulo, Brasil",
13
+ "id":19815179
14
+ },
15
+ "text":"Yesbaaaaaaa.... Completamos 1.000 usu\u00e1rios no Tuitersfera. http:\/\/tuitersfera.com.br\/",
16
+ "in_reply_to_screen_name":null,
17
+ "favorited":false,
18
+ "in_reply_to_user_id":null,
19
+ "in_reply_to_status_id":null,
20
+ "truncated":false,
21
+ "created_at":"Thu Feb 12 16:53:55 +0000 2009",
22
+ "id":1203219398,
23
+ "source":"<a href=\"http:\/\/www.twhirl.org\/\">twhirl<\/a>"
24
+ },
25
+ {
26
+ "user":
27
+ {
28
+ "description":"Projeto focado em medir a twittersfera brasileira.",
29
+ "profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/102032546\/tuit_normal.jpg",
30
+ "url":"http:\/\/tuitersfera.com.br\/",
31
+ "name":"Tuitersfera Brasil",
32
+ "protected":false,
33
+ "followers_count":1946,
34
+ "screen_name":"tuitersfera",
35
+ "location":"S\u00e3o Paulo, Brasil",
36
+ "id":19815179
37
+ },
38
+ "text":"Hello beautiful, how you're doing?",
39
+ "in_reply_to_screen_name":"HotCarla",
40
+ "favorited":false,
41
+ "in_reply_to_user_id":88888888,
42
+ "in_reply_to_status_id":null,
43
+ "truncated":false,
44
+ "created_at":"Sun Mar 22 12:10:21 +0000 2009",
45
+ "id":1203219398,
46
+ "source":"<a href=\"http:\/\/www.twhirl.org\/\">twhirl<\/a>"
47
+ }
48
+ ]
@@ -0,0 +1,29 @@
1
+ class Test::Unit::TestCase
2
+
3
+ def self.should_attr_accessor_for(klass, attributes)
4
+ object = klass.new
5
+
6
+ attributes.each do |attribute|
7
+ should "respond_to #{attribute}" do
8
+ assert object.respond_to?(attribute)
9
+ end
10
+
11
+ should "respond_to #{attribute}=" do
12
+ assert object.respond_to?("#{attribute}=")
13
+ end
14
+ end
15
+ end
16
+
17
+ def self.should_load_attribute_on_initialize(klass, attributes, expected_value = "value", setter_value = expected_value)
18
+
19
+ attributes.each do |attribute|
20
+ should "load attribute '#{attribute}' on initialize" do
21
+ data = eval("{'#{attribute}' => #{setter_value.inspect}}")
22
+
23
+ object = klass.new data
24
+ assert_equal(expected_value, object.send(attribute))
25
+ end
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,25 @@
1
+ require "rubygems"
2
+ require "test/unit"
3
+ require "shoulda"
4
+ require "mocha"
5
+ require 'fakeweb'
6
+
7
+ # begin
8
+ # require "quietbacktrace"
9
+ # Test::Unit::TestCase.quiet_backtrace = true
10
+ # Test::Unit::TestCase.backtrace_silencers = [:test_unit, :gem_root, :e1]
11
+ # Test::Unit::TestCase.backtrace_filters = [:method_name]
12
+ # rescue LoadError
13
+ # # Just ignore it
14
+ # rescue NoMethodError
15
+ # # Just ignore it
16
+ # end
17
+
18
+ require File.dirname(__FILE__) + "/../lib/tuiter"
19
+
20
+ #Load shoulda macros
21
+ %w(macros).each do |dirname|
22
+ Dir[File.dirname(__FILE__) + "/#{dirname}/*.rb"].each do |file|
23
+ require file
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class ClientTest < Test::Unit::TestCase
4
+
5
+ context "A valid Tuiter client" do
6
+
7
+ setup do
8
+ @username = "username"
9
+ @password = "password"
10
+ @client = Tuiter::Client.new(:username => @username, :password => @password)
11
+ end
12
+
13
+ context "posting data" do
14
+ setup do
15
+ @update_message = "I'm fine"
16
+ FakeWeb.register_uri(:post, "http://twitter.com/statuses/update.json", :string => @update_message, :status => "200")
17
+ end
18
+
19
+ should "allow the user to post an update to Twitter" do
20
+ # basic authentication and form data
21
+ Net::HTTP::Post.any_instance.expects(:basic_auth).with(@username, @password)
22
+ Net::HTTP::Post.any_instance.expects(:set_form_data).with('status' => @update_message, 'in_reply_to_status_id' => nil)
23
+
24
+ @response = @client.update(@update_message)
25
+
26
+ assert_instance_of Net::HTTPOK, @response
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ class StatusTest < Test::Unit::TestCase
4
+
5
+ STATUS_BASIC_ATTRIBUTES = %w(id text source truncated in_reply_to_status_id in_reply_to_user_id favorited in_reply_to_screen_name)
6
+
7
+ context "Status" do
8
+
9
+ context "Basic" do
10
+
11
+ should_attr_accessor_for Tuiter::StatusBasic, STATUS_BASIC_ATTRIBUTES
12
+ should_load_attribute_on_initialize Tuiter::StatusBasic, STATUS_BASIC_ATTRIBUTES
13
+
14
+ should "load attribute 'created_at' on initialize" do
15
+ now_str = "2009-10-31 18:59:20"
16
+ now = DateTime.parse(now_str)
17
+ user = Tuiter::UserExtended.new("created_at" => now_str)
18
+ assert_equal now, user.created_at
19
+ end
20
+
21
+ should "load attribute 'created_at' with current time" do
22
+ current_time = DateTime.now
23
+ DateTime.stubs(:now).returns(current_time)
24
+
25
+ user_extended = Tuiter::UserExtended.new
26
+ assert_equal current_time, user_extended.created_at
27
+ end
28
+
29
+ end # context "Basic"
30
+
31
+ context "for Twitter" do
32
+ should_attr_accessor_for Tuiter::Status, STATUS_BASIC_ATTRIBUTES
33
+ should_load_attribute_on_initialize Tuiter::Status, STATUS_BASIC_ATTRIBUTES
34
+
35
+ should "load attribute 'created_at' on initialize" do
36
+ now_str = "2009-10-31 18:59:20"
37
+ now = DateTime.parse(now_str)
38
+ user = Tuiter::UserExtended.new("created_at" => now_str)
39
+ assert_equal now, user.created_at
40
+ end
41
+
42
+ should "load attribute 'created_at' with current time" do
43
+ current_time = DateTime.now
44
+ DateTime.stubs(:now).returns(current_time)
45
+
46
+ user_extended = Tuiter::UserExtended.new
47
+ assert_equal current_time, user_extended.created_at
48
+ end
49
+
50
+ should "load user correctly" do
51
+ user_expected = Tuiter::UserBasic.new
52
+ Tuiter::UserBasic.expects(:new).with("user_data").returns(user_expected)
53
+ status = Tuiter::Status.new "user" => "user_data"
54
+ assert_equal user_expected, status.user
55
+ end
56
+ end # context "for Twitter"
57
+
58
+ end # context "Status"
59
+
60
+ end
61
+
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ class UserTest < Test::Unit::TestCase
4
+
5
+ USER_BASICS_ATTRIBUTES = %w(id name screen_name location description profile_image_url url protected followers_count)
6
+ USER_EXTEDNED_ATTRIBUTES = USER_BASICS_ATTRIBUTES + %w(profile_background_color profile_text_color profile_link_color profile_sidebar_fill_color profile_sidebar_border_color utc_offset time_zone profile_background_image_url profile_background_tile following notifications)
7
+ USER_EXTEDNED_ATTRIBUTES_INTEGER = %w(friends_count statuses_count favourites_count)
8
+ USER_EXTEDNED_ATTRIBUTES_TIME = %w(created_at)
9
+ USER_TWITTER_ATTRIBUTES = USER_BASICS_ATTRIBUTES + %w(status)
10
+
11
+ context "User" do
12
+ context "Basic" do
13
+ should_attr_accessor_for Tuiter::UserBasic, USER_BASICS_ATTRIBUTES
14
+ should_load_attribute_on_initialize Tuiter::UserBasic, USER_BASICS_ATTRIBUTES
15
+ end # context "Basic"
16
+
17
+ context "Extended" do
18
+ setup do
19
+ @now_str = "2009-10-31 18:59:20"
20
+ @now = DateTime.parse(@now_str)
21
+ end
22
+ should_attr_accessor_for Tuiter::UserExtended, USER_EXTEDNED_ATTRIBUTES
23
+ should_load_attribute_on_initialize Tuiter::UserExtended, USER_EXTEDNED_ATTRIBUTES
24
+ should_load_attribute_on_initialize Tuiter::UserExtended, USER_EXTEDNED_ATTRIBUTES_INTEGER, 10
25
+
26
+ should "load attribute 'created_at' on initialize" do
27
+ now_str = "2009-10-31 18:59:20"
28
+ now = DateTime.parse(now_str)
29
+ user = Tuiter::UserExtended.new("created_at" => now_str)
30
+ assert_equal now, user.created_at
31
+ end
32
+
33
+ should "load attribute 'created_at' with current time" do
34
+ current_time = DateTime.now
35
+ DateTime.stubs(:now).returns(current_time)
36
+
37
+ user_extended = Tuiter::UserExtended.new
38
+ assert_equal current_time, user_extended.created_at
39
+ end
40
+ end # context "Extended"
41
+
42
+ context "for Twitter" do
43
+ should_attr_accessor_for Tuiter::User, USER_TWITTER_ATTRIBUTES
44
+ should_load_attribute_on_initialize Tuiter::User, USER_BASICS_ATTRIBUTES
45
+
46
+ should "load attribute 'status' correctly" do
47
+ status_expected = Tuiter::StatusBasic.new
48
+ Tuiter::StatusBasic.expects(:new).with("teste").returns(status_expected)
49
+ user = Tuiter::User.new "status" => "teste"
50
+ assert_equal status_expected, user.status
51
+ end
52
+
53
+ end # context "for Twitter"
54
+
55
+
56
+
57
+ end # context "User"
58
+
59
+
60
+ end
61
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tuiter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manoel Lemos
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-03-20 00:00:00 -03:00
13
+ date: 2009-04-04 00:00:00 -03:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -39,13 +39,33 @@ files:
39
39
  - README.rdoc
40
40
  - lib/tuiter
41
41
  - lib/tuiter/client.rb
42
+ - lib/tuiter/client.rb~
42
43
  - lib/tuiter/data
44
+ - lib/tuiter/data/direct_message.rb
45
+ - lib/tuiter/data/direct_message.rb~
43
46
  - lib/tuiter/data/rate_limit.rb
44
47
  - lib/tuiter/data/status.rb
45
48
  - lib/tuiter/data/user.rb
49
+ - lib/tuiter/end_points.rb
46
50
  - lib/tuiter/version.rb
51
+ - lib/tuiter/version.rb~
52
+ - lib/tuiter.log
47
53
  - lib/tuiter.rb
54
+ - lib/tuiter.rb~
48
55
  - examples/basic_example.rb
56
+ - test/fixtures
57
+ - test/fixtures/followers.json
58
+ - test/fixtures/replies.json
59
+ - test/fixtures/tuitersfera.json
60
+ - test/fixtures/user_basic.json
61
+ - test/fixtures/user_timeline.json
62
+ - test/macros
63
+ - test/macros/attr_accessor_macro.rb
64
+ - test/test_helper.rb
65
+ - test/unit
66
+ - test/unit/client_test.rb
67
+ - test/unit/status_test.rb
68
+ - test/unit/user_test.rb
49
69
  has_rdoc: false
50
70
  homepage: http://github.com/webco/tuiter
51
71
  post_install_message: