def save(self, **params): if hasattr(self, '_PRE_SAVE'): for pre_save in self._PRE_SAVE: pre_save() def del_pre_save(): del self._PRE_SAVE self.register_post_save(del_pre_save) _attachments = self._attachments.copy() if self._attachments else {} for name, info in self._LAZY_ATTACHMENTS.items(): self.__remove_cached_attachment(name) data = info['content'] content_type = (info['content_type'] or ';'.join(filter(None, guess_type(name)))) if isinstance(data, unicode): data = data.encode('utf8') _attachments[name] = { 'content_type': content_type, 'data': data, } self._attachments = encode_attachments(_attachments) super(LazyAttachmentDoc, self).save(encode_attachments=False, **params) if hasattr(self, '_POST_SAVE'): for post_save in self._POST_SAVE: post_save() del self._POST_SAVE
def save(self, **params): if hasattr(self, "_PRE_SAVE"): for pre_save in self._PRE_SAVE: pre_save() def del_pre_save(): del self._PRE_SAVE self.register_post_save(del_pre_save) _attachments = self._attachments.copy() if self._attachments else {} for name, info in self._LAZY_ATTACHMENTS.items(): self.__remove_cached_attachment(name) data = info["content"] content_type = info["content_type"] or ";".join(filter(None, guess_type(name))) if isinstance(data, unicode): data = data.encode("utf8") _attachments[name] = {"content_type": content_type, "data": data} self._attachments = encode_attachments(_attachments) super(LazyAttachmentDoc, self).save(encode_attachments=False, **params) if hasattr(self, "_POST_SAVE"): for post_save in self._POST_SAVE: post_save() del self._POST_SAVE
def save(self, **params): if hasattr(self, '_PRE_SAVE'): for pre_save in self._PRE_SAVE: pre_save() def del_pre_save(): del self._PRE_SAVE self.register_post_save(del_pre_save) _attachments = self._attachments.copy() if self._attachments else {} for name, info in self._LAZY_ATTACHMENTS.items(): self.__remove_cached_attachment(name) data = info['content'] content_type = (info['content_type'] or ';'.join([_f for _f in guess_type(name) if _f])) if isinstance(data, unicode): data = data.encode('utf8') _attachments[name] = { 'content_type': content_type, 'data': data, } self._attachments = encode_attachments(_attachments) super(LazyAttachmentDoc, self).save(encode_attachments=False, **params) if hasattr(self, '_POST_SAVE'): for post_save in self._POST_SAVE: post_save() del self._POST_SAVE
def save_doc(self, doc, encode_attachments=True, force_update=False, _raw_json=False, **params): """ Save a document. It will use the `_id` member of the document or request a new uuid from CouchDB. IDs are attached to documents on the client side because POST has the curious property of being automatically retried by proxies in the event of network segmentation and lost responses. (Idee from `Couchrest <http://github.com/jchris/couchrest/>`) @param doc: dict. doc is updated with doc '_id' and '_rev' properties returned by CouchDB server when you save. @param force_update: boolean, if there is conlict, try to update with latest revision @param _raw_json: return raw json instead deserializing it @param params, list of optionnal params, like batch="ok" with `_raw_json=True` It return raw response. If False it update doc instance with new revision (if batch=False). @return res: result of save. doc is updated in the mean time """ if doc is None: doc = {} if '_attachments' in doc and encode_attachments: doc['_attachments'] = resource.encode_attachments(doc['_attachments']) if '_id' in doc: docid = doc['_id'] docid1 = resource.escape_docid(doc['_id']) try: res = maybe_raw(self.res.put(docid1, payload=doc, **params), raw=_raw_json) except resource.ResourceConflict: if force_update: doc['_rev'] = self.get_rev(docid) res = maybe_raw(self.res.put(docid1, payload=doc, **params), raw=_raw_json) else: raise else: try: doc['_id'] = self.server.next_uuid() res = maybe_raw(self.res.put(doc['_id'], payload=doc, **params), raw=_raw_json) except: res = maybe_raw(self.res.post(payload=doc, **params), raw=_raw_json) if _raw_json: return res if 'batch' in params and 'id' in res: doc.update({ '_id': res['id']}) else: doc.update({'_id': res['id'], '_rev': res['rev']}) return res
def create_xform_from_xml(xml_string, _id=None, process=None): """ create and save an XFormInstance from an xform payload (xml_string) optionally set the doc _id to a predefined value (_id) return doc _id of the created doc `process` is transformation to apply to the form right before saving This is to avoid having to save multiple times If xml_string is bad xml - raise couchforms.XMLSyntaxError - do not save form """ json_form = convert_xform_to_json(xml_string) _id = _id or _extract_meta_instance_id(json_form) kwargs = dict( _attachments=resource.encode_attachments({ "form.xml": { "content_type": "text/xml", "data": xml_string, }, }), form=json_form, xmlns=json_form.get('@xmlns'), received_on=datetime.datetime.utcnow(), ) if _id: kwargs['_id'] = _id xform = XFormInstance(**kwargs) try: if process: process(xform) except Exception: # if there's any problem with process just save what we had before # rather than whatever intermediate state `process` left it in xform = XFormInstance(**kwargs) raise finally: lock = acquire_lock_for_xform(_id) if _id else None with ReleaseOnError(lock): try: xform.save(encode_attachments=False) except ResourceConflict: raise DuplicateError() if not lock: lock = acquire_lock_for_xform(_id) return LockManager(xform.get_id, lock)