mingle4r 0.4.2 → 0.4.3

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.
@@ -1,3 +1,7 @@
1
+ 0.4.3
2
+ -----
3
+ * Lots of bug fixes
4
+
1
5
  0.4.2
2
6
  -----
3
7
  * Added functionality to get/set card type directly
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2009 Arusarka Haldar
3
+ Copyright (c) 2010 Arusarka Haldar
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README CHANGED
@@ -108,6 +108,22 @@ m_c.proj_id = 'great_mingle_project'
108
108
  card = m_c.project.cards[0]
109
109
  card.property_value('Status')
110
110
 
111
+ Creating a card
112
+ ---------------
113
+
114
+ Mingle4r::API::Card is the ActiveResource class which handles interaction with cards.
115
+ task = Mingle4r::API::Card.new
116
+ task.name = 'set up Cruise build'
117
+ task.type = 'task'
118
+ task.description = 'a basic cruise build needs to be set up so that we can start working'
119
+ task.save
120
+
121
+ Do not do it like this:
122
+
123
+ task = Mingle4r::API::new :name => 'set up Cruise build', :type => 'task',
124
+ :description => 'a basic cruise build needs to be set up so that we can start working'
125
+ task.save => It simply won't work, there is a workaround but rather use as described above.
126
+
111
127
  Setting a particular property
112
128
  -----------------------------
113
129
 
@@ -242,6 +258,11 @@ m_c.project.execute_mql('SELECT name, "Added in Iteration" WHERE Type = Story')
242
258
  1) active_resource gem, it would be automatically taken care of
243
259
  during gem install.
244
260
 
261
+ == LIMITATIONS:
262
+
263
+ updating a property on the card which is a link to another card does not work. So for now
264
+ only use it for other properties
265
+
245
266
  == INSTALL:
246
267
 
247
268
  since github no longer archives gems, I am hosting the gem at gemcutter. So you would need to
data/TODO.txt CHANGED
@@ -1,13 +1,19 @@
1
- update documentation - write about executing transitions directly on the transition
2
- clarify in docs difference between custom properties and native properties
3
- write tests for project class
1
+ will be fixed/implemented very soon
2
+ -----------------------------------
4
3
 
5
- refactorings
6
- ------------
4
+ * fix updation of card properties
7
5
 
8
- maybe nice to nave
9
- -------------------
6
+ will be implemented, but not very important for now
7
+ ----------------------------------------------------
10
8
 
11
- provide a easy mechanism to link to other cards
9
+ * update documentation - write about executing transitions directly on the transition
10
+ * provide a helper method to link to a card
11
+ * write tests for project class
12
+ * implement card_types for a project
13
+ * mingle client should have cards method
12
14
 
13
- should transtions give the list of properties to be changed directly
15
+ will be done when I've no other work
16
+ ------------------------------------
17
+
18
+ * clarify in docs difference between custom properties and native properties
19
+ * should transtions give the list of properties to be changed directly
@@ -6,15 +6,14 @@ require 'active_resource'
6
6
  require 'net/http'
7
7
 
8
8
  # This module should be used to interact with mingle. Look in the readme for examples.
9
- module Mingle4r
10
- AUTHOR = 'Asur'
11
- end
9
+ module Mingle4r; end
12
10
 
13
11
  require 'mingle_resource'
14
12
  require 'mingle4r/version'
15
13
  require 'mingle4r/common_class_methods'
16
14
  require 'mingle4r/helpers'
17
15
  require 'mingle4r/mingle_client'
16
+ require 'mingle4r/card_format'
18
17
 
19
18
  require 'mingle4r/api/card'
20
19
  require 'mingle4r/api/card/attachment'
@@ -3,13 +3,6 @@ module Mingle4r
3
3
  class Card
4
4
  extend Mingle4r::CommonClassMethods
5
5
 
6
- # overwrite the default find in CommonClassMethods
7
- def self.find(*args)
8
- scope = args.slice!(0)
9
- options = args.slice!(0) || {}
10
- @resource_class.find_without_pagination(scope, options)
11
- end
12
-
13
6
  module ClassMethods
14
7
  def find_without_pagination(*args)
15
8
  scope = args.slice!(0)
@@ -41,26 +34,22 @@ module Mingle4r
41
34
  attributes['card_type_name'] = type
42
35
  end
43
36
 
44
- def attachments(refresh = false)
45
- return @attachments if(!refresh && @attachments)
46
- set_attributes_for(Attachment)
37
+ def attachments
38
+ set_attributes_for(Attachment) unless attachment_class_set
47
39
  @attachments = Attachment.find(:all)
48
40
  end
49
41
 
50
- def comments(refresh = false)
51
- return @comments if(!refresh && @comments)
52
- set_attributes_for(Comment)
53
- @comments = Card::Comment.find(:all)
42
+ def comments
43
+ set_attributes_for(Comment) unless comment_class_set
44
+ Comment.find(:all)
54
45
  end
55
46
 
56
- def transitions(refresh = false)
57
- return @transitions if(!refresh && @transitions)
58
- set_attributes_for(Transition)
59
- @transitions = Card::Transition.find(:all)
47
+ def transitions
48
+ set_attributes_for(Transition) unless transition_class_set
49
+ @transitions = Transition.find(:all)
60
50
  end
61
51
 
62
- def murmurs(refresh = false)
63
- return @murmurs if(!refresh && @murmurs)
52
+ def murmurs
64
53
  set_attributes_for(Murmur)
65
54
  @murmurs = Murmur.find(:all)
66
55
  end
@@ -138,6 +127,24 @@ EOS
138
127
  klass.site = resource_site
139
128
  klass.user = self.class.user
140
129
  klass.password = self.class.password
130
+ setter_method = klass.name.demodulize.underscore + '_class_set'
131
+ send(setter_method, true)
132
+ klass
133
+ end
134
+
135
+ def comment_class_set(val = nil)
136
+ return @comment_class_set unless val
137
+ @comment_class_set = val
138
+ end
139
+
140
+ def attachment_class_set(val = nil)
141
+ return @attachment_class_set unless val
142
+ @attachment_class_set = val
143
+ end
144
+
145
+ def transition_class_set(val = nil)
146
+ return @transition_class_set unless val
147
+ @transition_class_set = val
141
148
  end
142
149
  end
143
150
  end
@@ -0,0 +1,15 @@
1
+ module Mingle4r
2
+ module API
3
+ class ExecuteMql
4
+ extend Mingle4r::CommonClassMethods
5
+
6
+ def self.query(query_string)
7
+ @resource_class.find(:all, :params => {:mql => query_string}).
8
+ collect { |res| res.attributes }
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ Mingle4r::API::ExecuteMql.collection_name = 'execute_mql'
15
+ Mingle4r::API::ExecuteMql.element_name = 'result'
@@ -2,56 +2,46 @@ module Mingle4r
2
2
  module API
3
3
  class Project
4
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)
5
+ # returns the cards for the project.
6
+ def cards
7
+ set_attributes_for(Card) unless card_class_set
8
+ Card.find_without_pagination(:all)
11
9
  end
12
10
 
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)
11
+ # returns the users for the project.
12
+ def users
13
+ set_attributes_for(User) unless user_class_set
14
+ User.find(:all)
19
15
  end
20
16
 
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)
17
+ # returns the wikis for the project.
18
+ def wikis
19
+ set_attributes_for(Wiki) unless wiki_class_set
20
+ Wiki.find(:all)
27
21
  end
28
22
 
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)
23
+ # returns the property definitions for the project.
24
+ def property_definitions
25
+ set_attributes_for(PropertyDefinition) unless property_definition_class_set
26
+ PropertyDefinition.find(:all)
35
27
  end
36
28
 
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)
29
+ # returns the murmurs for the project.
30
+ def murmurs
31
+ set_attributes_for(Murmur) unless murmur_class_set
32
+ Murmur.find(:all)
43
33
  end
44
34
 
45
35
  # posts a murmur
46
36
  def post_murmur(str)
47
- set_attributes_for(Murmur)
37
+ set_attributes_for(Murmur) unless murmur_class_set
48
38
  murmur = Murmur.new(:body => str.to_s)
49
39
  murmur.save
50
40
  end
51
41
 
52
42
  # executes an mql
53
43
  def execute_mql(query)
54
- set_attributes_for(ExecuteMql)
44
+ set_attributes_for(ExecuteMql) unless execute_mql_class_set
55
45
  ExecuteMql.query(query)
56
46
  end
57
47
 
@@ -62,6 +52,39 @@ module Mingle4r
62
52
  klass.site = resource_site
63
53
  klass.user = self.class.user
64
54
  klass.password = self.class.password
55
+ setter_method = klass.name.demodulize.underscore + '_class_set'
56
+ send(setter_method, true)
57
+ klass
58
+ end
59
+
60
+ def user_class_set(val = nil)
61
+ return @user_class_set unless val
62
+ @user_class_set = val
63
+ end
64
+
65
+ def card_class_set(val = nil)
66
+ return @card_class_set unless val
67
+ @card_class_set = val
68
+ end
69
+
70
+ def wiki_class_set(val = nil)
71
+ return @wiki_class_set unless val
72
+ @wiki_class_set = val
73
+ end
74
+
75
+ def property_definition_class_set(val = nil)
76
+ return @property_definition_class_set unless val
77
+ @property_definition_class_set = val
78
+ end
79
+
80
+ def murmur_class_set(val = nil)
81
+ return @murmur_class_set unless val
82
+ @murmur_class_set = val
83
+ end
84
+
85
+ def execute_mql_class_set(val = nil)
86
+ return @execute_mql_class_set unless val
87
+ @execute_mql_class_set = val
65
88
  end
66
89
  end # module InstanceMethods
67
90
 
@@ -0,0 +1,28 @@
1
+ module Mingle4r
2
+ class CardFormat
3
+ def extension
4
+ 'xml'
5
+ end
6
+
7
+ def mime_type
8
+ 'application/xml'
9
+ end
10
+
11
+ def decode(xml)
12
+ from_xml_data(Hash.from_xml(xml))
13
+ end
14
+
15
+ def encode(hash, options={})
16
+ hash.to_xml(options)
17
+ end
18
+
19
+ private
20
+ def from_xml_data(data)
21
+ if data.is_a?(Hash) && data.keys.size == 1
22
+ data.values.first
23
+ else
24
+ data
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,92 +1,5 @@
1
1
  module Mingle4r
2
- # ActiveResource makes connecting to rest resources very easy. However it has one problem
3
- # and a big one at that. If you try setting the authentication credentials or the site or
4
- # collection name, element name for the class for the second time it doesn't work. E.g.
5
- #
6
- # class Person < ActiveResource::base
7
- # self.site = 'http://localhost:9090/'
8
- # end
9
- #
10
- # After sometime you change it to
11
- #
12
- # Person.site = 'https://org-server/my_proj/'
13
- # Person.user = 'admin'
14
- # Person.password = 'secret'
15
- #
16
- # Then you do
17
- #
18
- # Person.find(:all) => It bombs
19
- #
20
- # This module provides a mechanism by which you can get rid of this problem. Extend this
21
- # class in the actual class itself. Do not extend the extended class from ActiveResource::Base.
22
- #
23
- # E.g.
24
- #
25
- # class Person
26
- # extend CommonClassMethods
27
- # end
28
- #
29
- # set the credentials
30
- #
31
- # Person.site = 'http://localhost:8080'
32
- # Person.user = 'foo'
33
- # Person.password = 'bar'
34
- #
35
- # Thats it. Now create some objects
36
- #
37
- # asur = Person.new(:name => 'Asur', :job => 'fooling around', :status => 'Single and ready 2 mingle')
38
- # asur.save
39
- #
40
- # Now change the class attributes
41
- #
42
- # Person.site = 'https://org-server/mingle'
43
- # Person.collection_name = 'boring_people'
44
- #
45
- # Now instantiate an object
46
- #
47
- # rakhshas = Person.new(:name => 'Rakhshas', :job => 'eating people', :status => 'just woke up and hungry')
48
- # rakhshas.save => Voila !!!!!!! it works
49
- #
50
- # CUSTOMIZATIONS
51
- # --------------
52
- #
53
- # No amount of wrapping can provide very detailed customizations. Either you have a lot of methods
54
- # that are not being used or there is hardly anything at all. To oversome this problem this module
55
- # was written to provide only those methods which are common to most active resource objects.
56
- # However if you want to have a little more control over your active resource objects its very easy.
57
- # Here's how you would do it normally
58
- #
59
- # class Person < ActiveResource::Base
60
- # def self.count
61
- # find(:all).size
62
- # end
63
- #
64
- # def occupation
65
- # return job if job
66
- # 'Unemployed'
67
- # end
68
- # end
69
- #
70
- # To do the same thing, here's how you do it using this library
71
- #
72
- # class Person
73
- # module ClassMethods
74
- # def count
75
- # find(:all).size
76
- # end
77
- # end
78
- #
79
- # module InstanceMethods
80
- # def occupation
81
- # return job if job
82
- # 'Unemployed'
83
- # end
84
- # end
85
- # extend CommonClassMethods
86
- # end
87
- #
88
- # The instance methods will be available as instance methods in the objects created, class methods
89
- # will be available as class methods in the class of the object.
2
+ class ResourceNotSetup < Exception; end
90
3
 
91
4
  module CommonClassMethods
92
5
  attr_reader :site, :user, :password
@@ -168,51 +81,56 @@ module Mingle4r
168
81
  # creates an active resource class dynamically. All the attributes are set automatically. Avoid calling
169
82
  # this method directly
170
83
  def create_resource_class
171
- # raise exceptions if site is not set
172
84
  raise "Please set the site for #{self} class." unless(self.site)
173
-
174
85
  created_class = Class.new(MingleResource)
175
-
176
- # set the resource options
177
- created_class.site = self.site
178
- created_class.user = self.user
179
- created_class.password = self.password
180
- created_class.collection_name = self.collection_name
181
- created_class.element_name = self.element_name
182
-
183
- # created_class_name = "#{self}::#{class_name}#{Mingle4r::Helpers.fast_token()}"
184
- created_class_name = class_name + Mingle4r::Helpers.fast_token()
185
- created_class = self.const_set(created_class_name, created_class)
186
- # eval "#{created_class_name} = created_class"
187
-
188
- # includes a module called InstanceMethods in the class created dynamically
189
- # if it is defined inside the wrapper class
190
- inst_meth_mod_name = instance_methods_module_name()
191
- created_class.send(:include, self.const_get(inst_meth_mod_name.to_sym)) if inst_meth_mod_name
192
-
193
- # extends the class created dynamically with a module called ClassMethods if
194
- # it is defined inside the wrapper class
195
- class_meth_mod_name = class_methods_module_name()
196
- created_class.extend(self.const_get(class_meth_mod_name)) if class_meth_mod_name
197
-
86
+ setup_class(created_class)
198
87
  created_class
199
88
  end
200
89
 
90
+ def setup_class(klass)
91
+ set_resource_options(klass)
92
+ set_class_name(klass)
93
+ include_instance_methods(klass)
94
+ include_singleton_methods(klass)
95
+ end
96
+
97
+ def include_singleton_methods(klass)
98
+ klass.extend(self.const_get(:ClassMethods)) if has_class_meths_module?
99
+ end
100
+
101
+ def include_instance_methods(klass)
102
+ klass.send(:include, self.const_get(:InstanceMethods)) if has_inst_meths_module?
103
+ end
104
+
105
+ def set_class_name(klass)
106
+ created_class_name = class_name + Mingle4r::Helpers.fast_token()
107
+ klass = self.const_set(created_class_name, klass)
108
+ klass
109
+ end
110
+
111
+ def set_resource_options(klass)
112
+ klass.site = self.site
113
+ klass.user = self.user
114
+ klass.password = self.password
115
+ klass.collection_name = self.collection_name
116
+ klass.element_name = self.element_name
117
+ klass
118
+ end
119
+
201
120
  def class_name
202
- self.name.split('::')[-1]
121
+ self.name.demodulize
203
122
  end
204
123
 
205
- def instance_methods_module_name
206
- inst_meth_mod_name = 'InstanceMethods'
207
- self.constants.detect { |const| const.split('::')[-1] =~ /#{inst_meth_mod_name}/ }
124
+ def has_inst_meths_module?
125
+ self.constants.detect { |const| const.demodulize == 'InstanceMethods' }
208
126
  end
209
127
 
210
- def class_methods_module_name
211
- class_meth_mod_name = 'ClassMethods'
212
- self.constants.detect { |const| const.split('::')[-1] =~ /#{class_meth_mod_name}/ }
128
+ def has_class_meths_module?
129
+ self.constants.detect { |const| const.demodulize == 'ClassMethods' }
213
130
  end
214
131
 
215
132
  def method_missing(meth_id, *args, &block)
133
+ raise ResourceNotSetup.new("Site is not set for #{name}. Please set it.") unless @resource_class
216
134
  @resource_class.send(meth_id.to_sym, *args, &block)
217
135
  end
218
136
  end
@@ -2,7 +2,7 @@ module Mingle4r
2
2
  module Version
3
3
  Major = '0'
4
4
  Minor = '4'
5
- Tiny = '2'
5
+ Tiny = '3'
6
6
 
7
7
  def self.to_s
8
8
  Major + '.' + Minor + '.' + Tiny
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mingle4r
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 9
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 4
8
- - 2
9
- version: 0.4.2
9
+ - 3
10
+ version: 0.4.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - asur
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-02-25 00:00:00 +05:30
18
+ date: 2010-05-24 00:00:00 +05:30
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: activeresource
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 3
27
30
  segments:
28
31
  - 0
29
32
  version: "0"
@@ -44,10 +47,12 @@ files:
44
47
  - lib/mingle4r/helpers.rb
45
48
  - lib/mingle4r/mingle_client.rb
46
49
  - lib/mingle4r/version.rb
50
+ - lib/mingle4r/card_format.rb
47
51
  - lib/mingle4r/api/card.rb
48
52
  - lib/mingle4r/api/card/attachment.rb
49
53
  - lib/mingle4r/api/card/comment.rb
50
54
  - lib/mingle4r/api/card/transition.rb
55
+ - lib/mingle4r/api/execute_mql.rb
51
56
  - lib/mingle4r/api/murmur.rb
52
57
  - lib/mingle4r/api/project.rb
53
58
  - lib/mingle4r/api/property_definition.rb
@@ -67,23 +72,27 @@ rdoc_options: []
67
72
  require_paths:
68
73
  - lib
69
74
  required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
70
76
  requirements:
71
77
  - - ">="
72
78
  - !ruby/object:Gem::Version
79
+ hash: 3
73
80
  segments:
74
81
  - 0
75
82
  version: "0"
76
83
  required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
77
85
  requirements:
78
86
  - - ">="
79
87
  - !ruby/object:Gem::Version
88
+ hash: 3
80
89
  segments:
81
90
  - 0
82
91
  version: "0"
83
92
  requirements: []
84
93
 
85
94
  rubyforge_project:
86
- rubygems_version: 1.3.6
95
+ rubygems_version: 1.3.7
87
96
  signing_key:
88
97
  specification_version: 3
89
98
  summary: Mingle connector using active resource