예제 #1
0
class GroupIndex(TagObjectSearchIndex, indexes.Indexable):
    text = TemplateResolveCharField(document=True, use_template=True)
    rendered = TemplateResolveCharField(use_template=True, indexed=False)

    name = indexes.CharField(model_attr='name')
    slug = indexes.CharField(model_attr='slug', indexed=False)
    public = indexes.BooleanField(model_attr='public')
    admins = indexes.MultiValueField(model_attr='admins', indexed=False)
    members = indexes.MultiValueField(model_attr='members', indexed=False)
    pendings = indexes.MultiValueField(model_attr='pendings', indexed=False)

    def get_model(self):
        return CosinnusGroup

    def index_queryset(self, using=None):
        return self.get_model().objects.select_related('media_tag').all()
예제 #2
0
class CosinnusConferenceIndex(CosinnusGroupIndexMixin, TagObjectSearchIndex,
                              indexes.Indexable):

    text = TemplateResolveNgramField(
        document=True,
        use_template=True,
        template_name='search/indexes/cosinnus/cosinnusgroup_{field_name}.txt')
    rendered = TemplateResolveCharField(
        use_template=True,
        indexed=False,
        template_name='search/indexes/cosinnus/cosinnusgroup_{field_name}.txt')

    from_date = indexes.DateTimeField(model_attr='from_date', null=True)
    to_date = indexes.DateTimeField(model_attr='to_date', null=True)
    humanized_event_time_html = indexes.CharField(stored=True, indexed=False)
    participants_limit_count = indexes.IntegerField(stored=True, indexed=False)

    def get_model(self):
        return CosinnusConference

    def prepare_participant_count(self, obj):
        """ Mirrored the member count for simplicity """
        return self.prepare_member_count(obj)

    def prepare_participants_limit_count(self, obj):
        """ Mirrored the member count for simplicity """
        participation_managements = obj.participation_management.all()
        if len(participation_managements) > 0:
            return participation_managements[0].participants_limit
        return 0

    def prepare_humanized_event_time_html(self, obj):
        return obj.get_humanized_event_time_html()

    def boost_model(self, obj, indexed_data):
        """ We boost a combined measure of 2 added factors: soonishnes (50%) and participant count (50%).
            This means that a soon happening event with lots of participants will rank highest and an far off event 
            with no participants lowest.
            But it also means that soon happening events with no participants will still rank quite high, 
            as will far off events with lots of participants.
            
            Factors:
            - The conference's date, highest being now() and lowest >= 12 months from now
            """

        if obj.from_date:
            future_date_timedelta = obj.from_date - now()
            if future_date_timedelta.days < 0:
                if obj.to_date and (obj.to_date - now()).days > 0:
                    rank_from_date = 0.1  # running events rank not nothing
                else:
                    rank_from_date = 0.0  # past events rank worst
            else:
                rank_from_date = max(
                    1.0 - (future_date_timedelta.days / 365.0), 0)
        else:
            rank_from_date = 0.0
        return rank_from_date
예제 #3
0
class CosinnusSocietyIndex(CosinnusGroupIndexMixin, TagObjectSearchIndex,
                           indexes.Indexable):

    text = TemplateResolveNgramField(
        document=True,
        use_template=True,
        template_name='search/indexes/cosinnus/cosinnusgroup_{field_name}.txt')
    rendered = TemplateResolveCharField(
        use_template=True,
        indexed=False,
        template_name='search/indexes/cosinnus/cosinnusgroup_{field_name}.txt')

    def get_model(self):
        return CosinnusSociety

    def prepare_participant_count(self, obj):
        """ child projects for groups """
        return obj.groups.count()
예제 #4
0
class CosinnusProjectIndex(CosinnusGroupIndexMixin, TagObjectSearchIndex,
                           indexes.Indexable):

    text = TemplateResolveNgramField(
        document=True,
        use_template=True,
        template_name='search/indexes/cosinnus/cosinnusgroup_{field_name}.txt')
    rendered = TemplateResolveCharField(
        use_template=True,
        indexed=False,
        template_name='search/indexes/cosinnus/cosinnusgroup_{field_name}.txt')

    def get_model(self):
        return CosinnusProject

    def prepare_group_slug(self, obj):
        """ For projects assigned to a parent group, we link that group """
        return obj.parent and obj.parent.slug or None

    def prepare_group_name(self, obj):
        """ Stub, overridden by individual indexes """
        return obj.parent and obj.parent.name or None
예제 #5
0
class UserProfileIndex(LocalCachedIndexMixin, DocumentBoostMixin,
                       StoredDataIndexMixin, TagObjectSearchIndex,
                       indexes.Indexable):
    text = TemplateResolveNgramField(
        document=True,
        use_template=True,
        template_name='search/indexes/cosinnus/userprofile_{field_name}.txt')
    rendered = TemplateResolveCharField(
        use_template=True,
        indexed=False,
        template_name='search/indexes/cosinnus/userprofile_{field_name}.txt')

    boosted = indexes.CharField(model_attr='get_full_name',
                                boost=BOOSTED_FIELD_BOOST)

    user_visibility_mode = indexes.BooleanField(
        default=True)  # switch to filter differently on mt_visibility
    membership_groups = indexes.MultiValueField(
        model_attr='cosinnus_groups_pks'
    )  # ids of all groups the user is member/admin of
    admin_groups = indexes.MultiValueField(
    )  # ids of all groups the user is member/admin of
    portals = indexes.MultiValueField()
    location = indexes.LocationField(null=True)
    user_id = indexes.IntegerField(model_attr='user__id')
    created = indexes.DateTimeField(model_attr='user__date_joined')

    local_cached_attrs = ['_memberships_count']

    def prepare_portals(self, obj):
        return list(
            obj.user.cosinnus_portal_memberships.values_list('group_id',
                                                             flat=True))

    def prepare_location(self, obj):
        if obj.media_tag and obj.media_tag.location_lat and obj.media_tag.location_lon:
            # this expects (lat,lon)!
            return "%s,%s" % (obj.media_tag.location_lat,
                              obj.media_tag.location_lon)
        return None

    def prepare_title(self, obj):
        return obj.user.get_full_name()

    def prepare_slug(self, obj):
        return obj.user.username

    def get_image_field_for_icon(self, obj):
        return obj.get_image_field_for_icon()

    def prepare_url(self, obj):
        """ NOTE: UserProfiles always contain a relative URL! """
        return reverse('cosinnus:profile-detail',
                       kwargs={'username': obj.user.username})

    def prepare_member_count(self, obj):
        """ Memberships for users """
        return self._get_memberships_count(obj)

    def prepare_admin_groups(self, obj):
        return list(
            get_cosinnus_group_model().objects.get_for_user_group_admin_pks(
                obj.user))

    def get_model(self):
        return get_user_profile_model()

    def index_queryset(self, using=None):
        qs = self.get_model().objects.all()
        qs = filter_active_users(qs, filter_on_user_profile_model=True)
        qs = qs.select_related('user').all()
        return qs

    def _get_memberships_count(self, obj):
        if not hasattr(obj, '_memberships_count'):
            setattr(obj, '_memberships_count',
                    obj.user.cosinnus_memberships.count())
        return obj._memberships_count

    def boost_model(self, obj, indexed_data):
        """ We boost by number of groups the user is a member of, normalized over
            the mean/stddev of the count of groups each portal user is a members of, 
            in a range of [0.0..1.0] """
        def qs_func():
            return filter_portal_users(
                filter_active_users(get_user_model().objects.all()))

        mean, stddev = self.get_mean_and_stddev(qs_func,
                                                'cosinnus_memberships')
        user_memberships_count = self._get_memberships_count(obj)
        memberships_rank = normalize_within_stddev(user_memberships_count,
                                                   mean,
                                                   stddev,
                                                   stddev_factor=2.0)
        return memberships_rank

    def apply_boost_penalty(self, obj, indexed_data):
        """ Penaliize by 15% for not having an avatar image.
            @return: 1.0 for no penalty, a float in range [0.0..1.0] for a penalty
        """
        if not self.get_image_field_for_icon(obj):
            return DEFAULT_BOOST_PENALTY_FOR_MISSING_IMAGE
        return 1.0