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
@@ -1,51 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V1
|
4
|
-
class Card
|
5
|
-
class Attachment
|
6
|
-
module InstanceMethods
|
7
|
-
# downloads the attachment. It an additional file path is given it saves it at the
|
8
|
-
# given path. The given path should be writable
|
9
|
-
def download(file_name = nil)
|
10
|
-
collection_uri = self.class.site
|
11
|
-
rel_down_url = self.url
|
12
|
-
base_url = "#{collection_uri.scheme}://#{collection_uri.host}:#{collection_uri.port}/"
|
13
|
-
down_uri = URI.join(base_url, rel_down_url)
|
14
|
-
req = Net::HTTP::Get.new(down_uri.path)
|
15
|
-
req.basic_auth self.class.user, self.class.password
|
16
|
-
begin
|
17
|
-
res = Net::HTTP.start(down_uri.host, down_uri.port) { |http| http.request(req) }
|
18
|
-
file_name ||= self.file_name()
|
19
|
-
File.open(file_name, 'w') { |f| f.print(res.body) }
|
20
|
-
rescue Exception => e
|
21
|
-
e.message
|
22
|
-
end
|
23
|
-
end # download
|
24
|
-
|
25
|
-
# alias for file_name
|
26
|
-
def name
|
27
|
-
file_name()
|
28
|
-
end
|
29
|
-
|
30
|
-
# so that active resource tries to find by proper id
|
31
|
-
def id
|
32
|
-
name()
|
33
|
-
end
|
34
|
-
|
35
|
-
# This method had to be overriden.
|
36
|
-
# normal active resource destroy doesn't work as mingle site for deleting attachments doesn't end with .xml.
|
37
|
-
def destroy
|
38
|
-
connection = self.send(:connection)
|
39
|
-
# deletes the attachment by removing .xml at the end
|
40
|
-
connection.delete(self.send(:element_path).gsub(/\.xml\z/, ''))
|
41
|
-
end
|
42
|
-
alias_method :delete, :destroy
|
43
|
-
end #module InstanceMethods
|
44
|
-
|
45
|
-
extend Mingle4r::CommonClassMethods
|
46
|
-
|
47
|
-
end # class Attachment
|
48
|
-
end # class Card
|
49
|
-
end # class V1
|
50
|
-
end # class API
|
51
|
-
end # module Mingle4r
|
@@ -1,71 +0,0 @@
|
|
1
|
-
# require File.dirname(__FILE__) + '/../common/project'
|
2
|
-
module Mingle4r
|
3
|
-
class API
|
4
|
-
class V1
|
5
|
-
class Project
|
6
|
-
|
7
|
-
extend Mingle4r::CommonClassMethods
|
8
|
-
|
9
|
-
module InstanceMethods
|
10
|
-
# returns the cards for the project. To hit the resource server without returning
|
11
|
-
# cached results pass true as an argument.
|
12
|
-
def cards(refresh = false)
|
13
|
-
return @cards if(!refresh && @cards_cached)
|
14
|
-
cards_site = File.join(self.class.site.to_s, "projects/#{self.identifier()}")
|
15
|
-
# card_class = API.new(self.class.site).card_class
|
16
|
-
Card.site = cards_site
|
17
|
-
Card.user = self.class.user
|
18
|
-
Card.password = self.class.password
|
19
|
-
# @cards = Card.send(:create_resource_class).find_without_pagination(:all)
|
20
|
-
@cards = Card.find_without_pagination(:all)
|
21
|
-
@cards_cached = true
|
22
|
-
@cards
|
23
|
-
end
|
24
|
-
|
25
|
-
# returns the users for the project. To hit the resource server without returning
|
26
|
-
# cached results pass true as an argument.
|
27
|
-
def users(refresh = false)
|
28
|
-
return @users if(!refresh && @users_cached)
|
29
|
-
users_site = File.join(self.class.site.to_s, "projects/#{self.identifier()}")
|
30
|
-
User.site = users_site
|
31
|
-
User.user = self.class.user
|
32
|
-
User.password = self.class.password
|
33
|
-
User.element_name = nil # reset
|
34
|
-
user_class = User.send(:create_resource_class)
|
35
|
-
@users = user_class.find(:all)
|
36
|
-
@users_cached = true
|
37
|
-
@users
|
38
|
-
end
|
39
|
-
|
40
|
-
# returns the wikis for the project. To hit the resource server without returning
|
41
|
-
# cached results pass true as an argument.
|
42
|
-
def wikis(refresh = false)
|
43
|
-
return @wikis if(!refresh && @wikis_cached)
|
44
|
-
wiki_site = File.join(self.class.site.to_s, "projects/#{self.identifier()}")
|
45
|
-
Wiki.site = wiki_site
|
46
|
-
Wiki.user = self.class.user
|
47
|
-
Wiki.password = self.class.password
|
48
|
-
wiki_class = Wiki.send(:create_resource_class)
|
49
|
-
@wikis = wiki_class.find(:all)
|
50
|
-
@wikis_cached = true
|
51
|
-
@wikis
|
52
|
-
end
|
53
|
-
|
54
|
-
# returns the property definitions for the project. To hit the resource server
|
55
|
-
# pass true as an argument
|
56
|
-
def property_definitions(refresh = false)
|
57
|
-
return @prop_definitions if(!refresh && @prop_definitions_cached)
|
58
|
-
properties_site = File.join(self.class.site.to_s, "/projects/#{self.identifier}")
|
59
|
-
PropertyDefinition.site = properties_site
|
60
|
-
PropertyDefinition.user = self.class.user
|
61
|
-
PropertyDefinition.password = self.class.password
|
62
|
-
prop_defn_class = PropertyDefinition.send(:create_resource_class)
|
63
|
-
@prop_definitions = prop_defn_class.find(:all)
|
64
|
-
@prop_definitions_cached = true
|
65
|
-
@prop_definitions
|
66
|
-
end
|
67
|
-
end # module InstanceMethods
|
68
|
-
end # class Project
|
69
|
-
end # class V1
|
70
|
-
end # class API
|
71
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V1
|
4
|
-
class PropertyDefinition
|
5
|
-
extend Mingle4r::CommonClassMethods
|
6
|
-
|
7
|
-
def self.column_name_for(prop_name)
|
8
|
-
property_def = @resource_class.find(:all).detect { |prop| prop.name == prop_name }
|
9
|
-
property_def ? property_def.column_name : nil
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
Mingle4r::API::V1::PropertyDefinition.element_name = 'record'
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V1
|
4
|
-
class TransitionExecution
|
5
|
-
extend Mingle4r::CommonClassMethods
|
6
|
-
module InstanceMethods
|
7
|
-
def execute
|
8
|
-
conn = self.class.connection
|
9
|
-
conn.post(self.class.collection_path, encode, self.class.headers)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/mingle4r/api/v1/user.rb
DELETED
data/lib/mingle4r/api/v1/wiki.rb
DELETED
data/lib/mingle4r/api/v2.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V2
|
4
|
-
def initialize(host_url)
|
5
|
-
@host_uri = URI.parse(host_url)
|
6
|
-
end
|
7
|
-
|
8
|
-
def base_url
|
9
|
-
File.join(@host_uri.to_s, '/api/v2')
|
10
|
-
end
|
11
|
-
|
12
|
-
def version
|
13
|
-
2
|
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/v2/card.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V2
|
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
|
-
# call ActiveResource::Base::find with proper options
|
21
|
-
find(scope, options)
|
22
|
-
end
|
23
|
-
|
24
|
-
# applies an mql filter on card types. Look at https://mingle05.thoughtworks.com/help/mql_reference.html
|
25
|
-
# for reference
|
26
|
-
def apply_filter(filter_string)
|
27
|
-
find_without_pagination(:all, :params => {'filters[mql]'.to_sym => filter_string})
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
module InstanceMethods
|
32
|
-
# so that active resource tries to find by number
|
33
|
-
def id
|
34
|
-
number()
|
35
|
-
end
|
36
|
-
|
37
|
-
def attachments(refresh = false)
|
38
|
-
return @attachments if(!refresh && @attachments)
|
39
|
-
attachment_site = File.join(self.class.site.to_s, "cards/#{self.number()}").to_s
|
40
|
-
Card::Attachment.site = attachment_site
|
41
|
-
Card::Attachment.user = self.class.user
|
42
|
-
Card::Attachment.password = self.class.password
|
43
|
-
attachment_class = Card::Attachment.send(:create_resource_class)
|
44
|
-
@attachments = attachment_class.find(:all)
|
45
|
-
end
|
46
|
-
|
47
|
-
def comments(refresh = false)
|
48
|
-
return @comments if(!refresh && @comments)
|
49
|
-
set_comment_class_attributes
|
50
|
-
@comments = Card::Comment.find(:all)
|
51
|
-
end
|
52
|
-
|
53
|
-
def transitions(refresh = false)
|
54
|
-
return @transitions if(!refresh && @transitions)
|
55
|
-
set_transition_class_attributes
|
56
|
-
@transitions = Card::Transition.find(:all)
|
57
|
-
end
|
58
|
-
|
59
|
-
def murmurs(refresh = false)
|
60
|
-
return @murmurs if(!refresh && @murmurs)
|
61
|
-
set_murmur_class_attributes
|
62
|
-
@murmurs = Murmur.find(:all)
|
63
|
-
end
|
64
|
-
|
65
|
-
def upload_attachment(file_path)
|
66
|
-
attachment_uri = URI.parse(File.join(self.class.site.to_s, "cards/#{self.number()}/attachments.xml"))
|
67
|
-
http = Net::HTTP.new(attachment_uri.host, attachment_uri.port)
|
68
|
-
http.use_ssl = attachment_uri.is_a?(URI::HTTPS)
|
69
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
|
70
|
-
basic_encode = 'Basic ' + ["#{self.class.user}:#{self.class.password}"].pack('m').delete("\r\n")
|
71
|
-
|
72
|
-
post_headers = {
|
73
|
-
'Authorization' => basic_encode,
|
74
|
-
'Content-Type' => 'multipart/form-data; boundary=----------XnJLe9ZIbbGUYtzPQJ16u1'
|
75
|
-
}
|
76
|
-
|
77
|
-
file_content = IO.read(file_path)
|
78
|
-
|
79
|
-
post_body = <<EOS
|
80
|
-
------------XnJLe9ZIbbGUYtzPQJ16u1\r
|
81
|
-
Content-Disposition: form-data; name="file"; filename="#{File.basename(file_path)}"\r
|
82
|
-
Content-Type: application/octet-stream\r
|
83
|
-
Content-Length: #{file_content.size}\r
|
84
|
-
\r
|
85
|
-
#{file_content}\r
|
86
|
-
------------XnJLe9ZIbbGUYtzPQJ16u1--\r
|
87
|
-
EOS
|
88
|
-
|
89
|
-
http.post(attachment_uri.path, post_body, post_headers)
|
90
|
-
end
|
91
|
-
|
92
|
-
def add_comment(str)
|
93
|
-
set_comment_class_attributes
|
94
|
-
comment = Card::Comment.new(:content => str.to_s)
|
95
|
-
comment.save
|
96
|
-
end
|
97
|
-
|
98
|
-
def execute_transition(args)
|
99
|
-
trans_name = args.symbolize_keys[:name]
|
100
|
-
transition = transitions.detect { |t| t.name == trans_name}
|
101
|
-
transition.execute(args)
|
102
|
-
end
|
103
|
-
|
104
|
-
# returns back the version of the card given. If an invalid version is given, the latest
|
105
|
-
# version is returned, takes a number or :next or :before
|
106
|
-
def at_version(version_no)
|
107
|
-
version_2_find = 0
|
108
|
-
case version_no
|
109
|
-
when :before
|
110
|
-
version_2_find = self.version.to_i - 1
|
111
|
-
when :next
|
112
|
-
version_2_find = self.version.to_i + 1
|
113
|
-
else
|
114
|
-
version_2_find = version_no.to_i
|
115
|
-
end
|
116
|
-
self.class.find(self.number, :params => {:version => version_2_find})
|
117
|
-
end
|
118
|
-
|
119
|
-
# Gets and sets the value of a property. The property name given should be the same
|
120
|
-
# as the mingle property name. the value is optional
|
121
|
-
def property_value(name, val = nil)
|
122
|
-
property = properties.detect { |p| p.name == name }
|
123
|
-
val ? property.value = val : property.value
|
124
|
-
end
|
125
|
-
|
126
|
-
# Gets the custom properties in the form of an array of hashes with the property names as keys and
|
127
|
-
# property values as the value
|
128
|
-
def custom_properties
|
129
|
-
properties.map { |p| {p.name => p.value} }
|
130
|
-
end
|
131
|
-
|
132
|
-
private
|
133
|
-
def set_comment_class_attributes
|
134
|
-
comment_site = File.join(self.class.site.to_s, "cards/#{self.number()}").to_s
|
135
|
-
Card::Comment.site = comment_site
|
136
|
-
Card::Comment.user = self.class.user
|
137
|
-
Card::Comment.password = self.class.password
|
138
|
-
end
|
139
|
-
|
140
|
-
def set_transition_class_attributes
|
141
|
-
transition_site = File.join(self.class.site.to_s, "cards/#{self.number()}").to_s
|
142
|
-
Card::Transition.site = transition_site
|
143
|
-
Card::Transition.user = self.class.user
|
144
|
-
Card::Transition.password = self.class.password
|
145
|
-
end
|
146
|
-
|
147
|
-
def set_murmur_class_attributes
|
148
|
-
murmur_site = File.join(self.class.site.to_s, "cards/#{self.number()}").to_s
|
149
|
-
V2::Murmur.site = murmur_site
|
150
|
-
V2::Murmur.user = self.class.user
|
151
|
-
V2::Murmur.password = self.class.password
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V2
|
4
|
-
class Card
|
5
|
-
class Attachment
|
6
|
-
module InstanceMethods
|
7
|
-
# downloads the attachment. It an additional file path is given it saves it at the
|
8
|
-
# given path. The given path should be writable
|
9
|
-
def download(file_name = nil)
|
10
|
-
collection_uri = self.class.site
|
11
|
-
rel_down_url = self.url
|
12
|
-
base_url = "#{collection_uri.scheme}://#{collection_uri.host}:#{collection_uri.port}/"
|
13
|
-
down_uri = URI.join(base_url, rel_down_url)
|
14
|
-
req = Net::HTTP::Get.new(down_uri.path)
|
15
|
-
req.basic_auth self.class.user, self.class.password
|
16
|
-
begin
|
17
|
-
res = Net::HTTP.start(down_uri.host, down_uri.port) { |http| http.request(req) }
|
18
|
-
file_name ||= self.file_name()
|
19
|
-
File.open(file_name, 'w') { |f| f.print(res.body) }
|
20
|
-
rescue Exception => e
|
21
|
-
e.message
|
22
|
-
end
|
23
|
-
end # download
|
24
|
-
|
25
|
-
# alias for file_name
|
26
|
-
def name
|
27
|
-
file_name()
|
28
|
-
end
|
29
|
-
|
30
|
-
# so that active resource tries to find by proper id
|
31
|
-
def id
|
32
|
-
name()
|
33
|
-
end
|
34
|
-
|
35
|
-
# This method had to be overriden.
|
36
|
-
# normal active resource destroy doesn't work as mingle site for deleting attachments doesn't end with .xml.
|
37
|
-
def destroy
|
38
|
-
connection = self.send(:connection)
|
39
|
-
# deletes the attachment by removing .xml at the end
|
40
|
-
connection.delete(self.send(:element_path).gsub(/\.xml\z/, ''))
|
41
|
-
end
|
42
|
-
alias_method :delete, :destroy
|
43
|
-
end #module InstanceMethods
|
44
|
-
|
45
|
-
extend Mingle4r::CommonClassMethods
|
46
|
-
|
47
|
-
end # class Attachment
|
48
|
-
end # class Card
|
49
|
-
end # class V2
|
50
|
-
end # class API
|
51
|
-
end # module Mingle4r
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Mingle4r
|
2
|
-
class API
|
3
|
-
class V2
|
4
|
-
class Card
|
5
|
-
class Transition
|
6
|
-
extend Mingle4r::CommonClassMethods
|
7
|
-
|
8
|
-
module InstanceMethods
|
9
|
-
def execute(args = {})
|
10
|
-
args.symbolize_keys!
|
11
|
-
trans_exec_xml = convert_to_xml(args)
|
12
|
-
# set_transition_execution_attributes
|
13
|
-
conn = self.class.connection
|
14
|
-
url_path =URI.parse(transition_execution_url()).path
|
15
|
-
conn.post(url_path, trans_exec_xml, self.class.headers)
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
def convert_to_xml(args)
|
20
|
-
hash = create_transition_exec_hash(args)
|
21
|
-
xmlize_trans_exec(hash)
|
22
|
-
end
|
23
|
-
|
24
|
-
def create_transition_exec_hash(args)
|
25
|
-
transition_hash = {}
|
26
|
-
transition_hash['card'] = (args.delete(:card) || associated_card_number).to_i
|
27
|
-
args.delete(:name) || args.delete(:transition)
|
28
|
-
|
29
|
-
comment = args.delete(:comment)
|
30
|
-
transition_hash['comment'] = comment if comment
|
31
|
-
properties = []
|
32
|
-
args.each do |name, value|
|
33
|
-
property = {'name' => name.to_s, 'value' => value}
|
34
|
-
properties.push(property)
|
35
|
-
end
|
36
|
-
transition_hash['properties'] = properties unless properties.empty?
|
37
|
-
transition_hash
|
38
|
-
end
|
39
|
-
|
40
|
-
def xmlize_trans_exec(hash)
|
41
|
-
hash.to_xml(:root => 'transition_execution', :dasherize => false)
|
42
|
-
end
|
43
|
-
|
44
|
-
def associated_card_number
|
45
|
-
File.basename(self.class.site.to_s).to_i
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|