# Copyright (C) 2012 Aleksey Lim # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from cStringIO import StringIO from os.path import isdir, abspath from sugar_network.toolkit import enforce from client import Client _logger = logging.getLogger('sugar_network.objects') class Object(object): def __init__(self, document, reply, guid=None, props=None, offset=None, **kwargs): self.document = document self._reply = reply or [] self._guid = guid self._props = props or {} self._dirty = set() self.offset = offset for prop, value in kwargs.items(): self[prop] = value @property def guid(self): return self._guid @property def is_author(self): return Client.sugar_uid in [(i.get('guid') or i.get('name')) for i in self['author']] def get(self, prop): if prop == 'guid': return self._guid result = self._props.get(prop) if result is None: enforce(prop in self._reply, 'Access to not requested %r property in %r', prop, self.document) self.fetch() result = self._props.get(prop) return result def fetch(self, props=None): enforce(self._guid, 'Object needs to be posted first') to_fetch = [] for prop in (props or self._reply): if prop not in self._props: to_fetch.append(prop) if not to_fetch: return response = Client.call('GET', [self.document, self._guid], reply=to_fetch) response.update(self._props) self._props = response def post(self): if not self._dirty: return props = {} for i in self._dirty: props[i] = self._props.get(i) if self._guid: Client.call('PUT', [self.document, self._guid], content=props) else: self._guid = Client.call('POST', [self.document], content=props) self._dirty.clear() return self._guid def get_blob(self, prop): return Client.call('GET', [self.document, self._guid, prop]) def upload_blob(self, prop, content, content_type): enforce(self._guid, 'Object needs to be posted first') Client.call('PUT', [self.document, self._guid, prop], content=content, content_type=content_type) def __getitem__(self, prop): result = self.get(prop) enforce(result is not None, KeyError, 'Property %r is absent in %r', prop, self.document) return result def __setitem__(self, prop, value): enforce(prop != 'guid', 'Property "guid" is read-only') if self._props.get(prop) == value: return self._props[prop] = value self._dirty.add(prop) def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.post()