<commit_before>from django.contrib.auth.models import User
from django.http import HttpResponse
from django.conf import settings

from haystack import indexes

from wheelcms_axle.content import Content
from wheelcms_axle.node import Node
from wheelcms_axle.forms import formfactory, FileFormfactory
from wheelcms_axle.workflows.default import DefaultWorkflow

from wheelcms_axle.models import type_registry
from wheelcms_axle.templates import template_registry

from .impexp import WheelSerializer
from .actions import action

from two.ol.util import classproperty

from warnings import warn


class SpokeCharField(indexes.CharField):
    def __init__(self, spoke, *args, **kw):
        super(SpokeCharField, self).__init__(*args, **kw)
        self.spoke = spoke

    def prepare(self, obj):
        instance = self.spoke(obj)
        ma = getattr(instance, self.model_attr, None)
        if ma:
            if callable(ma):
                res = ma()
            else:
                res = ma
        if res is None:
            return super(SpokeCharField, self).prepare(obj)

        return self.convert(res)

def indexfactory(spoke):
    """ return a generic index definition bound to 'spoke' """
    class WheelIndex(indexes.SearchIndex):
        text = SpokeCharField(spoke=spoke, document=True,
                              model_attr='searchable_text')
        title = indexes.CharField(stored=True, indexed=False,
                                  model_attr="title")
        language = indexes.CharField(stored=True, indexed=True,
                                  model_attr="language")
        description = indexes.CharField(stored=True, indexed=False,
                              model_attr='description')
        state = indexes.CharField(stored=True, indexed=True,
                                  model_attr='state')
        meta_type = indexes.CharField(stored=True, indexed=True,
                                      model_attr='meta_type')
        path = indexes.CharField(stored=True, indexed=True,
                              model_attr='get_absolute_url')
        slug = indexes.CharField(stored=True, indexed=True,
                                  model_attr='node__slug')
        created = indexes.DateField(stored=True, indexed=True,
                                    model_attr="created")
        modified = indexes.DateField(stored=True, indexed=True,
                                     model_attr="modified")
        publication = indexes.DateField(stored=True, indexed=True,
                                        model_attr="publication")
        expire = indexes.DateField(stored=True, indexed=True,
                                   model_attr="expire", null=True)
        icon = SpokeCharField(spoke=spoke, stored=True, indexed=False,
                              model_attr="full_icon_path")
        owner = SpokeCharField(spoke=spoke, stored=True, indexed=True,
                               model_attr="owner_name")

        def index_queryset(self):
            """ Should the content to be indexed restricted here?
                Or index everything and apply filters depending on
                context? """
            ## only index content that's attached.
            return spoke.model.objects.filter(node__isnull=False)
    return WheelIndex

class Spoke(object):
    model = Content  ## is it smart to set this to Content? A nonsensible default..
    workflowclass = DefaultWorkflow

    ## None means no restrictions, () means no subcontent allowed
    children = None

    ## The primary sub content. Used to create a quick shortcut
    primary = None

    ## can it be implicitly added?
    implicit_add = True

    ## explicit children - explicit children that can be added
    explicit_children = None

    ## is content discussable? Iow, is commenting allowed?
    discussable = False

    serializer = WheelSerializer

    ## default language - None to let the system decide,
    ## or an explicit language (usually 'any') to provide an overriding
    ## default
    default_language = None

    document_fields = ('title', 'description')

    ## index this type of content?
    add_to_index = True

    type_icon = icon = "page.png"

    def __init__(self, o):
        self.instance = o

    @property
    def o(self):
        warn("{0}.o is obsolete, please use {0}.instance".format(self),
             DeprecationWarning)
        return self.instance

    def icon_base(self):
        return settings.STATIC_URL + "img/icons"

    def full_icon_path(self):
        """ return the full icon path. Used for storing the icon in the
            search index """
        return self.icon_base() + '/' + self.icon

    @classmethod
    def full_type_icon_path(cls):
        """
            Icons are instance specific, this allows an spoke to change its
            content depending on the content it holds. E.g. turn a generic
            file icon into a pdf file icon.

            But in certain cases we want a generic type icon without an
            instance, e.g. in the create popup
        """
        return settings.STATIC_URL + "img/icons/" + cls.type_icon

    def owner_name(self):
        """ return the owner's name, as good as possible """
        try:
            owner = self.instance.owner
        except User.DoesNotExist:
            return "Anonymous"

        if owner is None:
            return "Anonymous"

        name = owner.get_full_name()

        return name.strip() or owner.username

    def save(self, *a, **kw):
        """ save the instance """
        self.instance.save(*a, **kw)

    @classmethod
    def index(cls):
        """ generate the search index definition """
        return indexfactory(cls)

    @classproperty
    def form(cls):
        return formfactory(cls.model)

    @classproperty
    def light_form(cls):
        """ a smaller, lightweight form with minimal requirements """
        return cls.form<commit_msg>start of Spoke API<commit_after>from django.contrib.auth.models import User
from django.http import HttpResponse
from django.conf import settings

from haystack import indexes

from wheelcms_axle.content import Content
from wheelcms_axle.node import Node
from wheelcms_axle.forms import formfactory, FileFormfactory
from wheelcms_axle.workflows.default import DefaultWorkflow

from wheelcms_axle.models import type_registry
from wheelcms_axle.templates import template_registry

from .impexp import WheelSerializer
from .actions import action

from two.ol.util import classproperty

from warnings import warn


class SpokeCharField(indexes.CharField):
    def __init__(self, spoke, *args, **kw):
        super(SpokeCharField, self).__init__(*args, **kw)
        self.spoke = spoke

    def prepare(self, obj):
        instance = self.spoke(obj)
        ma = getattr(instance, self.model_attr, None)
        if ma:
            if callable(ma):
                res = ma()
            else:
                res = ma
        if res is None:
            return super(SpokeCharField, self).prepare(obj)

        return self.convert(res)

def indexfactory(spoke):
    """ return a generic index definition bound to 'spoke' """
    class WheelIndex(indexes.SearchIndex):
        text = SpokeCharField(spoke=spoke, document=True,
                              model_attr='searchable_text')
        title = indexes.CharField(stored=True, indexed=False,
                                  model_attr="title")
        language = indexes.CharField(stored=True, indexed=True,
                                  model_attr="language")
        description = indexes.CharField(stored=True, indexed=False,
                              model_attr='description')
        state = indexes.CharField(stored=True, indexed=True,
                                  model_attr='state')
        meta_type = indexes.CharField(stored=True, indexed=True,
                                      model_attr='meta_type')
        path = indexes.CharField(stored=True, indexed=True,
                              model_attr='get_absolute_url')
        slug = indexes.CharField(stored=True, indexed=True,
                                  model_attr='node__slug')
        created = indexes.DateField(stored=True, indexed=True,
                                    model_attr="created")
        modified = indexes.DateField(stored=True, indexed=True,
                                     model_attr="modified")
        publication = indexes.DateField(stored=True, indexed=True,
                                        model_attr="publication")
        expire = indexes.DateField(stored=True, indexed=True,
                                   model_attr="expire", null=True)
        icon = SpokeCharField(spoke=spoke, stored=True, indexed=False,
                              model_attr="full_icon_path")
        owner = SpokeCharField(spoke=spoke, stored=True, indexed=True,
                               model_attr="owner_name")

        def index_queryset(self):
            """ Should the content to be indexed restricted here?
                Or index everything and apply filters depending on
                context? """
            ## only index content that's attached.
            return spoke.model.objects.filter(node__isnull=False)
    return WheelIndex

class Spoke(object):
    model = Content  ## is it smart to set this to Content? A nonsensible default..
    workflowclass = DefaultWorkflow

    ## None means no restrictions, () means no subcontent allowed
    children = None

    ## The primary sub content. Used to create a quick shortcut
    primary = None

    ## can it be implicitly added?
    implicit_add = True

    ## explicit children - explicit children that can be added
    explicit_children = None

    ## is content discussable? Iow, is commenting allowed?
    discussable = False

    serializer = WheelSerializer

    ## default language - None to let the system decide,
    ## or an explicit language (usually 'any') to provide an overriding
    ## default
    default_language = None

    document_fields = ('title', 'description')

    ## index this type of content?
    add_to_index = True

    type_icon = icon = "page.png"

    def __init__(self, o):
        self.instance = o

    @property
    def o(self):
        warn("{0}.o is obsolete, please use {0}.instance".format(self),
             DeprecationWarning)
        return self.instance

    def icon_base(self):
        return settings.STATIC_URL + "img/icons"

    def full_icon_path(self):
        """ return the full icon path. Used for storing the icon in the
            search index """
        return self.icon_base() + '/' + self.icon

    @classmethod
    def full_type_icon_path(cls):
        """
            Icons are instance specific, this allows an spoke to change its
            content depending on the content it holds. E.g. turn a generic
            file icon into a pdf file icon.

            But in certain cases we want a generic type icon without an
            instance, e.g. in the create popup
        """
        return settings.STATIC_URL + "img/icons/" + cls.type_icon

    def owner_name(self):
        """ return the owner's name, as good as possible """
        try:
            owner = self.instance.owner
        except User.DoesNotExist:
            return "Anonymous"

        if owner is None:
            return "Anonymous"

        name = owner.get_full_name()

        return name.strip() or owner.username

    ## Experimental API
    @property
    def node(self):
        """
            Return the node this Spoke is attached to
        """
        return self.instance.node

    @classmethod
    def fromNode(cls, node, slug=None):
        """
            Retrieve a spoke from a node, optionally resolving a childnode
        """
        if slug:
            node = node.child(slug)
            if node is None:
                return None
        content = node.content()
        if content is None:
            return None
        return content.spoke()

    @classmethod
    def create(cls, **kw):
        """
            Create a spoke with its instance, not connected
            to a specific node.
        """
        return cls(cls.model(**kw))

    def save(self, *a, **kw):
        """ save the instance """
        self.instance.save(*a, **kw)
        return self

    @classmethod
    def index(cls):
        """ generate the search index definition """
        return indexfactory(cls)

    @classproperty
    def form(cls):
        return formfactory(cls.model)

    @classproperty
    def light_form(cls):
        """ a smaller, lightweight form with minimal requirements """
        return cls.form
{'fraction_non_alphanumeric': 0.08371505291423156, 'fraction_numerical': 0.000315905860053704, 'mean_word_length': 2.090798144984135, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1168195', 'n_tokens_mistral': 3399, 'n_tokens_neox': 3212, 'n_words': 984}