Browse Source

Handling rank sorting in Model and rank modifier in EmComponent

Yann Weber 9 years ago
parent
commit
8bf864c597
2 changed files with 42 additions and 53 deletions
  1. 30
    50
      EditorialModel/components.py
  2. 12
    3
      EditorialModel/model.py

+ 30
- 50
EditorialModel/components.py View File

@@ -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

+ 12
- 3
EditorialModel/model.py View File

@@ -58,9 +58,9 @@ class Model(object):
58 58
             else:
59 59
                 raise ValueError("Unknow EmComponent class : '" + cls_name + "'")
60 60
 
61
-        for emclass in Model.components_class:
62
-            comp_list = self.components(emclass)
63
-            self._components[self.name_from_emclass] = sorted(comp_list, key=lambda cur_comp: cur_comp.rank)
61
+        #Sorting by rank
62
+        for component_class in Model.components_class:
63
+            self.sort_components(component_class)
64 64
 
65 65
         # TODO : check integrity
66 66
 
@@ -81,6 +81,15 @@ class Model(object):
81 81
     def component(self, uid):
82 82
         return False if uid not in self._components['uids'] else self._components['uids'][uid]
83 83
 
84
+    ## Sort components by rank in Model::_components
85
+    # @param emclass pythonClass : The type of components to sort
86
+    # @throw AttributeError if emclass is not valid
87
+    def sort_components(self, component_class):
88
+        if component_class not in self.components_class:
89
+            raise AttributeError("Bad argument emclass : '"+emclass+"', excpeting one of "+str(self.components_class))
90
+
91
+        self._components[self.name_from_emclass(component_class)] = sorted(self.components(component_class), key=lambda comp: comp.rank)
92
+
84 93
     ## Return a new uid
85 94
     # @return a new uid
86 95
     def new_uid(self):

Loading…
Cancel
Save