lrd-pivotal-tracker 0.5.14

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4f675f418e736a47d94ed4b17e7287199703f3d1
4
+ data.tar.gz: f4cf28bb95fae0a1703504a4c28fa640894a7ed7
5
+ SHA512:
6
+ metadata.gz: b252a7d31d5f589a563c22e18db527cb23c3be615b3f675f6a278048023f7b35745b977cd0966ed8a53228849fe0a5ad34327cfe9eac7393484d45373a3027c1
7
+ data.tar.gz: cb21073ac4d5347f5b2cca5299dc785fecab1542d1a13388fe1dc7ef8443da97121ffbc93699283fc028fce662fece0dad8d93051c539d28dc9986110276c202
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'corundum'
4
+ gem 'rspec'
5
+ gem 'rake'
6
+ gem 'jeweler'
7
+ gem 'vcr'
8
+ gem 'fakeweb'
9
+
10
+ gemspec :name => "lrd-pivotal-tracker"
@@ -0,0 +1,94 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lrd-pivotal-tracker (0.5.14)
5
+ builder
6
+ crack
7
+ happymapper (>= 0.3.2)
8
+ nokogiri (>= 1.5.5)
9
+ nokogiri-happymapper (>= 0.5.4)
10
+ rest-client (~> 1.6.0)
11
+
12
+ GEM
13
+ remote: http://rubygems.org/
14
+ specs:
15
+ builder (3.2.2)
16
+ calibrate (0.0.1)
17
+ caliph (0.3.1)
18
+ corundum (0.6.0)
19
+ bundler
20
+ caliph (~> 0.3)
21
+ mattock (~> 0.9)
22
+ paint (~> 0.8.7)
23
+ rspec (>= 2.0)
24
+ simplecov (>= 0.5.4)
25
+ simplecov-json (>= 0.2)
26
+ crack (0.4.2)
27
+ safe_yaml (~> 1.0.0)
28
+ diff-lcs (1.1.3)
29
+ docile (1.1.5)
30
+ fakeweb (1.3.0)
31
+ git (1.2.5)
32
+ happymapper (0.4.1)
33
+ libxml-ruby (~> 2.0)
34
+ jeweler (1.8.4)
35
+ bundler (~> 1.0)
36
+ git (>= 1.2.5)
37
+ rake
38
+ rdoc
39
+ json (1.7.5)
40
+ libxml-ruby (2.8.0)
41
+ mattock (0.10.0)
42
+ calibrate (~> 0.0.1)
43
+ caliph (~> 0.3.1)
44
+ rake (~> 10.0)
45
+ tilt (> 0)
46
+ valise (~> 1.1.1)
47
+ mime-types (1.25.1)
48
+ mini_portile (0.6.2)
49
+ multi_json (1.11.2)
50
+ nokogiri (1.6.6.2)
51
+ mini_portile (~> 0.6.0)
52
+ nokogiri-happymapper (0.5.9)
53
+ nokogiri (~> 1.5)
54
+ paint (0.8.7)
55
+ rake (10.0.2)
56
+ rdoc (3.12)
57
+ json (~> 1.4)
58
+ rest-client (1.6.9)
59
+ mime-types (~> 1.16)
60
+ rspec (2.12.0)
61
+ rspec-core (~> 2.12.0)
62
+ rspec-expectations (~> 2.12.0)
63
+ rspec-mocks (~> 2.12.0)
64
+ rspec-core (2.12.0)
65
+ rspec-expectations (2.12.0)
66
+ diff-lcs (~> 1.1.3)
67
+ rspec-mocks (2.12.0)
68
+ safe_yaml (1.0.4)
69
+ simplecov (0.9.2)
70
+ docile (~> 1.1.0)
71
+ multi_json (~> 1.0)
72
+ simplecov-html (~> 0.9.0)
73
+ simplecov-html (0.9.0)
74
+ simplecov-json (0.2)
75
+ json
76
+ simplecov
77
+ tilt (2.0.1)
78
+ valise (1.1.4)
79
+ vcr (2.5.0)
80
+
81
+ PLATFORMS
82
+ ruby
83
+
84
+ DEPENDENCIES
85
+ corundum
86
+ fakeweb
87
+ jeweler
88
+ lrd-pivotal-tracker!
89
+ rake
90
+ rspec
91
+ vcr
92
+
93
+ BUNDLED WITH
94
+ 1.10.6
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 Justin Smestad
2
+ Copyright (c) 2015 Hannah Howard, Judson Lester
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,82 @@
1
+ = pivotal-tracker.rb
2
+
3
+ Ruby wrapper for Pivotal Tracker API, no frameworks required. Simply Ruby.
4
+
5
+ {<img src="https://secure.travis-ci.org/jsmestad/pivotal-tracker.png" />}[http://travis-ci.org/jsmestad/pivotal-tracker]
6
+ {<img src="https://badge.fury.io/rb/pivotal-tracker.png" alt="Gem Version" />}[http://rubygems.org/gems/pivotal-tracker]
7
+
8
+ == Features
9
+
10
+ * Compatible with Pivotal Tracker API version 3
11
+ * ActiveRecord-style Wrapper API
12
+ * Support for SSL protected repositories
13
+
14
+ == Overview
15
+
16
+ PivotalTracker::Client.token('myusername@email.com', 'secretpassword') # Automatically fetch API Token
17
+ PivotalTracker::Client.token = 'jkfduisj97823974j2kl24899234' # Manually set API Token
18
+
19
+ @projects = PivotalTracker::Project.all # return all projects
20
+ @a_project = PivotalTracker::Project.find(84739) # find project with a given ID
21
+
22
+ @a_project.stories.all # return all stories for "a_project"
23
+ @a_project.stories.all(:label => 'overdue', :story_type => ['bug', 'chore']) # return all stories that match the passed filters
24
+ @a_project.stories.find(847762630) # find story with a given ID
25
+
26
+ @a_project.stories.create(:name => 'My Story', :story_type => 'feature') # create a story for this project
27
+
28
+ # all tracker defined filters are allowed, as well as :limit & :offset for pagination
29
+
30
+ # The below pattern below is planned to be added to the final release:
31
+
32
+ @a_project.stories << PivotalTracker::Story.new(84739, :name => 'Ur Story') # same as earlier story creation, useful for copying/cloning from proj
33
+
34
+
35
+ @story = @a_project.stories.find(847762630)
36
+ @story.notes.all # return all notes (comments) for a story
37
+ @story.notes.create(:text => 'A new comment', :noted_at => '06/29/2010 05:00 EST') # add a new note
38
+
39
+
40
+ @story.attachments # return an array of all attachment items (data only, not the files)
41
+ @story.upload_attachment(file_path) # add a file attachment to @story that can be found at file_path
42
+
43
+
44
+ # All 4 examples below return a PivotalTracker::Story from the new project, with the same story ID
45
+
46
+ @story.move_to_project(123456) # move @story to the project with ID 123456
47
+ @story.move_to_project('123456') # same as above
48
+ @story.move_to_project(@project) # move @story to @project
49
+ @story.move_to_project(@another_story) # move @story into the same project as @another_story
50
+
51
+
52
+ # Connect to custom API endpoint
53
+ PivotalTracker::Client.tracker_host = 'www.my-pivotal-tracker.com'
54
+
55
+ The API is based on the following this gist: http://gist.github.com/283120
56
+
57
+ == Getting Started
58
+
59
+ * Installing:
60
+
61
+ $ gem install pivotal-tracker
62
+
63
+ * Contributing (requires Bundler >= 0.9.7):
64
+
65
+ $ git clone git://github.com/jsmestad/pivotal-tracker
66
+ $ cd pivotal-tracker
67
+ $ bundle install
68
+ $ bundle exec rake
69
+
70
+ == Additional Information
71
+
72
+ * Wiki: http://wiki.github.com/jsmestad/pivotal-tracker
73
+ * Documentation: http://rdoc.info/projects/jsmestad/pivotal-tracker
74
+ * Pivotal API v3 Docs: http://www.pivotaltracker.com/help/api?version=v3
75
+
76
+ == Contributors along the way
77
+
78
+ * Justin Smestad (http://github.com/jsmestad)
79
+ * Josh Nichols (http://github.com/technicalpickles)
80
+ * Terence Lee (http://github.com/hone)
81
+ * Jon Mischo (http://github.com/supertaz)
82
+ * Gabor Ratky (http://github.com/rgabo)
@@ -0,0 +1,42 @@
1
+ require 'corundum/tasklibs'
2
+
3
+ module Corundum
4
+ Corundum::register_project(__FILE__)
5
+
6
+ core = Core.new
7
+
8
+ core.in_namespace do
9
+ GemspecFiles.new(core)
10
+
11
+ ["debug", "profanity", "ableism", "racism"].each do |type|
12
+ QuestionableContent.new(core) do |content|
13
+ content.type = type
14
+ end
15
+ end
16
+
17
+ rspec = RSpec.new(core)
18
+
19
+ SimpleCov.new(core, rspec) do |cov|
20
+ cov.threshold = 90
21
+ end
22
+
23
+ gem = GemBuilding.new(core)
24
+
25
+ GemCutter.new(core,gem)
26
+
27
+ Git.new(core) do |vc|
28
+ vc.branch = "master"
29
+ end
30
+ end
31
+ end
32
+
33
+ task :default => [:release]
34
+
35
+ begin
36
+ require 'yard'
37
+ YARD::Rake::YardocTask.new
38
+ rescue LoadError
39
+ task :yardoc do
40
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
41
+ end
42
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.11
@@ -0,0 +1,49 @@
1
+ require 'cgi'
2
+ require 'rest_client'
3
+ require 'happymapper'
4
+ require 'nokogiri'
5
+
6
+ HappyMapper::SupportedTypes.types.unshift(HappyMapper::SupportedTypes::CastWhenType.new (DateTime) { |value|
7
+ begin
8
+ DateTime.parse(value,&:to_s)
9
+ rescue TypeError, ArgumentError => ex
10
+ nil
11
+ end
12
+ })
13
+
14
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'validation')
15
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'extensions')
16
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'proxy')
17
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'client')
18
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'project')
19
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'attachment')
20
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'story')
21
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'task')
22
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'author')
23
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'membership')
24
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'activity')
25
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'iteration')
26
+ require File.join(File.dirname(__FILE__), 'pivotal-tracker', 'note')
27
+
28
+
29
+ module PivotalTracker
30
+
31
+ # define error types
32
+ class ProjectNotSpecified < StandardError; end
33
+
34
+ def self.encode_options(options)
35
+ options_strings = options.inject({}) do |m, (k,v)|
36
+ if [:limit, :offset].include?(k.to_sym)
37
+ m.update k => v
38
+ elsif k.to_sym == :search
39
+ m.update :filter => v
40
+ else
41
+ filter_query = %{#{k}:#{[v].flatten.join(",")}}
42
+ m.update :filter => (m[:filter] ? "#{m[:filter]} #{filter_query}" : filter_query)
43
+ end
44
+ end.map {|k,v| "#{k}=#{CGI.escape(v.to_s)}"}
45
+
46
+ %{?#{options_strings.join("&")}} unless options_strings.empty?
47
+ end
48
+
49
+ end
@@ -0,0 +1,68 @@
1
+ module PivotalTracker
2
+ class Activity
3
+ include HappyMapper
4
+ class << self
5
+
6
+ MAX_PIVOTAL_ACTIVITY = 100
7
+
8
+ def all(project=nil, options={})
9
+ options[:limit] ||= MAX_PIVOTAL_ACTIVITY
10
+ per_page = options[:limit]
11
+ auto_page = options[:auto_page]
12
+
13
+ params = self.encode_options(options)
14
+
15
+ if project
16
+ if auto_page && Client.api_version >= 4
17
+ page_through_activities(project, params, per_page)
18
+ else
19
+ parse(Client.connection["/projects/#{project.id}/activities#{params}"].get)
20
+ end
21
+ else
22
+ parse(Client.connection["/activities#{params}"].get)
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ def encode_options(options)
29
+ return nil if !options.is_a?(Hash) || options.empty?
30
+
31
+ options_string = []
32
+ options_string << "limit=#{options.delete(:limit)}"
33
+ options_string << "newer_than_version=#{options.delete(:newer_than_version)}" if options[:newer_than_version]
34
+
35
+ if options[:occurred_since]
36
+ options_string << "occurred_since_date=\"#{options[:occurred_since].utc}\""
37
+ elsif options[:occurred_since_date]
38
+ options_string << "occurred_since_date=#{URI.escape options[:occurred_since_date].strftime("%Y/%m/%d %H:%M:%S %Z")}"
39
+ end
40
+
41
+ return "?#{options_string.join('&')}"
42
+ end
43
+
44
+ def page_through_activities(project, params, per_page)
45
+ collections = []
46
+ page = 1
47
+ begin
48
+ collections << parse(Client.connection["/projects/#{project.id}/activities#{params}&page=#{page}"].get)
49
+ returned = collections.last.size
50
+ page += 1
51
+ end while returned == per_page
52
+ collections.flatten
53
+ end
54
+
55
+ end
56
+
57
+ element :id, Integer
58
+ element :version, Integer
59
+ element :event_type, String
60
+ element :occurred_at, DateTime
61
+ has_one :author, Author
62
+ element :project_id, Integer
63
+ element :description, String
64
+
65
+ has_many :stories, Story, :tag => "story"
66
+
67
+ end
68
+ end
@@ -0,0 +1,16 @@
1
+ module PivotalTracker
2
+ class Attachment
3
+ include HappyMapper
4
+
5
+ tag 'attachment'
6
+
7
+ element :id, Integer
8
+ element :filename, String
9
+ element :description, String
10
+ element :uploaded_by, String
11
+ element :uploaded_at, DateTime
12
+ element :url, String
13
+ element :status, String
14
+
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module PivotalTracker
2
+ class Person
3
+ include HappyMapper
4
+ element :id, Integer
5
+ element :email, String
6
+ element :name, String
7
+ element :initials, String
8
+ end
9
+
10
+ class Author
11
+ include HappyMapper
12
+ has_one :person, Person
13
+ end
14
+
15
+
16
+ end
@@ -0,0 +1,84 @@
1
+ module PivotalTracker
2
+
3
+ class Client
4
+
5
+ class NoToken < StandardError; end
6
+
7
+ class << self
8
+ attr_writer :use_ssl, :token, :tracker_host, :api_version
9
+ def use_ssl
10
+ @use_ssl || false
11
+ end
12
+
13
+ def token(username, password, method='post')
14
+ response = if method == 'post'
15
+ RestClient.post api_ssl_url + '/tokens/active', :username => username, :password => password
16
+ else
17
+ RestClient.get "#{api_ssl_url(username, password)}/tokens/active"
18
+ end
19
+ @token= Nokogiri::XML(response.body).search('guid').inner_html
20
+ end
21
+
22
+ # this is your connection for the entire module
23
+ def connection(options={})
24
+ raise NoToken if @token.to_s.empty?
25
+
26
+ @connections ||= {}
27
+
28
+ cached_connection? && !protocol_changed? ? cached_connection : new_connection
29
+ end
30
+
31
+ def clear_connections
32
+ @connections = nil
33
+ end
34
+
35
+ def tracker_host
36
+ @tracker_host ||= "www.pivotaltracker.com"
37
+ end
38
+
39
+ def api_ssl_url(user=nil, password=nil)
40
+ user_password = (user && password) ? "#{user}:#{password}@" : ''
41
+ "https://#{user_password}#{tracker_host}#{api_path}"
42
+ end
43
+
44
+ def api_url
45
+ "http://#{tracker_host}#{api_path}"
46
+ end
47
+
48
+ def api_version
49
+ @api_version ||= 3
50
+ end
51
+
52
+ protected
53
+
54
+ def protocol
55
+ use_ssl ? 'https' : 'http'
56
+ end
57
+
58
+ def cached_connection?
59
+ !@connections[@token].nil?
60
+ end
61
+
62
+ def cached_connection
63
+ @connections[@token]
64
+ end
65
+
66
+ def new_connection
67
+ @connections[@token] = RestClient::Resource.new("#{use_ssl ? api_ssl_url : api_url}", :headers => {'X-TrackerToken' => @token, 'Content-Type' => 'application/xml'})
68
+ end
69
+
70
+ def protocol_changed?
71
+ cached_connection? ? (cached_connection_protocol != protocol) : false
72
+ end
73
+
74
+ def cached_connection_protocol
75
+ cached_connection.url.match(/^(.*):\/\//).captures.first
76
+ end
77
+
78
+ def api_path
79
+ '/services/v' + api_version.to_s
80
+ end
81
+ end
82
+
83
+ end
84
+ end