|
@@ -163,78 +163,58 @@ class EmComponent(object):
|
163
|
163
|
def _get_max_rank(cls, ranked_in_value):
|
164
|
164
|
pass
|
165
|
165
|
|
166
|
|
- ## Only make a call to the class method
|
|
166
|
+ ## @brief Get the maximum rank given an EmComponent child class and a ranked_in filter
|
167
|
167
|
# @return A positive integer or -1 if no components
|
168
|
|
- # @see EmComponent::_get_max_rank()
|
169
|
|
- def get_max_rank(self, ranked_in_value):
|
170
|
|
- return self.__class__._get_max_rank(ranked_in_value)
|
|
168
|
+ def get_max_rank(self):
|
|
169
|
+ components = self.same_rank_group()
|
|
170
|
+ return -1 if len(components) == 0 else components[-1].rank
|
|
171
|
+
|
|
172
|
+ ## Return an array of instances that are concerned by the same rank
|
|
173
|
+ # @return An array of instances that are concerned by the same rank
|
|
174
|
+ def same_rank_group(self):
|
|
175
|
+ components = self.model.components(self.__class__)
|
|
176
|
+ ranked_in = self.__class__.ranked_in
|
|
177
|
+ return [ c for c in components if getattr(c, ranked_in) == getattr(self, ranked_in) ]
|
171
|
178
|
|
172
|
179
|
## Set a new rank for this component
|
173
|
180
|
# @note This function assume that ranks are properly set from 1 to x with no gap
|
174
|
181
|
# @param new_rank int: The new rank
|
175
|
|
- # @return True if success False if not
|
176
|
182
|
# @throw TypeError If bad argument type
|
177
|
183
|
# @throw ValueError if out of bound value
|
178
|
184
|
def set_rank(self, new_rank):
|
179
|
185
|
if not isinstance(new_rank, int):
|
180
|
186
|
raise TypeError("Excepted <class int> but got "+str(type(new_rank)))
|
181
|
|
- if new_rank < 0 or new_rank > self.get_max_rank(getattr(self, self.ranked_in)):
|
|
187
|
+ if new_rank <= 0 or new_rank > self.get_max_rank():
|
182
|
188
|
raise ValueError("Invalid new rank : "+str(new_rank))
|
183
|
189
|
|
184
|
|
- mod = new_rank - self.rank #Allow to know the "direction" of the "move"
|
|
190
|
+ mod = new_rank - self.rank #Indicates the "direction" of the "move"
|
185
|
191
|
|
186
|
|
- if mod == 0: #No modifications
|
|
192
|
+ if mod == 0:
|
187
|
193
|
return True
|
188
|
194
|
|
189
|
195
|
limits = [ self.rank + ( 1 if mod > 0 else -1), new_rank ] #The range of modified ranks
|
190
|
196
|
limits.sort()
|
191
|
197
|
|
192
|
|
- dbe = self.db_engine
|
193
|
|
- conn = dbe.connect()
|
194
|
|
- table = sqlutils.get_table(self)
|
195
|
|
-
|
196
|
|
- #Selecting the components that will be modified
|
197
|
|
- req = table.select().where( getattr(table.c, self.ranked_in) == getattr(self, self.ranked_in)).where(table.c.rank >= limits[0]).where(table.c.rank <= limits[1])
|
|
198
|
+ for component in [ c for c in self.same_rank_group() if c.rank >= limits[0] and c.rank <= limits[1] ] :
|
|
199
|
+ component._fields['rank'].value = component.rank + ( -1 if mod > 0 else 1 )
|
198
|
200
|
|
199
|
|
- res = conn.execute(req)
|
200
|
|
- if not res: #Db error... Maybe false is a bit silent for a failuer
|
201
|
|
- return False
|
|
201
|
+ self._fields['rank'].value = new_rank
|
202
|
202
|
|
203
|
|
- rows = res.fetchall()
|
|
203
|
+ self.model.sort_components(self.__class__)
|
204
|
204
|
|
205
|
|
- updated_ranks = [{'b_uid': self.uid, 'b_rank': new_rank}]
|
206
|
|
- for row in rows:
|
207
|
|
- updated_ranks.append({'b_uid': row['uid'], 'b_rank': row['rank'] + (-1 if mod > 0 else 1)})
|
208
|
|
- req = table.update().where(table.c.uid == sql.bindparam('b_uid')).values(rank=sql.bindparam('b_rank'))
|
209
|
|
- res = conn.execute(req, updated_ranks)
|
210
|
|
- conn.close()
|
|
205
|
+ pass
|
211
|
206
|
|
212
|
|
- if res:
|
213
|
|
- #Instance rank update
|
214
|
|
- self._fields['rank'].value = new_rank
|
215
|
|
- return bool(res)
|
216
|
|
-
|
217
|
|
- ## @brief Modify a rank given a sign and a new_rank
|
218
|
|
- # - If sign is '=' set the rank to new_rank
|
219
|
|
- # - If sign is '-' set the rank to cur_rank - new_rank
|
220
|
|
- # - If sign is '+' set the rank to cur_rank + new_rank
|
221
|
|
- # @param new_rank int: The new_rank or rank modifier
|
222
|
|
- # @param sign str: Can be one of '=', '+', '-'
|
223
|
|
- # @return True if success False if fails
|
224
|
|
- # @throw TypeError If bad argument type
|
225
|
|
- # @throw ValueError if out of bound value
|
226
|
|
- def modify_rank(self,new_rank, sign='='):
|
227
|
|
- if not isinstance(new_rank, int) or not isinstance(sign, str):
|
228
|
|
- raise TypeError("Excepted <class int>, <class str>. But got "+str(type(new_rank))+", "+str(type(sign)))
|
229
|
|
-
|
230
|
|
- if sign == '+':
|
231
|
|
- return self.set_rank(self.rank + new_rank)
|
232
|
|
- elif sign == '-':
|
233
|
|
- return self.set_rank(self.rank - new_rank)
|
234
|
|
- elif sign == '=':
|
235
|
|
- return self.set_rank(new_rank)
|
236
|
|
- else:
|
237
|
|
- raise ValueError("Excepted one of '=', '+', '-' for sign argument, but got "+sign)
|
|
207
|
+ ## Modify a rank given an integer modifier
|
|
208
|
+ # @param rank_mod int : can be a negative positive or zero integer
|
|
209
|
+ # @throw TypeError if rank_mod is not an integer
|
|
210
|
+ # @throw ValueError if rank_mod is out of bound
|
|
211
|
+ def modify_rank(self, rank_mod):
|
|
212
|
+ if not isinstance(rank_mod, int):
|
|
213
|
+ raise TypeError("Excepted <class int>, <class str>. But got "+str(type(rank_mod))+", "+str(type(sign)))
|
|
214
|
+ try:
|
|
215
|
+ self.set_rank(self.rank + rank_mod)
|
|
216
|
+ except ValueError:
|
|
217
|
+ raise ValueError("The rank modifier '"+str(rank_mod)+"' is out of bounds")
|
238
|
218
|
|
239
|
219
|
## @brief Return a string representation of the component
|
240
|
220
|
# @return A string representation of the component
|