Example #1
0
def direct_ccz(request, domain):
    """
    You must specify an app_id, and you may specify either 'version' or 'latest'
    latest can be one of:
        release: Latest starred version
        build: Latest version regardless of star
        save: Latest saved version of the application (even without a build)
    If 'version' and 'latest' aren't specified it will default to latest save
    You may also set 'include_multimedia=true' if you need multimedia.
    """
    def error(msg, code=400):
        return JsonResponse({'status': 'error', 'message': msg}, status=code)

    def get_app(app_id, version, latest):
        if version:
            return get_build_doc_by_version(domain, app_id, version)
        elif latest == 'build':
            return get_latest_build_doc(domain, app_id)
        elif latest == 'release':
            return get_latest_released_app_doc(domain, app_id)
        else:
            # either latest=='save' or they didn't specify
            return get_current_app(domain, app_id)

    app_id = request.GET.get('app_id', None)
    version = request.GET.get('version', None)
    latest = request.GET.get('latest', None)
    include_multimedia = request.GET.get('include_multimedia',
                                         'false').lower() == 'true'

    # Make sure URL params make sense
    if not app_id:
        return error("You must specify `app_id` in your GET parameters")
    if version and latest:
        return error("You can't specify both 'version' and 'latest'")
    if latest not in (
            None,
            'release',
            'build',
            'save',
    ):
        return error("latest must be either 'release', 'build', or 'save'")
    if version:
        try:
            version = int(version)
        except ValueError:
            return error("'version' must be an integer")

    try:
        app = get_app(app_id, version, latest)
        if not app:
            raise ResourceNotFound()
        app = app if isinstance(app, Document) else wrap_app(app)
    except (ResourceNotFound, DocTypeError):
        return error("Application not found", code=404)

    lang, langs = get_langs(request, app)

    with report_build_time(domain, app._id, 'live_preview'):
        return get_direct_ccz(domain, app, langs, version, include_multimedia)
Example #2
0
    def fetch_attachment(self, name, stream=False):
        """Get named attachment

        :param stream: When true, return a file-like object that can be
        read at least once (streamers should not expect to seek within
        or read the contents of the returned file more than once).
        """
        db = get_blob_db()
        try:
            try:
                key = self.external_blobs[name].key
            except KeyError:
                if self._migrating_blobs_from_couch:
                    return super(BlobMixin, self) \
                        .fetch_attachment(name, stream=stream)
                raise NotFound(name)
            blob = db.get(key=key)
        except NotFound:
            raise ResourceNotFound(
                "{model} {model_id} attachment: {name!r}".format(
                    model=type(self).__name__,
                    model_id=self._id,
                    name=name,
                ))
        if stream:
            return blob

        with blob:
            return blob.read()
Example #3
0
def get_cloudcare_app(domain, app_name):
    apps = get_cloudcare_apps(domain)
    app = filter(lambda x: x['name'] == app_name, apps)
    if app:
        return look_up_app_json(domain, app[0]['_id'])
    else:
        raise ResourceNotFound(_("Not found application by name: %s") % app_name)
Example #4
0
    def fetch_attachment(self, name, stream=False):
        """Get named attachment

        :param stream: When true, return a file-like object that can be
        read at least once (streamers should not expect to seek within
        or read the contents of the returned file more than once).
        """
        db = get_blob_db()
        try:
            try:
                meta = self.external_blobs[name]
            except KeyError:
                if self.migrating_blobs_from_couch:
                    return super(BlobMixin, self) \
                        .fetch_attachment(name, stream=stream)
                raise NotFound
            blob = db.get(meta.id, self._blobdb_bucket())
        except NotFound:
            raise ResourceNotFound(u"{model} attachment: {name!r}".format(
                                   model=type(self).__name__, name=name))
        if stream:
            return blob

        with blob:
            body = blob.read()
        try:
            body = body.decode("utf-8", "strict")
        except UnicodeDecodeError:
            # Return bytes on decode failure, otherwise unicode.
            # Ugly, but consistent with restkit.wrappers.Response.body_string
            pass
        return body
Example #5
0
def get_cloudcare_app(domain, app_name):
    apps = get_cloudcare_apps(domain)
    app = [x for x in apps if x['name'] == app_name]
    if app:
        return look_up_app_json(domain, app[0]['_id'])
    else:
        raise ResourceNotFound(_("Not found application by name: %s") % app_name)
Example #6
0
 def get(self, group_id):
     if group_id not in self.groups_by_id:
         group = Group.get(group_id)
         if group.domain != self.domain:
             raise ResourceNotFound()
         self.add_group(group)
     return self.groups_by_id[group_id]
Example #7
0
 def get_lite(cls, id):
     results = cls.get_db().view("case/get_lite",
                                 key=id,
                                 include_docs=False).one()
     if results is None:
         raise ResourceNotFound('no case with id %s exists' % id)
     return cls.wrap(results['value'])
Example #8
0
 def wrap(cls, data):
     if cls.__name__ == Repeater.__name__:
         cls_ = cls.get_class_from_doc_type(data['doc_type'])
         if cls_:
             return cls_.wrap(data)
         else:
             raise ResourceNotFound('Unknown repeater type: %s' % data)
     else:
         return super(Repeater, cls).wrap(data)
Example #9
0
 def get_lite(cls, id, wrap=True):
     from corehq.apps.hqcase.dbaccessors import get_lite_case_json
     results = get_lite_case_json(id)
     if results is None:
         raise ResourceNotFound('no case with id %s exists' % id)
     if wrap:
         return cls.wrap(results['value'])
     else:
         return results['value']
Example #10
0
 def wrap(cls, data):
     doc_type = data['doc_type'].replace(DELETED, '')
     if cls.__name__ == Repeater.__name__:
         if doc_type in repeater_types:
             return repeater_types[doc_type].wrap(data)
         else:
             raise ResourceNotFound('Unknown repeater type: %s', data)
     else:
         return super(Repeater, cls).wrap(data)
Example #11
0
    def put_attachment(self, content, name=None, content_type=None,
                       content_length=None, domain=None, type_code=None):
        """Put attachment in blob database

        See `get_short_identifier()` for restrictions on the upper bound
        for number of attachments per object.

        :param content: String or file object.
        """
        db = get_blob_db()

        if name is None:
            name = getattr(content, "name", None)
        if name is None:
            raise InvalidAttachment("cannot save attachment without name")
        if self._id is None:
            raise ResourceNotFound("cannot put attachment on unidentified document")
        if hasattr(self, "domain"):
            if domain is not None and self.domain != domain:
                raise ValueError("domain mismatch: %s != %s" % (self.domain, domain))
            domain = self.domain
        elif domain is None:
            raise ValueError("domain attribute or argument is required")
        old_meta = self.blobs.get(name)

        if isinstance(content, str):
            content = BytesIO(content.encode("utf-8"))
        elif isinstance(content, bytes):
            content = BytesIO(content)

        # do we need to worry about BlobDB reading beyond content_length?
        meta = db.put(
            content,
            domain=domain or self.domain,
            parent_id=self._id,
            name=name,
            type_code=(self._blobdb_type_code if type_code is None else type_code),
            content_type=content_type,
        )
        self.external_blobs[name] = BlobMetaRef(
            key=meta.key,
            blobmeta_id=meta.id,
            content_type=content_type,
            content_length=meta.content_length,
        )
        if self._migrating_blobs_from_couch and self._attachments:
            self._attachments.pop(name, None)
        if self._atomic_blobs is None:
            self.save()
            if old_meta and old_meta.key:
                db.delete(key=old_meta.key)
        elif old_meta and old_meta.key:
            self._atomic_blobs[name].append(old_meta.key)
        return True
Example #12
0
    def wrap(self, data):
        if 'is_sensitive' not in data and data.get('transform', None):
            data['is_sensitive'] = True

        if 'doc_type' in data and \
           self.__name__ == ExportColumn.__name__ and \
           self.__name__ != data['doc_type']:
            if data['doc_type'] in column_types:
                return column_types[data['doc_type']].wrap(data)
            else:
                raise ResourceNotFound('Unknown column type: %s', data)
        else:
            return super(ExportColumn, self).wrap(data)
Example #13
0
 def fetch_attachment(self, name, stream=False):
     if self._deferred_blobs and name in self._deferred_blobs:
         if self._deferred_blobs[name] is None:
             raise ResourceNotFound(
                 "{model} {model_id} attachment: {name!r}".format(
                     model=type(self).__name__,
                     model_id=self._id,
                     name=name,
                 ))
         body = self._deferred_blobs[name]["content"]
         if stream:
             return ClosingContextProxy(BytesIO(body))
         return body
     return super(DeferredBlobMixin, self).fetch_attachment(name, stream)
Example #14
0
 def get_with_attachments(form_id):
     doc = XFormInstance.get_db().get(form_id)
     doc = doc_types()[doc['doc_type']].wrap(doc)
     if doc.external_blobs:
         for name, meta in doc.external_blobs.items():
             with doc.fetch_attachment(name, stream=True) as content:
                 doc.deferred_put_attachment(
                     content,
                     name,
                     content_type=meta.content_type,
                     content_length=meta.content_length,
                 )
     else:
         # xforms are expected to at least have the XML attachment
         raise ResourceNotFound("XForm attachment missing: {}".format(form_id))
     return doc
Example #15
0
 def fetch_attachment(self, name, stream=False):
     if self._deferred_blobs and name in self._deferred_blobs:
         if self._deferred_blobs[name] is None:
             raise ResourceNotFound(
                 u"{model} {model_id} attachment: {name!r}".format(
                     model=type(self).__name__,
                     model_id=self._id,
                     name=name,
                 ))
         body = self._deferred_blobs[name]["content"]
         if stream:
             return ClosingContextProxy(StringIO(body))
         try:
             body = body.decode("utf-8", "strict")
         except UnicodeDecodeError:
             # Return bytes on decode failure, otherwise unicode.
             # Ugly, but consistent with restkit.wrappers.Response.body_string
             pass
         return body
     return super(DeferredBlobMixin, self).fetch_attachment(name, stream)
Example #16
0
def direct_ccz(request, domain):
    """
    You must specify an app_id, and you may specify either 'version' or 'latest'
    latest can be one of:
        release: Latest starred version
        build: Latest version regardless of star
        save: Latest saved version of the application (even without a build)
    If 'version' and 'latest' aren't specified it will default to latest save
    You may also set 'include_multimedia=true' if you need multimedia.
    """
    def error(msg, code=400):
        return json_response({
            'status': 'error',
            'message': msg
        },
                             status_code=code)

    def get_app(app_id, version, latest):
        if version:
            return get_build_doc_by_version(domain, app_id, version)
        elif latest == 'build':
            return get_latest_build_doc(domain, app_id)
        elif latest == 'release':
            return get_latest_released_app_doc(domain, app_id)
        else:
            # either latest=='save' or they didn't specify
            return get_current_app(domain, app_id)

    app_id = request.GET.get('app_id', None)
    version = request.GET.get('version', None)
    latest = request.GET.get('latest', None)
    include_multimedia = request.GET.get('include_multimedia',
                                         'false').lower() == 'true'

    # Make sure URL params make sense
    if not app_id:
        return error("You must specify `app_id` in your GET parameters")
    if version and latest:
        return error("You can't specify both 'version' and 'latest'")
    if latest not in (
            None,
            'release',
            'build',
            'save',
    ):
        return error("latest must be either 'release', 'build', or 'save'")
    if version:
        try:
            version = int(version)
        except ValueError:
            return error("'version' must be an integer")

    try:
        app = get_app(app_id, version, latest)
        if not app:
            raise ResourceNotFound()
        app = app if isinstance(app, Document) else wrap_app(app)
    except (ResourceNotFound, DocTypeError):
        return error("Application not found", code=404)

    if not app.copy_of:
        errors = app.validate_app()
    else:
        errors = None

    if errors:
        lang, langs = get_langs(request, app)
        error_html = render_to_string(
            "app_manager/partials/build_errors.html", {
                'request': request,
                'app': app,
                'build_errors': errors,
                'domain': domain,
                'langs': langs,
                'lang': lang
            })
        return json_response(
            {'error_html': error_html},
            status_code=400,
        )

    app.set_media_versions(None)
    download = FileDownload('application-{}-{}'.format(app_id, version))
    errors = build_application_zip(
        include_multimedia_files=include_multimedia,
        include_index_files=True,
        app=app,
        download_id=download.download_id,
        compress_zip=True,
        filename='{}.ccz'.format(slugify(app.name)),
    )

    if errors is not None and errors['errors']:
        return json_response(
            errors,
            status_code=400,
        )
    return FileDownload.get(download.download_id).toHttpResponse()
Example #17
0
def get_current_app_doc(domain, app_id):
    from .models import Application
    app = Application.get_db().get(app_id)
    if app.get('domain', None) != domain:
        raise ResourceNotFound()
    return app
Example #18
0
 def _blobdb_bucket(self):
     if self._id is None:
         raise ResourceNotFound(
             "cannot manipulate attachment on unidentified document")
     return join(_get_couchdb_name(type(self)), safe_id(self._id))