taskmapper-lighthouse 0.9.0
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.
- data/.document +5 -0
- data/.travis.yml +4 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +58 -0
- data/LICENSE +22 -0
- data/README.md +54 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/lib/provider/comment.rb +85 -0
- data/lib/provider/lighthouse.rb +77 -0
- data/lib/provider/project.rb +28 -0
- data/lib/provider/ticket.rb +153 -0
- data/lib/taskmapper-lighthouse.rb +42 -0
- data/spec/comments_spec.rb +65 -0
- data/spec/fixtures/projects.json +1 -0
- data/spec/fixtures/projects/54448.json +1 -0
- data/spec/fixtures/projects/54448.xml +27 -0
- data/spec/fixtures/projects/create.json +1 -0
- data/spec/fixtures/projects/create.xml +26 -0
- data/spec/fixtures/tickets.json +1 -0
- data/spec/fixtures/tickets/2.json +1 -0
- data/spec/fixtures/tickets/2.xml +317 -0
- data/spec/fixtures/tickets/5.json +1 -0
- data/spec/fixtures/tickets/5.xml +78 -0
- data/spec/fixtures/tickets/create.json +1 -0
- data/spec/fixtures/tickets/create.xml +26 -0
- data/spec/projects_spec.rb +73 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/taskmapper-lighthouse_spec.rb +22 -0
- data/spec/tickets_spec.rb +74 -0
- data/taskmapper-lighthouse.gemspec +91 -0
- metadata +166 -0
data/.document
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
gem "taskmapper", "~> 0.8"
|
7
|
+
gem "xml-simple", "~> 1.1"
|
8
|
+
gem "addressable", "~> 2.2"
|
9
|
+
gem "lighthouse-api", "~> 2.0"
|
10
|
+
# Add dependencies to develop your gem here.
|
11
|
+
# Include everything needed to run rake, tests, features, etc.
|
12
|
+
group :development do
|
13
|
+
gem "rspec", "~> 2.8"
|
14
|
+
gem "jeweler", "~> 1.6"
|
15
|
+
gem "simplecov", "~> 0.5", :platforms => :ruby_19
|
16
|
+
gem "rcov", "~> 1.0", :platforms => :ruby_18
|
17
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (3.2.1)
|
5
|
+
activesupport (= 3.2.1)
|
6
|
+
builder (~> 3.0.0)
|
7
|
+
activeresource (3.2.1)
|
8
|
+
activemodel (= 3.2.1)
|
9
|
+
activesupport (= 3.2.1)
|
10
|
+
activesupport (3.2.1)
|
11
|
+
i18n (~> 0.6)
|
12
|
+
multi_json (~> 1.0)
|
13
|
+
addressable (2.2.7)
|
14
|
+
builder (3.0.0)
|
15
|
+
diff-lcs (1.1.3)
|
16
|
+
git (1.2.5)
|
17
|
+
hashie (1.2.0)
|
18
|
+
i18n (0.6.0)
|
19
|
+
jeweler (1.6.4)
|
20
|
+
bundler (~> 1.0)
|
21
|
+
git (>= 1.2.5)
|
22
|
+
rake
|
23
|
+
lighthouse-api (2.0)
|
24
|
+
activeresource (>= 3.0.0)
|
25
|
+
activesupport (>= 3.0.0)
|
26
|
+
multi_json (1.0.4)
|
27
|
+
rake (0.9.2.2)
|
28
|
+
rcov (1.0.0)
|
29
|
+
rspec (2.8.0)
|
30
|
+
rspec-core (~> 2.8.0)
|
31
|
+
rspec-expectations (~> 2.8.0)
|
32
|
+
rspec-mocks (~> 2.8.0)
|
33
|
+
rspec-core (2.8.0)
|
34
|
+
rspec-expectations (2.8.0)
|
35
|
+
diff-lcs (~> 1.1.2)
|
36
|
+
rspec-mocks (2.8.0)
|
37
|
+
simplecov (0.5.4)
|
38
|
+
multi_json (~> 1.0.3)
|
39
|
+
simplecov-html (~> 0.5.3)
|
40
|
+
simplecov-html (0.5.3)
|
41
|
+
taskmapper (0.8.0)
|
42
|
+
activeresource (~> 3.0)
|
43
|
+
activesupport (~> 3.0)
|
44
|
+
hashie (~> 1.2)
|
45
|
+
xml-simple (1.1.1)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
addressable (~> 2.2)
|
52
|
+
jeweler (~> 1.6)
|
53
|
+
lighthouse-api (~> 2.0)
|
54
|
+
rcov (~> 1.0)
|
55
|
+
rspec (~> 2.8)
|
56
|
+
simplecov (~> 0.5)
|
57
|
+
taskmapper (~> 0.8)
|
58
|
+
xml-simple (~> 1.1)
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009-2010 The Hybrid Group
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
NONE
|
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
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# taskmapper-lighthouse
|
2
|
+
|
3
|
+
This is a provider for [taskmapper](http://ticketrb.com). It provides interoperability with [Lighthouse](http://www.lighthouseapp.com/) through the taskmapper gem.
|
4
|
+
|
5
|
+
# Usage and Examples
|
6
|
+
|
7
|
+
First we have to instantiate a new taskmapper instance:
|
8
|
+
|
9
|
+
lighthouse = TaskMapper.new(:lighthouse, {:subdomain => "rails"})
|
10
|
+
lighthouse = TaskMapper.new(:lighthouse, {:username => "code", :password => "m4st3r!", :account => "taskmapper"})
|
11
|
+
lighthouse = TaskMapper.new(:lighthouse, {:token => "5ff546af3df4a3c02d3a719b0ff1c3fcc5351c97", :account => "lhdemo"})
|
12
|
+
|
13
|
+
The :account is the name of the account which should be the same as the subdomain used to access the account's projects. For you convenience, you can also pass in :subdomain in place of :account. If you pass in both, it'll use the :account value. If you do not pass in the token or both the username and password, it will only access public information for the account.
|
14
|
+
|
15
|
+
Tokens allow access to a specific project or account without having to give out your login credentials. It can be nullified if necessary. I highly suggest you use tokens. For more information, please see Lighthouse's FAQ [How do I get an API token?](http://help.lighthouseapp.com/faqs/api/how-do-i-get-an-api-token)
|
16
|
+
|
17
|
+
== Finding Projects
|
18
|
+
|
19
|
+
project = lighthouse.project['project_name']
|
20
|
+
project = lighthouse.project.find(:id => 505)
|
21
|
+
|
22
|
+
== Finding Tickets
|
23
|
+
|
24
|
+
tickets = project.tickets
|
25
|
+
|
26
|
+
|
27
|
+
## Requirements
|
28
|
+
|
29
|
+
* rubygems (obviously)
|
30
|
+
* taskmapper gem (latest version preferred)
|
31
|
+
* jeweler gem (only if you want to repackage and develop)
|
32
|
+
|
33
|
+
The taskmapper gem should automatically be installed during the installation of this gem if it is not already installed.
|
34
|
+
|
35
|
+
## Other Notes
|
36
|
+
|
37
|
+
Since this and the taskmapper gem is still primarily a work-in-progress, minor changes may be incompatible with previous versions. Please be careful about using and updating this gem in production.
|
38
|
+
|
39
|
+
If you see or find any issues, feel free to open up an issue report.
|
40
|
+
|
41
|
+
|
42
|
+
## Note on Patches/Pull Requests
|
43
|
+
|
44
|
+
* Fork the project.
|
45
|
+
* Make your feature addition or bug fix.
|
46
|
+
* Add tests for it. This is important so I don't break it in a
|
47
|
+
future version unintentionally.
|
48
|
+
* Commit, do not mess with rakefile, version, or history.
|
49
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
50
|
+
* Send me a pull request. Bonus points for topic branches.
|
51
|
+
|
52
|
+
## Copyright
|
53
|
+
|
54
|
+
Copyright (c) 2010 The Hybrid Group. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "taskmapper-lighthouse"
|
8
|
+
gem.summary = %Q{TaskMapper Provider for Lighthouse}
|
9
|
+
gem.description = %Q{Allows taskmapper to interact with Lighthouse's issue tracking system.}
|
10
|
+
gem.email = "hong.quach@abigfisch.com"
|
11
|
+
gem.homepage = "http://github.com/kiafaldorius/taskmapper-lighthouse"
|
12
|
+
gem.authors = ["Hong"]
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'rspec/core'
|
21
|
+
require 'rspec/core/rake_task'
|
22
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
23
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
27
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
28
|
+
spec.rcov = true
|
29
|
+
end
|
30
|
+
|
31
|
+
task :default => :spec
|
32
|
+
|
33
|
+
require 'rake/rdoctask'
|
34
|
+
Rake::RDocTask.new do |rdoc|
|
35
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
36
|
+
|
37
|
+
rdoc.rdoc_dir = 'rdoc'
|
38
|
+
rdoc.title = "taskmapper-kanbanpad#{version}"
|
39
|
+
rdoc.rdoc_files.include('README*')
|
40
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
41
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.9.0
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module TaskMapper::Provider
|
2
|
+
module Lighthouse
|
3
|
+
# The comment class for taskmapper-lighthouse
|
4
|
+
#
|
5
|
+
# Due to the way lighthouse handles tickets, comments aren't really comments, but
|
6
|
+
# versions of the ticket.
|
7
|
+
#
|
8
|
+
# * author => user_name (read-only)
|
9
|
+
# * body => description
|
10
|
+
# * id => position in the versions array (set by the initializer)
|
11
|
+
# * created_at
|
12
|
+
# * updated_at
|
13
|
+
# * ticket_id => number (read-only)
|
14
|
+
# * project_id => (set by the initializer)
|
15
|
+
class Comment < TaskMapper::Provider::Base::Comment
|
16
|
+
API = ::Lighthouse::Ticket
|
17
|
+
|
18
|
+
# A custom find_by_id
|
19
|
+
# The "comment" id is it's index in the versions array. An id of 0 therefore exists and
|
20
|
+
# should be the first ticket (original)
|
21
|
+
def self.find_by_id(project_id, ticket_id, id)
|
22
|
+
self.new API.find(ticket_id, :params => {:project_id => project_id}), id
|
23
|
+
end
|
24
|
+
|
25
|
+
# A custom find_by_attributes
|
26
|
+
#
|
27
|
+
def self.find_by_attributes(project_id, ticket_id, attributes = {})
|
28
|
+
result = self.search(project_id, ticket_id, attributes)
|
29
|
+
result[0].shift
|
30
|
+
result[0].collect do |comment|
|
31
|
+
self.new(result[1], index_of(result[1].versions, comment)) if !comment.body.blank?
|
32
|
+
end.compact
|
33
|
+
end
|
34
|
+
|
35
|
+
# The Array#index method doesn't work for the versions...
|
36
|
+
# because it seems they're all equal.
|
37
|
+
def self.index_of(versions, needle)
|
38
|
+
result = nil
|
39
|
+
versions.each_with_index do |version, index|
|
40
|
+
result = index if version.attributes == needle.attributes
|
41
|
+
end
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.create(*options)
|
46
|
+
attributes = options.first
|
47
|
+
ticket_id = attributes.delete(:ticket_id) || attributes.delete('ticket_id')
|
48
|
+
project_id = attributes.delete(:project_id) || attributes.delete('project_id')
|
49
|
+
ticket = self::API.find(ticket_id, :params => {:project_id => project_id})
|
50
|
+
attributes.each do |k, v|
|
51
|
+
ticket.send("#{k}=", v)
|
52
|
+
end
|
53
|
+
versions = ticket.attributes.delete('versions')
|
54
|
+
ticket.save
|
55
|
+
ticket.attributes['versions'] = versions
|
56
|
+
self.find_by_id project_id, ticket_id, ticket.versions.length
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(ticket, id)
|
60
|
+
@system_data ||= {}
|
61
|
+
return super(ticket) unless ticket.respond_to?('versions') and ticket.versions.respond_to?('[]')
|
62
|
+
@system_data[:ticket] = @system_data[:client] = ticket
|
63
|
+
@system_data[:version] = ticket.versions[id]
|
64
|
+
self.project_id = ticket.prefix_options[:project_id]
|
65
|
+
self.id = id
|
66
|
+
super(@system_data[:version].attributes)
|
67
|
+
end
|
68
|
+
|
69
|
+
# A custom searcher
|
70
|
+
#
|
71
|
+
# It returns a custom result because we need the original ticket to make a comment.
|
72
|
+
def self.search(project_id, ticket_id, options = {}, limit = 1000)
|
73
|
+
ticket = API.find(ticket_id, :params => {:project_id => project_id})
|
74
|
+
comments = ticket.versions
|
75
|
+
[search_by_attribute(comments, options, limit), ticket]
|
76
|
+
end
|
77
|
+
|
78
|
+
# The author's name
|
79
|
+
def author
|
80
|
+
user_name
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module TaskMapper::Provider
|
2
|
+
# This is the Lighthouse Provider for taskmapper
|
3
|
+
module Lighthouse
|
4
|
+
include TaskMapper::Provider::Base
|
5
|
+
PROJECT_API = ::Lighthouse::Project
|
6
|
+
TICKET_API = ::Lighthouse::Ticket
|
7
|
+
|
8
|
+
# This is for cases when you want to instantiate using TaskMapper::Provider::Lighthouse.new(auth)
|
9
|
+
def self.new(auth = {})
|
10
|
+
TaskMapper.new(:lighthouse, auth)
|
11
|
+
end
|
12
|
+
|
13
|
+
# The authorize and initializer for this provider
|
14
|
+
def authorize(auth = {})
|
15
|
+
@authentication ||= TaskMapper::Authenticator.new(auth)
|
16
|
+
auth = @authentication
|
17
|
+
if auth.account.nil? or (auth.token.nil? and (auth.username.nil? and auth.password.nil?))
|
18
|
+
raise "Please provide at least an account (subdomain) and token or username and password)"
|
19
|
+
end
|
20
|
+
::Lighthouse::Base.format = :json
|
21
|
+
::Lighthouse.account = auth.account || auth.subdomain
|
22
|
+
if auth.token
|
23
|
+
::Lighthouse.token = auth.token
|
24
|
+
elsif auth.username && auth.password
|
25
|
+
::Lighthouse.authenticate(auth.username, auth.password)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid?
|
30
|
+
begin
|
31
|
+
PROJECT_API.find(:first)
|
32
|
+
true
|
33
|
+
rescue
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# The projects
|
39
|
+
#
|
40
|
+
# We have to merge in the auth information because, due to the class-based authentication
|
41
|
+
# mechanism, if we don't reset the authorize information for every request, it would
|
42
|
+
# end up using whatever the previous instantiated object's account info is.
|
43
|
+
def projects(*options)
|
44
|
+
authorize
|
45
|
+
super(*options)
|
46
|
+
end
|
47
|
+
|
48
|
+
# The project
|
49
|
+
def project(*options)
|
50
|
+
authorize
|
51
|
+
super(*options)
|
52
|
+
end
|
53
|
+
|
54
|
+
# The tickets
|
55
|
+
#
|
56
|
+
# Due to the nature of lighthouse, we must have the project_id to pull tickets. You can
|
57
|
+
# pass in the id through this format:
|
58
|
+
#
|
59
|
+
# .tickets(22)
|
60
|
+
# .tickets(:project_id => 22)
|
61
|
+
#
|
62
|
+
# To conform to taskmapper's standard of returning all tickets on a call to this method
|
63
|
+
# without any parameters, if no parameters are passed, it will return all tickets for whatever
|
64
|
+
# the first project is.
|
65
|
+
def tickets(*options)
|
66
|
+
authorize
|
67
|
+
super(*options)
|
68
|
+
end
|
69
|
+
|
70
|
+
# the ticket
|
71
|
+
def ticket(*options)
|
72
|
+
authorize
|
73
|
+
super(*options)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module TaskMapper::Provider
|
2
|
+
module Lighthouse
|
3
|
+
# Project class for taskmapper-lighthouse
|
4
|
+
#
|
5
|
+
#
|
6
|
+
class Project < TaskMapper::Provider::Base::Project
|
7
|
+
attr_accessor :prefix_options
|
8
|
+
API = ::Lighthouse::Project
|
9
|
+
# Delete this project
|
10
|
+
def destroy
|
11
|
+
result = super
|
12
|
+
result.is_a?(Net::HTTPOK)
|
13
|
+
end
|
14
|
+
|
15
|
+
# copy from this.copy(that) copies that into this
|
16
|
+
def copy(project)
|
17
|
+
project.tickets.each do |ticket|
|
18
|
+
copy_ticket = self.ticket!(:title => ticket.title, :description => ticket.description)
|
19
|
+
ticket.comments.each do |comment|
|
20
|
+
copy_ticket.comment!(:body => comment.body)
|
21
|
+
sleep 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module TaskMapper::Provider
|
2
|
+
module Lighthouse
|
3
|
+
# Ticket class for taskmapper-lighthouse
|
4
|
+
#
|
5
|
+
# Due to the way Lighthouse stores tickets, we actually end up creating a new ticket version
|
6
|
+
# every time we edit tickets. Their api FAQ states these attributes as the only editable ones(?):
|
7
|
+
#
|
8
|
+
# * title
|
9
|
+
# * body - follows the same formatting rules.
|
10
|
+
# * state - Can be any one of these: new, open, resolved, hold, invalid. Optional, set to open by default for new tickets.
|
11
|
+
# * assigned-user-id - optional
|
12
|
+
# * milestone-id - optional
|
13
|
+
# * tag - space or comma delimited list of tags
|
14
|
+
#
|
15
|
+
# We had to remap things a bit since lighthouse doesn't name things as taskmapper specifies.
|
16
|
+
#
|
17
|
+
# * id => number (read-only)
|
18
|
+
# * status => state
|
19
|
+
# * resolution => ticket.latest_body
|
20
|
+
# * description => ticket.original_body (setting a new description creates a new body)
|
21
|
+
# * assignee => assigned_user_name (read-only)
|
22
|
+
# * requestor => creator_name (read-only)
|
23
|
+
# * project_id => prefix_options[:project_id]
|
24
|
+
# * priority
|
25
|
+
# * title
|
26
|
+
# * created_at
|
27
|
+
# * updated_at
|
28
|
+
|
29
|
+
class Ticket < TaskMapper::Provider::Base::Ticket
|
30
|
+
@@allowed_states = ['new', 'open', 'resolved', 'hold', 'invalid']
|
31
|
+
attr_accessor :prefix_options
|
32
|
+
API = ::Lighthouse::Ticket
|
33
|
+
|
34
|
+
# This is to get the ticket id
|
35
|
+
# We can't set ids, so there's no 'id=' method.
|
36
|
+
def id
|
37
|
+
@system_data[:client].number
|
38
|
+
end
|
39
|
+
|
40
|
+
# This is to get the status, mapped to state
|
41
|
+
def status
|
42
|
+
state
|
43
|
+
end
|
44
|
+
|
45
|
+
# This is to set the status, mapped to state
|
46
|
+
def status=(stat)
|
47
|
+
stat = state unless @@allowed_states.include?(stat)
|
48
|
+
self.state = stat
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get the resolution, mapped to latest_body
|
52
|
+
def resolution
|
53
|
+
self.latest_body
|
54
|
+
end
|
55
|
+
|
56
|
+
# Set the resolution...also sets state to resolved
|
57
|
+
def resolution=(res)
|
58
|
+
state = 'resolved'
|
59
|
+
self.body = res
|
60
|
+
end
|
61
|
+
|
62
|
+
# Get the description, mapped to original_body
|
63
|
+
def description
|
64
|
+
self.original_body
|
65
|
+
end
|
66
|
+
|
67
|
+
# Set the description, mapped to body, which actually does a comment
|
68
|
+
def description=(desc)
|
69
|
+
self.body = desc
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get the assigned person's name
|
73
|
+
def assignee
|
74
|
+
self.assigned_user_name
|
75
|
+
end
|
76
|
+
|
77
|
+
# Get the requestor's name
|
78
|
+
def requestor
|
79
|
+
self.creator_name
|
80
|
+
end
|
81
|
+
|
82
|
+
# Get the project id
|
83
|
+
def project_id
|
84
|
+
prefix_options[:project_id]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Set the body
|
88
|
+
def body=(bod)
|
89
|
+
@system_data[:client].body = nil
|
90
|
+
super(bod)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Tags, a little helper for the ticket tagging
|
94
|
+
def tags
|
95
|
+
return @tags if @tags
|
96
|
+
tagz = self.tag.split(/([\w\d]+)|"([\w \d]+)"/)
|
97
|
+
tagz.delete(' ')
|
98
|
+
tagz.delete('')
|
99
|
+
@tags = tagz
|
100
|
+
end
|
101
|
+
|
102
|
+
# Gotta unset the body attribute...otherwise every save ends up using that body
|
103
|
+
def save
|
104
|
+
# self.tag = @tags.reduce([]) do |mem, t|
|
105
|
+
# t = "\"#{t}\"" if t.include?(' ')
|
106
|
+
# mem << t
|
107
|
+
# end.join(' ') if @tags
|
108
|
+
@system_data[:client].attributes.delete('versions')
|
109
|
+
result = super
|
110
|
+
body = nil
|
111
|
+
@system_data[:client].body = nil
|
112
|
+
result
|
113
|
+
end
|
114
|
+
|
115
|
+
# The closer
|
116
|
+
def close(resolution = 'resolved')
|
117
|
+
resolution = 'resolved' unless @@allowed_states.include?(resolution)
|
118
|
+
ticket = ::Lighthouse::Ticket.find(self.id, :params => {:project_id => self.prefix_options[:project_id]})
|
119
|
+
ticket.state = resolution
|
120
|
+
ticket.save
|
121
|
+
end
|
122
|
+
|
123
|
+
class << self
|
124
|
+
|
125
|
+
def create(options)
|
126
|
+
super translate options,
|
127
|
+
:description => :body,
|
128
|
+
:status => :state,
|
129
|
+
:assignee => :assigned_user_id
|
130
|
+
end
|
131
|
+
|
132
|
+
# Lighthouse limits us to a 100 ticket limit per page...
|
133
|
+
# Since the paging sucks...we probably want to store this rather than do a call each time
|
134
|
+
def search(project_id, options = {}, limit = 1000)
|
135
|
+
page = 1
|
136
|
+
tickets = ::Lighthouse::Ticket.find(:all, :params => {:project_id => project_id, :limit => 100, :page => page})
|
137
|
+
result = []
|
138
|
+
while tickets.length > 0 and page <= 3 #limit to page 3 since lighthouse is so slow...
|
139
|
+
result += tickets.collect { |ticket| self.new ticket }
|
140
|
+
page += 1
|
141
|
+
tickets = ::Lighthouse::Ticket.find(:all, :params => {:project_id => project_id, :limit => 100, :page => page})
|
142
|
+
end
|
143
|
+
search_by_attribute(result, options, limit)
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
def translate(hash, mapping)
|
148
|
+
Hash[hash.map { |k, v| [mapping[k] ||= k, v]}]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|