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.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +0 -1
  5. data/Guardfile +6 -0
  6. data/LICENSE.txt +1 -0
  7. data/README.md +46 -3
  8. data/Rakefile +11 -0
  9. data/bin/troo +12 -0
  10. data/configuration.yml.example +7 -0
  11. data/features/add_board.feature +1 -0
  12. data/features/add_card.feature +1 -0
  13. data/features/add_comment.feature +1 -0
  14. data/features/add_list.feature +1 -0
  15. data/features/cleanup.feature +0 -0
  16. data/features/move_card_to_list.feature +1 -0
  17. data/features/refresh.feature +1 -0
  18. data/features/set_default.feature +7 -0
  19. data/features/show_board.feature +1 -0
  20. data/features/show_boards.feature +1 -0
  21. data/features/show_card.feature +1 -0
  22. data/features/show_comments.feature +1 -0
  23. data/features/show_list.feature +1 -0
  24. data/features/status.feature +1 -0
  25. data/features/step_definitions/troo_steps.rb +0 -0
  26. data/features/support/env.rb +31 -0
  27. data/features/troo.feature +1 -0
  28. data/features/version.feature +8 -0
  29. data/lib/troo.rb +24 -2
  30. data/lib/troo/actions/create_board.rb +43 -0
  31. data/lib/troo/actions/create_card.rb +43 -0
  32. data/lib/troo/actions/create_comment.rb +44 -0
  33. data/lib/troo/actions/create_list.rb +41 -0
  34. data/lib/troo/actions/move_card.rb +36 -0
  35. data/lib/troo/actions/refresh_all.rb +79 -0
  36. data/lib/troo/actions/set_default.rb +35 -0
  37. data/lib/troo/cli/add_cli.rb +83 -0
  38. data/lib/troo/cli/default_cli.rb +37 -0
  39. data/lib/troo/cli/main_cli.rb +130 -0
  40. data/lib/troo/cli/show_cli.rb +83 -0
  41. data/lib/troo/cli/thor_fixes.rb +9 -0
  42. data/lib/troo/display/board_decorator.rb +58 -0
  43. data/lib/troo/display/board_presenter.rb +65 -0
  44. data/lib/troo/display/card_decorator.rb +105 -0
  45. data/lib/troo/display/card_presenter.rb +27 -0
  46. data/lib/troo/display/comment_decorator.rb +32 -0
  47. data/lib/troo/display/comment_presenter.rb +35 -0
  48. data/lib/troo/display/decorator_helpers.rb +76 -0
  49. data/lib/troo/display/list_decorator.rb +53 -0
  50. data/lib/troo/display/list_presenter.rb +43 -0
  51. data/lib/troo/display/member_decorator.rb +24 -0
  52. data/lib/troo/display/member_presenter.rb +59 -0
  53. data/lib/troo/external/board.rb +49 -0
  54. data/lib/troo/external/board_adaptor.rb +43 -0
  55. data/lib/troo/external/card.rb +70 -0
  56. data/lib/troo/external/card_adaptor.rb +78 -0
  57. data/lib/troo/external/comment.rb +64 -0
  58. data/lib/troo/external/comment_adaptor.rb +53 -0
  59. data/lib/troo/external/list.rb +58 -0
  60. data/lib/troo/external/list_adaptor.rb +48 -0
  61. data/lib/troo/external/member.rb +52 -0
  62. data/lib/troo/external/member_adaptor.rb +63 -0
  63. data/lib/troo/models/board.rb +26 -0
  64. data/lib/troo/models/board_persistence.rb +53 -0
  65. data/lib/troo/models/board_retrieval.rb +45 -0
  66. data/lib/troo/models/card.rb +54 -0
  67. data/lib/troo/models/card_persistence.rb +53 -0
  68. data/lib/troo/models/card_retrieval.rb +49 -0
  69. data/lib/troo/models/comment.rb +32 -0
  70. data/lib/troo/models/comment_persistence.rb +53 -0
  71. data/lib/troo/models/comment_retrieval.rb +32 -0
  72. data/lib/troo/models/list.rb +27 -0
  73. data/lib/troo/models/list_persistence.rb +53 -0
  74. data/lib/troo/models/list_retrieval.rb +45 -0
  75. data/lib/troo/models/member.rb +18 -0
  76. data/lib/troo/models/member_persistence.rb +53 -0
  77. data/lib/troo/models/member_retrieval.rb +36 -0
  78. data/lib/troo/models/model_helpers.rb +32 -0
  79. data/lib/troo/models/refresh.rb +23 -0
  80. data/lib/troo/presentation/template.rb +31 -0
  81. data/lib/troo/troo.rb +69 -0
  82. data/lib/troo/version.rb +2 -1
  83. data/lib/troo/views/card.erb +17 -0
  84. data/lib/troo/views/comment.erb +3 -0
  85. data/logs/.gitkeep +0 -0
  86. data/test/cassettes/board_by_id.yml +59 -0
  87. data/test/cassettes/boards_all.yml +118 -0
  88. data/test/cassettes/card_by_card_id.yml +58 -0
  89. data/test/cassettes/cards_by_board_id.yml +117 -0
  90. data/test/cassettes/cards_by_list_id.yml +114 -0
  91. data/test/cassettes/comments_by_board_id.yml +122 -0
  92. data/test/cassettes/comments_by_card_id.yml +114 -0
  93. data/test/cassettes/comments_by_list_id.yml +109 -0
  94. data/test/cassettes/create_board.yml +62 -0
  95. data/test/cassettes/create_card.yml +63 -0
  96. data/test/cassettes/create_comment.yml +67 -0
  97. data/test/cassettes/create_list.yml +60 -0
  98. data/test/cassettes/list_by_list_id.yml +56 -0
  99. data/test/cassettes/lists_by_board_id.yml +118 -0
  100. data/test/cassettes/member_by_member_id.yml +60 -0
  101. data/test/cassettes/members_by_board_id.yml +109 -0
  102. data/test/cassettes/move_card.yml +61 -0
  103. data/test/lib/troo/actions/create_board_test.rb +47 -0
  104. data/test/lib/troo/actions/create_card_test.rb +54 -0
  105. data/test/lib/troo/actions/create_comment_test.rb +49 -0
  106. data/test/lib/troo/actions/create_list_test.rb +49 -0
  107. data/test/lib/troo/actions/move_card_test.rb +46 -0
  108. data/test/lib/troo/actions/refresh_all_test.rb +68 -0
  109. data/test/lib/troo/actions/set_default_test.rb +44 -0
  110. data/test/lib/troo/cli/add_cli_test.rb +216 -0
  111. data/test/lib/troo/cli/default_cli_test.rb +79 -0
  112. data/test/lib/troo/cli/main_cli_test.rb +232 -0
  113. data/test/lib/troo/cli/show_cli_test.rb +221 -0
  114. data/test/lib/troo/cli/thor_fixes_test.rb +21 -0
  115. data/test/lib/troo/display/board_decorator_test.rb +126 -0
  116. data/test/lib/troo/display/board_presenter_test.rb +77 -0
  117. data/test/lib/troo/display/card_decorator_test.rb +221 -0
  118. data/test/lib/troo/display/card_presenter_test.rb +38 -0
  119. data/test/lib/troo/display/comment_decorator_test.rb +65 -0
  120. data/test/lib/troo/display/comment_presenter_test.rb +47 -0
  121. data/test/lib/troo/display/decorator_helpers_test.rb +7 -0
  122. data/test/lib/troo/display/list_decorator_test.rb +98 -0
  123. data/test/lib/troo/display/list_presenter_test.rb +48 -0
  124. data/test/lib/troo/display/member_decorator_test.rb +42 -0
  125. data/test/lib/troo/display/member_presenter_test.rb +70 -0
  126. data/test/lib/troo/external/board_adaptor_test.rb +36 -0
  127. data/test/lib/troo/external/board_test.rb +69 -0
  128. data/test/lib/troo/external/card_adaptor_test.rb +50 -0
  129. data/test/lib/troo/external/card_test.rb +108 -0
  130. data/test/lib/troo/external/comment_adaptor_test.rb +41 -0
  131. data/test/lib/troo/external/comment_test.rb +88 -0
  132. data/test/lib/troo/external/list_adaptor_test.rb +38 -0
  133. data/test/lib/troo/external/list_test.rb +65 -0
  134. data/test/lib/troo/external/member_adaptor_test.rb +44 -0
  135. data/test/lib/troo/external/member_test.rb +65 -0
  136. data/test/lib/troo/models/board_persistence_test.rb +61 -0
  137. data/test/lib/troo/models/board_retrieval_test.rb +93 -0
  138. data/test/lib/troo/models/board_test.rb +50 -0
  139. data/test/lib/troo/models/card_persistence_test.rb +60 -0
  140. data/test/lib/troo/models/card_retrieval_test.rb +101 -0
  141. data/test/lib/troo/models/card_test.rb +102 -0
  142. data/test/lib/troo/models/comment_persistence_test.rb +65 -0
  143. data/test/lib/troo/models/comment_retrieval_test.rb +46 -0
  144. data/test/lib/troo/models/comment_test.rb +59 -0
  145. data/test/lib/troo/models/list_persistence_test.rb +60 -0
  146. data/test/lib/troo/models/list_retrieval_test.rb +93 -0
  147. data/test/lib/troo/models/list_test.rb +53 -0
  148. data/test/lib/troo/models/member_persistence_test.rb +59 -0
  149. data/test/lib/troo/models/member_retrieval_test.rb +58 -0
  150. data/test/lib/troo/models/member_test.rb +44 -0
  151. data/test/lib/troo/models/model_helpers_test.rb +103 -0
  152. data/test/lib/troo/models/refresh_test.rb +45 -0
  153. data/test/lib/troo/presentation/template_test.rb +40 -0
  154. data/test/support/fabrication.rb +56 -0
  155. data/test/support/template.erb +3 -0
  156. data/test/support/vcr_setup.rb +36 -0
  157. data/test/test_helper.rb +30 -0
  158. data/troo.gemspec +24 -5
  159. 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