Esempio n. 1
0
class ModelCollection(Collection):
    model = schema.ModelReferenceField(ContentType)
    mixins = schema.SetField(schema.CharField(), choices=MODEL_COLLECTION_MIXINS.choices, blank=True)

    @classmethod
    def get_available_mixins(self):
        return MODEL_COLLECTION_MIXINS

    def get_model(self):
        return self.model.model_class()

    def get_object_class(self):
        return self.get_model()

    def get_resource_class(self):
        from dockitcms.resources.collection import ModelResource
        return ModelResource

    class Meta:
        typed_key = 'dockitcms.model'
Esempio n. 2
0
 class MixinSchema(schema.Schema, EventMixin):
     mixins = schema.SetField(schema.CharField(), choices=mixin_choices, blank=True)
     
     @classmethod
     def register_mixin(self, key, mixin_class):
         MIXINS[key] = mixin_class
     
     @classmethod
     def get_available_mixins(self):
         return MIXINS
     
     def __getattribute__(self, name):
         function_events = object.__getattribute__(self, 'mixin_function_events')
         if name in function_events:
             return EventMixin.__getattribute__(self, name)
         return schema.Schema.__getattribute__(self, name)
     
     def get_active_mixins(self, target=None): #CONSIDER: this modifies the fields we have
         mixins = list()
         target = target or self
         available_mixins = self.get_available_mixins()
         for mixin_key in self.mixins:
             if mixin_key in available_mixins:
                 mixin_cls = available_mixins[mixin_key]
                 mixins.append(mixin_cls(target))
         return mixins
     
     def make_bound_schema(self):
         if getattr(self, '_mixin_bound', False):
             return type(self)
         
         original_fields = self._meta.fields.keys()
         
         def get_active_mixins(kls, target=None):
             return self.get_active_mixins(target=target)
         
         def send_mixin_event(kls, event, kwargs):
             return self.send_mixin_event(event, kwargs)
         
         cls = type(self)
         
         document_kwargs = {
             'fields':{},#copy(self._meta.fields.fields), #fields => uber dictionary, fields.fields => fields we defined
             'proxy': True,
             'name': cls.__name__,
             'parents': (cls,),
             'module': cls.__module__,
             'attrs': {'get_active_mixins':classmethod(get_active_mixins),
                       'send_mixin_event':classmethod(send_mixin_event),
                       '_mixin_bound':True},
         }
         self.send_mixin_event('document_kwargs', {'document_kwargs':document_kwargs})
         new_cls = create_document(**document_kwargs)
         assert self._meta.fields.keys() == original_fields
         return new_cls
     
     @classmethod
     def to_python(cls, val, parent=None):
         #chicken and egg problem
         #hack because super(cls).to_python does not work
         original_to_python = schema.Document.to_python.im_func
         self = original_to_python(cls, val, parent)
         if getattr(cls, '_mixin_bound', False):
             return self
         else:
             new_cls = self.make_bound_schema()
             return original_to_python(new_cls, val, parent)
Esempio n. 3
0
class Collection(ManageUrlsMixin, schema.Document, EventMixin):
    key = schema.SlugField(unique=True)
    application = schema.ReferenceField(Application)
    admin_options = schema.SchemaField(AdminOptions)
    title = None

    mixins = schema.SetField(schema.CharField(), choices=COLLECTION_MIXINS.choices, blank=True)

    mixin_function_events = {
        'get_document_kwargs': {
            'post': PostEventFunction(event='document_kwargs', keyword='document_kwargs'),
        },
        #'get_view_endpoints': {
            #'collect': CollectEventFunction(event='view_endpoints', extend_function='extends'),
            #'post': PostEventFunction(event='view_endpoints', keyword='view_endpoints'),
        #},
    }

    @classmethod
    def register_mixin(self, key, mixin_class):
        self.get_available_mixins()[key] = mixin_class

    @classmethod
    def get_available_mixins(self):
        return COLLECTION_MIXINS

    def __getattribute__(self, name):
        function_events = object.__getattribute__(self, 'mixin_function_events')
        if name in function_events:
            ret = object.__getattribute__(self, name)
            return self._mixin_function(ret, function_events[name])
        return schema.Document.__getattribute__(self, name)

    def get_active_mixins(self):
        mixins = list()
        available_mixins = self.get_available_mixins()
        for mixin_key in self.mixins:
            if mixin_key in available_mixins:
                mixin_cls = available_mixins[mixin_key]
                mixins.append(mixin_cls(self))
        return mixins

    @permalink
    def get_admin_manage_url(self):
        return self.get_resource_item().get_absolute_url()

    def admin_manage_link(self):
        url = self.get_admin_manage_url()
        return '<a href="%s">%s</a>' % (url, _('Manage'))
    admin_manage_link.short_description = _('Manage')
    admin_manage_link.allow_tags = True

    def get_object_class(self):
        raise NotImplementedError

    def get_resource_class(self):
        raise NotImplementedError

    @classmethod
    def get_collection_admin_client(cls):
        #TODO this should be configurable
        from dockitcms.urls import admin_client
        return admin_client.api_endpoint

    def get_collection_resource(self):
        admin_client = self.get_collection_admin_client()
        cls = self.get_object_class()
        try:
            return admin_client.registry[cls]
        except Exception as error:
            seen = list()
            for key, resource in admin_client.registry.iteritems():
                seen.append((resource.collection.collection_type, key, resource.collection))
                #if resource.collection.collection_type != 'dockitcms.virtualdocument':
                #    assert False, str("%s, %s, %s, %s" % (resource.collection, self, resource.collection==self, resource.collection.collection_type))
                if hasattr(resource, 'collection') and resource.collection == self:
                    return resource
            assert False, str(seen)

    def register_collection(self):
        pass

    def save(self, *args, **kwargs):
        ret = super(Collection, self).save(*args, **kwargs)
        self.register_collection()
        return ret

    class Meta:
        typed_field = 'collection_type'
        verbose_name = 'collection'
Esempio n. 4
0
class VirtualDocumentCollection(Collection, DocumentDesign):
    mixins = schema.SetField(schema.CharField(), choices=VIRTUAL_COLLECTION_MIXINS.choices, blank=True)

    @classmethod
    def get_available_mixins(self):
        return VIRTUAL_COLLECTION_MIXINS

    def get_collection_name(self):
        return 'dockitcms.virtual.%s' % self.key

    def get_document_kwargs(self, **kwargs):
        kwargs = super(VirtualDocumentCollection, self).get_document_kwargs(**kwargs)
        kwargs.setdefault('attrs', dict())
        parents = list(kwargs.get('parents', list()))

        parents.append(VirtualManageUrlsMixin)
        if not any([issubclass(parent, schema.Document) for parent in parents]):
            parents.append(schema.Document)

        if parents:
            kwargs['parents'] = tuple(parents)
        if self.application:
            kwargs['app_label'] = self.application.name

        kwargs['attrs']['_collection_document'] = self
        return kwargs

    def register_collection(self):
        doc = DocumentDesign.get_document(self, virtual=False, verbose_name=self.title, collection=self.get_collection_name())
        force_register_documents(doc._meta.app_label, doc)
        return doc

    def get_document(self):
        key = self.get_collection_name()
        #TODO how do we know if we should recreate the document? ie what if the design was modified on another node
        try:
            return get_base_document(key)
        except KeyError:
            doc = self.register_collection()
            return doc

    def get_object_class(self):
        return self.get_document()

    def get_resource_class(self):
        from dockitcms.resources.collection import VirtualDocumentResource
        return VirtualDocumentResource

    def get_collection_resource(self):
        admin_client = self.get_collection_admin_client()
        cls = self.get_object_class()
        try:
            return admin_client.registry[cls]
        except Exception as error:
            for key, resource in admin_client.registry.iteritems():
                if isinstance(key, type) and issubclass(cls, key):
                    return resource
                #TODO why do we need this?
                if issubclass(key, schema.Document) and key._meta.collection == cls._meta.collection:
                    return resource

    def __unicode__(self):
        if self.title:
            return self.title
        else:
            return self.__repr__()

    class Meta:
        typed_key = 'dockitcms.virtualdocument'
Esempio n. 5
0
class Collection(BaseCollection, DocumentDesign, EventMixin):
    key = schema.SlugField(unique=True)
    mixins = schema.SetField(schema.CharField(),
                             choices=mixin_choices,
                             blank=True)

    mixin_function_events = {
        'get_document_kwargs': {
            'post':
            PostEventFunction(event='document_kwargs',
                              keyword='document_kwargs')
        },
    }

    @classmethod
    def register_mixin(self, key, mixin_class):
        COLLECTION_MIXINS[key] = mixin_class

    @classmethod
    def get_available_mixins(self):
        return COLLECTION_MIXINS

    def __getattribute__(self, name):
        function_events = object.__getattribute__(self,
                                                  'mixin_function_events')
        if name in function_events:
            ret = object.__getattribute__(self, name)
            return self._mixin_function(ret, function_events[name])
        return BaseCollection.__getattribute__(self, name)

    def get_active_mixins(self):
        mixins = list()
        available_mixins = self.get_available_mixins()
        for mixin_key in self.mixins:
            if mixin_key in available_mixins:
                mixin_cls = available_mixins[mixin_key]
                mixins.append(mixin_cls(self))
        return mixins

    def save(self, *args, **kwargs):
        ret = super(Collection, self).save(*args, **kwargs)
        self.register_collection()
        return ret

    def get_collection_name(self):
        return 'dockitcms.virtual.%s' % self.key

    def get_document_kwargs(self, **kwargs):
        kwargs = super(Collection, self).get_document_kwargs(**kwargs)
        kwargs.setdefault('attrs', dict())
        parents = list(kwargs.get('parents', list()))

        if parents and not any(
            [issubclass(parent, schema.Document) for parent in parents]):
            parents.append(schema.Document)
        if parents:
            kwargs['parents'] = tuple(parents)
        if self.application:
            kwargs['app_label'] = self.application.name

        def get_manage_urls(instance):
            base_url = self.get_admin_manage_url()
            urls = {
                'add': base_url + 'add/',
                'list': base_url,
            }
            if instance.pk:
                urls['edit'] = base_url + instance.pk + '/'
            return urls

        kwargs['attrs']['get_manage_urls'] = get_manage_urls
        kwargs['attrs']['_collection_document'] = self
        return kwargs

    def register_collection(self):
        doc = DocumentDesign.get_document(
            self,
            virtual=False,
            verbose_name=self.title,
            collection=self.get_collection_name())
        force_register_documents(doc._meta.app_label, doc)
        return doc

    def get_document(self):
        key = self.get_collection_name()
        #TODO how do we know if we should recreate the document? ie what if the design was modified on another node
        try:
            return get_base_document(key)
        except KeyError:
            doc = self.register_collection()
            return doc

    def __unicode__(self):
        if self.title:
            return self.title
        else:
            return self.__repr__()

    class Meta:
        typed_key = 'document'