ruby-trello 0.4.4.3 → 0.5.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/lib/trello/board.rb CHANGED
@@ -11,17 +11,18 @@ module Trello
11
11
  class << self
12
12
  # Finds a board.
13
13
  def find(id)
14
- super(:boards, id)
14
+ client.find(:board, id)
15
15
  end
16
16
 
17
17
  def create(fields)
18
- new('name' => fields[:name],
19
- 'desc' => fields[:description],
20
- 'closed' => fields[:closed] || false).save
18
+ client.create(:board,
19
+ 'name' => fields[:name],
20
+ 'desc' => fields[:description],
21
+ 'closed' => fields[:closed] || false)
21
22
  end
22
23
 
23
24
  def all
24
- Client.get("/members/#{Member.find(:me).username}/boards").json_into(self)
25
+ client.get("/members/#{Member.find(:me).username}/boards").json_into(self)
25
26
  end
26
27
  end
27
28
 
@@ -32,7 +33,7 @@ module Trello
32
33
  fields.merge!(:desc => description) if description
33
34
  fields.merge!(:idOrganization => organization_id) if organization_id
34
35
 
35
- Client.post("/boards", fields).json_into(self)
36
+ client.post("/boards", fields).json_into(self)
36
37
  end
37
38
 
38
39
  def update!
@@ -41,7 +42,7 @@ module Trello
41
42
  @previously_changed = changes
42
43
  @changed_attributes.clear
43
44
 
44
- Client.put("/boards/#{self.id}/", {
45
+ client.put("/boards/#{self.id}/", {
45
46
  :name => attributes[:name],
46
47
  :description => attributes[:description],
47
48
  :closed => attributes[:closed]
@@ -68,7 +69,7 @@ module Trello
68
69
  end
69
70
 
70
71
  def find_card(card_id)
71
- Client.get("/boards/#{self.id}/cards/#{card_id}").json_into(Card)
72
+ client.get("/boards/#{self.id}/cards/#{card_id}").json_into(Card)
72
73
  end
73
74
 
74
75
  # Return all the cards on this board.
@@ -93,7 +94,7 @@ module Trello
93
94
  many :members, :filter => :all
94
95
 
95
96
  # Returns a reference to the organization this board belongs to.
96
- one :organization, :using => :organization_id
97
+ one :organization, :path => :organizations, :using => :organization_id
97
98
 
98
99
  # :nodoc:
99
100
  def request_prefix
data/lib/trello/card.rb CHANGED
@@ -12,14 +12,15 @@ module Trello
12
12
  class << self
13
13
  # Find a specific card by its id.
14
14
  def find(id)
15
- super(:cards, id)
15
+ client.find(:card, id)
16
16
  end
17
17
 
18
18
  # Create a new card and save it on Trello.
19
19
  def create(options)
20
- new('name' => options[:name],
20
+ client.create(:card,
21
+ 'name' => options[:name],
21
22
  'idList' => options[:list_id],
22
- 'desc' => options[:description]).save
23
+ 'desc' => options[:description])
23
24
  end
24
25
  end
25
26
 
@@ -43,7 +44,7 @@ module Trello
43
44
  end
44
45
 
45
46
  # Returns a reference to the board this card is part of.
46
- one :board, :using => :board_id
47
+ one :board, :path => :boards, :using => :board_id
47
48
 
48
49
  # Returns a list of checklists associated with the card.
49
50
  #
@@ -53,18 +54,18 @@ module Trello
53
54
  many :checklists, :filter => :all
54
55
 
55
56
  def check_item_states
56
- states = Client.get("/cards/#{self.id}/checkItemStates").json_into(CheckItemState)
57
+ states = client.get("/cards/#{self.id}/checkItemStates").json_into(CheckItemState)
57
58
  MultiAssociation.new(self, states).proxy
58
59
  end
59
60
 
60
61
 
61
62
  # Returns a reference to the list this card is currently in.
62
- one :list, :using => :list_id
63
+ one :list, :path => :lists, :using => :list_id
63
64
 
64
65
  # Returns a list of members who are assigned to this card.
65
66
  def members
66
67
  members = member_ids.map do |member_id|
67
- Client.get("/members/#{member_id}").json_into(Member)
68
+ client.get("/members/#{member_id}").json_into(Member)
68
69
  end
69
70
  MultiAssociation.new(self, members).proxy
70
71
  end
@@ -74,7 +75,7 @@ module Trello
74
75
  # If we have an id, just update our fields.
75
76
  return update! if id
76
77
 
77
- Client.post("/cards", {
78
+ client.post("/cards", {
78
79
  :name => name,
79
80
  :desc => description,
80
81
  :idList => list_id
@@ -87,18 +88,16 @@ module Trello
87
88
  # this object before making your changes, and before updating the record.
88
89
  def update!
89
90
  @previously_changed = changes
91
+ # extract only new values to build payload
92
+ payload = Hash[changes.map { |key, values| [key.to_sym, values[1]] }]
90
93
  @changed_attributes.clear
91
94
 
92
- Client.put("/cards/#{id}", {
93
- :name => name,
94
- :desc => description,
95
- :due => due && due.utc.iso8601,
96
- :closed => closed,
97
- :idList => list_id,
98
- :idBoard => board_id,
99
- :idMembers => member_ids,
100
- :pos => pos
101
- })
95
+ client.put("/cards/#{id}", payload)
96
+ end
97
+
98
+ # Delete this card
99
+ def delete
100
+ client.delete("/cards/#{id}")
102
101
  end
103
102
 
104
103
  # Check if the card is not active anymore.
@@ -122,45 +121,49 @@ module Trello
122
121
 
123
122
  # Add a comment with the supplied text.
124
123
  def add_comment(text)
125
- Client.post("/cards/#{id}/actions/comments", :text => text)
124
+ client.post("/cards/#{id}/actions/comments", :text => text)
126
125
  end
127
126
 
128
127
  # Add a checklist to this card
129
128
  def add_checklist(checklist)
130
- Client.post("/cards/#{id}/checklists", {
129
+ client.post("/cards/#{id}/checklists", {
131
130
  :value => checklist.id
132
131
  })
133
132
  end
134
133
 
135
134
  # Move this card to the given list
136
135
  def move_to_list(list)
137
- Client.put("/cards/#{id}/idList", {
138
- :value => list.id
139
- })
136
+ unless list_id == list.id
137
+ client.put("/cards/#{id}/idList", {
138
+ :value => list.id
139
+ })
140
+ end
140
141
  end
141
142
 
142
143
  # Move this card to the given board (and optional list on this board)
143
144
  def move_to_board(new_board, new_list = nil)
144
- payload = { :value => new_board.id }
145
- payload[:idList] = new_list.id if new_list
146
- Client.put("/cards/#{id}/idBoard", payload)
145
+ unless board_id == new_board.id
146
+ payload = { :value => new_board.id }
147
+ payload[:idList] = new_list.id if new_list
148
+ client.put("/cards/#{id}/idBoard", payload)
149
+ end
147
150
  end
148
151
 
149
152
  # Add a member to this card
150
153
  def add_member(member)
151
- Client.post("/cards/#{id}/members", {
154
+ client.post("/cards/#{id}/members", {
152
155
  :value => member.id
153
156
  })
154
157
  end
155
158
 
156
159
  # Remove a member from this card
157
160
  def remove_member(member)
158
- Client.delete("/cards/#{id}/members/#{member.id}")
161
+ client.delete("/cards/#{id}/members/#{member.id}")
159
162
  end
160
163
 
161
164
  # Retrieve a list of labels
162
165
  def labels
163
- labels = Client.get("/cards/#{id}/labels").json_into(Label)
166
+ labels = client.get("/cards/#{id}/labels").json_into(Label)
164
167
  MultiAssociation.new(self, labels).proxy
165
168
  end
166
169
 
@@ -170,7 +173,7 @@ module Trello
170
173
  errors.add(:label, "colour '#{colour}' does not exist")
171
174
  return Trello.logger.warn "The label colour '#{colour}' does not exist."
172
175
  end
173
- Client.post("/cards/#{id}/labels", { :value => colour })
176
+ client.post("/cards/#{id}/labels", { :value => colour })
174
177
  end
175
178
 
176
179
  # Remove a label
@@ -179,18 +182,18 @@ module Trello
179
182
  errors.add(:label, "colour '#{colour}' does not exist")
180
183
  return Trello.logger.warn "The label colour '#{colour}' does not exist." unless %w{green yellow orange red purple blue}.include? colour
181
184
  end
182
- Client.delete("/cards/#{id}/labels/#{colour}")
185
+ client.delete("/cards/#{id}/labels/#{colour}")
183
186
  end
184
187
 
185
188
  # Add an attachment to this card
186
189
  def add_attachment(attachment, name='')
187
190
  if attachment.is_a? File
188
- Client.post("/cards/#{id}/attachments", {
191
+ client.post("/cards/#{id}/attachments", {
189
192
  :file => attachment,
190
193
  :name => name
191
194
  })
192
195
  else
193
- Client.post("/cards/#{id}/attachments", {
196
+ client.post("/cards/#{id}/attachments", {
194
197
  :url => attachment,
195
198
  :name => name
196
199
  })
@@ -199,13 +202,13 @@ module Trello
199
202
 
200
203
  # Retrieve a list of attachments
201
204
  def attachments
202
- attachments = Client.get("/cards/#{id}/attachments").json_into(Attachment)
205
+ attachments = client.get("/cards/#{id}/attachments").json_into(Attachment)
203
206
  MultiAssociation.new(self, attachments).proxy
204
207
  end
205
208
 
206
209
  # Remove an attachment from this card
207
210
  def remove_attachment(attachment)
208
- Client.delete("/cards/#{id}/attachments/#{attachment.id}")
211
+ client.delete("/cards/#{id}/attachments/#{attachment.id}")
209
212
  end
210
213
 
211
214
  # :nodoc:
@@ -9,12 +9,13 @@ module Trello
9
9
  class << self
10
10
  # Locate a specific checklist by its id.
11
11
  def find(id)
12
- super(:checklists, id)
12
+ client.find(:checklist, id)
13
13
  end
14
14
 
15
15
  def create(options)
16
- new('name' => options[:name],
17
- 'idBoard' => options[:board_id]).save
16
+ client.create(:checklist,
17
+ 'name' => options[:name],
18
+ 'idBoard' => options[:board_id])
18
19
  end
19
20
  end
20
21
 
@@ -30,6 +31,7 @@ module Trello
30
31
  attributes[:url] = fields['url']
31
32
  attributes[:check_items] = fields['checkItems']
32
33
  attributes[:board_id] = fields['idBoard']
34
+ attributes[:list_id] = fields['idList']
33
35
  attributes[:member_ids] = fields['idMembers']
34
36
  self
35
37
  end
@@ -43,14 +45,14 @@ module Trello
43
45
  def save
44
46
  return update! if id
45
47
 
46
- Client.post("/checklists", {
48
+ client.post("/checklists", {
47
49
  :name => name,
48
50
  :idBoard => board_id
49
51
  }).json_into(self)
50
52
  end
51
53
 
52
54
  def update!
53
- Client.put("/checklists/#{id}", { :name => name }).json_into(self)
55
+ client.put("/checklists/#{id}", { :name => name }).json_into(self)
54
56
  end
55
57
 
56
58
  # Return a list of items on the checklist.
@@ -61,10 +63,10 @@ module Trello
61
63
  end
62
64
 
63
65
  # Return a reference to the board the checklist is on.
64
- one :board, :using => :board_id
66
+ one :board, :path => :checklists, :using => :board_id
65
67
 
66
68
  # Return a reference to the list the checklist is on.
67
- one :list, :using => :list_id
69
+ one :list, :path => :lists, :using => :list_id
68
70
 
69
71
  # Return a list of members active in this checklist.
70
72
  def members
@@ -76,7 +78,7 @@ module Trello
76
78
 
77
79
  # Add an item to the checklist
78
80
  def add_item(name)
79
- Client.post("/checklists/#{id}/checkItems", { :name => name })
81
+ client.post("/checklists/#{id}/checkItems", { :name => name })
80
82
  end
81
83
  end
82
84
  end
data/lib/trello/client.rb CHANGED
@@ -2,48 +2,117 @@ require 'addressable/uri'
2
2
 
3
3
  module Trello
4
4
  class Client
5
- extend Authorization
5
+ extend Forwardable
6
+ include Authorization
6
7
 
7
- class << self
8
- def get(path, params = {})
9
- uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
10
- uri.query_values = params unless params.empty?
11
- invoke_verb(:get, uri)
12
- end
8
+ def_delegators :configuration, :credentials, *Configuration.configurable_attributes
9
+
10
+ def initialize(attrs = {})
11
+ self.configuration.attributes = attrs
12
+ end
13
+
14
+ def get(path, params = {})
15
+ uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
16
+ uri.query_values = params unless params.empty?
17
+ invoke_verb(:get, uri)
18
+ end
19
+
20
+ def post(path, body = {})
21
+ uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
22
+ invoke_verb(:post, uri, body)
23
+ end
13
24
 
14
- def post(path, body = {})
15
- uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
16
- invoke_verb(:post, uri, body)
25
+ def put(path, body = {})
26
+ uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
27
+ invoke_verb(:put, uri, body)
28
+ end
29
+
30
+ def delete(path)
31
+ uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
32
+ invoke_verb(:delete, uri)
33
+ end
34
+
35
+ # Finds given resource by id
36
+ #
37
+ # Examples:
38
+ # client.find(:board, "board1234")
39
+ # client.find(:member, "user1234")
40
+ #
41
+ def find(path, id)
42
+ response = get("/#{path.to_s.pluralize}/#{id}")
43
+ trello_class = class_from_path(path)
44
+ trello_class.parse response do |data|
45
+ data.client = self
17
46
  end
47
+ end
18
48
 
19
- def put(path, body = {})
20
- uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
21
- invoke_verb(:put, uri, body)
49
+ # Finds given resource by path with params
50
+ def find_many(trello_class, path, params = {})
51
+ response = get(path, params)
52
+ trello_class.parse_many response do |data|
53
+ data.client = self
22
54
  end
55
+ end
23
56
 
24
- def delete(path)
25
- uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
26
- invoke_verb(:delete, uri)
57
+ # Creates resource with given options (attributes)
58
+ #
59
+ # Examples:
60
+ # client.create(:member, options)
61
+ # client.create(:board, options)
62
+ #
63
+ def create(path, options)
64
+ trello_class = class_from_path(path)
65
+ trello_class.save options do |data|
66
+ data.client = self
27
67
  end
68
+ end
28
69
 
29
- def invoke_verb(name, uri, body = nil)
30
- request = Request.new name, uri, {}, body
31
- response = TInternet.execute AuthPolicy.authorize(request)
70
+ def configure
71
+ yield configuration if block_given?
72
+ end
73
+
74
+ def configuration
75
+ @configuration ||= Configuration.new
76
+ end
32
77
 
33
- return '' unless response
78
+ def auth_policy
79
+ @auth_policy ||= auth_policy_class.new(credentials)
80
+ end
34
81
 
35
- if response.code.to_i == 401 && response.body =~ /expired token/
36
- Trello.logger.error("[401 #{name.to_s.upcase} #{uri}]: Your access token has expired.")
37
- raise InvalidAccessToken, response.body
38
- end
82
+ private
39
83
 
40
- unless [200, 201].include? response.code
41
- Trello.logger.error("[#{response.code} #{name.to_s.upcase} #{uri}]: #{response.body}")
42
- raise Error, response.body
43
- end
84
+ def invoke_verb(name, uri, body = nil)
85
+ request = Request.new name, uri, {}, body
86
+ response = TInternet.execute auth_policy.authorize(request)
87
+
88
+ return '' unless response
89
+
90
+ if response.code.to_i == 401 && response.body =~ /expired token/
91
+ Trello.logger.error("[401 #{name.to_s.upcase} #{uri}]: Your access token has expired.")
92
+ raise InvalidAccessToken, response.body
93
+ end
44
94
 
45
- response.body
95
+ unless [200, 201].include? response.code
96
+ Trello.logger.error("[#{response.code} #{name.to_s.upcase} #{uri}]: #{response.body}")
97
+ raise Error, response.body
46
98
  end
99
+
100
+ response.body
101
+ end
102
+
103
+ def auth_policy_class
104
+ if configuration.oauth?
105
+ OAuthPolicy
106
+ elsif configuration.basic?
107
+ BasicAuthPolicy
108
+ else
109
+ AuthPolicy
110
+ end
111
+ end
112
+
113
+ def class_from_path(path_or_class)
114
+ return path_or_class if path_or_class.is_a?(Class)
115
+ Trello.const_get(path_or_class.to_s.singularize.camelize)
47
116
  end
48
117
  end
49
118
  end