Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
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)
Esempio n. 6
0
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)