troo 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/.gitignore +7 -0
- data/.ruby-version +1 -0
- data/Gemfile +0 -1
- data/Guardfile +6 -0
- data/LICENSE.txt +1 -0
- data/README.md +46 -3
- data/Rakefile +11 -0
- data/bin/troo +12 -0
- data/configuration.yml.example +7 -0
- data/features/add_board.feature +1 -0
- data/features/add_card.feature +1 -0
- data/features/add_comment.feature +1 -0
- data/features/add_list.feature +1 -0
- data/features/cleanup.feature +0 -0
- data/features/move_card_to_list.feature +1 -0
- data/features/refresh.feature +1 -0
- data/features/set_default.feature +7 -0
- data/features/show_board.feature +1 -0
- data/features/show_boards.feature +1 -0
- data/features/show_card.feature +1 -0
- data/features/show_comments.feature +1 -0
- data/features/show_list.feature +1 -0
- data/features/status.feature +1 -0
- data/features/step_definitions/troo_steps.rb +0 -0
- data/features/support/env.rb +31 -0
- data/features/troo.feature +1 -0
- data/features/version.feature +8 -0
- data/lib/troo.rb +24 -2
- data/lib/troo/actions/create_board.rb +43 -0
- data/lib/troo/actions/create_card.rb +43 -0
- data/lib/troo/actions/create_comment.rb +44 -0
- data/lib/troo/actions/create_list.rb +41 -0
- data/lib/troo/actions/move_card.rb +36 -0
- data/lib/troo/actions/refresh_all.rb +79 -0
- data/lib/troo/actions/set_default.rb +35 -0
- data/lib/troo/cli/add_cli.rb +83 -0
- data/lib/troo/cli/default_cli.rb +37 -0
- data/lib/troo/cli/main_cli.rb +130 -0
- data/lib/troo/cli/show_cli.rb +83 -0
- data/lib/troo/cli/thor_fixes.rb +9 -0
- data/lib/troo/display/board_decorator.rb +58 -0
- data/lib/troo/display/board_presenter.rb +65 -0
- data/lib/troo/display/card_decorator.rb +105 -0
- data/lib/troo/display/card_presenter.rb +27 -0
- data/lib/troo/display/comment_decorator.rb +32 -0
- data/lib/troo/display/comment_presenter.rb +35 -0
- data/lib/troo/display/decorator_helpers.rb +76 -0
- data/lib/troo/display/list_decorator.rb +53 -0
- data/lib/troo/display/list_presenter.rb +43 -0
- data/lib/troo/display/member_decorator.rb +24 -0
- data/lib/troo/display/member_presenter.rb +59 -0
- data/lib/troo/external/board.rb +49 -0
- data/lib/troo/external/board_adaptor.rb +43 -0
- data/lib/troo/external/card.rb +70 -0
- data/lib/troo/external/card_adaptor.rb +78 -0
- data/lib/troo/external/comment.rb +64 -0
- data/lib/troo/external/comment_adaptor.rb +53 -0
- data/lib/troo/external/list.rb +58 -0
- data/lib/troo/external/list_adaptor.rb +48 -0
- data/lib/troo/external/member.rb +52 -0
- data/lib/troo/external/member_adaptor.rb +63 -0
- data/lib/troo/models/board.rb +26 -0
- data/lib/troo/models/board_persistence.rb +53 -0
- data/lib/troo/models/board_retrieval.rb +45 -0
- data/lib/troo/models/card.rb +54 -0
- data/lib/troo/models/card_persistence.rb +53 -0
- data/lib/troo/models/card_retrieval.rb +49 -0
- data/lib/troo/models/comment.rb +32 -0
- data/lib/troo/models/comment_persistence.rb +53 -0
- data/lib/troo/models/comment_retrieval.rb +32 -0
- data/lib/troo/models/list.rb +27 -0
- data/lib/troo/models/list_persistence.rb +53 -0
- data/lib/troo/models/list_retrieval.rb +45 -0
- data/lib/troo/models/member.rb +18 -0
- data/lib/troo/models/member_persistence.rb +53 -0
- data/lib/troo/models/member_retrieval.rb +36 -0
- data/lib/troo/models/model_helpers.rb +32 -0
- data/lib/troo/models/refresh.rb +23 -0
- data/lib/troo/presentation/template.rb +31 -0
- data/lib/troo/troo.rb +69 -0
- data/lib/troo/version.rb +2 -1
- data/lib/troo/views/card.erb +17 -0
- data/lib/troo/views/comment.erb +3 -0
- data/logs/.gitkeep +0 -0
- data/test/cassettes/board_by_id.yml +59 -0
- data/test/cassettes/boards_all.yml +118 -0
- data/test/cassettes/card_by_card_id.yml +58 -0
- data/test/cassettes/cards_by_board_id.yml +117 -0
- data/test/cassettes/cards_by_list_id.yml +114 -0
- data/test/cassettes/comments_by_board_id.yml +122 -0
- data/test/cassettes/comments_by_card_id.yml +114 -0
- data/test/cassettes/comments_by_list_id.yml +109 -0
- data/test/cassettes/create_board.yml +62 -0
- data/test/cassettes/create_card.yml +63 -0
- data/test/cassettes/create_comment.yml +67 -0
- data/test/cassettes/create_list.yml +60 -0
- data/test/cassettes/list_by_list_id.yml +56 -0
- data/test/cassettes/lists_by_board_id.yml +118 -0
- data/test/cassettes/member_by_member_id.yml +60 -0
- data/test/cassettes/members_by_board_id.yml +109 -0
- data/test/cassettes/move_card.yml +61 -0
- data/test/lib/troo/actions/create_board_test.rb +47 -0
- data/test/lib/troo/actions/create_card_test.rb +54 -0
- data/test/lib/troo/actions/create_comment_test.rb +49 -0
- data/test/lib/troo/actions/create_list_test.rb +49 -0
- data/test/lib/troo/actions/move_card_test.rb +46 -0
- data/test/lib/troo/actions/refresh_all_test.rb +68 -0
- data/test/lib/troo/actions/set_default_test.rb +44 -0
- data/test/lib/troo/cli/add_cli_test.rb +216 -0
- data/test/lib/troo/cli/default_cli_test.rb +79 -0
- data/test/lib/troo/cli/main_cli_test.rb +232 -0
- data/test/lib/troo/cli/show_cli_test.rb +221 -0
- data/test/lib/troo/cli/thor_fixes_test.rb +21 -0
- data/test/lib/troo/display/board_decorator_test.rb +126 -0
- data/test/lib/troo/display/board_presenter_test.rb +77 -0
- data/test/lib/troo/display/card_decorator_test.rb +221 -0
- data/test/lib/troo/display/card_presenter_test.rb +38 -0
- data/test/lib/troo/display/comment_decorator_test.rb +65 -0
- data/test/lib/troo/display/comment_presenter_test.rb +47 -0
- data/test/lib/troo/display/decorator_helpers_test.rb +7 -0
- data/test/lib/troo/display/list_decorator_test.rb +98 -0
- data/test/lib/troo/display/list_presenter_test.rb +48 -0
- data/test/lib/troo/display/member_decorator_test.rb +42 -0
- data/test/lib/troo/display/member_presenter_test.rb +70 -0
- data/test/lib/troo/external/board_adaptor_test.rb +36 -0
- data/test/lib/troo/external/board_test.rb +69 -0
- data/test/lib/troo/external/card_adaptor_test.rb +50 -0
- data/test/lib/troo/external/card_test.rb +108 -0
- data/test/lib/troo/external/comment_adaptor_test.rb +41 -0
- data/test/lib/troo/external/comment_test.rb +88 -0
- data/test/lib/troo/external/list_adaptor_test.rb +38 -0
- data/test/lib/troo/external/list_test.rb +65 -0
- data/test/lib/troo/external/member_adaptor_test.rb +44 -0
- data/test/lib/troo/external/member_test.rb +65 -0
- data/test/lib/troo/models/board_persistence_test.rb +61 -0
- data/test/lib/troo/models/board_retrieval_test.rb +93 -0
- data/test/lib/troo/models/board_test.rb +50 -0
- data/test/lib/troo/models/card_persistence_test.rb +60 -0
- data/test/lib/troo/models/card_retrieval_test.rb +101 -0
- data/test/lib/troo/models/card_test.rb +102 -0
- data/test/lib/troo/models/comment_persistence_test.rb +65 -0
- data/test/lib/troo/models/comment_retrieval_test.rb +46 -0
- data/test/lib/troo/models/comment_test.rb +59 -0
- data/test/lib/troo/models/list_persistence_test.rb +60 -0
- data/test/lib/troo/models/list_retrieval_test.rb +93 -0
- data/test/lib/troo/models/list_test.rb +53 -0
- data/test/lib/troo/models/member_persistence_test.rb +59 -0
- data/test/lib/troo/models/member_retrieval_test.rb +58 -0
- data/test/lib/troo/models/member_test.rb +44 -0
- data/test/lib/troo/models/model_helpers_test.rb +103 -0
- data/test/lib/troo/models/refresh_test.rb +45 -0
- data/test/lib/troo/presentation/template_test.rb +40 -0
- data/test/support/fabrication.rb +56 -0
- data/test/support/template.erb +3 -0
- data/test/support/vcr_setup.rb +36 -0
- data/test/test_helper.rb +30 -0
- data/troo.gemspec +24 -5
- metadata +501 -23
@@ -0,0 +1,58 @@
|
|
1
|
+
module Troo
|
2
|
+
module External
|
3
|
+
class List
|
4
|
+
class << self
|
5
|
+
def fetch(external_id, options = {})
|
6
|
+
new(external_id, options).fetch_by_external_id.map do |resource|
|
7
|
+
Troo::ListPersistence.for(resource) unless closed?(resource)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def closed?(resource)
|
14
|
+
resource.nil? || resource.closed?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(external_id, options = {})
|
19
|
+
@external_id = external_id
|
20
|
+
@options = options
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch_by_external_id
|
24
|
+
case options.fetch(:mode)
|
25
|
+
when :board then board_mode
|
26
|
+
when :list then list_mode
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
attr_reader :external_id
|
32
|
+
|
33
|
+
def options
|
34
|
+
defaults.merge!(@options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def defaults
|
38
|
+
{ mode: :board }
|
39
|
+
end
|
40
|
+
|
41
|
+
def board_mode
|
42
|
+
Trello::Board.find(external_id).lists
|
43
|
+
rescue Trello::InvalidAccessToken
|
44
|
+
raise Troo::InvalidAccessToken
|
45
|
+
rescue Trello::Error
|
46
|
+
[]
|
47
|
+
end
|
48
|
+
|
49
|
+
def list_mode
|
50
|
+
[Trello::List.find(external_id)]
|
51
|
+
rescue Trello::InvalidAccessToken
|
52
|
+
raise Troo::InvalidAccessToken
|
53
|
+
rescue Trello::Error
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Troo
|
2
|
+
module External
|
3
|
+
class ListAdaptor
|
4
|
+
class << self
|
5
|
+
def adapt(resource)
|
6
|
+
new(resource).adapted
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(resource)
|
11
|
+
@resource = resource
|
12
|
+
end
|
13
|
+
|
14
|
+
def adapted
|
15
|
+
{
|
16
|
+
external_board_id: external_board_id,
|
17
|
+
external_list_id: external_list_id,
|
18
|
+
name: name,
|
19
|
+
position: position,
|
20
|
+
closed: closed,
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
attr_reader :resource
|
26
|
+
|
27
|
+
def external_board_id
|
28
|
+
resource.board_id
|
29
|
+
end
|
30
|
+
|
31
|
+
def external_list_id
|
32
|
+
resource.id
|
33
|
+
end
|
34
|
+
|
35
|
+
def name
|
36
|
+
resource.name
|
37
|
+
end
|
38
|
+
|
39
|
+
def position
|
40
|
+
resource.pos.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def closed
|
44
|
+
resource.closed.to_s
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Troo
|
2
|
+
module External
|
3
|
+
class Member
|
4
|
+
class << self
|
5
|
+
def fetch(external_id, options = {})
|
6
|
+
new(external_id, options).fetch_by_external_id.map do |resource|
|
7
|
+
Troo::MemberPersistence.for(resource)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(external_id, options = {})
|
13
|
+
@external_id = external_id
|
14
|
+
@options = options
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch_by_external_id
|
18
|
+
case options.fetch(:mode)
|
19
|
+
when :board then board_mode
|
20
|
+
when :member then member_mode
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
attr_reader :external_id
|
26
|
+
|
27
|
+
def options
|
28
|
+
defaults.merge!(@options)
|
29
|
+
end
|
30
|
+
|
31
|
+
def defaults
|
32
|
+
{ mode: :board }
|
33
|
+
end
|
34
|
+
|
35
|
+
def board_mode
|
36
|
+
Trello::Board.find(external_id).members
|
37
|
+
rescue Trello::InvalidAccessToken
|
38
|
+
raise Troo::InvalidAccessToken
|
39
|
+
rescue Trello::Error
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
|
43
|
+
def member_mode
|
44
|
+
[Trello::Member.find(external_id)]
|
45
|
+
rescue Trello::InvalidAccessToken
|
46
|
+
raise Troo::InvalidAccessToken
|
47
|
+
rescue Trello::Error
|
48
|
+
[]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Troo
|
2
|
+
module External
|
3
|
+
class MemberAdaptor
|
4
|
+
class << self
|
5
|
+
def adapt(resource)
|
6
|
+
new(resource).adapted
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(resource)
|
11
|
+
@resource = resource
|
12
|
+
end
|
13
|
+
|
14
|
+
def adapted
|
15
|
+
{
|
16
|
+
external_member_id: external_member_id,
|
17
|
+
username: username,
|
18
|
+
email: email,
|
19
|
+
full_name: full_name,
|
20
|
+
initials: initials,
|
21
|
+
avatar_id: avatar_id,
|
22
|
+
bio: bio,
|
23
|
+
url: url,
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
attr_reader :resource
|
29
|
+
|
30
|
+
def external_member_id
|
31
|
+
resource.id
|
32
|
+
end
|
33
|
+
|
34
|
+
def username
|
35
|
+
resource.username
|
36
|
+
end
|
37
|
+
|
38
|
+
def email
|
39
|
+
resource.email
|
40
|
+
end
|
41
|
+
|
42
|
+
def full_name
|
43
|
+
resource.full_name
|
44
|
+
end
|
45
|
+
|
46
|
+
def initials
|
47
|
+
resource.initials
|
48
|
+
end
|
49
|
+
|
50
|
+
def avatar_id
|
51
|
+
resource.avatar_id
|
52
|
+
end
|
53
|
+
|
54
|
+
def bio
|
55
|
+
resource.bio
|
56
|
+
end
|
57
|
+
|
58
|
+
def url
|
59
|
+
resource.url
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Troo
|
2
|
+
class Board < Ohm::Model
|
3
|
+
include Ohm::DataTypes
|
4
|
+
include ModelHelpers
|
5
|
+
|
6
|
+
attribute :name
|
7
|
+
attribute :description
|
8
|
+
attribute :default, Type::Boolean
|
9
|
+
attribute :closed, Type::Boolean
|
10
|
+
attribute :external_board_id
|
11
|
+
|
12
|
+
index :default
|
13
|
+
index :external_board_id
|
14
|
+
|
15
|
+
alias_method :default?, :default
|
16
|
+
|
17
|
+
def lists
|
18
|
+
Troo::List.find(external_board_id: self.external_board_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def cards
|
22
|
+
Troo::Card.find(external_board_id: self.external_board_id)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Troo
|
2
|
+
class BoardPersistence
|
3
|
+
class << self
|
4
|
+
def for(resource, options = {})
|
5
|
+
new(resource, options).persist
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(resource, options = {})
|
10
|
+
@resource = resource
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def persist
|
15
|
+
return local if local_identical?
|
16
|
+
return updated if local_exists?
|
17
|
+
return created
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
attr_reader :resource, :options
|
22
|
+
|
23
|
+
def created
|
24
|
+
Troo::Board.create(remote)
|
25
|
+
end
|
26
|
+
|
27
|
+
def updated
|
28
|
+
local.update(remote) && local
|
29
|
+
end
|
30
|
+
|
31
|
+
def local_identical?
|
32
|
+
return false unless local_exists?
|
33
|
+
return false if local_data != remote
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def local_data
|
38
|
+
local.external_attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
def local_exists?
|
42
|
+
!!local
|
43
|
+
end
|
44
|
+
|
45
|
+
def local
|
46
|
+
@local ||= Troo::Board.first(external_board_id: resource.id)
|
47
|
+
end
|
48
|
+
|
49
|
+
def remote
|
50
|
+
@remote ||= Troo::External::BoardAdaptor.adapt(resource)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Troo
|
2
|
+
class BoardRetrieval
|
3
|
+
class << self
|
4
|
+
def all
|
5
|
+
Troo::Board.all
|
6
|
+
end
|
7
|
+
|
8
|
+
def default
|
9
|
+
new.retrieve
|
10
|
+
end
|
11
|
+
|
12
|
+
def retrieve(id = nil)
|
13
|
+
new(id).retrieve
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(id = nil)
|
18
|
+
@id = id
|
19
|
+
end
|
20
|
+
|
21
|
+
def retrieve
|
22
|
+
return default unless id
|
23
|
+
by_id || by_external_id || remote
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
attr_reader :id
|
28
|
+
|
29
|
+
def default
|
30
|
+
Troo::Board.default
|
31
|
+
end
|
32
|
+
|
33
|
+
def by_id
|
34
|
+
Troo::Board[id]
|
35
|
+
end
|
36
|
+
|
37
|
+
def by_external_id
|
38
|
+
Troo::Board.first(external_board_id: id)
|
39
|
+
end
|
40
|
+
|
41
|
+
def remote
|
42
|
+
External::Board.fetch(id).first
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Troo
|
2
|
+
class Card < Ohm::Model
|
3
|
+
include Ohm::DataTypes
|
4
|
+
include ModelHelpers
|
5
|
+
|
6
|
+
attribute :short_id
|
7
|
+
attribute :name
|
8
|
+
attribute :desc
|
9
|
+
attribute :url
|
10
|
+
attribute :external_member_ids, Type::Array
|
11
|
+
attribute :position
|
12
|
+
attribute :last_activity_date
|
13
|
+
attribute :default, Type::Boolean
|
14
|
+
attribute :closed, Type::Boolean
|
15
|
+
attribute :external_board_id
|
16
|
+
attribute :external_list_id
|
17
|
+
attribute :external_card_id
|
18
|
+
|
19
|
+
index :short_id
|
20
|
+
index :default
|
21
|
+
index :external_board_id
|
22
|
+
index :external_list_id
|
23
|
+
index :external_card_id
|
24
|
+
|
25
|
+
alias_method :default?, :default
|
26
|
+
|
27
|
+
def board
|
28
|
+
Troo::BoardRetrieval.retrieve(self.external_board_id)
|
29
|
+
end
|
30
|
+
|
31
|
+
def list
|
32
|
+
Troo::ListRetrieval.retrieve(self.external_list_id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def comments
|
36
|
+
Troo::Comment.find(external_card_id: self.external_card_id)
|
37
|
+
end
|
38
|
+
|
39
|
+
def recent_comments
|
40
|
+
comments.sort(by: :date, limit: [0, 3])
|
41
|
+
end
|
42
|
+
|
43
|
+
def members
|
44
|
+
if external_member_ids.any?
|
45
|
+
m = external_member_ids.map do |external_member_id|
|
46
|
+
Troo::Member.first(external_member_id: external_member_id)
|
47
|
+
end.compact
|
48
|
+
else
|
49
|
+
[]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Troo
|
2
|
+
class CardPersistence
|
3
|
+
class << self
|
4
|
+
def for(resource, options = {})
|
5
|
+
new(resource, options).persist
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(resource, options = {})
|
10
|
+
@resource = resource
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def persist
|
15
|
+
return local if local_identical?
|
16
|
+
return updated if local_exists?
|
17
|
+
return created
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
attr_reader :resource, :options
|
22
|
+
|
23
|
+
def created
|
24
|
+
Troo::Card.create(remote)
|
25
|
+
end
|
26
|
+
|
27
|
+
def updated
|
28
|
+
local.update(remote) && local
|
29
|
+
end
|
30
|
+
|
31
|
+
def local_identical?
|
32
|
+
return false unless local_exists?
|
33
|
+
return false if local_data != remote
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def local_data
|
38
|
+
local.external_attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
def local_exists?
|
42
|
+
!!local
|
43
|
+
end
|
44
|
+
|
45
|
+
def local
|
46
|
+
@local ||= Troo::Card.first(external_card_id: resource.id)
|
47
|
+
end
|
48
|
+
|
49
|
+
def remote
|
50
|
+
@remote ||= Troo::External::CardAdaptor.adapt(resource)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|