trello-fs 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/Gemfile +3 -0
- data/README.md +52 -0
- data/examples/demo_board/A_List_of_Cards/README.md +6 -0
- data/examples/demo_board/A_List_of_Cards/TrelloFs_Features.md +14 -0
- data/examples/demo_board/A_List_of_Cards/TrelloFs_Installation.md +37 -0
- data/examples/demo_board/A_Second_List_of_Cards/A_card_with_an_image.md +13 -0
- data/examples/demo_board/A_Second_List_of_Cards/README.md +6 -0
- data/examples/demo_board/A_Second_List_of_Cards/This_one_has_a_puppy.md +13 -0
- data/examples/demo_board/Attachments/A_card_with_an_image/cats-cute-cat-animal-cute-grass-photo.jpg +0 -0
- data/examples/demo_board/Attachments/This_one_has_a_puppy/Puppy_2.jpg +0 -0
- data/examples/demo_board/Home +13 -0
- data/examples/demo_board/Labels/cats.md +5 -0
- data/examples/demo_board/Labels/images.md +6 -0
- data/examples/demo_board/Labels/no_name.md +4 -0
- data/examples/demo_board/Labels/puppies.md +5 -0
- data/examples/demo_board/Labels/readme.md +6 -0
- data/examples/demo_board/README.md +13 -0
- data/examples/demo_board.rb +8 -0
- data/examples/welcome_board/Advanced/Get_the_apps_for_iOS_Android_and_Windows_8.md +12 -0
- data/examples/welcome_board/Advanced/Need_help.md +10 -0
- data/examples/welcome_board/Advanced/README.md +10 -0
- data/examples/welcome_board/Advanced/Use_as_many_boards_as_you_want.md +8 -0
- data/examples/welcome_board/Advanced/Want_tips_usage_examples_or_API_info.md +8 -0
- data/examples/welcome_board/Advanced/Want_to_use_keyboard_shortcuts_We_have_them.md +10 -0
- data/examples/welcome_board/Advanced/Want_updates_on_new_features.md +14 -0
- data/examples/welcome_board/Attachments/You_can_attach_pictures_and_files/taco.png +0 -0
- data/examples/welcome_board/Basics/Click_on_a_card_to_see_whats_behind_it.md +8 -0
- data/examples/welcome_board/Basics/README.md +10 -0
- data/examples/welcome_board/Basics/This_is_a_card.md +8 -0
- data/examples/welcome_board/Basics/Welcome_to_Trello.md +8 -0
- data/examples/welcome_board/Basics/You_can_attach_pictures_and_files.md +13 -0
- data/examples/welcome_board/Basics/any_kind_of_hyperlink_.md +8 -0
- data/examples/welcome_board/Basics/or_checklists.md +8 -0
- data/examples/welcome_board/Home +31 -0
- data/examples/welcome_board/Intermediate/Drag_people_onto_a_card_to_indicate_that_theyre_responsible_for_it.md +8 -0
- data/examples/welcome_board/Intermediate/Finished_with_a_card_Archive_it.md +12 -0
- data/examples/welcome_board/Intermediate/Invite_your_team_to_this_board_using_the_Add_Members_button.md +8 -0
- data/examples/welcome_board/Intermediate/Make_as_many_lists_as_you_need.md +8 -0
- data/examples/welcome_board/Intermediate/README.md +11 -0
- data/examples/welcome_board/Intermediate/Try_dragging_cards_anywhere.md +8 -0
- data/examples/welcome_board/Intermediate/Use_color-coded_labels_for_organization.md +8 -0
- data/examples/welcome_board/Intermediate/You_can_change_the_board_background.md +8 -0
- data/examples/welcome_board/Labels/no_name.md +4 -0
- data/examples/welcome_board/Labels/red_one.md +6 -0
- data/examples/welcome_board/README.md +31 -0
- data/examples/welcome_board.rb +8 -0
- data/lib/trello-fs/attachment_builder.rb +60 -0
- data/lib/trello-fs/attachment_cleaner.rb +39 -0
- data/lib/trello-fs/board_builder.rb +61 -0
- data/lib/trello-fs/builder.rb +31 -0
- data/lib/trello-fs/card_builder.rb +87 -0
- data/lib/trello-fs/label_builder.rb +60 -0
- data/lib/trello-fs/labels_builder.rb +16 -0
- data/lib/trello-fs/list_builder.rb +68 -0
- data/lib/trello-fs/repository.rb +36 -0
- data/lib/trello-fs/repository_cleaner.rb +18 -0
- data/lib/trello-fs/string_to_file_name.rb +9 -0
- data/lib/trello-fs/trello_api.rb +83 -0
- data/lib/trello-fs/version.rb +3 -0
- data/lib/trello-fs.rb +8 -0
- data/spec/helpers/test_repository.rb +21 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/trello-fs/attachment_builder_spec.rb +37 -0
- data/spec/trello-fs/attachment_cleaner_spec.rb +44 -0
- data/spec/trello-fs/board_builder_spec.rb +28 -0
- data/spec/trello-fs/card_builder_spec.rb +60 -0
- data/spec/trello-fs/label_builder_spec.rb +36 -0
- data/spec/trello-fs/list_builder_spec.rb +32 -0
- data/spec/trello-fs/repository_spec.rb +9 -0
- data/spec/trello-fs/string_to_file_name_spec.rb +19 -0
- data/spec/trello-fs/trello_api_spec.rb +144 -0
- data/trello-fs.gemspec +24 -0
- metadata +170 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
module TrelloFs
|
4
|
+
class AttachmentBuilder
|
5
|
+
attr_reader :card_builder, :attachment
|
6
|
+
|
7
|
+
def initialize(card_builder, attachment)
|
8
|
+
@card_builder = card_builder
|
9
|
+
@attachment = attachment
|
10
|
+
end
|
11
|
+
|
12
|
+
def build
|
13
|
+
return if already_downloaded?
|
14
|
+
|
15
|
+
download_and_save
|
16
|
+
end
|
17
|
+
|
18
|
+
def download_and_save
|
19
|
+
data = download
|
20
|
+
return unless data
|
21
|
+
|
22
|
+
FileUtils.mkpath(full_folder_path) unless File.exist? full_folder_path
|
23
|
+
File.open(path, 'wb') do |file|
|
24
|
+
file.write data
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def path
|
29
|
+
File.join(full_folder_path, file_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def relative_path
|
33
|
+
File.join(folder_path, file_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
def folder_path
|
37
|
+
File.join('Attachments', StringToFileName.convert(@card_builder.card_name))
|
38
|
+
end
|
39
|
+
|
40
|
+
def full_folder_path
|
41
|
+
File.join(repository.path, folder_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def file_name
|
45
|
+
@attachment.name.gsub(/ /, '_')
|
46
|
+
end
|
47
|
+
|
48
|
+
def already_downloaded?
|
49
|
+
File.exist? path
|
50
|
+
end
|
51
|
+
|
52
|
+
def download
|
53
|
+
open(@attachment.url).read
|
54
|
+
end
|
55
|
+
|
56
|
+
def repository
|
57
|
+
@card_builder.repository
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module TrelloFs
|
5
|
+
class AttachmentCleaner
|
6
|
+
def initialize(repository, board)
|
7
|
+
@repository = repository
|
8
|
+
@board = board
|
9
|
+
end
|
10
|
+
|
11
|
+
def set_of_attachment_paths
|
12
|
+
@board.attachments.map do |attachment|
|
13
|
+
AttachmentBuilder.new(
|
14
|
+
CardBuilder.new(
|
15
|
+
ListBuilder.new(
|
16
|
+
BoardBuilder.new(@repository, @board),
|
17
|
+
attachment.card.list
|
18
|
+
), attachment.card
|
19
|
+
), attachment).path
|
20
|
+
end.to_set
|
21
|
+
end
|
22
|
+
|
23
|
+
def remove_old_attachments
|
24
|
+
new_attachments = set_of_attachment_paths
|
25
|
+
|
26
|
+
Dir.
|
27
|
+
glob(File.join(@repository.path, "Attachments/**/*")).
|
28
|
+
reject {|fn| File.directory?(fn) }.
|
29
|
+
each do |file|
|
30
|
+
next if new_attachments.include? file
|
31
|
+
FileUtils.rm(file)
|
32
|
+
|
33
|
+
# remove parent dir if empty
|
34
|
+
dirname = File.dirname(file)
|
35
|
+
FileUtils.rm_rf(dirname) if Dir[File.join(dirname, '*')].empty?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module TrelloFs
|
2
|
+
class BoardBuilder
|
3
|
+
attr_reader :repository, :board
|
4
|
+
|
5
|
+
def initialize(repository, board)
|
6
|
+
@repository = repository
|
7
|
+
@board = board
|
8
|
+
end
|
9
|
+
|
10
|
+
def build
|
11
|
+
board.lists.each do |list|
|
12
|
+
ListBuilder.new(self, list).build
|
13
|
+
end
|
14
|
+
LabelsBuilder.new(@repository, @board).build
|
15
|
+
|
16
|
+
build_readme
|
17
|
+
end
|
18
|
+
|
19
|
+
def build_readme
|
20
|
+
readme_path = File.join(path, 'README.md')
|
21
|
+
File.open(readme_path, 'w') do |file|
|
22
|
+
file.write(readme_content)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def readme_content
|
27
|
+
[
|
28
|
+
"# [#{board_name}](#{@board.url})",
|
29
|
+
labels_content,
|
30
|
+
board.lists.map do |list|
|
31
|
+
list_builder = ListBuilder.new(self, list)
|
32
|
+
list_link = "[#{list_builder.list_name}](#{list_builder.file_name}/README.md)"
|
33
|
+
|
34
|
+
[
|
35
|
+
"## #{list_link}",
|
36
|
+
list_builder.content(true)
|
37
|
+
].join("\n\n")
|
38
|
+
end.join("\n\n")
|
39
|
+
].join("\n\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
def labels_content
|
43
|
+
return '' unless @board.labels && @board.labels.any?
|
44
|
+
|
45
|
+
@board.labels.sort {|a, b| a.name <=> b.name }.
|
46
|
+
select {|lbl| lbl.cards.any? }.
|
47
|
+
map do |label|
|
48
|
+
label_builder = LabelBuilder.new(LabelsBuilder.new(@repository, @board), label)
|
49
|
+
"[`#{label_builder.label_name}`](#{label_builder.relative_path})"
|
50
|
+
end.join(' ')
|
51
|
+
end
|
52
|
+
|
53
|
+
def path
|
54
|
+
@repository.path
|
55
|
+
end
|
56
|
+
|
57
|
+
def board_name
|
58
|
+
@board.name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module TrelloFs
|
2
|
+
class Builder
|
3
|
+
attr_reader :config
|
4
|
+
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def build
|
10
|
+
repository = Repository.new config, self
|
11
|
+
board = TrelloApi.new(repository).board
|
12
|
+
|
13
|
+
# remove old files from the repo
|
14
|
+
RepositoryCleaner.new(repository).clean
|
15
|
+
|
16
|
+
BoardBuilder.new(repository, board).build
|
17
|
+
copy_readme_to_home(repository)
|
18
|
+
|
19
|
+
# remove old attachments
|
20
|
+
AttachmentCleaner.new(repository, board).remove_old_attachments
|
21
|
+
end
|
22
|
+
|
23
|
+
def copy_readme_to_home(repository)
|
24
|
+
FileUtils.cp(File.join(repository.path, 'README.md'), File.join(repository.path, 'Home'))
|
25
|
+
end
|
26
|
+
|
27
|
+
def trello_api_board(repository)
|
28
|
+
Trello::Board.find(repository.board_id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module TrelloFs
|
2
|
+
class CardBuilder
|
3
|
+
def initialize(list_builder, card)
|
4
|
+
@card = card
|
5
|
+
@list_builder = list_builder
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
@list_builder.build_path
|
10
|
+
|
11
|
+
attachment_paths = @card.attachments.map do |attachment|
|
12
|
+
attachment_builder = AttachmentBuilder.new(self, attachment)
|
13
|
+
attachment_builder.build
|
14
|
+
attachment_builder.relative_path
|
15
|
+
end
|
16
|
+
|
17
|
+
File.open(path, 'w') do |file|
|
18
|
+
file.write(content(attachment_paths))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def path
|
23
|
+
File.join(@list_builder.path, file_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def relative_path
|
27
|
+
File.join(@list_builder.file_name, file_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def file_name
|
31
|
+
"#{StringToFileName.convert(@card.name)}.md"
|
32
|
+
end
|
33
|
+
|
34
|
+
def content(attachment_paths = [])
|
35
|
+
labels = card_labels.map do |lbl|
|
36
|
+
label_builder = LabelBuilder.new(LabelsBuilder.new(repository, board), lbl)
|
37
|
+
"[`#{label_builder.label_name}`](../#{label_builder.relative_path})"
|
38
|
+
end.sort.join(' ')
|
39
|
+
list_name = @list_builder.list_name
|
40
|
+
board_name = @list_builder.board_name
|
41
|
+
|
42
|
+
[
|
43
|
+
"# [#{card_name}](#{@card.url})",
|
44
|
+
[
|
45
|
+
"[#{board_name}](../README.md)",
|
46
|
+
"[#{list_name}](README.md)"
|
47
|
+
].join(' > '),
|
48
|
+
labels,
|
49
|
+
@card.desc,
|
50
|
+
attachments_content(attachment_paths)
|
51
|
+
].join("\n\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
def attachments_content(attachment_paths = [])
|
55
|
+
return '' unless attachment_paths.any?
|
56
|
+
|
57
|
+
links = attachment_paths.map do |path|
|
58
|
+
name = path.split('/').last
|
59
|
+
path = "../#{path}"
|
60
|
+
link = "[#{name}](#{path})"
|
61
|
+
if path.end_with?('.png') || path.end_with?('.jpg') || path.end_with?('gif')
|
62
|
+
"!#{link}"
|
63
|
+
else
|
64
|
+
link
|
65
|
+
end
|
66
|
+
end.join(" \n")
|
67
|
+
|
68
|
+
"\n\n## Attachments\n\n#{links}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def card_name
|
72
|
+
@card.name
|
73
|
+
end
|
74
|
+
|
75
|
+
def repository
|
76
|
+
@list_builder.repository
|
77
|
+
end
|
78
|
+
|
79
|
+
def card_labels
|
80
|
+
@card_labels ||= @card.labels
|
81
|
+
end
|
82
|
+
|
83
|
+
def board
|
84
|
+
@list_builder.board_builder.board
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module TrelloFs
|
2
|
+
class LabelBuilder
|
3
|
+
def initialize(labels_builder, label)
|
4
|
+
@labels_builder = labels_builder
|
5
|
+
@repository = @labels_builder.repository
|
6
|
+
@board = @labels_builder.board
|
7
|
+
@label = label
|
8
|
+
end
|
9
|
+
|
10
|
+
def build
|
11
|
+
FileUtils.mkpath(folder_path)
|
12
|
+
|
13
|
+
File.open(path, 'w') do |f|
|
14
|
+
f.write content
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def path
|
19
|
+
File.join(folder_path, file_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def relative_path
|
23
|
+
File.join('Labels', file_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def folder_path
|
27
|
+
File.join(@repository.path, 'Labels')
|
28
|
+
end
|
29
|
+
|
30
|
+
def file_name
|
31
|
+
"#{StringToFileName.convert(label_name)}.md"
|
32
|
+
end
|
33
|
+
|
34
|
+
def content
|
35
|
+
[
|
36
|
+
"# `#{label_name}`",
|
37
|
+
"[#{@board.name}](../README.md)",
|
38
|
+
card_links
|
39
|
+
].join("\n\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
def card_links
|
43
|
+
@label.cards.sort {|a,b| a.name <=> b.name }.map do |card|
|
44
|
+
card_builder = CardBuilder.new(
|
45
|
+
ListBuilder.new(
|
46
|
+
BoardBuilder.new(@repository, @board),
|
47
|
+
card.list
|
48
|
+
), card
|
49
|
+
)
|
50
|
+
path = '../' + card_builder.relative_path
|
51
|
+
link = "[#{card_builder.card_name}](#{path})"
|
52
|
+
"- #{link}"
|
53
|
+
end.join("\n")
|
54
|
+
end
|
55
|
+
|
56
|
+
def label_name
|
57
|
+
@label.name.empty? ? 'no name' : @label.name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module TrelloFs
|
2
|
+
class LabelsBuilder
|
3
|
+
attr_reader :repository, :board
|
4
|
+
|
5
|
+
def initialize(repository, board)
|
6
|
+
@repository = repository
|
7
|
+
@board = board
|
8
|
+
end
|
9
|
+
|
10
|
+
def build
|
11
|
+
@board.labels.each do |label|
|
12
|
+
LabelBuilder.new(self, label).build
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module TrelloFs
|
2
|
+
class ListBuilder
|
3
|
+
attr_reader :board_builder, :list
|
4
|
+
|
5
|
+
def initialize(board_builder, list)
|
6
|
+
@board_builder = board_builder
|
7
|
+
@list = list
|
8
|
+
end
|
9
|
+
|
10
|
+
def build
|
11
|
+
list.cards.each do |card|
|
12
|
+
CardBuilder.new(self, card).build
|
13
|
+
end
|
14
|
+
|
15
|
+
build_readme
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_readme
|
19
|
+
build_path
|
20
|
+
readme_path = File.join(path, 'README.md')
|
21
|
+
File.open(readme_path, 'w') do |file|
|
22
|
+
file.write(readme_content)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def readme_content
|
27
|
+
[
|
28
|
+
"# #{list_name}",
|
29
|
+
"[#{board_name}](../README.md)",
|
30
|
+
content
|
31
|
+
].join("\n\n")
|
32
|
+
end
|
33
|
+
|
34
|
+
def content(full_path = false)
|
35
|
+
@list.cards.map do |card|
|
36
|
+
cb = CardBuilder.new(self, card)
|
37
|
+
card_path = cb.file_name
|
38
|
+
card_path = File.join(file_name, card_path) if full_path
|
39
|
+
|
40
|
+
"- [#{cb.card_name}](#{card_path})"
|
41
|
+
end.join("\n")
|
42
|
+
end
|
43
|
+
|
44
|
+
def path
|
45
|
+
File.join(@board_builder.path, file_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def file_name
|
49
|
+
StringToFileName.convert(@list.name)
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_path
|
53
|
+
FileUtils.mkpath(path) unless File.exist? path
|
54
|
+
end
|
55
|
+
|
56
|
+
def list_name
|
57
|
+
@list.name
|
58
|
+
end
|
59
|
+
|
60
|
+
def board_name
|
61
|
+
@board_builder.board_name
|
62
|
+
end
|
63
|
+
|
64
|
+
def repository
|
65
|
+
@board_builder.repository
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module TrelloFs
|
2
|
+
class Repository
|
3
|
+
attr_reader :config
|
4
|
+
|
5
|
+
def initialize(config, builder = nil)
|
6
|
+
raise 'Wrong arguments' unless has_required_configuration?(config)
|
7
|
+
|
8
|
+
@config = config
|
9
|
+
@builder = builder
|
10
|
+
end
|
11
|
+
|
12
|
+
def path
|
13
|
+
@config[:path]
|
14
|
+
end
|
15
|
+
|
16
|
+
def board_id
|
17
|
+
@config[:board_id]
|
18
|
+
end
|
19
|
+
|
20
|
+
def developer_public_key
|
21
|
+
config[:developer_public_key]
|
22
|
+
end
|
23
|
+
|
24
|
+
def member_token
|
25
|
+
config[:member_token]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def has_required_configuration?(config)
|
31
|
+
config.has_key?(:path) &&
|
32
|
+
config.has_key?(:developer_public_key) &&
|
33
|
+
config.has_key?(:member_token)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module TrelloFs
|
4
|
+
class RepositoryCleaner
|
5
|
+
def initialize(repository)
|
6
|
+
@repository = repository
|
7
|
+
end
|
8
|
+
|
9
|
+
def clean
|
10
|
+
Dir.entries(@repository.path).each do |path|
|
11
|
+
next if path.start_with? '.'
|
12
|
+
next if path == 'Attachments'
|
13
|
+
|
14
|
+
FileUtils.rm_rf File.join(@repository.path, path)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module TrelloFs
|
5
|
+
class TrelloApi
|
6
|
+
def initialize(repository)
|
7
|
+
@repository = repository
|
8
|
+
end
|
9
|
+
|
10
|
+
def board
|
11
|
+
@board ||= new_board
|
12
|
+
end
|
13
|
+
|
14
|
+
def new_board
|
15
|
+
json = download_board_json
|
16
|
+
board = OpenStruct.new(name: json['name'],
|
17
|
+
desc: json['desc'],
|
18
|
+
id: json['id'],
|
19
|
+
url: json['url'])
|
20
|
+
labels, lists = {}, {}
|
21
|
+
board.attachments = []
|
22
|
+
|
23
|
+
board.organization_name = json['organization']['displayName'] if json['organization']
|
24
|
+
|
25
|
+
json['labels'].each do |label|
|
26
|
+
labels[label['id']] = OpenStruct.new name: label['name'], id: label['id'], cards: []
|
27
|
+
end
|
28
|
+
|
29
|
+
json['lists'].each do |list|
|
30
|
+
lists[list['id']] = OpenStruct.new(name: list['name'],
|
31
|
+
id: list['id'],
|
32
|
+
board: board,
|
33
|
+
cards: [])
|
34
|
+
end
|
35
|
+
|
36
|
+
cards = json['cards'].map do |card|
|
37
|
+
list = lists[card['idList']]
|
38
|
+
c = OpenStruct.new(id: card['id'],
|
39
|
+
name: card['name'],
|
40
|
+
desc: card['desc'],
|
41
|
+
url: card['url'],
|
42
|
+
list: list)
|
43
|
+
list.cards << c
|
44
|
+
|
45
|
+
c.labels = card['idLabels'].map do |label_id|
|
46
|
+
label = labels[label_id]
|
47
|
+
label.cards << c
|
48
|
+
label
|
49
|
+
end
|
50
|
+
|
51
|
+
c.checklists = card['checklists'].map do |checklist|
|
52
|
+
OpenStruct.new(
|
53
|
+
name: checklist['name'],
|
54
|
+
items: checklist['checkItems'].map do |item|
|
55
|
+
OpenStruct.new(name: item['name'], state: item['state'])
|
56
|
+
end
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
c.attachments = card['attachments'].map do |attachment|
|
61
|
+
a = OpenStruct.new(name: attachment['name'],
|
62
|
+
url: attachment['url'],
|
63
|
+
id: attachment['id'],
|
64
|
+
card: c)
|
65
|
+
board.attachments << a
|
66
|
+
a
|
67
|
+
end
|
68
|
+
|
69
|
+
c
|
70
|
+
end
|
71
|
+
|
72
|
+
board.labels = labels.values
|
73
|
+
board.lists = lists.values
|
74
|
+
|
75
|
+
board
|
76
|
+
end
|
77
|
+
|
78
|
+
def download_board_json
|
79
|
+
url = "https://api.trello.com/1/boards/#{@repository.board_id}?key=#{@repository.developer_public_key}&token=#{@repository.member_token}&cards=all&lists=all&labels=all&card_checklists=all&card_attachments=true&organization=true"
|
80
|
+
JSON.parse(open(url).read)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/trello-fs.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
class TestRepository < TrelloFs::Repository
|
4
|
+
def initialize
|
5
|
+
super({
|
6
|
+
path: TestRepository.path,
|
7
|
+
developer_public_key: '',
|
8
|
+
member_token: ''
|
9
|
+
})
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.path
|
13
|
+
p = 'tmp/test_repo'
|
14
|
+
FileUtils.mkpath p
|
15
|
+
p
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.remove
|
19
|
+
FileUtils.rm_rf path
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TrelloFs::AttachmentBuilder do
|
4
|
+
let(:attachment) { OpenStruct.new(id: '1', name: 'Attachment Name') }
|
5
|
+
let(:card) { OpenStruct.new(name: 'Card Name', attachments: [attachment]) }
|
6
|
+
let(:list) { OpenStruct.new(name: 'List Name', cards: [card]) }
|
7
|
+
let(:board) { OpenStruct.new(name: 'Board') }
|
8
|
+
|
9
|
+
let(:board_builder) { TrelloFs::BoardBuilder.new(TestRepository.new, board) }
|
10
|
+
let(:list_builder) { TrelloFs::ListBuilder.new(board_builder, list) }
|
11
|
+
let(:card_builder) { TrelloFs::CardBuilder.new(list_builder, card) }
|
12
|
+
let(:attachment_builder) { TrelloFs::AttachmentBuilder.new(card_builder, attachment) }
|
13
|
+
|
14
|
+
subject { attachment_builder }
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
allow(attachment_builder).to receive(:download) { 'data' }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#path' do
|
21
|
+
subject { attachment_builder.path }
|
22
|
+
|
23
|
+
it { should include 'Card_Name' }
|
24
|
+
it { should include 'Attachment Name' }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#already_downloaded?' do
|
28
|
+
subject { attachment_builder.already_downloaded? }
|
29
|
+
|
30
|
+
it { should eq false }
|
31
|
+
|
32
|
+
it 'returns true after download' do
|
33
|
+
attachment_builder.build
|
34
|
+
should eq true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|