ruby-trello-czuger 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +182 -0
- data/lib/trello.rb +163 -0
- data/lib/trello/action.rb +68 -0
- data/lib/trello/association.rb +14 -0
- data/lib/trello/association_proxy.rb +42 -0
- data/lib/trello/attachment.rb +40 -0
- data/lib/trello/authorization.rb +187 -0
- data/lib/trello/basic_data.rb +132 -0
- data/lib/trello/board.rb +211 -0
- data/lib/trello/card.rb +467 -0
- data/lib/trello/checklist.rb +143 -0
- data/lib/trello/client.rb +120 -0
- data/lib/trello/comment.rb +62 -0
- data/lib/trello/configuration.rb +68 -0
- data/lib/trello/core_ext/array.rb +6 -0
- data/lib/trello/core_ext/hash.rb +6 -0
- data/lib/trello/core_ext/string.rb +6 -0
- data/lib/trello/cover_image.rb +8 -0
- data/lib/trello/has_actions.rb +9 -0
- data/lib/trello/item.rb +37 -0
- data/lib/trello/item_state.rb +30 -0
- data/lib/trello/json_utils.rb +64 -0
- data/lib/trello/label.rb +108 -0
- data/lib/trello/label_name.rb +31 -0
- data/lib/trello/list.rb +114 -0
- data/lib/trello/member.rb +112 -0
- data/lib/trello/multi_association.rb +12 -0
- data/lib/trello/net.rb +39 -0
- data/lib/trello/notification.rb +61 -0
- data/lib/trello/organization.rb +68 -0
- data/lib/trello/plugin_datum.rb +34 -0
- data/lib/trello/token.rb +37 -0
- data/lib/trello/webhook.rb +103 -0
- data/spec/action_spec.rb +149 -0
- data/spec/array_spec.rb +13 -0
- data/spec/association_spec.rb +26 -0
- data/spec/basic_auth_policy_spec.rb +51 -0
- data/spec/board_spec.rb +442 -0
- data/spec/card_spec.rb +822 -0
- data/spec/checklist_spec.rb +296 -0
- data/spec/client_spec.rb +257 -0
- data/spec/configuration_spec.rb +95 -0
- data/spec/hash_spec.rb +15 -0
- data/spec/integration/how_to_authorize_spec.rb +53 -0
- data/spec/integration/how_to_use_boards_spec.rb +48 -0
- data/spec/integration/integration_test.rb +40 -0
- data/spec/item_spec.rb +75 -0
- data/spec/json_utils_spec.rb +73 -0
- data/spec/label_spec.rb +205 -0
- data/spec/list_spec.rb +253 -0
- data/spec/member_spec.rb +159 -0
- data/spec/notification_spec.rb +143 -0
- data/spec/oauth_policy_spec.rb +160 -0
- data/spec/organization_spec.rb +71 -0
- data/spec/spec_helper.rb +435 -0
- data/spec/string_spec.rb +55 -0
- data/spec/token_spec.rb +89 -0
- data/spec/trello_spec.rb +134 -0
- data/spec/webhook_spec.rb +130 -0
- metadata +200 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module Trello
|
2
|
+
# Represents the state of an item.
|
3
|
+
#
|
4
|
+
# @!attribute [r] id
|
5
|
+
# @return [String]
|
6
|
+
# @!attribute [r] state
|
7
|
+
# @return [Object]
|
8
|
+
# @!attribute [r] item_id
|
9
|
+
# @return [String]
|
10
|
+
class CheckItemState < BasicData
|
11
|
+
register_attributes :id, :state, :item_id, readonly: [ :id, :state, :item_id ]
|
12
|
+
validates_presence_of :id, :item_id
|
13
|
+
|
14
|
+
# Update the fields of an item state.
|
15
|
+
#
|
16
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
17
|
+
# an item state.
|
18
|
+
def update_fields(fields)
|
19
|
+
attributes[:id] = fields['id'] || attributes[:id]
|
20
|
+
attributes[:state] = fields['state'] || attributes[:state]
|
21
|
+
attributes[:item_id] = fields['idCheckItem'] || attributes[:item_id]
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return the item this state belongs to.
|
26
|
+
def item
|
27
|
+
Item.find(item_id)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Trello
|
2
|
+
module JsonUtils
|
3
|
+
def self.included(base)
|
4
|
+
base.send :include, InstanceMethods
|
5
|
+
base.send :extend, ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
def from_response(*args)
|
10
|
+
update_fields parse_json(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_json(*args)
|
14
|
+
self.class.parse_json(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
# Public - Decodes some JSON text in the receiver, and marshals it into a class specified
|
20
|
+
# in _obj_.
|
21
|
+
#
|
22
|
+
# For instance:
|
23
|
+
#
|
24
|
+
# class Stuff
|
25
|
+
# attr_reader :a, :b
|
26
|
+
# def initialize(values)
|
27
|
+
# @a = values['a']
|
28
|
+
# @b = values['b']
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# thing = Stuff.from_response '{"a":42,"b":"foo"}'
|
32
|
+
# thing.a == 42
|
33
|
+
# thing.b == "foo"
|
34
|
+
#
|
35
|
+
def from_response(data, encoding = 'UTF-8')
|
36
|
+
from_json(parse_json(data, encoding))
|
37
|
+
end
|
38
|
+
|
39
|
+
def from_json(json)
|
40
|
+
case json
|
41
|
+
when Array
|
42
|
+
json.map { |element| from_json(element) }
|
43
|
+
when Hash
|
44
|
+
self.new(json)
|
45
|
+
else
|
46
|
+
json
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_json(string, encoding = 'UTF-8')
|
51
|
+
JSON.parse(string.force_encoding(encoding))
|
52
|
+
rescue JSON::ParserError => json_error
|
53
|
+
if json_error.message =~ /model not found/
|
54
|
+
Trello.logger.error "Could not find that record."
|
55
|
+
raise Trello::Error, "Request could not be found."
|
56
|
+
elsif json_error.message =~ /A JSON text must at least contain two octets/
|
57
|
+
else
|
58
|
+
Trello.logger.error "Unknown error."
|
59
|
+
raise
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/trello/label.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
module Trello
|
2
|
+
|
3
|
+
# A colored Label attached to a card
|
4
|
+
#
|
5
|
+
# @!attribute [rw] id
|
6
|
+
# @return [String]
|
7
|
+
# @!attribute [rw] color
|
8
|
+
# @return [String]
|
9
|
+
class Label < BasicData
|
10
|
+
register_attributes :id, :name, :board_id, :uses,
|
11
|
+
readonly: [ :id, :uses, :board_id ]
|
12
|
+
validates_presence_of :id, :uses, :board_id, :name
|
13
|
+
validates_length_of :name, in: 1..16384
|
14
|
+
|
15
|
+
SYMBOL_TO_STRING = {
|
16
|
+
id: 'id',
|
17
|
+
name: 'name',
|
18
|
+
board_id: 'idBoard',
|
19
|
+
color: 'color',
|
20
|
+
uses: 'uses'
|
21
|
+
}
|
22
|
+
|
23
|
+
class << self
|
24
|
+
VALID_LABEL_COLOURS = %w{green yellow orange red purple blue sky lime pink black} << ''
|
25
|
+
|
26
|
+
# Find a specific card by its id.
|
27
|
+
def find(id, params = {})
|
28
|
+
client.find(:label, id, params)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create a new label and save it on Trello.
|
32
|
+
def create(options)
|
33
|
+
client.create(:label,
|
34
|
+
'name' => options[:name],
|
35
|
+
'idBoard' => options[:board_id],
|
36
|
+
'color' => options[:color],
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Label colours
|
41
|
+
def label_colours
|
42
|
+
VALID_LABEL_COLOURS
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
define_attribute_methods [:color]
|
47
|
+
|
48
|
+
def color
|
49
|
+
@attributes[:color]
|
50
|
+
end
|
51
|
+
|
52
|
+
def color= colour
|
53
|
+
unless Label.label_colours.include? colour
|
54
|
+
errors.add(:label, "color '#{colour}' does not exist")
|
55
|
+
return Trello.logger.warn "The label colour '#{colour}' does not exist."
|
56
|
+
end
|
57
|
+
|
58
|
+
self.send(:"color_will_change!") unless colour == @attributes[:color]
|
59
|
+
@attributes[:color] = colour
|
60
|
+
end
|
61
|
+
|
62
|
+
# Update the fields of a label.
|
63
|
+
#
|
64
|
+
# Supply a hash of stringkeyed data retrieved from the Trello API representing
|
65
|
+
# a label.
|
66
|
+
def update_fields(fields)
|
67
|
+
attributes[:id] = fields['id'] || attributes[:id]
|
68
|
+
attributes[:name] = fields['name'] || fields[:name] || attributes[:name]
|
69
|
+
attributes[:color] = fields['color'] || fields[:color] || attributes[:color]
|
70
|
+
attributes[:board_id] = fields['idBoard'] || fields[:board_id] || attributes[:board_id]
|
71
|
+
attributes[:uses] = fields['uses'] if fields.has_key?('uses')
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns a reference to the board this label is currently connected.
|
76
|
+
one :board, path: :boards, using: :board_id
|
77
|
+
|
78
|
+
# Saves a record.
|
79
|
+
def save
|
80
|
+
# If we have an id, just update our fields.
|
81
|
+
return update! if id
|
82
|
+
|
83
|
+
from_response client.post("/labels", {
|
84
|
+
name: name,
|
85
|
+
color: color,
|
86
|
+
idBoard: board_id,
|
87
|
+
})
|
88
|
+
end
|
89
|
+
|
90
|
+
# Update an existing record.
|
91
|
+
# Warning, this updates all fields using values already in memory. If
|
92
|
+
# an external resource has updated these fields, you should refresh!
|
93
|
+
# this object before making your changes, and before updating the record.
|
94
|
+
def update!
|
95
|
+
@previously_changed = changes
|
96
|
+
# extract only new values to build payload
|
97
|
+
payload = Hash[changes.map { |key, values| [SYMBOL_TO_STRING[key.to_sym].to_sym, values[1]] }]
|
98
|
+
@changed_attributes.clear
|
99
|
+
|
100
|
+
client.put("/labels/#{id}", payload)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Delete this label
|
104
|
+
def delete
|
105
|
+
client.delete("/labels/#{id}")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Trello
|
2
|
+
|
3
|
+
# A colored Label attached to a card
|
4
|
+
class LabelName < BasicData
|
5
|
+
register_attributes :yellow, :red, :orange, :green, :purple, :blue, :sky, :pink, :lime, :black
|
6
|
+
|
7
|
+
# Update the fields of a label.
|
8
|
+
#
|
9
|
+
# Supply a hash of stringkeyed data retrieved from the Trello API representing
|
10
|
+
# a label.
|
11
|
+
def update_fields(fields)
|
12
|
+
attributes[:yellow] = fields['yellow'] || attributes[:yellow]
|
13
|
+
attributes[:red] = fields['red'] || attributes[:red]
|
14
|
+
attributes[:orange] = fields['orange'] || attributes[:orange]
|
15
|
+
attributes[:green] = fields['green'] || attributes[:green]
|
16
|
+
attributes[:purple] = fields['purple'] || attributes[:purple]
|
17
|
+
attributes[:blue] = fields['blue'] || attributes[:blue]
|
18
|
+
attributes[:sky] = fields['sky'] || attributes[:sky]
|
19
|
+
attributes[:pink] = fields['pink'] || attributes[:pink]
|
20
|
+
attributes[:lime] = fields['lime'] || attributes[:lime]
|
21
|
+
attributes[:black] = fields['black'] || attributes[:black]
|
22
|
+
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
one :board, path: :boards, using: :board_id
|
27
|
+
|
28
|
+
many :cards, filter: :all
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/trello/list.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
module Trello
|
2
|
+
# A List is a container which holds cards. Lists are items on a board.
|
3
|
+
#
|
4
|
+
# @!attribute [r] id
|
5
|
+
# @return [String]
|
6
|
+
# @!attribute [rw] name
|
7
|
+
# @return [String]
|
8
|
+
# @!attribute [rw] closed
|
9
|
+
# @return [Boolean]
|
10
|
+
# @!attribute [r] board_id
|
11
|
+
# @return [String] A 24-character hex string
|
12
|
+
# @!attribute [rw] pos
|
13
|
+
# @return [Object]
|
14
|
+
class List < BasicData
|
15
|
+
register_attributes :id, :name, :closed, :board_id, :pos, :source_list_id, readonly: [ :id, :board_id ]
|
16
|
+
validates_presence_of :id, :name, :board_id
|
17
|
+
validates_length_of :name, in: 1..16384
|
18
|
+
|
19
|
+
include HasActions
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Finds a specific list, given an id.
|
23
|
+
#
|
24
|
+
# @param [id] id the list's ID on Trello (24-character hex string).
|
25
|
+
# @param [Hash] params
|
26
|
+
def find(id, params = {})
|
27
|
+
client.find(:list, id, params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create(options)
|
31
|
+
client.create(:list,
|
32
|
+
'name' => options[:name],
|
33
|
+
'idBoard' => options[:board_id],
|
34
|
+
'pos' => options[:pos],
|
35
|
+
'idListSource' => options[:source_list_id])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Updates the fields of a list.
|
40
|
+
#
|
41
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
42
|
+
# a List.
|
43
|
+
def update_fields(fields)
|
44
|
+
attributes[:id] = fields['id'] || attributes[:id]
|
45
|
+
attributes[:name] = fields['name'] || fields[:name] || attributes[:name]
|
46
|
+
attributes[:closed] = fields['closed'] if fields.has_key?('closed')
|
47
|
+
attributes[:board_id] = fields['idBoard'] || fields[:board_id] || attributes[:board_id]
|
48
|
+
attributes[:pos] = fields['pos'] || fields[:pos] || attributes[:pos]
|
49
|
+
attributes[:source_list_id] = fields['idListSource'] || fields[:source_list_id] || attributes[:source_list_id]
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def save
|
54
|
+
return update! if id
|
55
|
+
|
56
|
+
from_response client.post("/lists", {
|
57
|
+
name: name,
|
58
|
+
closed: closed || false,
|
59
|
+
idBoard: board_id,
|
60
|
+
pos: pos,
|
61
|
+
idListSource: source_list_id
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
def update!
|
66
|
+
client.put("/lists/#{id}", {
|
67
|
+
name: name,
|
68
|
+
closed: closed,
|
69
|
+
pos: pos
|
70
|
+
})
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check if the list is not active anymore.
|
74
|
+
def closed?
|
75
|
+
closed
|
76
|
+
end
|
77
|
+
|
78
|
+
def close
|
79
|
+
self.closed = true
|
80
|
+
end
|
81
|
+
|
82
|
+
def close!
|
83
|
+
close
|
84
|
+
save
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return the board the list is connected to.
|
88
|
+
one :board, path: :boards, using: :board_id
|
89
|
+
|
90
|
+
# Returns all the cards on this list.
|
91
|
+
#
|
92
|
+
# The options hash may have a filter key which can have its value set as any
|
93
|
+
# of the following values:
|
94
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
95
|
+
many :cards, filter: :open
|
96
|
+
|
97
|
+
def move_all_cards(other_list)
|
98
|
+
client.post("/lists/#{id}/moveAllCards", {
|
99
|
+
idBoard: other_list.board_id,
|
100
|
+
idList: other_list.id
|
101
|
+
})
|
102
|
+
end
|
103
|
+
|
104
|
+
# Archives all the cards of the list
|
105
|
+
def archive_all_cards
|
106
|
+
client.post("/lists/#{id}/archiveAllCards")
|
107
|
+
end
|
108
|
+
|
109
|
+
# :nodoc:
|
110
|
+
def request_prefix
|
111
|
+
"/lists/#{id}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Trello
|
2
|
+
# A Member is a user of the Trello service.
|
3
|
+
#
|
4
|
+
# @!attribute [r] id
|
5
|
+
# @return [String]
|
6
|
+
# @!attribute [r] username
|
7
|
+
# @return [String]
|
8
|
+
# @!attribute [rw] email
|
9
|
+
# @return [String]
|
10
|
+
# @!attribute [rw] full_name
|
11
|
+
# @return [String]
|
12
|
+
# @!attribute [rw] initials
|
13
|
+
# @return [String]
|
14
|
+
# @!attribute [r] avatar_id
|
15
|
+
# @return [String]
|
16
|
+
# @!attribute [rw] bio
|
17
|
+
# @return [String]
|
18
|
+
# @!attribute [r] url
|
19
|
+
# @return [String]
|
20
|
+
class Member < BasicData
|
21
|
+
register_attributes :id, :username, :email, :full_name, :initials, :avatar_id, :bio, :url, readonly: [ :id, :username, :avatar_id, :url ]
|
22
|
+
validates_presence_of :id, :username
|
23
|
+
validates_length_of :full_name, minimum: 4
|
24
|
+
validates_length_of :bio, maximum: 16384
|
25
|
+
|
26
|
+
include HasActions
|
27
|
+
|
28
|
+
class << self
|
29
|
+
# Finds a user
|
30
|
+
#
|
31
|
+
# The argument may be specified as either an _id_ or a _username_.
|
32
|
+
def find(id_or_username, params = {})
|
33
|
+
client.find(:member, id_or_username, params)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Update the fields of a member.
|
38
|
+
#
|
39
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
40
|
+
# an Member.
|
41
|
+
def update_fields(fields)
|
42
|
+
attributes[:id] = fields['id'] || attributes[:id]
|
43
|
+
attributes[:full_name] = fields['fullName'] || attributes[:full_name]
|
44
|
+
attributes[:email] = fields['email'] || attributes[:email]
|
45
|
+
attributes[:username] = fields['username'] || attributes[:username]
|
46
|
+
attributes[:initials] = fields['initials'] || attributes[:initials]
|
47
|
+
attributes[:avatar_id] = fields['avatarHash'] || attributes[:avatar_id]
|
48
|
+
attributes[:bio] = fields['bio'] || attributes[:bio]
|
49
|
+
attributes[:url] = fields['url'] || attributes[:url]
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
# Retrieve a URL to the avatar.
|
54
|
+
#
|
55
|
+
# Valid values for options are:
|
56
|
+
# :large (170x170)
|
57
|
+
# :small (30x30)
|
58
|
+
def avatar_url(options = { size: :large })
|
59
|
+
size = options[:size] == :small ? 30 : 170
|
60
|
+
"https://trello-avatars.s3.amazonaws.com/#{avatar_id}/#{size}.png"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns a list of the boards a member is a part of.
|
64
|
+
#
|
65
|
+
# This method, when called, can take a hash table with a filter key containing any
|
66
|
+
# of the following values:
|
67
|
+
# :filter => [ :none, :members, :organization, :public, :open, :closed, :all ] # default: :all
|
68
|
+
# i.e.,
|
69
|
+
# me.boards(:filter => :closed) # retrieves all closed boards
|
70
|
+
many :boards, filter: :all
|
71
|
+
|
72
|
+
# Returns a list of cards the member is assigned to.
|
73
|
+
#
|
74
|
+
# This method, when called, can take a hash table with a filter key containing any
|
75
|
+
# of the following values:
|
76
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
77
|
+
# i.e.,
|
78
|
+
# me.cards(:filter => :closed) # retrieves all closed cards
|
79
|
+
many :cards, filter: :open
|
80
|
+
|
81
|
+
# Returns a list of the organizations this member is a part of.
|
82
|
+
#
|
83
|
+
# This method, when called, can take a hash table with a filter key containing any
|
84
|
+
# of the following values:
|
85
|
+
# :filter => [ :none, :members, :public, :all ] # default: all
|
86
|
+
# i.e.,
|
87
|
+
# me.organizations(:filter => :public) # retrieves all public organizations
|
88
|
+
many :organizations, filter: :all
|
89
|
+
|
90
|
+
# Returns a list of notifications for the user
|
91
|
+
many :notifications
|
92
|
+
|
93
|
+
def save
|
94
|
+
@previously_changed = changes
|
95
|
+
@changed_attributes.clear
|
96
|
+
|
97
|
+
return update! if id
|
98
|
+
end
|
99
|
+
|
100
|
+
def update!
|
101
|
+
from_response client.put(request_prefix, {
|
102
|
+
fullName: full_name,
|
103
|
+
bio: bio
|
104
|
+
})
|
105
|
+
end
|
106
|
+
|
107
|
+
# :nodoc:
|
108
|
+
def request_prefix
|
109
|
+
"/members/#{id}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|