comparison roundup/rest.py @ 5595:65caddd54da2 REST-rebased

Handle operation for patch separately Patch remove operation is now able to remove element from list and dict, Added more test on new changes committer: Ralf Schlatterbeck <rsc@runtux.com>
author Chau Nguyen <dangchau1991@yahoo.com>
date Wed, 30 Jan 2019 10:26:35 +0100
parents 864cf6cb5790
children 55fa81de6a57
comparison
equal deleted inserted replaced
5594:864cf6cb5790 5595:65caddd54da2
10 import json 10 import json
11 import pprint 11 import pprint
12 import sys 12 import sys
13 import time 13 import time
14 import traceback 14 import traceback
15 import xml
15 from roundup import hyperdb 16 from roundup import hyperdb
16 from roundup.exceptions import * 17 from roundup.exceptions import *
17 18
18 19
19 def _data_decorator(func): 20 def _data_decorator(func):
221 if source is not None: 222 if source is not None:
222 result['error']['source'] = source 223 result['error']['source'] = source
223 224
224 return result 225 return result
225 226
227 def patch_data(self, op, old_val, new_val):
228 """Perform patch operation based on old_val and new_val
229
230 Args:
231 op (string): PATCH operation: add, replace, remove
232 old_val: old value of the property
233 new_val: new value of the property
234
235 Returns:
236 result (string): value after performed the operation
237 """
238 # add operation: If neither of the value is None, use the other one
239 # Otherwise, concat those 2 value
240 if op == 'add':
241 if old_val is None:
242 result = new_val
243 elif new_val is None:
244 result = old_val
245 else:
246 result = old_val + new_val
247 # Replace operation: new value is returned
248 elif op == 'replace':
249 result = new_val
250 # Remove operation:
251 # if old_val is not a list/dict, change it to None
252 # if old_val is a list/dict, but the parameter is empty,
253 # change it to none
254 # if old_val is a list/dict, and parameter is not empty
255 # proceed to remove the values from parameter from the list/dict
256 elif op == 'remove':
257 if isinstance(old_val, list):
258 if new_val is None:
259 result = []
260 elif isinstance(new_val, list):
261 result = [x for x in old_val if x not in new_val]
262 else:
263 if new_val in old_val:
264 old_val.remove(new_val)
265 elif isinstance(old_val, dict):
266 if new_val is None:
267 result = {}
268 elif isinstance(new_val, dict):
269 for x in new_val:
270 old_val.pop(x, None)
271 else:
272 old_val.pop(new_val, None)
273 else:
274 result = None
275 else:
276 raise UsageError('PATCH Operation %s is not allowed' % op)
277
278 return result
279
226 @_data_decorator 280 @_data_decorator
227 def get_collection(self, class_name, input): 281 def get_collection(self, class_name, input):
228 """GET resource from class URI. 282 """GET resource from class URI.
229 283
230 This function returns only items have View permission 284 This function returns only items have View permission
702 raise Unauthorised( 756 raise Unauthorised(
703 'Permission to edit %s of %s%s denied' % 757 'Permission to edit %s of %s%s denied' %
704 (prop, class_name, item_id) 758 (prop, class_name, item_id)
705 ) 759 )
706 760
707 if op == 'add': 761 props[prop] = self.patch_data(
708 props[prop] = class_obj.get(item_id, prop) + props[prop] 762 op, class_obj.get(item_id, prop), props[prop]
709 elif op == 'replace': 763 )
710 pass
711 elif op == 'remove':
712 current_prop = class_obj.get(item_id, prop)
713 if isinstance(current_prop, list):
714 props[prop] = []
715 else:
716 props[prop] = None
717 else:
718 raise UsageError('PATCH Operation %s is not allowed' % op)
719 764
720 try: 765 try:
721 result = class_obj.set(item_id, **props) 766 result = class_obj.set(item_id, **props)
722 self.db.commit() 767 self.db.commit()
723 except (TypeError, IndexError, ValueError), message: 768 except (TypeError, IndexError, ValueError), message:
774 prop: self.prop_from_arg( 819 prop: self.prop_from_arg(
775 class_obj, prop, input['data'].value, item_id 820 class_obj, prop, input['data'].value, item_id
776 ) 821 )
777 } 822 }
778 823
779 if op == 'add': 824 props[prop] = self.patch_data(
780 props[prop] = class_obj.get(item_id, prop) + props[prop] 825 op, class_obj.get(item_id, prop), props[prop]
781 elif op == 'replace': 826 )
782 pass
783 elif op == 'remove':
784 current_prop = class_obj.get(item_id, prop)
785 if isinstance(current_prop, list):
786 props[prop] = []
787 else:
788 props[prop] = None
789 else:
790 raise UsageError('PATCH Operation %s is not allowed' % op)
791 827
792 try: 828 try:
793 result = class_obj.set(item_id, **props) 829 result = class_obj.set(item_id, **props)
794 self.db.commit() 830 self.db.commit()
795 except (TypeError, IndexError, ValueError), message: 831 except (TypeError, IndexError, ValueError), message:

Roundup Issue Tracker: http://roundup-tracker.org/