mingle4r 0.3.0 → 0.4.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/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
|