card_printer 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/bin/card_printer +18 -21
- data/lib/card_printer/parser/base.rb +21 -0
- data/lib/card_printer/parser/csv.rb +16 -0
- data/lib/card_printer/parser/json_line.rb +12 -0
- data/lib/card_printer/parser/trello_json_export.rb +73 -0
- data/lib/card_printer/parser.rb +33 -0
- data/lib/card_printer/six_by_four_renderer.rb +14 -0
- data/lib/card_printer/story.rb +7 -3
- data/lib/card_printer/version.rb +1 -1
- data/lib/card_printer.rb +1 -1
- metadata +19 -14
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YTllZGMwNGI0OWVjYWFmN2U0NTYyNzUwMGFhZmIxYWZlODhkYWNlZQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7ae51cf4fc64c025bf64e8b930b7f8c0221d7f00
|
4
|
+
data.tar.gz: 6da9286634464482d7e13e7828ef51d9e0743ae8
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
Nzk3YjM4YzQzM2YwNWM1Zjk3ZDUyNTE1MWRiOWNmN2I4ZjNlNzFlZTc1ZmZi
|
11
|
-
MjA0ZTNiYjNkYThhMjgwOTQ1Y2M0MTg4Yzk1OTE5ZTNkYTdmZmE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NWIzYTk1MWQxZTI5ZTQwZmIwNjAyYzZiNTExNWE3ZjEwNTVmNGRhN2QwNDZm
|
14
|
-
YzRkMTFhY2Y5YzEyZjBlNzk2ZDUxMzQwMGQyMjUwNWUxMGI0NmMyY2YxZGRh
|
15
|
-
MDFmYjQ1NGViNzdiYTk2OGY0ZmNiZmEzOTJjYjI2ZDdiNzM2ZjI=
|
6
|
+
metadata.gz: cfa85bcd78b645d00baa81a8f08af260baf27bd4b4153e8508a165b8cb1491726c394828a5e402ddd9ec4881bee56c85fb8bbd34b0029bfc17d64ec4e782272b
|
7
|
+
data.tar.gz: f9249df5fc9c9db11fc1f41e6bd530b70ee53e1b934124638cdfbb1067265fc4ccd0772fdef9a77a273e084afb8c1827b62d729be965ca0b318a3a2969531d4f
|
data/bin/card_printer
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'slop'
|
4
4
|
require 'card_printer'
|
5
|
-
require 'card_printer/
|
5
|
+
require 'card_printer/parser'
|
6
6
|
require 'json'
|
7
7
|
|
8
8
|
# stories << CardPrinter::Story.new(name: "Foobar")
|
@@ -15,13 +15,19 @@ class Cli
|
|
15
15
|
class BadCliOptionError < StandardError; end
|
16
16
|
|
17
17
|
def initialize
|
18
|
-
@opts = Slop.parse
|
19
|
-
banner "Usage: #{File.basename(__FILE__)} [options] <output file.pdf>"
|
20
|
-
separator %{Options:}
|
21
|
-
on
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
@opts = Slop.parse do |o|
|
19
|
+
o.banner = "Usage: #{File.basename(__FILE__)} [options] <output file.pdf>"
|
20
|
+
o.separator %{Options:}
|
21
|
+
o.on('-p=', 'parser',
|
22
|
+
%Q{Choose input parser (one of '#{CardPrinter::Parser.available_parsers.join("', '")}', default: trello_json_export)},
|
23
|
+
default: 'trello_json_export'
|
24
|
+
)
|
25
|
+
o.on('-r=', 'renderer', "Choose layout renderer (one of '#{CardPrinter.available_layouts.join("', '")}', default: '6x4')",
|
26
|
+
default: '6x4'
|
27
|
+
)
|
28
|
+
o.on '-h=', %Q{display this help message}
|
29
|
+
|
30
|
+
o.separator %{
|
25
31
|
Data input:
|
26
32
|
|
27
33
|
Provide story data on standard input in json-lines format (one JSON object per
|
@@ -41,26 +47,17 @@ e.g.
|
|
41
47
|
{"name": "Second story", "description": "Do some things", "label": "epic one", "story_type": "feature", "estimate": "1"}
|
42
48
|
}
|
43
49
|
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def renderer_name
|
48
|
-
opts[:renderer] || "6x4"
|
49
50
|
end
|
50
51
|
|
51
52
|
def run
|
52
53
|
if ARGV.size == 1
|
53
|
-
stories = []
|
54
|
-
|
55
|
-
data = JSON.parse(line)
|
56
|
-
stories << CardPrinter::Story.new(data)
|
57
|
-
end
|
58
|
-
|
59
|
-
CardPrinter.render(stories, ARGV[0])
|
54
|
+
stories = CardPrinter::Parser.parse($stdin, opts[:parser])
|
55
|
+
CardPrinter.render(stories, ARGV[0], opts[:renderer])
|
60
56
|
else
|
61
57
|
puts opts
|
58
|
+
puts opts['parser']
|
62
59
|
end
|
63
60
|
end
|
64
61
|
end
|
65
62
|
|
66
|
-
Cli.new.run
|
63
|
+
Cli.new.run
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'card_printer'
|
2
|
+
require 'card_printer/parser'
|
3
|
+
require 'card_printer/story'
|
4
|
+
|
5
|
+
class CardPrinter::Parser::Base
|
6
|
+
attr_reader :iostream
|
7
|
+
|
8
|
+
def initialize(iostream)
|
9
|
+
@iostream = iostream
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse
|
13
|
+
@iostream.each_line.map do |line|
|
14
|
+
CardPrinter::Story.new(parse_line(line))
|
15
|
+
end.compact
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_line(line)
|
19
|
+
raise "parse_line not implemented"
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'card_printer/parser'
|
2
|
+
require 'card_printer/parser/base'
|
3
|
+
|
4
|
+
class CardPrinter::Parser::CsvParser < CardPrinter::Parser::Base
|
5
|
+
def parse_line(line)
|
6
|
+
parsed = CSV.parse_line(line)
|
7
|
+
if @headers
|
8
|
+
Hash[@headers.zip(parsed)]
|
9
|
+
else
|
10
|
+
@headers = parsed
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
CardPrinter::Parser.register_parser('csv', CardPrinter::Parser::CsvParser)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'card_printer/parser'
|
2
|
+
require 'card_printer/parser/base'
|
3
|
+
|
4
|
+
class CardPrinter::Parser::JsonLine < CardPrinter::Parser::Base
|
5
|
+
def parse_line(line)
|
6
|
+
JSON.parse(line)
|
7
|
+
rescue
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
CardPrinter::Parser.register_parser('json_lines', CardPrinter::Parser::JsonLine)
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'card_printer/parser'
|
3
|
+
require 'card_printer/parser/base'
|
4
|
+
|
5
|
+
###*****
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
class CardPrinter::Parser::TrelloJsonExport < CardPrinter::Parser::Base
|
9
|
+
def parse
|
10
|
+
lists.map do |list|
|
11
|
+
list.cards.map do |card|
|
12
|
+
story_from_card(list, card)
|
13
|
+
end
|
14
|
+
end.flatten
|
15
|
+
end
|
16
|
+
|
17
|
+
def data
|
18
|
+
@data ||= JSON.load(iostream)
|
19
|
+
end
|
20
|
+
|
21
|
+
def lists
|
22
|
+
data['lists'].map do |list|
|
23
|
+
List.new(list).tap do |l|
|
24
|
+
l.cards = cards_for_list_id(l.id)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def cards_for_list_id(list_id)
|
30
|
+
data['cards'].select do |card|
|
31
|
+
card['idList'] == list_id
|
32
|
+
end.map do |card|
|
33
|
+
Card.new(card)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def story_from_card(list, card)
|
38
|
+
CardPrinter::Story.new(
|
39
|
+
name: "#{card.name}",
|
40
|
+
description: card.desc,
|
41
|
+
story_type: story_type(card),
|
42
|
+
estimate: "",
|
43
|
+
label: "",
|
44
|
+
id: "##{card.idShort}"
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def story_type(card)
|
49
|
+
case label_of(card)
|
50
|
+
when /feature/i
|
51
|
+
"feature"
|
52
|
+
when /bug/i
|
53
|
+
"bug"
|
54
|
+
when /chore/i
|
55
|
+
"chore"
|
56
|
+
else
|
57
|
+
"other"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def label_of(card)
|
62
|
+
if card.labels.any?
|
63
|
+
card.labels.first['name']
|
64
|
+
else
|
65
|
+
""
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class List < OpenStruct; end
|
70
|
+
class Card < OpenStruct; end
|
71
|
+
end
|
72
|
+
|
73
|
+
CardPrinter::Parser.register_parser('trello_json_export', CardPrinter::Parser::TrelloJsonExport)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'csv'
|
3
|
+
require 'card_printer'
|
4
|
+
|
5
|
+
module CardPrinter::Parser
|
6
|
+
def self.parse(iostream, parser_type = default_parser)
|
7
|
+
parser_for(parser_type).call(iostream)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.available_parsers
|
11
|
+
@parsers.keys
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.default_parser
|
15
|
+
'trello_json_export'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.parser_for(parser_type)
|
19
|
+
parser_class = @parsers.fetch(parser_type)
|
20
|
+
->(iostream) { parser_class.new(iostream).parse }
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.register_parser(name, klass)
|
24
|
+
@parsers[name] = klass
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
@parsers = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'card_printer/parser/csv'
|
32
|
+
require 'card_printer/parser/json_line'
|
33
|
+
require 'card_printer/parser/trello_json_export'
|
@@ -86,6 +86,7 @@ class CardPrinter::SixByFourRenderer
|
|
86
86
|
render_crest
|
87
87
|
render_story_title(story)
|
88
88
|
render_story_points(story, padding_y)
|
89
|
+
render_story_id(story, padding_y)
|
89
90
|
end
|
90
91
|
render_iteration_number(story)
|
91
92
|
end
|
@@ -146,6 +147,19 @@ class CardPrinter::SixByFourRenderer
|
|
146
147
|
end
|
147
148
|
end
|
148
149
|
|
150
|
+
def render_story_id(story, padding_y)
|
151
|
+
return if story.id.to_s.empty?
|
152
|
+
@pdf.fill_color "000000"
|
153
|
+
@pdf.font "Helvetica" do
|
154
|
+
@pdf.text_box story.id.to_s,
|
155
|
+
:size => 10.mm * @scale,
|
156
|
+
:at => [@pdf.bounds.left, padding_y + 10.mm * @scale],
|
157
|
+
:width => @pdf.bounds.right - @pdf.bounds.left,
|
158
|
+
valign: :bottom,
|
159
|
+
align: :center
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
149
163
|
def render_iteration_number(story)
|
150
164
|
@pdf.fill_color "000000"
|
151
165
|
text_height = 6.mm * @scale
|
data/lib/card_printer/story.rb
CHANGED
@@ -2,8 +2,8 @@ require "card_printer"
|
|
2
2
|
|
3
3
|
class CardPrinter::Story
|
4
4
|
# story_type = {feature|bug|chore|other}
|
5
|
-
ATTRS = [:name, :description, :story_type, :estimate, :label]
|
6
|
-
|
5
|
+
ATTRS = [:name, :description, :story_type, :estimate, :label, :id]
|
6
|
+
|
7
7
|
attr_accessor *ATTRS
|
8
8
|
|
9
9
|
def initialize(data = {})
|
@@ -11,4 +11,8 @@ class CardPrinter::Story
|
|
11
11
|
self.send(:"#{attr_name}=", data[attr_name] || data[attr_name.to_s])
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
Hash[ATTRS.map {|a| [a, self.send(a)] }].to_s
|
17
|
+
end
|
18
|
+
end
|
data/lib/card_printer/version.rb
CHANGED
data/lib/card_printer.rb
CHANGED
@@ -10,7 +10,7 @@ module CardPrinter
|
|
10
10
|
"a5" => CardPrinter::Renderer
|
11
11
|
}
|
12
12
|
|
13
|
-
def self.render(stories, destination_path, renderer_name
|
13
|
+
def self.render(stories, destination_path, renderer_name, opts = {})
|
14
14
|
renderer = LAYOUTS[renderer_name] || raise("Unknown layout renderer #{renderer_name}")
|
15
15
|
renderer.new(stories, opts).render_to(destination_path)
|
16
16
|
end
|
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: card_printer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heath
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prawn
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 1.3.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: slop
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: Produce nicely formatted PDFs of story cards for printing
|
@@ -74,7 +74,7 @@ executables:
|
|
74
74
|
extensions: []
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
|
-
- .gitignore
|
77
|
+
- ".gitignore"
|
78
78
|
- Gemfile
|
79
79
|
- LICENSE.txt
|
80
80
|
- README.md
|
@@ -85,6 +85,11 @@ files:
|
|
85
85
|
- images/label_icon.jpg
|
86
86
|
- lib/card_printer.rb
|
87
87
|
- lib/card_printer/a6_renderer.rb
|
88
|
+
- lib/card_printer/parser.rb
|
89
|
+
- lib/card_printer/parser/base.rb
|
90
|
+
- lib/card_printer/parser/csv.rb
|
91
|
+
- lib/card_printer/parser/json_line.rb
|
92
|
+
- lib/card_printer/parser/trello_json_export.rb
|
88
93
|
- lib/card_printer/renderer.rb
|
89
94
|
- lib/card_printer/six_by_four_renderer.rb
|
90
95
|
- lib/card_printer/story.rb
|
@@ -99,17 +104,17 @@ require_paths:
|
|
99
104
|
- lib
|
100
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
101
106
|
requirements:
|
102
|
-
- -
|
107
|
+
- - ">="
|
103
108
|
- !ruby/object:Gem::Version
|
104
109
|
version: '0'
|
105
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
111
|
requirements:
|
107
|
-
- -
|
112
|
+
- - ">="
|
108
113
|
- !ruby/object:Gem::Version
|
109
114
|
version: '0'
|
110
115
|
requirements: []
|
111
116
|
rubyforge_project:
|
112
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.2.2
|
113
118
|
signing_key:
|
114
119
|
specification_version: 4
|
115
120
|
summary: ''
|