pivotalprinter 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.swp
2
+ pkg
3
+ Gemfile.lock
data/COPYING ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 pkw.de full name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # vim: set ft=ruby:
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gemspec
data/History.txt ADDED
@@ -0,0 +1,18 @@
1
+ === 0.1.7 2011-07-19
2
+
3
+ * use a newver prawn version
4
+
5
+ === 0.1.4 2011-01-20
6
+
7
+ * print multiple stories by id
8
+ * story id is now included at the sheet
9
+
10
+ === 0.1.2 2010-12-22
11
+
12
+ * removed dependencies:
13
+ * pivotal-tracker no longer needed
14
+
15
+ === 0.0.1 2010-12-07
16
+
17
+ * 1 major enhancement:
18
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,20 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ bin/pivotalprinter
7
+ images/bug.png
8
+ images/chore.png
9
+ images/feature.png
10
+ images/release.png
11
+ lib/pivotalprinter.rb
12
+ lib/pivotalprinter/client.rb
13
+ lib/pivotalprinter/story.rb
14
+ lib/pivotalprinter/iteration.rb
15
+ pivotalprinter.gemspec
16
+ script/console
17
+ script/destroy
18
+ script/generate
19
+ test/test_helper.rb
20
+ test/test_pivotalprinter.rb
data/PostInstall.txt ADDED
@@ -0,0 +1 @@
1
+ For more information on pivotalprinter, see http://github.com/pkwde/pivotalprinter
data/README.rdoc ADDED
@@ -0,0 +1,22 @@
1
+ = pivotalprinter
2
+
3
+ * https://github.com/caroo/pivotalprinter
4
+
5
+ == DESCRIPTION:
6
+
7
+ Script to print use stories in pivotal printer
8
+
9
+ == INSTALL:
10
+
11
+ Just type
12
+
13
+ $ gem install privotalprinter
14
+
15
+
16
+ == AUTHORS
17
+
18
+ pkw.de Development Team
19
+
20
+ == LICENSE:
21
+
22
+ The MIT License, see the COPYING file
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+ # inspired by from http://ephemera.karmi.cz/post/622136360/create-printable-pdf-cards-for-your-pivotal-tracker-stor
3
+
4
+ require 'pivotalprinter'
5
+
6
+ class String; include Term::ANSIColor; end
7
+
8
+ module Pivotalprinter
9
+ class ConfigNeeded < StandardError; end
10
+ class TokenMissing < StandardError; end
11
+ class ProjectMissing < StandardError; end
12
+ end
13
+
14
+ module Pivotalprinter
15
+ class Printer
16
+ def run
17
+ opts = parse_options
18
+ yaml = load_yaml_config
19
+ project,token = extract_config(opts, yaml)
20
+ Pivotalprinter::Client.project = project
21
+ Pivotalprinter::Client.token = token
22
+ @stories = case ARGV.last
23
+ when "done" : Pivotalprinter::Iteration.open('done').stories
24
+ when "backlog": Pivotalprinter::Iteration.open('backlog').stories
25
+ when /^\d+$/ : Pivotalprinter::Story.open(ARGV.map(&:to_i))
26
+ else Pivotalprinter::Iteration.open('current').stories
27
+ end
28
+ generate_output
29
+ rescue ConfigNeeded
30
+ print_config
31
+ rescue TokenMissing
32
+ Trollop::die :token, "token must be specified through config file or explicitly"
33
+ rescue ProjectMissing
34
+ Trollop::die :project, "project must be a valid number or one of the configured projects (#{(yaml.keys - ["default"]).join(", ")}) if no default is configured in $HOME/.pivotalprinterrc"
35
+ rescue SystemExit
36
+ rescue Exception
37
+ puts "[!] There was an error while generating the PDF file... What happened was:".white.on_red
38
+ raise
39
+ end
40
+
41
+ def print_config
42
+ puts %{---\ndefault: &default\n token: "YOUR TOKEN HERE"\n project: 123\n\nsome_project:\n <<: *default # so you don't need to rewrite the token\n project: 789}
43
+ end
44
+
45
+ def parse_options
46
+ opts = Trollop::options do
47
+ version "pivotalprinter #{Pivotalprinter::VERSION} (c) 2010#{(year = Time.now.year) > 2010 ? "-#{year}" : ''} pkw.de"
48
+ banner <<-EOS
49
+ Pivotalprinter is an awesome program to print stories from the PivotalTracker.
50
+
51
+ Useage:
52
+ pivotalprinter [-p PROJECT] [-t TOKEN] [current|backlog|done|STORY]
53
+ pivotalprinter --config > ~/.pivotalprinterrc
54
+
55
+ Options:
56
+ EOS
57
+ opt :project, "Project Name defined in $HOME/.pivotalprinterrc or project number", :short => "-p", :type => :string
58
+ opt :token, "Pivotaltracker Token", :short => "-t", :type => :string
59
+ opt :config, "show example configuration", :short => "-c"
60
+ end
61
+
62
+ raise ConfigNeeded if opts[:config]
63
+ opts
64
+ end
65
+
66
+ def load_yaml_config
67
+ File.exist?("#{ENV["HOME"]}/.pivotalprinterrc") ? YAML::load_file("#{ENV["HOME"]}/.pivotalprinterrc") : {}
68
+ end
69
+
70
+ def extract_config(opts, yaml)
71
+ if opts[:project].nil? && yaml.key?("default")
72
+ return yaml["default"]["project"], yaml["default"]["token"]
73
+ elsif opts[:project] =~ /[0-9]+/
74
+ return opts[:project], (opts[:token] || yaml["default"]["project"])
75
+ elsif yaml.key?(opts[:project])
76
+ return yaml[opts[:project]]["project"], yaml[opts[:project]]["token"]
77
+ else
78
+ raise ProjectMissing
79
+ end
80
+ end
81
+
82
+ def generate_output
83
+ Prawn::Document.generate("/tmp/stories.pdf", :page_layout => :landscape, :margin => [25, 25, 50, 25], :page_size => 'A4') do |pdf|
84
+ @num_cards_on_page = 0
85
+ pdf.font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
86
+ @stories.each_with_index do |story, i|
87
+ # --- Split pages
88
+ if i > 0 and i % 4 == 0
89
+ # puts "New page..."
90
+ pdf.start_new_page
91
+ @num_cards_on_page = 1
92
+ else
93
+ @num_cards_on_page += 1
94
+ end
95
+
96
+ # --- Define 2x2 grid
97
+ pdf.define_grid(:columns => 2, :rows => 2, :gutter => 42)
98
+ # pdf.grid.show_all
99
+
100
+ row = (@num_cards_on_page+1) / 4
101
+ column = i % 2
102
+ padding = 12
103
+ cell = pdf.grid( row, column )
104
+ cell.bounding_box do
105
+
106
+ pdf.stroke_color = "666666"
107
+ pdf.stroke_bounds
108
+
109
+ pdf.text_box story.name, :size => 14, :height => 50, :overflow => :truncate, :width => cell.width-(padding*2)-50, :at => [pdf.bounds.left+padding+50, pdf.bounds.top-padding]
110
+ pdf.text_box story.description, :size => 8, :overflow => :truncate, :width => cell.width-(padding*2), :height => cell.height-(padding*7), :at => [pdf.bounds.left+padding, pdf.bounds.top-padding-55]
111
+ pdf.text_box "ID #{story.id}", :size => 8, :at => [pdf.bounds.left, pdf.bounds.bottom+padding], :align => :right
112
+ pdf.text_box story.created_at.strftime('%F'), :size => 8, :at => [pdf.bounds.left, pdf.bounds.bottom+padding], :align => :left
113
+
114
+ x, y = 32, 205
115
+ if story.story_type=="feature"
116
+ pdf.fill_color story.points_background
117
+ pdf.fill_circle [x,y], 25
118
+ pdf.font_size = 36
119
+ pdf.font "Helvetica", :style => :bold
120
+ pdf.fill_color 'ffffff'
121
+ pdf.draw_text "#{story.points}", :at => [x-10, y-12]
122
+ pdf.fill_color '000000'
123
+ pdf.font_size = 14
124
+ pdf.font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf", :style => :normal
125
+ else
126
+ pdf.image open("#{File.dirname(__FILE__)}/../images/#{story.story_type}.png"), :position => 5, :vposition => 5
127
+ end
128
+ end
129
+ end
130
+ end
131
+ puts ">>> Generated PDF file in 'stories.pdf' with #{@stories.size} stories".black.on_green
132
+ system "open /tmp/stories.pdf"
133
+ end
134
+ end
135
+ end
136
+
137
+ Pivotalprinter::Printer.new.run
data/images/bug.png ADDED
Binary file
data/images/chore.png ADDED
Binary file
Binary file
Binary file
@@ -0,0 +1,13 @@
1
+ module Pivotalprinter
2
+ class Client
3
+ class << self
4
+ attr_accessor :token, :project
5
+
6
+ def get(path, options={})
7
+ raise TokenMissing if @token.nil?
8
+ raise ProjectMissing if @project.nil?
9
+ open("http://www.pivotaltracker.com/services/v3#{path}", 'X-TrackerToken' => @token, 'Content-Type' => 'application/xml').read
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module Pivotalprinter
2
+ class Iteration
3
+
4
+ attr_accessor :stories
5
+
6
+ def self.open(name)
7
+ self.new(name)
8
+ end
9
+
10
+ def initialize(name)
11
+ @stories = []
12
+ extract_stories(Client.get "/projects/#{Client.project}/iterations/#{name}")
13
+ end
14
+
15
+ private
16
+
17
+ def extract_stories(response)
18
+ response = Nokogiri::XML.parse(response)
19
+ response.css("story").each do |story|
20
+ @stories << Story.new(story)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ require 'time'
2
+
3
+ module Pivotalprinter
4
+ class Story
5
+ FIELDS = [ :name, :id, :story_type, :estimate, :current_state, :description, :requested_by, :labels, :created_at, :updated_at ]
6
+ attr_accessor *FIELDS
7
+
8
+ def initialize(xml)
9
+ FIELDS.each do |field|
10
+ value = xml.css("#{field}")
11
+ send "#{field}=", value.first.full? { |v| v.send(:text) } || value.send(:text)
12
+ end
13
+ created_at and self.created_at = Time.parse(created_at)
14
+ updated_at and self.updated_at = Time.parse(updated_at)
15
+ end
16
+
17
+ def self.open(ids)
18
+ stories = ids.map do |id|
19
+ response = Client.get "/projects/#{Client.project}/stories/#{id}"
20
+ response = Nokogiri::XML.parse(response)
21
+ self.new(response.css('story'))
22
+ end
23
+ end
24
+
25
+ def points
26
+ estimate.to_i >= 0 ? estimate.to_i : '?'
27
+ end
28
+
29
+ def points_background
30
+ case points
31
+ when '?': 'cccccc'
32
+ when 0: 'ccff66'
33
+ when 1: '408000'
34
+ when 2: '808000'
35
+ when 3: 'ffcc66'
36
+ when 5: 'ff8000'
37
+ when 8: 'ff0000'
38
+ else 'aa0000'
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module Pivotalprinter
2
+ VERSION = '0.1.7'
3
+ end
@@ -0,0 +1,19 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Pivotalprinter
5
+ require 'rubygems'
6
+ require 'pivotalprinter/version'
7
+ require 'term/ansicolor'
8
+ require 'prawn'
9
+ require 'prawn/layout/grid'
10
+ require 'spruz/xt/full'
11
+ require 'trollop'
12
+ require 'yaml'
13
+ require "rubygems"
14
+ require "open-uri"
15
+ require "nokogiri"
16
+ require "pivotalprinter/client"
17
+ require "pivotalprinter/iteration"
18
+ require "pivotalprinter/story"
19
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.unshift 'lib'
3
+ require "pivotalprinter/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "pivotalprinter"
7
+ s.version = Pivotalprinter::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["pkw.de"]
10
+ s.email = ["dev@pkw.de"]
11
+ s.homepage = "http://pkw.de"
12
+ s.summary = %q{Story printer for pivotaltracker}
13
+ s.description = %q{Generate nice story cards from pivotaltracker.}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency('term-ansicolor','>= 0.4.4')
21
+ s.add_dependency('prawn','~>0.11.1')
22
+ s.add_dependency('spruz','>= 0.2.0')
23
+ s.add_dependency('trollop','>= 1.16.2')
24
+ s.add_dependency('nokogiri','>= 1.4.4')
25
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/pivotalprinter.rb'}"
9
+ puts "Loading pivotalprinter gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/pivotalprinter'
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestPivotalprinter < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pivotalprinter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 7
10
+ version: 0.1.7
11
+ platform: ruby
12
+ authors:
13
+ - pkw.de
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-19 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: term-ansicolor
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 7
29
+ segments:
30
+ - 0
31
+ - 4
32
+ - 4
33
+ version: 0.4.4
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: prawn
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 49
45
+ segments:
46
+ - 0
47
+ - 11
48
+ - 1
49
+ version: 0.11.1
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: spruz
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 23
61
+ segments:
62
+ - 0
63
+ - 2
64
+ - 0
65
+ version: 0.2.0
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: trollop
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 83
77
+ segments:
78
+ - 1
79
+ - 16
80
+ - 2
81
+ version: 1.16.2
82
+ type: :runtime
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: nokogiri
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 15
93
+ segments:
94
+ - 1
95
+ - 4
96
+ - 4
97
+ version: 1.4.4
98
+ type: :runtime
99
+ version_requirements: *id005
100
+ description: Generate nice story cards from pivotaltracker.
101
+ email:
102
+ - dev@pkw.de
103
+ executables:
104
+ - pivotalprinter
105
+ extensions: []
106
+
107
+ extra_rdoc_files: []
108
+
109
+ files:
110
+ - .gitignore
111
+ - COPYING
112
+ - Gemfile
113
+ - History.txt
114
+ - Manifest.txt
115
+ - PostInstall.txt
116
+ - README.rdoc
117
+ - Rakefile
118
+ - bin/pivotalprinter
119
+ - images/bug.png
120
+ - images/chore.png
121
+ - images/feature.png
122
+ - images/release.png
123
+ - lib/pivotalprinter.rb
124
+ - lib/pivotalprinter/client.rb
125
+ - lib/pivotalprinter/iteration.rb
126
+ - lib/pivotalprinter/story.rb
127
+ - lib/pivotalprinter/version.rb
128
+ - pivotalprinter.gemspec
129
+ - script/console
130
+ - script/destroy
131
+ - script/generate
132
+ - test/test_helper.rb
133
+ - test/test_pivotalprinter.rb
134
+ homepage: http://pkw.de
135
+ licenses: []
136
+
137
+ post_install_message:
138
+ rdoc_options: []
139
+
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ hash: 3
148
+ segments:
149
+ - 0
150
+ version: "0"
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ requirements: []
161
+
162
+ rubyforge_project:
163
+ rubygems_version: 1.7.2
164
+ signing_key:
165
+ specification_version: 3
166
+ summary: Story printer for pivotaltracker
167
+ test_files:
168
+ - test/test_helper.rb
169
+ - test/test_pivotalprinter.rb