def get_model_class(self, application, model):
        """Klasse zu 'model' zurückgeben."""

        for model_class in self._registry:
            if model == xdb_kind(
                    model_class) and application == util.get_app_name(
                        model_class):
                return model_class
Beispiel #2
0
    def get(self):
        """Zeige Template mit allen registrierten Models an"""

        apps = {}
        for model_class in site.registry.keys():
            application = get_app_name(model_class)
            apps.setdefault(application, []).append(xdb_kind(model_class))
        self.render({'apps': apps}, 'admin/index.html')
Beispiel #3
0
    def export_view_xls(self, handler, extra_context=None):  # pylint: disable=W0613
        """Request zum Exportieren von allen Objekten behandeln.

        `extra_context` ist für die Signatur erforderlich, wird aber nicht genutzt.
        """
        exporter = modelexporter.ModelExporter(self.model)
        filename = '%s-%s.xls' % (compat.xdb_kind(self.model), datetime.datetime.now())
        handler.response.headers['Content-Type'] = 'application/msexcel'
        handler.response.headers['content-disposition'] = \
            'attachment; filename=%s' % filename
        exporter.to_xls(handler.response)
    def export_view_xls(self, handler, extra_context=None):  # pylint: disable=W0613
        """Request zum Exportieren von allen Objekten behandeln.

        `extra_context` ist für die Signatur erforderlich, wird aber nicht genutzt.
        """
        exporter = modelexporter.ModelExporter(self.model)
        filename = '%s-%s.xls' % (compat.xdb_kind(
            self.model), datetime.datetime.now())
        handler.response.headers['Content-Type'] = 'application/msexcel'
        handler.response.headers['content-disposition'] = \
            'attachment; filename=%s' % filename
        exporter.to_xls(handler.response)
Beispiel #5
0
    def export_view_csv(self, handler, extra_context=None):  # pylint: disable=W0613
        """Request zum Exportieren von allen Objekten behandeln.

        `extra_context` ist für die Signatur erforderlich, wird aber nicht genutzt.
        """
        # irgendwann werden wir hier einen longtask nutzen muessen
        exporter = modelexporter.ModelExporter(self.model)
        filename = '%s-%s.csv' % (compat.xdb_kind(self.model), datetime.datetime.now())
        handler.response.headers['Content-Type'] = 'text/csv; charset=utf-8'
        handler.response.headers['content-disposition'] = \
            'attachment; filename=%s' % filename
        exporter.to_csv(handler.response)
    def export_view_csv(self, handler, extra_context=None):  # pylint: disable=W0613
        """Request zum Exportieren von allen Objekten behandeln.

        `extra_context` ist für die Signatur erforderlich, wird aber nicht genutzt.
        """
        # irgendwann werden wir hier einen longtask nutzen muessen
        exporter = modelexporter.ModelExporter(self.model)
        filename = '%s-%s.csv' % (compat.xdb_kind(
            self.model), datetime.datetime.now())
        handler.response.headers['Content-Type'] = 'text/csv; charset=utf-8'
        handler.response.headers['content-disposition'] = \
            'attachment; filename=%s' % filename
        exporter.to_csv(handler.response)
Beispiel #7
0
def upload_to_blobstore(obj, key_name, blob):
    """
    Lade ein Datei-ähnliches Objekt in den Blobstore

    Der Rückgabewert ist der Blob-Key des neuen Objekts.
    """
    mime_type, _ = mimetypes.guess_type(blob.filename)
    bucket = getattr(config, 'GCS_BUCKET_NAME', app_identity.get_default_gcs_bucket_name())
    file_name = '/%s/admin/%s/%s/%s' % (bucket, xdb_kind(obj), key_name, blob.filename)
    with cloudstorage.open(file_name, 'w', content_type=mime_type) as fileobj:
        while blob.file:
            data = blob.file.read(8192)
            if not data:
                break
            fileobj.write(data)
    return blobstore.BlobKey(blobstore.create_gs_key('/gs' + file_name))
    def get_impl(self, typ, additional_context=None):
        query = self.prepare_query()
        model_class = compat.xdb_kind_from_query(query)
        kind = compat.xdb_kind(model_class)
        if not self.filename:
            self.filename = u'%s-%s-%s' % (kind, datetime.datetime.now(),
                                           self.credential.uid)

        exporter = modelexporter.ModelExporter(model_class,
                                               query=query,
                                               uid=self.credential.uid,
                                               **self.exporter_config)

        typ = typ.strip('/')
        if typ in {'xls', 'csv'}:
            self.check_download_permission()
            self.handle_download(typ, kind, exporter)
        else:
            loginfo = gaetk_ExportLog.query(
                gaetk_ExportLog.tablename == kind).order(
                    -gaetk_ExportLog.created_at).fetch_async(10)

            rowtemplate, headtemplate = self.get_rowtemplate(exporter)

            myvalues = self.default_template_vars({})

            values = dict(
                title=myvalues.get('title', self.title),
                widetable=self.widetable,
                filename=self.filename,
                downloadlog=loginfo.get_result(),
                header=self.header,
                rowtemplate=rowtemplate,
                headtemplate=headtemplate,
            )

            values.update(self.get_pagination(query))

            if additional_context:
                values.update(additional_context)

            if self.request.path.endswith('.html'):
                parsed_url = urlparse.urlparse(self.request.path)
                values[
                    'listviewer_urlbase'] = '://' + parsed_url.netloc + parsed_url.path

            self.render(values, self.template)
Beispiel #9
0
    def register(self, model_class, admin_class=None):
        """Registers the given model with the given admin class."""

        # We have some very nasty problems with cyclic imports
        # site registry depends on options and options depends
        # on a lot of stuff which depends on the site registry
        # if we would be able to break the dependency between the registry
        # AdminSite and ModelAdmin things would be much easier.
        if admin_class is None:
            admin_class = ModelAdmin

        # # Don't import the humongous validation code unless required
        # if admin_class and settings.DEBUG:
        #     from django.contrib.admin.validation import validate
        # else:
        #     validate = lambda model, adminclass: None

        if model_class in self._registry:
            logging.warn(u'The model %s is already registered', xdb_kind(model_class))

        # Instantiate the admin class to save in the registry
        self._registry[model_class] = admin_class(model_class, self)
Beispiel #10
0
    def register(self, model_class, admin_class=None):
        """Registers the given model with the given admin class."""

        # We have some very nasty problems with cyclic imports
        # site registry depends on options and options depends
        # on a lot of stuff which depends on the site registry
        # if we would be able to break the dependency between the registry
        # AdminSite and ModelAdmin things would be much easier.
        if admin_class is None:
            admin_class = ModelAdmin

        # # Don't import the humongous validation code unless required
        # if admin_class and settings.DEBUG:
        #     from django.contrib.admin.validation import validate
        # else:
        #     validate = lambda model, adminclass: None

        if model_class in self._registry:
            logger.warn(u'The model %s is already registered',
                        xdb_kind(model_class))

        # Instantiate the admin class to save in the registry
        self._registry[model_class] = admin_class(model_class, self)
Beispiel #11
0
    def add_view(self, handler, extra_context=None):
        """View zum Hinzufügen eines neuen Objekts"""
        form_class = self.get_form()

        # Standardmaessig lassen wir die App Engine fuer das Model automatisch einen
        # Key generieren. Es besteht jedoch in der Admin-Klasse die Moeglichkeit, via
        # 'db_key_field=[propertyname]' ein Feld festzulegen, dessen Inhalt im Formular
        # als Key beim Erzeugen der Instanz genutzt wird.
        admin_class = site.get_admin_class(self.model)
        key_field = None
        if admin_class and hasattr(admin_class, 'db_key_field'):
            key_field = admin_class.db_key_field

        # Wenn das Formular abgeschickt wurde und gültig ist,
        # speichere das veränderte Objekt und leite auf die Übersichtsseite um.
        if handler.request.method == 'POST':
            form = form_class(handler.request.POST)

            if form.validate():
                form_data = self._convert_property_data(form.data)
                key_name = form_data.get(key_field) if key_field else None

                # TODO: util.create_instance nutzen oder entfernen
                if hasattr(self.model, 'create'):
                    factory = self.model.create
                else:
                    factory = self.model

                if issubclass(self.model, ndb.Model):
                    obj = factory(id=key_name, **form_data)
                else:
                    obj = factory(key_name=key_name, **form_data)

                # Beim Anlegen muss dann halt einmal gespeichert werden,
                # ansonsten ist der ID unbekannt.
                if self.blob_upload_fields and key_name is None:
                    key_name = compat.xdb_id_or_name(obj.put())
                    self.handle_blobstore_fields(handler, obj, key_name)

                key = obj.put()
                handler.add_message(
                    'success',
                    u'<strong><a href="/admin/{}/{}/{}/">{} {}</a></strong> wurde angelegt.'
                    .format(util.get_app_name(self.model),
                            compat.xdb_kind(self.model),
                            compat.xdb_str_key(key),
                            compat.xdb_kind(self.model),
                            compat.xdb_id_or_name(key)))

                # Indexierung für Admin-Volltextsuche
                from gaetk.admin.search import add_to_index
                deferred.defer(add_to_index, key)

                # Call post-create-hooks
                if isinstance(self.post_create_hooks, collections.Iterable):
                    for hook in self.post_create_hooks:
                        deferred.defer(util.call_hook, hook,
                                       compat.xdb_str_key(key))

                raise gaetk.handler.HTTP302_Found(location='..')
        else:
            form = form_class()

        template_values = {
            'form': form,
            'field_args': self.field_args,
            'admin_class': self
        }
        if extra_context is not None:
            template_values.update(extra_context)
        handler.render(template_values, self.get_template('add'))
Beispiel #12
0
    def change_view(self, handler, object_id, extra_context=None):
        """View zum Bearbeiten eines vorhandenen Objekts"""

        obj = self.get_object(object_id)
        if obj is None:
            raise gaetk.handler.HTTP404_NotFound

        model_class = type(obj)
        form_class = self.get_form()

        if handler.request.get('delete') == 'yesiwant':
            # Der User hat gebeten, dieses Objekt zu löschen.
            key = compat.xdb_key(obj)
            data = compat.xdb_to_protobuf(obj)
            dblayer = 'ndb' if compat.xdb_is_ndb(obj) else 'db'
            archived = DeletedObject(key_name=str(key),
                                     model_class=model_class.__name__,
                                     old_key=str(key),
                                     dblayer=dblayer,
                                     data=data)
            archived.put()
            # Indexierung für Admin-Volltextsuche
            from gaetk.admin.search import remove_from_index
            if compat.xdb_is_ndb(obj):
                obj.key.delete()
                deferred.defer(remove_from_index, obj.key)
            else:
                obj.delete()
                deferred.defer(remove_from_index, obj.key())

            handler.add_message(
                'warning',
                u'<strong>{} {}</strong> wurde gelöscht. <a href="{}">Objekt wiederherstellen!</a>'
                .format(compat.xdb_kind(self.model),
                        compat.xdb_id_or_name(key), archived.undelete_url()))
            raise gaetk.handler.HTTP302_Found(
                location='/admin/%s/%s/' %
                (util.get_app_name(model_class), compat.xdb_kind(model_class)))

        # Wenn das Formular abgeschickt wurde und gültig ist,
        # speichere das veränderte Objekt und leite auf die Übersichtsseite um.
        if handler.request.method == 'POST':
            form = form_class(handler.request.POST)
            if form.validate():
                key_name = compat.xdb_id_or_name(compat.xdb_key(obj))
                self.handle_blobstore_fields(handler, obj, key_name)
                if hasattr(obj, 'update'):
                    obj.update(form.data)
                else:
                    form.populate_obj(obj)
                key = obj.put()
                handler.add_message(
                    'success',
                    u'<strong><a href="/admin/{}/{}/{}/">{} {}</a></strong> wurde gespeichert.'
                    .format(util.get_app_name(self.model),
                            compat.xdb_kind(self.model),
                            compat.xdb_str_key(key),
                            compat.xdb_kind(self.model),
                            compat.xdb_id_or_name(key)))

                # Indexierung für Admin-Volltextsuche
                from gaetk.admin.search import add_to_index
                deferred.defer(add_to_index, key)
                raise gaetk.handler.HTTP302_Found(
                    location='/admin/%s/%s/' % (util.get_app_name(model_class),
                                                compat.xdb_kind(model_class)))
        else:
            form = form_class(obj=obj)

        template_values = {
            'object': obj,
            'form': form,
            'field_args': self.field_args,
            'admin_class': self
        }
        if extra_context is not None:
            template_values.update(extra_context)
        handler.render(template_values, self.get_template('change'))
Beispiel #13
0
    def get_model_class(self, application, model):
        """Klasse zu 'model' zurückgeben."""

        for model_class in self._registry:
            if model == xdb_kind(model_class) and application == util.get_app_name(model_class):
                return model_class
Beispiel #14
0
    def add_view(self, handler, extra_context=None):
        """View zum Hinzufügen eines neuen Objekts"""
        form_class = self.get_form()

        # Standardmaessig lassen wir die App Engine fuer das Model automatisch einen
        # Key generieren. Es besteht jedoch in der Admin-Klasse die Moeglichkeit, via
        # 'db_key_field=[propertyname]' ein Feld festzulegen, dessen Inhalt im Formular
        # als Key beim Erzeugen der Instanz genutzt wird.
        admin_class = site.get_admin_class(self.model)
        key_field = None
        if admin_class and hasattr(admin_class, 'db_key_field'):
            key_field = admin_class.db_key_field

        # Wenn das Formular abgeschickt wurde und gültig ist,
        # speichere das veränderte Objekt und leite auf die Übersichtsseite um.
        if handler.request.method == 'POST':
            form = form_class(handler.request.POST)

            if form.validate():
                form_data = self._convert_property_data(form.data)
                key_name = form_data.get(key_field) if key_field else None

                # TODO: util.create_instance nutzen oder entfernen
                if hasattr(self.model, 'create'):
                    factory = self.model.create
                else:
                    factory = self.model

                if issubclass(self.model, ndb.Model):
                    obj = factory(id=key_name, **form_data)
                else:
                    obj = factory(key_name=key_name, **form_data)

                # Beim Anlegen muss dann halt einmal gespeichert werden,
                # ansonsten ist der ID unbekannt.
                if self.blob_upload_fields and key_name is None:
                    key_name = compat.xdb_id_or_name(obj.put())
                    self.handle_blobstore_fields(handler, obj, key_name)

                key = obj.put()
                handler.add_message(
                    'success',
                    u'<strong><a href="/admin/{}/{}/{}/">{} {}</a></strong> wurde angelegt.'.format(
                        util.get_app_name(self.model),
                        compat.xdb_kind(self.model),
                        compat.xdb_str_key(key),
                        compat.xdb_kind(self.model),
                        compat.xdb_id_or_name(key)))

                # Indexierung für Admin-Volltextsuche
                from gaetk.admin.search import add_to_index
                deferred.defer(add_to_index, key)

                # Call post-create-hooks
                if isinstance(self.post_create_hooks, collections.Iterable):
                    for hook in self.post_create_hooks:
                        deferred.defer(util.call_hook, hook, compat.xdb_str_key(key))

                raise gaetk.handler.HTTP302_Found(location='..')
        else:
            form = form_class()

        template_values = {'form': form, 'field_args': self.field_args, 'admin_class': self}
        if extra_context is not None:
            template_values.update(extra_context)
        handler.render(template_values, self.get_template('add'))
Beispiel #15
0
    def change_view(self, handler, object_id, extra_context=None):
        """View zum Bearbeiten eines vorhandenen Objekts"""

        obj = self.get_object(object_id)
        if obj is None:
            raise gaetk.handler.HTTP404_NotFound

        model_class = type(obj)
        form_class = self.get_form()

        if handler.request.get('delete') == 'yesiwant':
            # Der User hat gebeten, dieses Objekt zu löschen.
            key = compat.xdb_key(obj)
            data = compat.xdb_to_protobuf(obj)
            dblayer = 'ndb' if compat.xdb_is_ndb(obj) else 'db'
            archived = DeletedObject(key_name=str(key), model_class=model_class.__name__,
                                     old_key=str(key), dblayer=dblayer, data=data)
            archived.put()
            # Indexierung für Admin-Volltextsuche
            from gaetk.admin.search import remove_from_index
            if compat.xdb_is_ndb(obj):
                obj.key.delete()
                deferred.defer(remove_from_index, obj.key)
            else:
                obj.delete()
                deferred.defer(remove_from_index, obj.key())

            handler.add_message(
                'warning',
                u'<strong>{} {}</strong> wurde gelöscht. <a href="{}">Objekt wiederherstellen!</a>'.format(
                    compat.xdb_kind(self.model), compat.xdb_id_or_name(key), archived.undelete_url()))
            raise gaetk.handler.HTTP302_Found(location='/admin/%s/%s/' % (
                util.get_app_name(model_class), compat.xdb_kind(model_class)))

        # Wenn das Formular abgeschickt wurde und gültig ist,
        # speichere das veränderte Objekt und leite auf die Übersichtsseite um.
        if handler.request.method == 'POST':
            form = form_class(handler.request.POST)
            if form.validate():
                key_name = compat.xdb_id_or_name(compat.xdb_key(obj))
                self.handle_blobstore_fields(handler, obj, key_name)
                if hasattr(obj, 'update'):
                    obj.update(form.data)
                else:
                    form.populate_obj(obj)
                key = obj.put()
                handler.add_message(
                    'success',
                    u'<strong><a href="/admin/{}/{}/{}/">{} {}</a></strong> wurde gespeichert.'.format(
                        util.get_app_name(self.model),
                        compat.xdb_kind(self.model),
                        compat.xdb_str_key(key),
                        compat.xdb_kind(self.model),
                        compat.xdb_id_or_name(key)))

                # Indexierung für Admin-Volltextsuche
                from gaetk.admin.search import add_to_index
                deferred.defer(add_to_index, key)
                raise gaetk.handler.HTTP302_Found(location='/admin/%s/%s/' % (
                    util.get_app_name(model_class), compat.xdb_kind(model_class)))
        else:
            form = form_class(obj=obj)

        template_values = {'object': obj, 'form': form, 'field_args': self.field_args, 'admin_class': self}
        if extra_context is not None:
            template_values.update(extra_context)
        handler.render(template_values, self.get_template('change'))