lrd-pivotal-tracker 0.5.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -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