mingle4r 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/History.txt +6 -0
  2. data/README +53 -20
  3. data/TODO.txt +8 -4
  4. data/lib/mingle4r.rb +9 -23
  5. data/lib/mingle4r/api/card.rb +137 -0
  6. data/lib/mingle4r/api/card/attachment.rb +47 -0
  7. data/lib/mingle4r/api/card/comment.rb +12 -0
  8. data/lib/mingle4r/api/card/transition.rb +48 -0
  9. data/lib/mingle4r/api/murmur.rb +12 -0
  10. data/lib/mingle4r/api/project.rb +64 -0
  11. data/lib/mingle4r/api/property_definition.rb +7 -0
  12. data/lib/mingle4r/api/user.rb +7 -0
  13. data/lib/mingle4r/api/wiki.rb +10 -0
  14. data/lib/mingle4r/common_class_methods.rb +0 -1
  15. data/lib/mingle4r/mingle_client.rb +16 -14
  16. data/lib/mingle4r/version.rb +1 -1
  17. metadata +11 -22
  18. data/lib/mingle4r/api.rb +0 -31
  19. data/lib/mingle4r/api/v1.rb +0 -25
  20. data/lib/mingle4r/api/v1/card.rb +0 -173
  21. data/lib/mingle4r/api/v1/card/attachment.rb +0 -51
  22. data/lib/mingle4r/api/v1/project.rb +0 -71
  23. data/lib/mingle4r/api/v1/property_definition.rb +0 -16
  24. data/lib/mingle4r/api/v1/transition_execution.rb +0 -15
  25. data/lib/mingle4r/api/v1/user.rb +0 -9
  26. data/lib/mingle4r/api/v1/wiki.rb +0 -12
  27. data/lib/mingle4r/api/v2.rb +0 -25
  28. data/lib/mingle4r/api/v2/card.rb +0 -157
  29. data/lib/mingle4r/api/v2/card/attachment.rb +0 -51
  30. data/lib/mingle4r/api/v2/card/comment.rb +0 -16
  31. data/lib/mingle4r/api/v2/card/transition.rb +0 -52
  32. data/lib/mingle4r/api/v2/murmur.rb +0 -14
  33. data/lib/mingle4r/api/v2/project.rb +0 -90
  34. data/lib/mingle4r/api/v2/property_definition.rb +0 -14
  35. data/lib/mingle4r/api/v2/user.rb +0 -9
  36. data/lib/mingle4r/api/v2/wiki.rb +0 -12
  37. 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
@@ -1,9 +0,0 @@
1
- module Mingle4r
2
- class API
3
- class V1
4
- class User
5
- extend Mingle4r::CommonClassMethods
6
- end
7
- end
8
- end
9
- end
@@ -1,12 +0,0 @@
1
- module Mingle4r
2
- class API
3
- class V1
4
- class Wiki
5
- extend Mingle4r::CommonClassMethods
6
- end
7
- end
8
- end
9
- end
10
-
11
- Mingle4r::API::V1::Wiki.collection_name = 'wiki'
12
- Mingle4r::API::V1::Wiki.element_name = 'page'
@@ -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
@@ -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,16 +0,0 @@
1
- module Mingle4r
2
- class API
3
- class V2
4
- class Card
5
- class Comment
6
- module InstanceMethods
7
- def to_s
8
- attributes['content']
9
- end
10
- end
11
- extend Mingle4r::CommonClassMethods
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -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