ruby-trello 0.2.0 → 0.2.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/lib/trello.rb +30 -5
- data/lib/trello/action.rb +26 -26
- data/lib/trello/basic_data.rb +16 -9
- data/lib/trello/board.rb +50 -47
- data/lib/trello/card.rb +69 -41
- data/lib/trello/checklist.rb +34 -28
- data/lib/trello/client.rb +33 -8
- data/lib/trello/item.rb +10 -21
- data/lib/trello/item_state.rb +12 -29
- data/lib/trello/list.rb +31 -26
- data/lib/trello/member.rb +60 -51
- data/lib/trello/notification.rb +10 -0
- data/lib/trello/organization.rb +24 -43
- data/lib/trello/string.rb +33 -0
- data/spec/board_spec.rb +1 -1
- data/spec/card_spec.rb +27 -0
- data/spec/list_spec.rb +5 -8
- data/spec/member_spec.rb +4 -15
- data/spec/spec_helper.rb +9 -0
- metadata +11 -9
data/lib/trello.rb
CHANGED
@@ -1,10 +1,28 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
require 'oauth'
|
6
2
|
require 'json'
|
7
3
|
|
4
|
+
# Ruby wrapper around the Trello[http://trello.com] API
|
5
|
+
#
|
6
|
+
# First, set up your key information. You can get this information by {clicking here}[https://trello.com/1/appKey/generate].
|
7
|
+
#
|
8
|
+
# Trello.public_key = 'xxxxxxxxxxxxxxxxx'
|
9
|
+
# Trello.secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
10
|
+
#
|
11
|
+
# All the calls this library make to Trello require authentication using these keys. Be sure to protect them.
|
12
|
+
#
|
13
|
+
# So lets say you want to get information about the user *bobtester*. We can do something like this:
|
14
|
+
#
|
15
|
+
# bob = Member.find("bobtester")
|
16
|
+
# # Print out his name
|
17
|
+
# puts bob.full_name # "Bob Tester"
|
18
|
+
# # Print his bio
|
19
|
+
# puts bob.bio # A wonderfully delightful test user
|
20
|
+
# # How about a list of his boards?
|
21
|
+
# bob.boards
|
22
|
+
#
|
23
|
+
# And so much more. Consult the rest of the documentation for more information.
|
24
|
+
#
|
25
|
+
# Feel free to {peruse and participate in our Trello board}[https://trello.com/board/ruby-trello/4f092b2ee23cb6fe6d1aaabd]. It's completely open to the public.
|
8
26
|
module Trello
|
9
27
|
autoload :Action, 'trello/action'
|
10
28
|
autoload :BasicData, 'trello/basic_data'
|
@@ -15,5 +33,12 @@ module Trello
|
|
15
33
|
autoload :ItemState, 'trello/item_state'
|
16
34
|
autoload :List, 'trello/list'
|
17
35
|
autoload :Member, 'trello/member'
|
36
|
+
autoload :Notification, 'trello/notification'
|
18
37
|
autoload :Organization, 'trello/organization'
|
19
|
-
|
38
|
+
|
39
|
+
# Version of the Trello API that we use by default.
|
40
|
+
API_VERSION = 1
|
41
|
+
|
42
|
+
# Raise this when we can't find a record.
|
43
|
+
class RecordNotFound < StandardError; end
|
44
|
+
end
|
data/lib/trello/action.rb
CHANGED
@@ -1,48 +1,48 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# Action represents some event that occurred. For instance, when a card is created.
|
6
3
|
class Action < BasicData
|
4
|
+
attr_reader :id, :type, :data, :member_creator_id
|
5
|
+
|
7
6
|
class << self
|
7
|
+
# Locate a specific action and return a new Action object.
|
8
8
|
def find(id)
|
9
9
|
super(:actions, id)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
fields['
|
21
|
-
|
22
|
-
|
23
|
-
def data
|
24
|
-
fields['data']
|
13
|
+
# Update the attributes of an action
|
14
|
+
#
|
15
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
16
|
+
# an Action.
|
17
|
+
def update_fields(fields)
|
18
|
+
@id = fields['id']
|
19
|
+
@type = fields['type']
|
20
|
+
@data = fields['data']
|
21
|
+
@member_creator_id = fields['idMemberCreator']
|
25
22
|
end
|
26
23
|
|
27
|
-
#
|
28
|
-
|
24
|
+
# Returns the board this action occurred on.
|
29
25
|
def board
|
30
|
-
|
31
|
-
|
26
|
+
return @board if @board
|
27
|
+
@board = Client.get("/actions/#{id}/board").json_into(Board)
|
32
28
|
end
|
33
29
|
|
30
|
+
# Returns the card the action occurred on.
|
34
31
|
def card
|
35
|
-
|
36
|
-
|
32
|
+
return @card if @card
|
33
|
+
@card = Client.get("/actions/#{id}/card").json_into(Card)
|
37
34
|
end
|
38
35
|
|
36
|
+
# Returns the list the action occurred on.
|
39
37
|
def list
|
40
|
-
|
41
|
-
|
38
|
+
return @list if @list
|
39
|
+
@list = Client.get("/actions/#{id}/list").json_into(List)
|
42
40
|
end
|
43
41
|
|
42
|
+
# Returns the member who created the action.
|
44
43
|
def member_creator
|
45
|
-
|
44
|
+
return @member_creator if @member_creator
|
45
|
+
@member_creator = Member.find(member_creator_id)
|
46
46
|
end
|
47
47
|
end
|
48
|
-
end
|
48
|
+
end
|
data/lib/trello/basic_data.rb
CHANGED
@@ -1,25 +1,32 @@
|
|
1
|
-
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
1
|
+
require 'trello/string'
|
4
2
|
|
5
3
|
module Trello
|
6
4
|
class BasicData
|
7
|
-
attr_reader :
|
5
|
+
attr_reader :id
|
8
6
|
|
9
7
|
class << self
|
8
|
+
# Perform a query to retrieve some information at a specific path for a specific id.
|
10
9
|
def find(path, id)
|
11
|
-
|
12
|
-
new(JSON.parse(response.read_body))
|
10
|
+
Client.get("/#{path}/#{id}").json_into(self)
|
13
11
|
end
|
14
12
|
end
|
15
13
|
|
16
|
-
# Fields
|
17
14
|
def initialize(fields = {})
|
18
|
-
|
15
|
+
update_fields(fields)
|
19
16
|
end
|
20
17
|
|
18
|
+
def update_fields(fields)
|
19
|
+
raise NotImplementedError, "#{self.class} does not implement update_fields."
|
20
|
+
end
|
21
|
+
|
22
|
+
# Refresh the contents of our object.
|
23
|
+
def refresh!
|
24
|
+
self.class.find(id)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Two objects are equal if their _id_ methods are equal.
|
21
28
|
def ==(other)
|
22
|
-
|
29
|
+
id == other.id
|
23
30
|
end
|
24
31
|
end
|
25
32
|
end
|
data/lib/trello/board.rb
CHANGED
@@ -1,70 +1,73 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# A board is a container which holds lists. This is where everything lives.
|
6
3
|
class Board < BasicData
|
4
|
+
attr_reader :id, :name, :description, :closed, :url, :organization_id
|
5
|
+
|
7
6
|
class << self
|
7
|
+
# Locate a board given a specific id.
|
8
8
|
def find(id)
|
9
|
-
|
10
|
-
new(JSON.parse(response.read_body))
|
9
|
+
super(:boards, id)
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
fields['
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
fields['desc']
|
13
|
+
# Update the fields of a board.
|
14
|
+
#
|
15
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
16
|
+
# a board.
|
17
|
+
def update_fields(fields)
|
18
|
+
@id = fields['id']
|
19
|
+
@name = fields['name']
|
20
|
+
@description = fields['desc']
|
21
|
+
@closed = fields['closed']
|
22
|
+
@url = fields['url']
|
23
|
+
@organization_id = fields['idOrganization']
|
26
24
|
end
|
27
25
|
|
28
|
-
|
29
|
-
|
26
|
+
# Check if the board is active.
|
27
|
+
def closed?
|
28
|
+
closed
|
30
29
|
end
|
31
30
|
|
32
|
-
|
33
|
-
fields['url']
|
34
|
-
end
|
35
|
-
|
36
|
-
# Links to other data structures
|
37
|
-
|
31
|
+
# Return a timeline of actions related to this board.
|
38
32
|
def actions
|
39
|
-
|
40
|
-
|
41
|
-
Action.new(action_fields)
|
42
|
-
end
|
33
|
+
return @actions if @actions
|
34
|
+
@actions = Client.get("/boards/#{id}/actions").json_into(Action)
|
43
35
|
end
|
44
36
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
37
|
+
# Return all the cards on this board.
|
38
|
+
#
|
39
|
+
# The options hash may have a filter key which can have its value set as any
|
40
|
+
# of the following values:
|
41
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
42
|
+
def cards(options = { :filter => :open })
|
43
|
+
return @cards if @cards
|
44
|
+
@cards = Client.get("/boards/#{id}/cards").json_into(Card)
|
50
45
|
end
|
51
46
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
47
|
+
# Returns all the lists on this board.
|
48
|
+
#
|
49
|
+
# The options hash may have a filter key which can have its value set as any
|
50
|
+
# of the following values:
|
51
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
52
|
+
def lists(options = { :filter => :open })
|
53
|
+
return @lists if @lists
|
54
|
+
@lists = Client.get("/boards/#{id}/lists", options).json_into(List)
|
57
55
|
end
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
# Returns an array of members who are associated with this board.
|
58
|
+
#
|
59
|
+
# The options hash may have a filter key which can have its value set as any
|
60
|
+
# of the following values:
|
61
|
+
# :filter => [ :none, :normal, :owners, :all ] # default :all
|
62
|
+
def members(options = { :filter => :all })
|
63
|
+
return @members if @members
|
64
|
+
@members = Client.get("/boards/#{id}/members").json_into(Member)
|
64
65
|
end
|
65
66
|
|
67
|
+
# Returns a reference to the organization this board belongs to.
|
66
68
|
def organization
|
67
|
-
|
69
|
+
return @organization if @organization
|
70
|
+
@organization = Organization.find(organization_id)
|
68
71
|
end
|
69
72
|
end
|
70
|
-
end
|
73
|
+
end
|
data/lib/trello/card.rb
CHANGED
@@ -1,71 +1,99 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# A Card is a container that can house checklists and comments; it resides inside a List.
|
6
3
|
class Card < BasicData
|
4
|
+
attr_reader :id
|
5
|
+
attr_accessor :name, :description, :closed, :url, :board_id, :member_ids, :list_id
|
6
|
+
|
7
7
|
class << self
|
8
|
+
# Find a specific card by its id.
|
8
9
|
def find(id)
|
9
10
|
super(:cards, id)
|
10
11
|
end
|
11
|
-
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
# Create a new card and save it on Trello.
|
14
|
+
def create(options)
|
15
|
+
new('name' => options[:name],
|
16
|
+
'idList' => options[:list_id],
|
17
|
+
'desc' => options[:description]).save!
|
18
|
+
end
|
17
19
|
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
+
# Update the fields of a card.
|
22
|
+
#
|
23
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
24
|
+
# a card.
|
25
|
+
def update_fields(fields)
|
26
|
+
@id = fields['id']
|
27
|
+
@name = fields['name']
|
28
|
+
@description = fields['desc']
|
29
|
+
@closed = fields['closed']
|
30
|
+
@url = fields['url']
|
31
|
+
@board_id = fields['idBoard']
|
32
|
+
@member_ids = fields['idMembers']
|
33
|
+
@list_id = fields['idList']
|
21
34
|
end
|
22
35
|
|
23
|
-
|
24
|
-
|
36
|
+
# Returns a list of the actions associated with this card.
|
37
|
+
def actions
|
38
|
+
return @actions if @actions
|
39
|
+
@actions = Client.get("/cards/#{id}/actions").json_into(Action)
|
25
40
|
end
|
26
41
|
|
27
|
-
|
28
|
-
|
42
|
+
# Returns a reference to the board this card is part of.
|
43
|
+
def board
|
44
|
+
return @board if @board
|
45
|
+
@board = Board.find(board_id)
|
29
46
|
end
|
30
47
|
|
31
|
-
|
32
|
-
|
48
|
+
# Returns a list of checklists associated with the card.
|
49
|
+
#
|
50
|
+
# The options hash may have a filter key which can have its value set as any
|
51
|
+
# of the following values:
|
52
|
+
# :filter => [ :none, :all ] # default :all
|
53
|
+
def checklists(options = { :filter => :all })
|
54
|
+
return @checklists if @checklists
|
55
|
+
@checklists = Client.get("/cards/#{id}/checklists", options).json_into(Checklist)
|
33
56
|
end
|
34
57
|
|
35
|
-
#
|
58
|
+
# Returns a reference to the list this card is currently in.
|
59
|
+
def list
|
60
|
+
return @list if @list
|
61
|
+
@list = List.find(list_id)
|
62
|
+
end
|
36
63
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
64
|
+
# Returns a list of members who are assigned to this card.
|
65
|
+
def members
|
66
|
+
return @members if @members
|
67
|
+
@members = member_ids.map do |member_id|
|
68
|
+
Client.get("/members/#{member_id}").json_into(Member)
|
41
69
|
end
|
42
70
|
end
|
43
71
|
|
44
|
-
|
45
|
-
|
46
|
-
|
72
|
+
# Saves a record.
|
73
|
+
def save!
|
74
|
+
return update! if id
|
47
75
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
76
|
+
Client.post("/cards", {
|
77
|
+
:name => @name,
|
78
|
+
:desc => @description,
|
79
|
+
:idList => @list_id
|
80
|
+
})
|
53
81
|
end
|
54
82
|
|
55
|
-
|
56
|
-
|
83
|
+
# Update an existing record.
|
84
|
+
def update!
|
85
|
+
# Trello doesn't support this yet. But Daniel is working on it as I
|
86
|
+
# place this comment here!
|
57
87
|
end
|
58
88
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
Member.new(JSON.parse(response.read_body))
|
63
|
-
end
|
89
|
+
# Is the record valid?
|
90
|
+
def valid?
|
91
|
+
@name && @list_id
|
64
92
|
end
|
65
93
|
|
66
|
-
# Add a comment
|
67
|
-
def
|
68
|
-
|
94
|
+
# Add a comment with the supplied text.
|
95
|
+
def add_comment(text)
|
96
|
+
Client.put("/cards/#{id}/actions/comments", :text => text)
|
69
97
|
end
|
70
98
|
end
|
71
|
-
end
|
99
|
+
end
|
data/lib/trello/checklist.rb
CHANGED
@@ -1,57 +1,63 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# A Checklist holds items which are like a "todo" list. Checklists are linked to a card.
|
6
3
|
class Checklist < BasicData
|
4
|
+
attr_reader :id, :name, :description, :closed, :url, :check_items, :board_id, :list_id, :member_ids
|
5
|
+
|
7
6
|
class << self
|
7
|
+
# Locate a specific checklist by its id.
|
8
8
|
def find(id)
|
9
9
|
super(:checklists, id)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
fields['
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
fields['
|
13
|
+
# Update the fields of a checklist.
|
14
|
+
#
|
15
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
16
|
+
# a checklist.
|
17
|
+
def update_fields(fields)
|
18
|
+
@id = fields['id']
|
19
|
+
@name = fields['name']
|
20
|
+
@description = fields['desc']
|
21
|
+
@closed = fields['closed']
|
22
|
+
@url = fields['url']
|
23
|
+
@check_items = fields['checkItems']
|
24
|
+
@board_id = fields['idBoard']
|
25
|
+
@member_ids = fields['idMembers']
|
25
26
|
end
|
26
27
|
|
28
|
+
# Check if the checklist is currently active.
|
27
29
|
def closed?
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def url
|
32
|
-
fields['url']
|
30
|
+
closed
|
33
31
|
end
|
34
32
|
|
35
|
-
#
|
36
|
-
|
33
|
+
# Return a list of items on the checklist.
|
37
34
|
def items
|
38
|
-
|
35
|
+
return @items if @items
|
36
|
+
|
37
|
+
@items = check_items.map do |item_fields|
|
39
38
|
Item.new(item_fields)
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
42
|
+
# Return a reference to the board the checklist is on.
|
43
43
|
def board
|
44
|
-
|
44
|
+
return @board if @board
|
45
|
+
@board = Board.find(board_id)
|
45
46
|
end
|
46
47
|
|
48
|
+
# Return a reference to the list the checklist is on.
|
47
49
|
def list
|
48
|
-
|
50
|
+
return @list if @list
|
51
|
+
@list = List.find(list_id)
|
49
52
|
end
|
50
53
|
|
54
|
+
# Return a list of members active in this checklist.
|
51
55
|
def members
|
52
|
-
|
56
|
+
return @members if @members
|
57
|
+
|
58
|
+
@members = member_ids.map do |member_id|
|
53
59
|
Member.find(member_id)
|
54
60
|
end
|
55
61
|
end
|
56
62
|
end
|
57
|
-
end
|
63
|
+
end
|
data/lib/trello/client.rb
CHANGED
@@ -1,22 +1,47 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
require 'addressable/uri'
|
6
2
|
|
7
3
|
module Trello
|
4
|
+
# Client is used to handle the OAuth connection to Trello as well as send requests over that authenticated socket.
|
8
5
|
class Client
|
9
6
|
class EnterYourPublicKey < StandardError; end
|
10
7
|
class EnterYourSecret < StandardError; end
|
11
8
|
|
12
9
|
class << self
|
13
|
-
attr_writer :public_key, :secret
|
10
|
+
attr_writer :public_key, :secret
|
14
11
|
|
15
|
-
|
16
|
-
|
12
|
+
# call-seq:
|
13
|
+
# get(path, params)
|
14
|
+
# post(path, params)
|
15
|
+
# put(path, params)
|
16
|
+
# delete(path, params)
|
17
|
+
# query(api_version, path, options)
|
18
|
+
#
|
19
|
+
# Makes a query to a specific path via one of the four HTTP methods, optionally
|
20
|
+
# with a hash specifying parameters to pass to Trello.
|
21
|
+
#
|
22
|
+
# You should use one of _.get_, _.post_, _.put_ or _.delete_ instead of this method.
|
23
|
+
def query(api_version, path, options = { :method => :get, :params => {} })
|
24
|
+
uri = Addressable::URI.parse("https://api.trello.com/#{api_version}#{path}")
|
17
25
|
uri.query_values = options[:params]
|
18
26
|
|
19
27
|
access_token.send(options[:method], uri.to_s)
|
28
|
+
rescue OAuth::Problem => e
|
29
|
+
headers = []
|
30
|
+
e.request.each_header do |k,v|
|
31
|
+
headers << [k, v]
|
32
|
+
end
|
33
|
+
|
34
|
+
logger.error("[#{@access_token}] Disposing of access token.\n#{e.inspect}")
|
35
|
+
logger.info("[#{@access_token}] Headers: #{headers.inspect}\nRequest Body: #{e.request.body}")
|
36
|
+
@access_token = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
%w{get post put delete}.each do |http_method|
|
40
|
+
send(:define_method, http_method) do |*args|
|
41
|
+
path = args[0]
|
42
|
+
params = args[1] || {}
|
43
|
+
query(API_VERSION, path, :method => http_method, :params => params).read_body
|
44
|
+
end
|
20
45
|
end
|
21
46
|
|
22
47
|
protected
|
@@ -39,4 +64,4 @@ module Trello
|
|
39
64
|
end
|
40
65
|
end
|
41
66
|
end
|
42
|
-
end
|
67
|
+
end
|
data/lib/trello/item.rb
CHANGED
@@ -1,27 +1,16 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# An Item is a basic task that can be checked off and marked as completed.
|
6
3
|
class Item < BasicData
|
7
|
-
|
8
|
-
def find(nothing)
|
9
|
-
raise 'This operation does not make sense'
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# Fields
|
14
|
-
|
15
|
-
def id
|
16
|
-
fields['id']
|
17
|
-
end
|
18
|
-
|
19
|
-
def name
|
20
|
-
fields['name']
|
21
|
-
end
|
4
|
+
attr_reader :id, :name, :type
|
22
5
|
|
23
|
-
|
24
|
-
|
6
|
+
# Updates the fields of an item.
|
7
|
+
#
|
8
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
9
|
+
# an item.
|
10
|
+
def update_fields(fields)
|
11
|
+
@id = fields['id']
|
12
|
+
@name = fields['name']
|
13
|
+
@type = fields['type']
|
25
14
|
end
|
26
15
|
end
|
27
16
|
end
|
data/lib/trello/item_state.rb
CHANGED
@@ -1,38 +1,21 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# Represents the state of an item.
|
6
3
|
class ItemState < BasicData
|
7
|
-
|
8
|
-
def find(nothing)
|
9
|
-
raise 'This operation does not make sense'
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# Fields
|
14
|
-
|
15
|
-
def id
|
16
|
-
fields['id']
|
17
|
-
end
|
18
|
-
|
19
|
-
def state
|
20
|
-
fields['state']
|
21
|
-
end
|
4
|
+
attr_reader :id, :state, :item_id
|
22
5
|
|
23
|
-
#
|
24
|
-
|
25
|
-
|
6
|
+
# Update the fields of an item state.
|
7
|
+
#
|
8
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
9
|
+
# an item state.
|
10
|
+
def update_fields(fields)
|
11
|
+
@id = fields['id']
|
12
|
+
@state = fields['state']
|
13
|
+
@item_id = fields['idItem']
|
26
14
|
end
|
27
15
|
|
28
|
-
#
|
29
|
-
|
16
|
+
# Return the item this state belongs to.
|
30
17
|
def item
|
31
|
-
|
32
|
-
# needs an API to query check items in my estimation. Otherwise, the "idCheckItem"
|
33
|
-
# key serves no good purpose. I'd have to know what checklist this state belongs
|
34
|
-
# to, and then query all of its items, comparing the ID as I go. O(n) at the best
|
35
|
-
# of times. If I don't have the checklist, then we're O(m*n^2). Horrible.
|
18
|
+
Item.find(@item_id)
|
36
19
|
end
|
37
20
|
end
|
38
21
|
end
|
data/lib/trello/list.rb
CHANGED
@@ -1,46 +1,51 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# A List is a container which holds cards. Lists are items on a board.
|
6
3
|
class List < BasicData
|
4
|
+
attr_reader :id, :name, :closed, :board_id
|
5
|
+
|
7
6
|
class << self
|
7
|
+
# Finds a specific list, given an id.
|
8
8
|
def find(id)
|
9
9
|
super(:lists, id)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
fields['
|
13
|
+
# Updates the fields of a list.
|
14
|
+
#
|
15
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
16
|
+
# a List.
|
17
|
+
def update_fields(fields)
|
18
|
+
@id = fields['id']
|
19
|
+
@name = fields['name']
|
20
|
+
@closed = fields['closed']
|
21
|
+
@board_id = fields['idBoard']
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
# Check if the list is not active anymore.
|
25
|
+
def closed?
|
26
|
+
closed
|
25
27
|
end
|
26
28
|
|
27
|
-
#
|
28
|
-
|
29
|
+
# Return a timeline of events related to this list.
|
29
30
|
def actions
|
30
|
-
|
31
|
-
|
32
|
-
Action.new(action_fields)
|
33
|
-
end
|
31
|
+
return @actions if @actions
|
32
|
+
@actions = Client.get("/lists/#{id}/actions").json_into(Action)
|
34
33
|
end
|
35
34
|
|
35
|
+
# Return the board the list is connected to.
|
36
36
|
def board
|
37
|
-
|
37
|
+
return @board if @board
|
38
|
+
@board = Board.find(board_id)
|
38
39
|
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
# Returns all the cards on this list.
|
42
|
+
#
|
43
|
+
# The options hash may have a filter key which can have its value set as any
|
44
|
+
# of the following values:
|
45
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
46
|
+
def cards(options = { :filter => :open })
|
47
|
+
return @cards if @cards
|
48
|
+
@cards = Client.get("/lists/#{id}/cards", options).json_into(Card)
|
44
49
|
end
|
45
50
|
end
|
46
|
-
end
|
51
|
+
end
|
data/lib/trello/member.rb
CHANGED
@@ -1,73 +1,82 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# A Member is a user of the Trello service.
|
6
3
|
class Member < BasicData
|
4
|
+
attr_reader :id
|
5
|
+
attr_accessor :full_name, :username, :gravatar_id, :bio, :url
|
6
|
+
|
7
7
|
class << self
|
8
|
+
# Finds a user
|
9
|
+
#
|
10
|
+
# The argument may be specified as either an _id_ or a _username_.
|
8
11
|
def find(id_or_username)
|
9
12
|
super(:members, id_or_username)
|
10
13
|
end
|
11
14
|
end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@fields['
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@fields['fullName']
|
25
|
-
end
|
26
|
-
|
27
|
-
def username
|
28
|
-
@fields['username']
|
16
|
+
# Update the fields of a member.
|
17
|
+
#
|
18
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
19
|
+
# an Member.
|
20
|
+
def update_fields(fields)
|
21
|
+
@id = fields['id']
|
22
|
+
@full_name = fields['fullName']
|
23
|
+
@username = fields['username']
|
24
|
+
@gravatar_id = fields['gravatar']
|
25
|
+
@bio = fields['bio']
|
26
|
+
@url = fields['url']
|
29
27
|
end
|
30
28
|
|
31
|
-
|
32
|
-
|
29
|
+
# Returns a list of the users actions.
|
30
|
+
def actions
|
31
|
+
return @actions if @actions
|
32
|
+
@actions = Client.get("/members/#{username}/actions").json_into(Action)
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
# Returns a list of the boards a member is a part of.
|
36
|
+
#
|
37
|
+
# The options hash may have a filter key which can have its value set as any
|
38
|
+
# of the following values:
|
39
|
+
# :filter => [ :none, :members, :organization, :public, :open, :closed, :all ] # default: :all
|
40
|
+
def boards(options = { :filter => :all })
|
41
|
+
return @boards if @boards
|
42
|
+
@boards = Client.get("/members/#{username}/boards", options).json_into(Board)
|
37
43
|
end
|
38
44
|
|
39
|
-
|
40
|
-
|
45
|
+
# Returns a list of cards the member is assigned to.
|
46
|
+
#
|
47
|
+
# The options hash may have a filter key which can have its value set as any
|
48
|
+
# of the following values:
|
49
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
50
|
+
def cards(options = { :filter => :open })
|
51
|
+
return @cards if @cards
|
52
|
+
@cards = Client.get("/members/#{username}/cards", options).json_into(Card)
|
41
53
|
end
|
42
54
|
|
43
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
55
|
+
# Returns a list of the organizations this member is a part of.
|
56
|
+
#
|
57
|
+
# The options hash may have a filter key which can have its value set as any
|
58
|
+
# of the following values:
|
59
|
+
# :filter => [ :none, :members, :public, :all ] # default: all
|
60
|
+
def organizations(options = { :filter => :all })
|
61
|
+
return @organizations if @organizations
|
62
|
+
@organizations = Client.get("/members/#{username}/organizations", options).json_into(Organization)
|
50
63
|
end
|
51
64
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
Board.new(board_fields)
|
56
|
-
end
|
65
|
+
# Returns a list of notifications for the user
|
66
|
+
def notifications
|
67
|
+
Client.get("/members/#{username}/notifications").json_into(Notification)
|
57
68
|
end
|
58
69
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
Organization.new(org_fields)
|
70
|
-
end
|
70
|
+
# Returns a hash of the items that would be returned by Trello.
|
71
|
+
def to_hash
|
72
|
+
{
|
73
|
+
'id' => id,
|
74
|
+
'fullName' => full_name,
|
75
|
+
'username' => username,
|
76
|
+
'gravatar' => gravatar_id,
|
77
|
+
'bio' => bio,
|
78
|
+
'url' => url
|
79
|
+
}
|
71
80
|
end
|
72
81
|
end
|
73
|
-
end
|
82
|
+
end
|
data/lib/trello/organization.rb
CHANGED
@@ -1,62 +1,43 @@
|
|
1
|
-
# Ruby wrapper around the Trello API
|
2
|
-
# Copyright (c) 2012, Jeremy Tregunna
|
3
|
-
# Use and distribution terms may be found in the file LICENSE included in this distribution.
|
4
|
-
|
5
1
|
module Trello
|
2
|
+
# Organizations are useful for linking members together.
|
6
3
|
class Organization < BasicData
|
4
|
+
attr_reader :id, :name, :display_name, :description, :url
|
5
|
+
|
7
6
|
class << self
|
7
|
+
# Find an organization by its id.
|
8
8
|
def find(id)
|
9
9
|
super(:organizations, id)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@fields['
|
21
|
-
|
22
|
-
|
23
|
-
def name
|
24
|
-
@fields['name']
|
25
|
-
end
|
26
|
-
|
27
|
-
def display_name
|
28
|
-
@fields['display_name']
|
13
|
+
# Update the fields of an organization.
|
14
|
+
#
|
15
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
16
|
+
# an Organization.
|
17
|
+
def update_fields(fields)
|
18
|
+
@id = fields['id']
|
19
|
+
@name = fields['name']
|
20
|
+
@display_name = fields['displayName']
|
21
|
+
@description = fields['description']
|
22
|
+
@url = fields['url']
|
29
23
|
end
|
30
24
|
|
31
|
-
|
32
|
-
@fields['desc']
|
33
|
-
end
|
34
|
-
|
35
|
-
def url
|
36
|
-
@fields['url']
|
37
|
-
end
|
38
|
-
|
39
|
-
# Links to other data structures
|
40
|
-
|
25
|
+
# Returns a timeline of actions.
|
41
26
|
def actions
|
42
|
-
|
43
|
-
|
44
|
-
Action.new(action_fields)
|
45
|
-
end
|
27
|
+
return @actions if @actions
|
28
|
+
@actions = Client.get("/organizations/#{id}/actions").json_into(Action)
|
46
29
|
end
|
47
30
|
|
31
|
+
# Returns a list of boards under this organization.
|
48
32
|
def boards
|
49
|
-
|
50
|
-
|
51
|
-
Board.new(board_fields)
|
52
|
-
end
|
33
|
+
return @boards if @boards
|
34
|
+
@boards = Client.get("/organizations/#{id}/boards/all").json_into(Board)
|
53
35
|
end
|
54
36
|
|
37
|
+
# Returns an array of members associated with the organization.
|
55
38
|
def members
|
56
|
-
|
57
|
-
|
58
|
-
Member.new(member_fields)
|
59
|
-
end
|
39
|
+
return @members if @members
|
40
|
+
@members = Client.get("/organizations/#{id}/members/all").json_into(Member)
|
60
41
|
end
|
61
42
|
end
|
62
|
-
end
|
43
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class String
|
2
|
+
# Decodes some JSON text in the receiver, and marshals it into a class specified
|
3
|
+
# in _obj_. If _obj_ is not a class, then we marshall the data into that instance
|
4
|
+
# via _update_fields_.
|
5
|
+
#
|
6
|
+
# For instance:
|
7
|
+
#
|
8
|
+
# class Stuff
|
9
|
+
# attr_reader :a, :b
|
10
|
+
# def initialize(values)
|
11
|
+
# @a = values['a']
|
12
|
+
# @b = values['b']
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
# thing = '{"a":42,"b":"foo"}'.json_into(Stuff)
|
16
|
+
# thing.a == 42
|
17
|
+
# thing.b == "foo"
|
18
|
+
def json_into(obj)
|
19
|
+
data = JSON.parse(self)
|
20
|
+
action = obj.kind_of?(Class) ? :new : :update_fields
|
21
|
+
if data.kind_of? Hash
|
22
|
+
obj.send(action, JSON.parse(self))
|
23
|
+
else
|
24
|
+
data.map { |element| obj.send(action, element) }
|
25
|
+
end
|
26
|
+
rescue JSON::ParserError => json_error
|
27
|
+
if json_error.message =~ /model not found/
|
28
|
+
raise Trello::RecordNotFound
|
29
|
+
else
|
30
|
+
raise
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/board_spec.rb
CHANGED
@@ -41,7 +41,7 @@ module Trello
|
|
41
41
|
|
42
42
|
context "cards" do
|
43
43
|
it "gets its list of cards" do
|
44
|
-
stub_request(:get, "https://api.trello.com/1/boards/abcdef123456789123456789/cards
|
44
|
+
stub_request(:get, "https://api.trello.com/1/boards/abcdef123456789123456789/cards?").
|
45
45
|
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
46
46
|
to_return(:status => 200, :headers => {}, :body => cards_payload)
|
47
47
|
|
data/spec/card_spec.rb
CHANGED
@@ -17,6 +17,33 @@ module Trello
|
|
17
17
|
@card = Card.find('abcdef123456789123456789')
|
18
18
|
end
|
19
19
|
|
20
|
+
context "creating" do
|
21
|
+
it "creates a new record" do
|
22
|
+
card = Card.new(cards_details.first)
|
23
|
+
card.should be_valid
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'must not be valid if not given a name' do
|
27
|
+
card = Card.new('idList' => lists_details.first['id'])
|
28
|
+
card.should_not be_valid
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'must not be valid if not given a list id' do
|
32
|
+
card = Card.new('name' => lists_details.first['name'])
|
33
|
+
card.should_not be_valid
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'creates a new record and saves it on Trello' do
|
37
|
+
payload = {
|
38
|
+
:name => 'Test Card',
|
39
|
+
:desc => '',
|
40
|
+
}
|
41
|
+
stub_trello_request!(:post, '/cards', payload.merge(:idList => lists_details.first['id']))
|
42
|
+
card = Card.create(payload.merge(:list_id => lists_details.first['id']))
|
43
|
+
card.should == ''
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
20
47
|
context "fields" do
|
21
48
|
it "gets its id" do
|
22
49
|
@card.id.should_not be_nil
|
data/spec/list_spec.rb
CHANGED
@@ -10,14 +10,10 @@ module Trello
|
|
10
10
|
end
|
11
11
|
|
12
12
|
before(:each) do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
18
|
-
to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
|
19
|
-
|
20
|
-
@list = List.find("abcdef123456789123456789")
|
13
|
+
stub_trello_request!(:get, "/lists/abcdef123456789123456789?", nil, JSON.generate(lists_details.first))
|
14
|
+
stub_trello_request!(:get, "/boards/abcdef123456789123456789?", nil, JSON.generate(boards_details.first))
|
15
|
+
|
16
|
+
@list = List.find("abcdef123456789123456789")
|
21
17
|
end
|
22
18
|
|
23
19
|
context "fields" do
|
@@ -40,6 +36,7 @@ module Trello
|
|
40
36
|
|
41
37
|
context "cards" do
|
42
38
|
it "has a list of cards" do
|
39
|
+
stub_trello_request!(:get, "/lists/abcdef123456789123456789/cards?", { :filter => :open }, cards_payload)
|
43
40
|
@list.cards.count.should be > 0
|
44
41
|
end
|
45
42
|
end
|
data/spec/member_spec.rb
CHANGED
@@ -12,29 +12,21 @@ module Trello
|
|
12
12
|
end
|
13
13
|
|
14
14
|
before(:each) do
|
15
|
-
|
16
|
-
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
17
|
-
to_return(:status => 200, :headers => {}, :body => user_payload)
|
15
|
+
stub_trello_request!(:get, '/members/me?', nil, user_payload)
|
18
16
|
|
19
17
|
@member = Member.find('me')
|
20
18
|
end
|
21
19
|
|
22
20
|
context "actions" do
|
23
21
|
it "retrieves a list of actions" do
|
24
|
-
|
25
|
-
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
26
|
-
to_return(:status => 200, :headers => {}, :body => actions_payload)
|
27
|
-
|
22
|
+
stub_trello_request!(:get, '/members/me/actions?', nil, actions_payload)
|
28
23
|
@member.actions.count.should be > 0
|
29
24
|
end
|
30
25
|
end
|
31
26
|
|
32
27
|
context "boards" do
|
33
28
|
it "has a list of boards" do
|
34
|
-
|
35
|
-
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
36
|
-
to_return(:status => 200, :headers => {}, :body => boards_payload)
|
37
|
-
|
29
|
+
stub_trello_request!(:get, '/members/me/boards?', { :filter => :all }, boards_payload)
|
38
30
|
boards = @member.boards
|
39
31
|
boards.count.should be > 0
|
40
32
|
end
|
@@ -42,10 +34,7 @@ module Trello
|
|
42
34
|
|
43
35
|
context "organizations" do
|
44
36
|
it "has a list of organizations" do
|
45
|
-
|
46
|
-
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
47
|
-
to_return(:status => 200, :headers => {}, :body => orgs_payload)
|
48
|
-
|
37
|
+
stub_trello_request!(:get, '/members/me/organizations?', { :filter => :all }, orgs_payload)
|
49
38
|
orgs = @member.organizations
|
50
39
|
orgs.count.should be > 0
|
51
40
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -17,6 +17,15 @@ require 'trello'
|
|
17
17
|
require 'webmock/rspec'
|
18
18
|
|
19
19
|
module Helpers
|
20
|
+
def stub_trello_request!(http_method, path, data, returning = '')
|
21
|
+
uri = Addressable::URI.parse("https://api.trello.com/#{Trello::API_VERSION}#{path}")
|
22
|
+
uri.query_values = data.kind_of?(String) ? JSON.parse(data) : data if data
|
23
|
+
|
24
|
+
stub_request(http_method, uri.to_s).
|
25
|
+
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
26
|
+
to_return(:status => 200, :headers => {}, :body => returning)
|
27
|
+
end
|
28
|
+
|
20
29
|
def user_details
|
21
30
|
{
|
22
31
|
"id" => "abcdef123456789012345678",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-trello
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-01-07 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|
16
|
-
requirement: &
|
16
|
+
requirement: &70096518301420 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.1.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70096518301420
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: oauth
|
27
|
-
requirement: &
|
27
|
+
requirement: &70096518300720 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.4.5
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70096518300720
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: addressable
|
38
|
-
requirement: &
|
38
|
+
requirement: &70096518300060 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.2.6
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70096518300060
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
|
-
requirement: &
|
49
|
+
requirement: &70096518299380 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: 1.0.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70096518299380
|
58
58
|
description: A wrapper around the trello.com API.
|
59
59
|
email: jeremy@tregunna.ca
|
60
60
|
executables: []
|
@@ -72,7 +72,9 @@ files:
|
|
72
72
|
- lib/trello/item_state.rb
|
73
73
|
- lib/trello/list.rb
|
74
74
|
- lib/trello/member.rb
|
75
|
+
- lib/trello/notification.rb
|
75
76
|
- lib/trello/organization.rb
|
77
|
+
- lib/trello/string.rb
|
76
78
|
- lib/trello.rb
|
77
79
|
- README.md
|
78
80
|
- spec/action_spec.rb
|