Added v 0.2.2 snapshot.
[twitter4r-core.git] / lib / twitter / core.rb
blob825108dc914c0b3bc5147c96c812047bf2cdf742
1 # The Twitter4R API provides a nicer Ruby object API to work with 
2 # instead of coding around the REST API.
4 # Module to encapsule the Twitter4R API.
5 module Twitter
6   # Mixin module for classes that need to have a constructor similar to
7   # Rails' models, where a <tt>Hash</tt> is provided to set attributes
8   # appropriately.
9   # 
10   # To define a class that uses this mixin, use the following code:
11   #  class FilmActor
12   #    include ClassUtilMixin
13   #  end
14   module ClassUtilMixin #:nodoc:
15     def self.included(base) #:nodoc:
16       base.send(:include, InstanceMethods)
17     end
18     
19     # Instance methods defined for <tt>Twitter::ModelMixin</tt> module.
20     module InstanceMethods #:nodoc:
21       # Constructor/initializer that takes a hash of parameters that 
22       # will initialize *members* or instance attributes to the 
23       # values given.  For example,
24       # 
25       #  class FilmActor
26       #    include Twitter::ClassUtilMixin
27       #    attr_accessor :name
28       #  end
29       #  
30       #  class Production
31       #    include Twitter::ClassUtilMixin
32       #    attr_accessor :title, :year, :actors
33       #  end
34       #  
35       #  # Favorite actress...
36       #  jodhi = FilmActor.new(:name => "Jodhi May")
37       #  jodhi.name # => "Jodhi May"
38       #  
39       #  # Favorite actor...
40       #  robert = FilmActor.new(:name => "Robert Lindsay")
41       #  robert.name # => "Robert Lindsay"
42       #  
43       #  # Jane is also an excellent pick...gotta love her accent!
44       #  jane = FilmActor.new(name => "Jane Horrocks")
45       #  jane.name # => "Jane Horrocks"
46       #  
47       #  # Witty BBC series...
48       #  mrs_pritchard = Production.new(:title => "The Amazing Mrs. Pritchard", 
49       #                                 :year => 2005, 
50       #                                 :actors => [jodhi, jane])
51       #  mrs_pritchard.title  # => "The Amazing Mrs. Pritchard"
52       #  mrs_pritchard.year   # => 2005
53       #  mrs_pritchard.actors # => [#<FilmActor:0xb79d6bbc @name="Jodhi May">, 
54       #  <FilmActor:0xb79d319c @name="Jane Horrocks">]
55       #  # Any Ros Pritchard's out there to save us from the Tony Blair
56       #  # and Gordon Brown *New Labour* debacle?  You've got my vote! 
57       #  
58       #  jericho = Production.new(:title => "Jericho", 
59       #                           :year => 2005, 
60       #                           :actors => [robert])
61       #  jericho.title   # => "Jericho"
62       #  jericho.year    # => 2005
63       #  jericho.actors  # => [#<FilmActor:0xc95d3eec @name="Robert Lindsay">]
64       # 
65       # Assuming class <tt>FilmActor</tt> includes 
66       # <tt>Twitter::ClassUtilMixin</tt> in the class definition 
67       # and has an attribute of <tt>name</tt>, then that instance 
68       # attribute will be set to "Jodhi May" for the <tt>actress</tt> 
69       # object during object initialization (aka construction for 
70       # you Java heads).
71       def initialize(params = {})
72         params.each do |key,val|
73           self.send("#{key}=", val) if self.respond_to? key
74         end
75         self.send(:init) if self.respond_to? :init
76       end
77       
78       protected
79         # Helper method to provide an easy and terse way to require 
80         # a block is provided to a method.
81         def require_block(block_given)
82           raise ArgumentError, "Must provide a block" unless block_given
83         end
84     end
85   end # ClassUtilMixin
86   
87   # Exception subclass raised when there is an error encountered upon 
88   # querying or posting to the remote Twitter REST API.
89   # 
90   # To consume and query any <tt>RESTError</tt> raised by Twitter4R:
91   #  begin
92   #    # Do something with your instance of <tt>Twitter::Client</tt>.
93   #    # Maybe something like:
94   #    timeline = twitter.timeline_for(:public)
95   #  rescue RESTError => re
96   #    puts re.code, re.message, re.uri
97   #  end
98   # Which on the code raising a <tt>RESTError</tt> will output something like:
99   #  404
100   #  Resource Not Found
101   #  /i_am_crap.json
102   class RESTError < Exception
103     include ClassUtilMixin
104     attr_accessor :code, :message, :uri
105     
106     # Returns string in following format:
107     #  "HTTP #{@code}: #{@message} at #{@uri}"
108     # For example,
109     #  "HTTP 404: Resource Not Found at /i_am_crap.json"
110     def to_s
111       "HTTP #{@code}: #{@message} at #{@uri}"
112     end
113   end # RESTError
114   
115   # Remote REST API interface representation
116   # 
117   class RESTInterfaceSpec
118         include ClassUtilMixin
119         
120   end
121   
122   # Remote REST API method representation
123   # 
124   class RESTMethodSpec
125         include ClassUtilMixin
126         attr_accessor :uri, :method, :parameters
127   end
128   
129   # Remote REST API method parameter representation
130   # 
131   class RESTParameterSpec
132         include ClassUtilMixin
133         attr_accessor :name, :type, :required
134         def required?; @required; end
135   end