mingle4r 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README +53 -20
- data/TODO.txt +8 -4
- data/lib/mingle4r.rb +9 -23
- data/lib/mingle4r/api/card.rb +137 -0
- data/lib/mingle4r/api/card/attachment.rb +47 -0
- data/lib/mingle4r/api/card/comment.rb +12 -0
- data/lib/mingle4r/api/card/transition.rb +48 -0
- data/lib/mingle4r/api/murmur.rb +12 -0
- data/lib/mingle4r/api/project.rb +64 -0
- data/lib/mingle4r/api/property_definition.rb +7 -0
- data/lib/mingle4r/api/user.rb +7 -0
- data/lib/mingle4r/api/wiki.rb +10 -0
- data/lib/mingle4r/common_class_methods.rb +0 -1
- data/lib/mingle4r/mingle_client.rb +16 -14
- data/lib/mingle4r/version.rb +1 -1
- metadata +11 -22
- data/lib/mingle4r/api.rb +0 -31
- data/lib/mingle4r/api/v1.rb +0 -25
- data/lib/mingle4r/api/v1/card.rb +0 -173
- data/lib/mingle4r/api/v1/card/attachment.rb +0 -51
- data/lib/mingle4r/api/v1/project.rb +0 -71
- data/lib/mingle4r/api/v1/property_definition.rb +0 -16
- data/lib/mingle4r/api/v1/transition_execution.rb +0 -15
- data/lib/mingle4r/api/v1/user.rb +0 -9
- data/lib/mingle4r/api/v1/wiki.rb +0 -12
- data/lib/mingle4r/api/v2.rb +0 -25
- data/lib/mingle4r/api/v2/card.rb +0 -157
- data/lib/mingle4r/api/v2/card/attachment.rb +0 -51
- data/lib/mingle4r/api/v2/card/comment.rb +0 -16
- data/lib/mingle4r/api/v2/card/transition.rb +0 -52
- data/lib/mingle4r/api/v2/murmur.rb +0 -14
- data/lib/mingle4r/api/v2/project.rb +0 -90
- data/lib/mingle4r/api/v2/property_definition.rb +0 -14
- data/lib/mingle4r/api/v2/user.rb +0 -9
- data/lib/mingle4r/api/v2/wiki.rb +0 -12
- data/lib/mingle4r/common_dyn_class_instance_methods.rb +0 -5
@@ -0,0 +1,64 @@
|
|
1
|
+
module Mingle4r
|
2
|
+
module API
|
3
|
+
class Project
|
4
|
+
module InstanceMethods
|
5
|
+
# returns the cards for the project. To hit the resource server without returning
|
6
|
+
# cached results pass true as an argument.
|
7
|
+
def cards(refresh = false)
|
8
|
+
return @cards if(!refresh && @cards)
|
9
|
+
set_attributes_for(Card)
|
10
|
+
@cards = Card.find_without_pagination(:all)
|
11
|
+
end
|
12
|
+
|
13
|
+
# returns the users for the project. To hit the resource server without returning
|
14
|
+
# cached results pass true as an argument.
|
15
|
+
def users(refresh = false)
|
16
|
+
return @users if(!refresh && @users)
|
17
|
+
set_attributes_for(User)
|
18
|
+
@users = User.find(:all)
|
19
|
+
end
|
20
|
+
|
21
|
+
# returns the wikis for the project. To hit the resource server without returning
|
22
|
+
# cached results pass true as an argument.
|
23
|
+
def wikis(refresh = false)
|
24
|
+
return @wikis if(!refresh && @wikis)
|
25
|
+
set_attributes_for(Wiki)
|
26
|
+
@wikis = Wiki.find(:all)
|
27
|
+
end
|
28
|
+
|
29
|
+
# returns the property definitions for the project. To hit the resource server
|
30
|
+
# pass true as an argument
|
31
|
+
def property_definitions(refresh = false)
|
32
|
+
return @prop_definitions if(!refresh && @prop_definitions)
|
33
|
+
set_attributes_for(PropertyDefinition)
|
34
|
+
@prop_definitions = PropertyDefinition.find(:all)
|
35
|
+
end
|
36
|
+
|
37
|
+
# returns the murmurs for the project. To hit the resource server without returning
|
38
|
+
# cached results pass true as an argument.
|
39
|
+
def murmurs(refresh = false)
|
40
|
+
return @murmurs if(!refresh && @murmurs)
|
41
|
+
set_attributes_for(Murmur)
|
42
|
+
@murmurs = Murmur.find(:all)
|
43
|
+
end
|
44
|
+
|
45
|
+
# posts a murmur
|
46
|
+
def post_murmur(str)
|
47
|
+
set_attributes_for(Murmur)
|
48
|
+
murmur = Murmur.new(:body => str.to_s)
|
49
|
+
murmur.save
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def set_attributes_for(klass)
|
54
|
+
resource_site = File.join(self.class.site.to_s, "projects/#{self.identifier}")
|
55
|
+
klass.site = resource_site
|
56
|
+
klass.user = self.class.user
|
57
|
+
klass.password = self.class.password
|
58
|
+
end
|
59
|
+
end # module InstanceMethods
|
60
|
+
|
61
|
+
extend Mingle4r::CommonClassMethods
|
62
|
+
end # class Project
|
63
|
+
end # class API
|
64
|
+
end
|
@@ -189,7 +189,6 @@ module Mingle4r
|
|
189
189
|
# if it is defined inside the wrapper class
|
190
190
|
inst_meth_mod_name = instance_methods_module_name()
|
191
191
|
created_class.send(:include, self.const_get(inst_meth_mod_name.to_sym)) if inst_meth_mod_name
|
192
|
-
created_class.send(:include, Mingle4r::CommonDynClassInstanceMethods)
|
193
192
|
|
194
193
|
# extends the class created dynamically with a module called ClassMethods if
|
195
194
|
# it is defined inside the wrapper class
|
@@ -3,7 +3,7 @@ module Mingle4r
|
|
3
3
|
attr_reader :site, :user, :password, :proj_id
|
4
4
|
|
5
5
|
def initialize(site, user, password, proj_id = nil)
|
6
|
-
@site = site
|
6
|
+
@site = site.to_s
|
7
7
|
@user = user
|
8
8
|
@password = password
|
9
9
|
@proj_id = proj_id
|
@@ -46,44 +46,46 @@ module Mingle4r
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def valid_credentials?
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
project_class.password = password
|
49
|
+
API::Project.site = base_url
|
50
|
+
API::Project.user = user
|
51
|
+
API::Project.password = password
|
53
52
|
begin
|
54
|
-
|
53
|
+
API::Project.find(:all)
|
55
54
|
true
|
56
55
|
rescue Exception => e
|
57
|
-
|
56
|
+
false
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
60
|
def project
|
62
61
|
raise 'proj_id attribute not set' unless @proj_id
|
63
|
-
@project =
|
62
|
+
@project = API::Project.find(@proj_id) unless(@project && (@proj_id == @project.identifier))
|
64
63
|
@project
|
65
64
|
end
|
66
65
|
|
67
66
|
def projects
|
68
|
-
|
67
|
+
API::Project.find(:all)
|
69
68
|
end
|
70
69
|
|
71
70
|
def users
|
72
|
-
|
71
|
+
API::User.find(:all)
|
73
72
|
end
|
74
73
|
|
75
74
|
private
|
76
75
|
def set_resource_attributes
|
77
|
-
|
78
|
-
set_attributes(
|
79
|
-
set_attributes(@api.user_class)
|
76
|
+
set_attributes(API::Project)
|
77
|
+
set_attributes(API::User)
|
80
78
|
end
|
81
79
|
|
82
80
|
def set_attributes(klass)
|
83
|
-
klass.site =
|
81
|
+
klass.site = base_url
|
84
82
|
klass.user = @user
|
85
83
|
klass.password = @password
|
86
84
|
end
|
85
|
+
|
86
|
+
def base_url
|
87
|
+
File.join(@site.to_s, '/api/v2/')
|
88
|
+
end
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
data/lib/mingle4r/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mingle4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- asur
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-02-02 00:00:00 +05:30
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -33,30 +33,19 @@ extra_rdoc_files:
|
|
33
33
|
files:
|
34
34
|
- lib/mingle4r.rb
|
35
35
|
- lib/mingle_resource.rb
|
36
|
-
- lib/mingle4r/api.rb
|
37
36
|
- lib/mingle4r/common_class_methods.rb
|
38
|
-
- lib/mingle4r/common_dyn_class_instance_methods.rb
|
39
37
|
- lib/mingle4r/helpers.rb
|
40
38
|
- lib/mingle4r/mingle_client.rb
|
41
39
|
- lib/mingle4r/version.rb
|
42
|
-
- lib/mingle4r/api/
|
43
|
-
- lib/mingle4r/api/
|
44
|
-
- lib/mingle4r/api/
|
45
|
-
- lib/mingle4r/api/
|
46
|
-
- lib/mingle4r/api/
|
47
|
-
- lib/mingle4r/api/
|
48
|
-
- lib/mingle4r/api/
|
49
|
-
- lib/mingle4r/api/
|
50
|
-
- lib/mingle4r/api/
|
51
|
-
- lib/mingle4r/api/v2/card.rb
|
52
|
-
- lib/mingle4r/api/v2/card/attachment.rb
|
53
|
-
- lib/mingle4r/api/v2/card/comment.rb
|
54
|
-
- lib/mingle4r/api/v2/card/transition.rb
|
55
|
-
- lib/mingle4r/api/v2/murmur.rb
|
56
|
-
- lib/mingle4r/api/v2/project.rb
|
57
|
-
- lib/mingle4r/api/v2/property_definition.rb
|
58
|
-
- lib/mingle4r/api/v2/user.rb
|
59
|
-
- lib/mingle4r/api/v2/wiki.rb
|
40
|
+
- lib/mingle4r/api/card.rb
|
41
|
+
- lib/mingle4r/api/card/attachment.rb
|
42
|
+
- lib/mingle4r/api/card/comment.rb
|
43
|
+
- lib/mingle4r/api/card/transition.rb
|
44
|
+
- lib/mingle4r/api/murmur.rb
|
45
|
+
- lib/mingle4r/api/project.rb
|
46
|
+
- lib/mingle4r/api/property_definition.rb
|
47
|
+
- lib/mingle4r/api/user.rb
|
48
|
+
- lib/mingle4r/api/wiki.rb
|
60
49
|
- MIT-LICENSE
|
61
50
|
- History.txt
|
62
51
|
- README
|
data/lib/mingle4r/api.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
require 'net/https'
|
3
|
-
|
4
|
-
module Mingle4r
|
5
|
-
class API
|
6
|
-
class << self
|
7
|
-
def create(url)
|
8
|
-
@host_uri = URI.parse(url)
|
9
|
-
api_ver = mingle_version.to_i - 1
|
10
|
-
class_name = 'V' + api_ver.to_s
|
11
|
-
ver_class = send(:const_get, class_name.to_sym)
|
12
|
-
ver_class.new(url)
|
13
|
-
end
|
14
|
-
|
15
|
-
def mingle_version
|
16
|
-
html = mingle_about_page
|
17
|
-
match = html.match('<dd>Version</dd>\n.*<dt>([_\d]*)</dt>')
|
18
|
-
raise Exception, 'Not a proper mingle instance' unless match
|
19
|
-
@mingle_version = match[1].gsub('_','.').to_f
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
def mingle_about_page
|
24
|
-
http = Net::HTTP.new(@host_uri.host, @host_uri.port)
|
25
|
-
http.use_ssl = true if @host_uri.is_a?(URI::HTTPS)
|
26
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
|
27
|
-
http.get('/about').body
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end # class API
|
31
|
-
end
|
data/lib/mingle4r/api/v1.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V1
|
4
|
-
def initialize(host_url)
|
5
|
-
@host_uri = URI.parse(host_url)
|
6
|
-
end
|
7
|
-
|
8
|
-
def base_url
|
9
|
-
@host_uri.to_s
|
10
|
-
end
|
11
|
-
|
12
|
-
def version
|
13
|
-
1
|
14
|
-
end
|
15
|
-
|
16
|
-
def project_class
|
17
|
-
Project
|
18
|
-
end
|
19
|
-
|
20
|
-
def user_class
|
21
|
-
User
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/mingle4r/api/v1/card.rb
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V1
|
4
|
-
class Card
|
5
|
-
extend Mingle4r::CommonClassMethods
|
6
|
-
|
7
|
-
# overwrite the default find in CommonClassMethods
|
8
|
-
def self.find(*args)
|
9
|
-
scope = args.slice!(0)
|
10
|
-
options = args.slice!(0) || {}
|
11
|
-
@resource_class.find_without_pagination(scope, options)
|
12
|
-
end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
def find_without_pagination(*args)
|
16
|
-
scope = args.slice!(0)
|
17
|
-
options = args.slice!(0) || {}
|
18
|
-
options[:params] ||= {}
|
19
|
-
options[:params].merge!({:page => 'all'})
|
20
|
-
|
21
|
-
# call ActiveResource::Base::find with proper options
|
22
|
-
find(scope, options)
|
23
|
-
end
|
24
|
-
|
25
|
-
# applies an mql filter on card types. Look at https://mingle05.thoughtworks.com/help/mql_reference.html
|
26
|
-
# for reference
|
27
|
-
def apply_filter(filter_string)
|
28
|
-
find_without_pagination(:all, :params => {'filters[mql]'.to_sym => filter_string})
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
module InstanceMethods
|
33
|
-
def attachments(refresh = false)
|
34
|
-
return @attachments if(!refresh && @attachments_cached)
|
35
|
-
attachment_site = File.join(self.class.site.to_s, "cards/#{self.number()}").to_s
|
36
|
-
Attachment.site = attachment_site
|
37
|
-
Attachment.user = self.class.user
|
38
|
-
Attachment.password = self.class.password
|
39
|
-
attachment_class = Attachment.send(:create_resource_class)
|
40
|
-
@attachments = attachment_class.find(:all)
|
41
|
-
@attachments_cached = true
|
42
|
-
@attachments
|
43
|
-
end
|
44
|
-
|
45
|
-
def upload_attachment(file_path)
|
46
|
-
attachment_uri = URI.parse(File.join(self.class.site.to_s, "cards/#{self.number()}/attachments.xml"))
|
47
|
-
http = Net::HTTP.new(attachment_uri.host, attachment_uri.port)
|
48
|
-
http.use_ssl = attachment_uri.is_a?(URI::HTTPS)
|
49
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
|
50
|
-
basic_encode = 'Basic ' + ["#{self.class.user}:#{self.class.password}"].pack('m').delete("\r\n")
|
51
|
-
|
52
|
-
post_headers = {
|
53
|
-
'Authorization' => basic_encode,
|
54
|
-
'Content-Type' => 'multipart/form-data; boundary=----------XnJLe9ZIbbGUYtzPQJ16u1'
|
55
|
-
}
|
56
|
-
|
57
|
-
file_content = IO.read(file_path)
|
58
|
-
|
59
|
-
post_body = <<EOS
|
60
|
-
------------XnJLe9ZIbbGUYtzPQJ16u1\r
|
61
|
-
Content-Disposition: form-data; name="file"; filename="#{File.basename(file_path)}"\r
|
62
|
-
Content-Type: application/octet-stream\r
|
63
|
-
Content-Length: #{file_content.size}\r
|
64
|
-
\r
|
65
|
-
#{file_content}\r
|
66
|
-
------------XnJLe9ZIbbGUYtzPQJ16u1--\r
|
67
|
-
EOS
|
68
|
-
|
69
|
-
http.post(attachment_uri.path, post_body, post_headers)
|
70
|
-
end
|
71
|
-
|
72
|
-
# returns back the version of the card given. If an invalid version is given, the latest
|
73
|
-
# version is returned, takes a number or :next or :before
|
74
|
-
def at_version(version_no)
|
75
|
-
version_2_find = 0
|
76
|
-
case version_no
|
77
|
-
when :before
|
78
|
-
version_2_find = self.version.to_i - 1
|
79
|
-
when :next
|
80
|
-
version_2_find = self.version.to_i + 1
|
81
|
-
else
|
82
|
-
version_2_find = version_no.to_i
|
83
|
-
end
|
84
|
-
self.class.find(self.number, :params => {:version => version_2_find})
|
85
|
-
end
|
86
|
-
|
87
|
-
# adds a comment to a card.
|
88
|
-
def add_comment(comment)
|
89
|
-
comment_uri = URI.parse(File.join(self.class.site.to_s, "cards/add_comment?card_id=#{self.id}"))
|
90
|
-
|
91
|
-
http = Net::HTTP.new(comment_uri.host, comment_uri.port)
|
92
|
-
http.use_ssl = comment_uri.is_a?(URI::HTTPS)
|
93
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
|
94
|
-
|
95
|
-
basic_encode = 'Basic ' + ["#{self.class.user}:#{self.class.password}"].pack('m').delete("\r\n")
|
96
|
-
|
97
|
-
post_headers = {
|
98
|
-
'Authorization' => basic_encode,
|
99
|
-
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'
|
100
|
-
}
|
101
|
-
|
102
|
-
post_body = "comment=#{comment}&card_id=#{self.id}"
|
103
|
-
|
104
|
-
http.post(comment_uri.path, post_body, post_headers)
|
105
|
-
end
|
106
|
-
|
107
|
-
# Executes the given transition on the card.
|
108
|
-
# Example :
|
109
|
-
# defect_card.execute_transition(:name => 'Close Defect', :Owner => nil, :Status => 'Closed', :transition_comment => comment)
|
110
|
-
# transition_comment is mandatory if the transition is set that way.
|
111
|
-
# after transition 'Owner' would have value 'Not Set' and 'Status' would be 'Closed' for defect card
|
112
|
-
def execute_transition(args = {})
|
113
|
-
V1::TransitionExecution.site = self.class.site.to_s
|
114
|
-
V1::TransitionExecution.user = self.class.user
|
115
|
-
V1::TransitionExecution.password = self.class.password
|
116
|
-
|
117
|
-
args.symbolize_keys!
|
118
|
-
trans_hash = create_transition_exec_hash(args)
|
119
|
-
V1::TransitionExecution.new(trans_hash).execute
|
120
|
-
end
|
121
|
-
|
122
|
-
# gets the value of a property. The property name given should be the same name as
|
123
|
-
# the mingle property name
|
124
|
-
def property_value(name, val = nil)
|
125
|
-
set_property_definitions_attributes
|
126
|
-
column_name = PropertyDefinition.column_name_for(name.to_s)
|
127
|
-
val ? attributes[column_name] = val : attributes[column_name]
|
128
|
-
end
|
129
|
-
|
130
|
-
def custom_properties
|
131
|
-
set_property_definitions_attributes
|
132
|
-
custom_props = []
|
133
|
-
card_props = attributes.keys
|
134
|
-
PropertyDefinition.find(:all).each do |prop|
|
135
|
-
if(card_props.include?(prop.column_name))
|
136
|
-
custom_prop = {prop.name => attributes[prop.column_name]}
|
137
|
-
custom_props.push(custom_prop)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
custom_props
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
def boundary
|
145
|
-
'----------XnJLe9ZIbbGUYtzPQJ16u1'
|
146
|
-
end
|
147
|
-
|
148
|
-
def create_transition_exec_hash(args)
|
149
|
-
transition_hash = {}
|
150
|
-
transition_hash['card'] = (args.delete(:card) || self.number).to_i
|
151
|
-
transition_hash['transition'] = (args.delete(:name) || args.delete(:transition))
|
152
|
-
|
153
|
-
comment = args.delete(:comment)
|
154
|
-
transition_hash['comment'] = comment if comment
|
155
|
-
properties = []
|
156
|
-
args.each do |name, value|
|
157
|
-
property = {'name' => name.to_s, 'value' => value}
|
158
|
-
properties.push(property)
|
159
|
-
end
|
160
|
-
transition_hash['properties'] = properties unless properties.empty?
|
161
|
-
transition_hash
|
162
|
-
end
|
163
|
-
|
164
|
-
def set_property_definitions_attributes
|
165
|
-
PropertyDefinition.site = self.class.site.to_s
|
166
|
-
PropertyDefinition.user = self.class.user
|
167
|
-
PropertyDefinition.password = self.class.password
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|