mingle4r 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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