def traverse_object(obj, callback, seen=None): seen = seen or set() if isinstance(obj, leancloud.Object): if obj in seen: return seen.add(obj) traverse_object(obj._attributes, callback, seen) return callback(obj) if isinstance(obj, (leancloud.Relation, leancloud.File)): return callback(obj) if isinstance(obj, (list, tuple)): for idx, child in enumerate(obj): new_child = traverse_object(child, callback, seen) if new_child: obj[idx] = new_child return callback(obj) if isinstance(obj, dict): for key, child in iteritems(obj): new_child = traverse_object(child, callback, seen) if new_child: obj[key] = new_child return callback(obj) return callback(obj)
def decode(key, value): if isinstance(value, get_dumpable_types()): return value if isinstance(value, (tuple, list)): return [decode(key, x) for x in value] if not isinstance(value, dict): return value if '__type' not in value: return dict([(k, decode(k, v)) for k, v in iteritems(value)]) _type = value['__type'] if _type == 'Pointer': value = copy.deepcopy(value) class_name = value['className'] pointer = leancloud.Object.create(class_name) if 'createdAt' in value: value.pop('__type') value.pop('className') pointer._update_data(value) else: pointer._update_data({'objectId': value['objectId']}) return pointer if _type == 'Object': value = copy.deepcopy(value) class_name = value['className'] value.pop('__type') value.pop('className') obj = leancloud.Object.create(class_name) obj._update_data(value) return obj if _type == 'Date': return arrow.get(iso8601.parse_date(value['iso'])).to('local').datetime if _type == 'GeoPoint': return leancloud.GeoPoint(latitude=value['latitude'], longitude=value['longitude']) if key == 'ACL': if isinstance(value, leancloud.ACL): return value return leancloud.ACL(value) if _type == 'Relation': relation = leancloud.Relation(None, key) relation.target_class_name = value['className'] return relation if _type == 'File': f = leancloud.File(value['name']) meta_data = value.get('metaData') if meta_data: f._metadata = meta_data f._url = value['url'] f.id = value['objectId'] return f
def _finish_fetch(self, server_data, existed): self._op_set_queue = [{}] self._merge_magic_field(server_data) for key, value in iteritems(server_data): self._server_data[key] = utils.decode(key, value) self._rebuild_attributes() self._op_set_queue = [{}] self._existed = existed
def _finish_save(self, server_data): saved_changes = self._op_set_queue[0] self._op_set_queue = self._op_set_queue[1:] self._apply_op_set(saved_changes, self._server_data) self._merge_magic_field(server_data) for key, value in iteritems(server_data): self._server_data[key] = utils.decode(key, value) self._rebuild_attributes()
def get(url, params=None, headers=None): if not params: params = {} else: for k, v in iteritems(params): if isinstance(v, dict): params[k] = json.dumps(v, separators=(',', ':')) response = requests.get(get_base_url() + url, headers=headers, params=params, timeout=TIMEOUT_SECONDS) return response
def _cancel_save(self): failed_changes = self._op_set_queue.pop(0) next_changes = self._op_set_queue[0] for key, op in iteritems(failed_changes): op1 = failed_changes[key] op2 = next_changes[key] if op1 and op2: next_changes[key] = op2._merge(op1) elif op1: next_changes[key] = op1
def _dump(self): obj = copy.deepcopy(self._attributes) for k, v in iteritems(obj): obj[k] = utils.encode(v) if self.id is not None: obj['objectId'] = self.id obj['__type'] = 'Object' obj['className'] = self._class_name return obj
def __init__(self, **attrs): """ 创建一个新的 leancloud.Object :param attrs: 对象属性 :return: """ self.id = None self._class_name = self._class_name # for IDE self._changes = {} self._attributes = {} self.created_at = None self.updated_at = None self.fetch_when_save = False for k, v in iteritems(attrs): self.set(k, v)
def __init__(self, **attrs): """ 创建一个新的 leancloud.Object :param attrs: 对象属性 :return: """ self.id = None self._class_name = self._class_name # for IDE self._changes = {} self._attributes = {} self._flags = {} self.created_at = None self.updated_at = None for k, v in iteritems(attrs): self.set(k, v)
def encode(value, disallow_objects=False): if isinstance(value, LocalProxy): value = value._get_current_object() if isinstance(value, datetime): tzinfo = value.tzinfo if tzinfo is None: tzinfo = tz.tzlocal() result = OrderedDict() result["__type"] = "Date" result["iso"] = arrow.get( value, tzinfo).to('utc').format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z' return result if isinstance(value, leancloud.Object): if disallow_objects: raise ValueError('leancloud.Object not allowed') return value._to_pointer() if isinstance(value, leancloud.File): if not value.url and not value.id: raise ValueError( 'Tried to save an object containing an unsaved file.') return { '__type': 'File', 'id': value.id, 'name': value.name, 'url': value.url, } if isinstance(value, get_dumpable_types()): return value.dump() if isinstance(value, (tuple, list)): return [encode(x, disallow_objects) for x in value] if isinstance(value, dict): return dict([(k, encode(v, disallow_objects)) for k, v in iteritems(value)]) return value
def encode(value, disallow_objects=False): if isinstance(value, LocalProxy): value = value._get_current_object() if isinstance(value, datetime): tzinfo = value.tzinfo if tzinfo is None: tzinfo = tz.tzlocal() return { '__type': 'Date', 'iso': arrow.get(value, tzinfo).to('utc').format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z', } if isinstance(value, leancloud.Object): if disallow_objects: raise ValueError('leancloud.Object not allowed') return value._to_pointer() if isinstance(value, leancloud.File): if not value.url and not value.id: raise ValueError('Tried to save an object containing an unsaved file.') return { '__type': 'File', 'id': value.id, 'name': value.name, 'url': value.url, } if isinstance(value, get_dumpable_types()): return value.dump() if isinstance(value, (tuple, list)): return [encode(x, disallow_objects) for x in value] if isinstance(value, dict): return dict([(k, encode(v, disallow_objects)) for k, v in iteritems(value)]) return value
def __init__(self, **attrs): """ 创建一个新的 leancloud.Object :param attrs: 对象属性 :return: """ self.id = None self._class_name = self._class_name # for IDE self._server_data = {} self._op_set_queue = [{}] self._attributes = {} self._existed = False self.created_at = None self.updated_at = None self.fetch_when_save = False for k, v in iteritems(attrs): self.set(k, v)
def _dump_save(self): return {k:v.dump() for k,v in iteritems(self._changes)}
def _apply_op_set(self, op_set, target): for key, change in iteritems(op_set): target[key] = change._apply(target.get(key), self, key) if target[key] == operation._UNSET: del target[key]
def _dump_save(self): result = copy.deepcopy(self._op_set_queue[0]) for k, v in iteritems(result): result[k] = v.dump() return result
def _update_data(self, server_data): self._merge_metadata(server_data) for key, value in iteritems(server_data): self._attributes[key] = utils.decode(key, value) self._changes = {}
def _dump_save(self): data = {k: v.dump() for k, v in iteritems(self._changes)} data.update(self._flags) return data