trelloscrum 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ebcf1017670544951a750a392c016fe4f6f0183f
4
- data.tar.gz: fd5ee6f51bbc62d7e212bbd36f957685e9b2a4c8
3
+ metadata.gz: 3cbe70f6d030bb2ce6e272830a4c6cec23db6d58
4
+ data.tar.gz: d35e622d219b3a6af6b8ad663340fba302e0429a
5
5
  SHA512:
6
- metadata.gz: 540362e17cb52828a01951ab2646204debca8af3e916437b973ab44ab1168aa5e2c15635672db4dd0bcb93be11c9995669d5ca6f024d0d5b8bec1800d5900873
7
- data.tar.gz: 7cff2bbf9918d7691f95296d0f7c127ede4ea413faa5ee9ae759273d999045a7d039aa99f0436b713946fbe6ed94b985155d41c72b52727e09e88f82ac168727
6
+ metadata.gz: 0b82568a2d5aa71863a92cddb6ee13e5f47627e21956de5f5636353de0afdfea17dd28fe73df3849888380ec8f845d7cdaae1cb0955ebbc6d21694020756eb88
7
+ data.tar.gz: f3b8b1e92ac72f3c1a8a2710a0948b2f75ff30b69528c19884056378e794c14f2634defaded0d6bc38296e7e020b9e6c6fff265b9ab80da3de05b98e54c14f32
data/lib/cli.rb CHANGED
@@ -3,8 +3,11 @@ require 'thor'
3
3
  require 'json'
4
4
  require 'chronic'
5
5
  require 'trello'
6
+ require 'launchy'
6
7
 
8
+ require_relative 'trello_interface'
7
9
  require_relative 'pdf'
10
+ require_relative 'spreadsheet'
8
11
 
9
12
  module TrelloScrum
10
13
  class Cli < Thor
@@ -17,11 +20,36 @@ module TrelloScrum
17
20
  method_option :"list", :type => :string, :desc => "Listname to use"
18
21
  method_option :"board", :type => :string, :desc => "Board id to use"
19
22
  method_option :"filter-title", :type => :string, :desc => "Regexp to filter on titles, only show's cards matching title"
20
-
21
23
  def pdf(outfile)
22
- setup_trello
23
- cards = get_cards
24
- generate_pdf(cards, outfile)
24
+ trello = setup_trello
25
+
26
+ list_name = options.list || config["list_name"]
27
+
28
+ if !list_name || list_name.empty?
29
+ say "Please enter a listname (using --list) or configure one using setup"
30
+ exit(1)
31
+ end
32
+
33
+ lists_with_cards = trello.get_cards(list_name, options)
34
+
35
+ pdf = Pdf.new
36
+ pdf.render_cards(lists_with_cards)
37
+ pdf.save(outfile)
38
+ end
39
+
40
+ desc "excel OUTFILE", "generate Excel file for cards"
41
+ method_option :"only-estimated", :default => true, :type => :boolean, :desc => "Wether or not to output only estimates"
42
+ method_option :"list", :type => :string, :desc => "Listname to use (if not set it will take all lists)"
43
+ method_option :"include-archived-lists", :default => false, :type => :boolean, :desc => "Include archived lists"
44
+ method_option :"board", :type => :string, :desc => "Board id to use"
45
+ method_option :"filter-title", :type => :string, :desc => "Regexp to filter on titles, only show's cards matching title"
46
+ def excel(outfile)
47
+ trello = setup_trello
48
+ lists_with_cards = trello.get_cards(options.list || config["list_name"], options)
49
+
50
+ sheet = Spreadsheet.new
51
+ sheet.render_cards(lists_with_cards)
52
+ sheet.save(outfile)
25
53
  end
26
54
 
27
55
  desc "setup DEVELOPER_PUBLIC_KEY MEMBER_TOKEN [BOARD_ID] [LIST_NAME]", "config trello"
@@ -48,86 +76,79 @@ module TrelloScrum
48
76
  self.config["board_id"] = board_id if board_id
49
77
  self.config["list_name"] = list_name if list_name
50
78
 
51
- File.open(options.config, "w") do |f|
52
- f.write JSON.pretty_generate(self.config)
53
- end
54
-
55
- puts "New config written to #{options.config}"
79
+ write_config!
56
80
  end
57
81
 
58
- protected
82
+ desc "authorize", "Re-authorize trello"
83
+ long_desc <<-EOT
84
+ A simple way to launch the browser with the correct url. It will
85
+ also provide you with a way to paste your MEMBER_TOKEN.
86
+ EOT
87
+ def authorize
88
+ # Open the browser
89
+ url = "https://trello.com/1/connect"
90
+ url << "?key=#{self.config["developer_public_key"]}"
91
+ url << "&name=TrelloScrumCard&response_type=token"
92
+ Launchy.open(url)
93
+
94
+ member_token = ask("Paste member token here:")
95
+
96
+ if member_token =~ /.+/
97
+ self.config["member_token"] = member_token
98
+ write_config!
99
+ else
100
+ say "No member token entered. Not saving new member token"
101
+ end
102
+ end
59
103
 
60
- def log(msg)
61
- puts msg if options.verbose
104
+ no_commands do
105
+ def log(msg)
106
+ say msg if options.verbose
107
+ end
62
108
  end
109
+ protected
63
110
 
64
111
  def setup_trello
65
112
  if !config["developer_public_key"] || config["developer_public_key"].empty?
66
- puts "Please make sure you have configured a developer public key (run setup help for more info)"
113
+ say "Please make sure you have configured a developer public key (run setup help for more info)"
67
114
  exit(1)
68
115
  end
69
116
 
70
117
  if !config["member_token"] || config["member_token"].empty?
71
- puts "Please make sure you have configured a member token (run setup help for more info)"
72
- exit(1)
73
- end
74
-
75
- Trello.configure do |c|
76
- c.developer_public_key = config["developer_public_key"]
77
- c.member_token = config["member_token"]
78
- end
79
- end
80
-
81
- def config
82
- if File.exist?(options.config)
83
- @config ||= JSON.parse(File.read(options.config));
84
- else
85
- @config ||= {}
86
- end
87
- end
88
-
89
- def get_cards
90
- list_name = options.list || config["list_name"]
91
-
92
- if !list_name || list_name.empty?
93
- puts "Please enter a listname (using --list) or configure one using setup"
118
+ say "Please make sure you have configured a member token (run setup help for more info)"
94
119
  exit(1)
95
120
  end
96
121
 
97
122
  board_id = options.board || config["board_id"]
98
-
99
123
  if !board_id || board_id.empty?
100
- puts "Please enter a board_id (using --board) or configure one using setup "
124
+ say "Please enter a board_id (using --board) or configure one using setup "
101
125
  exit(1)
102
126
  end
103
127
 
104
- log "Getting cards from list #{list_name} of board #{board_id}"
105
-
106
- board = Trello::Board.find(board_id)
107
-
108
- list = board.lists.find{|l| l.name == list_name }
109
-
110
- log "Found list: #{list ? "yes" : "no"}"
111
-
112
- cards = list.cards.sort!{|a, b| a.pos <=> b.pos }
113
-
114
- log "List contains #{cards.size} cards"
128
+ TrelloInterface.new(
129
+ board_id,
130
+ config["developer_public_key"],
131
+ config["member_token"],
132
+ {
133
+ cli: self
134
+ }
135
+ )
136
+ end
115
137
 
116
- cards.find_all do |card|
117
- keep = true
118
- keep = false if options[:"only-estimated"] && !(card.name =~ /^\(\d+/)
119
- keep = false if options[:"filter-title"] && !(card.name =~ Regexp.new(options[:"filter-title"]))
120
- keep
138
+ def write_config!
139
+ File.open(options.config, "w") do |f|
140
+ f.write JSON.pretty_generate(self.config)
121
141
  end
142
+ say "Config written to #{options.config}"
122
143
  end
123
144
 
124
- def generate_pdf(cards, output_path)
125
- pdf = Pdf.new
126
- pdf.render_cards(cards)
127
- pdf.save(output_path)
145
+ def config
146
+ if File.exist?(options.config)
147
+ @config ||= JSON.parse(File.read(options.config));
148
+ else
149
+ @config ||= {}
150
+ end
128
151
  end
129
152
 
130
-
131
-
132
153
  end
133
154
  end
data/lib/pdf.rb CHANGED
@@ -31,6 +31,9 @@ module TrelloScrum
31
31
  end
32
32
 
33
33
  def render_cards(cards)
34
+ # Flatten the structure
35
+ cards = cards.map{|list| list[:cards]}.flatten
36
+
34
37
  cards.each_with_index do |card, i|
35
38
  render_card(card)
36
39
 
@@ -0,0 +1,56 @@
1
+ require 'axlsx'
2
+ require 'pry'
3
+
4
+ module TrelloScrum
5
+
6
+ class Spreadsheet
7
+
8
+ attr_reader :package, :workbook
9
+
10
+ def initialize
11
+ @package = Axlsx::Package.new
12
+ @workbook = @package.workbook
13
+ end
14
+
15
+ def render_cards(lists_with_cards)
16
+ list_name_style = workbook.styles.add_style :sz => 16, :b => true
17
+ header_style = workbook.styles.add_style :b => true
18
+
19
+ workbook.add_worksheet(:name => "Cards") do |sheet|
20
+ lists_with_cards.each do |list|
21
+ # The list title
22
+ sheet.add_row [
23
+ list[:list].name.to_s + (list[:list].closed ? " (archived)" : "")
24
+ ], style: list_name_style
25
+
26
+ # Header
27
+ sheet.add_row [
28
+ "Points",
29
+ "Title",
30
+ "Client",
31
+ "URL"
32
+ ], style: header_style
33
+
34
+ list[:cards].each do |card|
35
+ sheet.add_row [
36
+ card.scrum_points,
37
+ card.scrum_title,
38
+ card.scrum_client,
39
+ card.url
40
+ ]
41
+ end
42
+
43
+ # Add some empty rows
44
+ sheet.add_row
45
+ end
46
+
47
+ sheet.column_widths 10, nil, nil, nil
48
+ end
49
+ end
50
+
51
+ def save(filename)
52
+ package.serialize(filename)
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,88 @@
1
+ module TrelloScrum
2
+
3
+ class TrelloInterface
4
+
5
+ attr_accessor :board_id, :options
6
+
7
+ def initialize(board_id, developer_public_key, member_token, options = {})
8
+ Trello.configure do |c|
9
+ c.developer_public_key = developer_public_key
10
+ c.member_token = member_token
11
+ end
12
+
13
+ self.board_id = board_id
14
+
15
+ self.options = options
16
+ end
17
+
18
+
19
+ def get_cards(list_name = nil, options = {})
20
+ log "Getting cards from list #{list_name} of board #{board_id}"
21
+
22
+ lists = get_lists(list_name, options)
23
+
24
+ lists.map do |list|
25
+ cards = list.cards.sort!{|a, b| a.pos <=> b.pos }
26
+
27
+ log "List '#{list.name}' contains #{cards.size} cards"
28
+
29
+ filtered_cards = cards.find_all do |card|
30
+ keep = true
31
+ keep = false if options[:"only-estimated"] && !(card.name =~ /^\(\d+/)
32
+ keep = false if options[:"filter-title"] && !(card.name =~ Regexp.new(options[:"filter-title"]))
33
+ keep
34
+ end
35
+
36
+ filtered_cards.map! do |card|
37
+ class << card
38
+ attr_accessor :scrum_points, :scrum_client, :scrum_title
39
+ end
40
+ points,client,title = parse_card_title(card.name)
41
+ card.scrum_points = points
42
+ card.scrum_client = client
43
+ card.scrum_title = title
44
+ card
45
+ end
46
+
47
+ {
48
+ list: list,
49
+ cards: filtered_cards
50
+ }
51
+ end
52
+ end
53
+
54
+ def get_lists(list_name, options = {})
55
+ board = Trello::Board.find(board_id)
56
+
57
+ lists = board.lists filter: (options[:"include-archived-lists"] ? :all : :open)
58
+
59
+ if list_name && !list_name.empty?
60
+ lists = lists.find_all{|l| l.name == list_name }
61
+ end
62
+
63
+ lists.sort!{|a, b| a.pos <=> b.pos }
64
+
65
+ log "Found lists: #{lists.map(&:name).inspect}"
66
+
67
+ lists
68
+ end
69
+
70
+ protected
71
+
72
+ def parse_card_title(title)
73
+ match = title.match(/^\s*(\((\d+)\))?\s*(\[(.*?)\])?\s*(.*)/)
74
+ [match[2], match[4], match[5]]
75
+ end
76
+
77
+ def log(msg)
78
+ if options[:cli]
79
+ options[:cli].log msg
80
+ else
81
+ puts msg
82
+ end
83
+ end
84
+
85
+
86
+ end
87
+
88
+ end
@@ -1,3 +1,3 @@
1
1
  module TrelloScrum
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -26,6 +26,8 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "chronic", "~> 0.10.2"
27
27
  spec.add_dependency "ruby-trello", "~> 1.1.2"
28
28
  spec.add_dependency "thor", "~> 0.19.1"
29
+ spec.add_dependency "launchy", "~> 2.4.3"
30
+ spec.add_dependency "axlsx", "~> 2.0.1"
29
31
 
30
32
  spec.homepage = "https://github.com/flurin/trelloscrum"
31
33
  spec.description = <<END_DESC
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trelloscrum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Flurin Egger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-01 00:00:00.000000000 Z
11
+ date: 2015-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.19.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: launchy
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 2.4.3
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 2.4.3
111
+ - !ruby/object:Gem::Dependency
112
+ name: axlsx
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 2.0.1
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 2.0.1
97
125
  description: |2
98
126
  Generates PDF's with (+/-) one page per card with title, body and checklists. Print 4 of them on an A4 for the best action.
99
127
  email:
@@ -107,6 +135,8 @@ files:
107
135
  - bin/trelloscrum
108
136
  - lib/cli.rb
109
137
  - lib/pdf.rb
138
+ - lib/spreadsheet.rb
139
+ - lib/trello_interface.rb
110
140
  - lib/version.rb
111
141
  - readme.md
112
142
  - resources/Apache License.txt