예제 #1
0
class Tokenable(Entity):
    """Question class"""

    tokens_opposition = CompositeMultipleProperty('tokens_opposition')
    tokens_support = CompositeMultipleProperty('tokens_support')

    def __init__(self, **kwargs):
        super(Tokenable, self).__init__(**kwargs)
        self.set_data(kwargs)
        self.allocated_tokens = OOBTree()
        self.len_allocated_tokens = PersistentDict({})

    def add_token(self, user, evaluation_type):
        user_oid = get_oid(user)
        if user_oid in self.allocated_tokens:
            self.remove_token(user)

        self.allocated_tokens[user_oid] = evaluation_type
        self.len_allocated_tokens.setdefault(evaluation_type, 0)
        self.len_allocated_tokens[evaluation_type] += 1

    def remove_token(self, user):
        user_oid = get_oid(user)
        if user_oid in self.allocated_tokens:
            evaluation_type = self.allocated_tokens.pop(user_oid)
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] -= 1

    def evaluators(self, evaluation_type=None):
        if evaluation_type:
            return [
                get_obj(key) for value, key in self.allocated_tokens.byValue(
                    evaluation_type)
            ]

        return [get_obj(key) for key in self.allocated_tokens.keys()]

    def evaluation(self, user):
        user_oid = get_oid(user, None)
        return self.allocated_tokens.get(user_oid, None)

    def remove_tokens(self, force=False):
        evaluators = self.evaluators()
        for user in evaluators:
            user.remove_token(self)
            if force:
                self.remove_token(user)

    def user_has_token(self, user, root=None):
        if hasattr(user, 'has_token'):
            return user.has_token(self, root)

        return False

    def init_support_history(self):
        # [(user_oid, date, support_type), ...], support_type = {1:support, 0:oppose, -1:withdraw}
        if not hasattr(self, '_support_history'):
            setattr(self, '_support_history', PersistentList())

    @property
    def len_support(self):
        return self.len_allocated_tokens.get(Evaluations.support, 0)

    @property
    def len_opposition(self):
        return self.len_allocated_tokens.get(Evaluations.oppose, 0)
예제 #2
0
파일: core.py 프로젝트: ecreall/nova-ideo
class Tokenable(Entity):
    """Question class"""

    tokens_opposition = CompositeMultipleProperty('tokens_opposition')
    tokens_support = CompositeMultipleProperty('tokens_support')

    def __init__(self, **kwargs):
        super(Tokenable, self).__init__(**kwargs)
        self.set_data(kwargs)
        self.allocated_tokens = OOBTree()
        self.len_allocated_tokens = PersistentDict({})

    def add_token(self, user, evaluation_type):
        user_oid = get_oid(user)
        if user_oid in self.allocated_tokens:
            self.remove_token(user)

        self.allocated_tokens[user_oid] = evaluation_type
        self.len_allocated_tokens.setdefault(evaluation_type, 0)
        self.len_allocated_tokens[evaluation_type] += 1

    def remove_token(self, user):
        user_oid = get_oid(user)
        if user_oid in self.allocated_tokens:
            evaluation_type = self.allocated_tokens.pop(user_oid)
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] -= 1

    def evaluators(self, evaluation_type=None):
        if evaluation_type:
            return [get_obj(key) for value, key
                    in self.allocated_tokens.byValue(evaluation_type)]

        return [get_obj(key) for key
                in self.allocated_tokens.keys()]

    def evaluation(self, user):
        user_oid = get_oid(user, None)
        return self.allocated_tokens.get(user_oid, None)

    def remove_tokens(self, force=False):
        evaluators = self.evaluators()
        for user in evaluators:
            user.remove_token(self)
            if force:
                self.remove_token(user)

    def user_has_token(self, user, root=None):
        if hasattr(user, 'has_token'):
            return user.has_token(self, root)

        return False

    def init_support_history(self):
        # [(user_oid, date, support_type), ...], support_type = {1:support, 0:oppose, -1:withdraw}
        if not hasattr(self, '_support_history'):
            setattr(self, '_support_history', PersistentList())

    @property
    def len_support(self):
        return self.len_allocated_tokens.get(Evaluations.support, 0)

    @property
    def len_opposition(self):
        return self.len_allocated_tokens.get(Evaluations.oppose, 0)
예제 #3
0
파일: person.py 프로젝트: ecreall/KuneAgi
class Person(User, SearchableEntity, CorrelableEntity, Debatable):
    """Person class"""

    type_title = _('Person')
    icon = 'icon glyphicon glyphicon-user'  #'icon novaideo-icon icon-user'
    templates = {
        'default': 'novaideo:views/templates/person_result.pt',
        'bloc': 'novaideo:views/templates/person_bloc.pt',
        'small': 'novaideo:views/templates/small_person_result.pt',
        'popover': 'novaideo:views/templates/person_popover.pt',
        'card': 'novaideo:views/templates/person_card.pt',
        'header': 'novaideo:views/templates/person_header.pt',
    }
    default_picture = 'novaideo:static/images/user100.png'
    name = renamer()
    tokens = CompositeMultipleProperty('tokens')
    tokens_ref = SharedMultipleProperty('tokens_ref')
    organization = SharedUniqueProperty('organization', 'members')
    events = SharedMultipleProperty('events', 'author')
    picture = CompositeUniqueProperty('picture')
    cover_picture = CompositeUniqueProperty('cover_picture')
    ideas = SharedMultipleProperty('ideas', 'author')
    selections = SharedMultipleProperty('selections')
    working_groups = SharedMultipleProperty('working_groups', 'members')
    wg_participations = SharedMultipleProperty('wg_participations',
                                               'wating_list_participation')
    old_alerts = SharedMultipleProperty('old_alerts')
    following_channels = SharedMultipleProperty('following_channels',
                                                'members')
    folders = SharedMultipleProperty('folders', 'author')
    questions = SharedMultipleProperty('questions', 'author')
    challenges = SharedMultipleProperty('challenges', 'author')
    ballots = CompositeMultipleProperty('ballots')
    mask = SharedUniqueProperty('mask', 'member')

    def __init__(self, **kwargs):
        self.branches = PersistentList()
        self.keywords = PersistentList()
        super(Person, self).__init__(**kwargs)
        kwargs.pop('password', None)
        self.set_data(kwargs)
        self.set_title()
        self.last_connection = datetime.datetime.now(tz=pytz.UTC)
        self._read_at = OOBTree()
        self.guide_tour_data = PersistentDict({})
        self.confidence_index = 0
        self._notes = OOBTree()
        self.allocated_tokens = OOBTree()
        self.len_allocated_tokens = PersistentDict({})
        self.reserved_tokens = PersistentList([])
        self._submited_at = OOBTree()
        self._reported_at = OOBTree()

    def __setattr__(self, name, value):
        super(Person, self).__setattr__(name, value)
        if name == 'organization' and value:
            self.init_contents_organizations()

    def get_len_tokens(self, root=None, exclude_reserved_tokens=False):
        root = root or getSite()
        return root.tokens_mini if exclude_reserved_tokens \
            else root.tokens_mini + len(self.reserved_tokens)

    def get_len_evaluations(self, exclude_reserved_tokens=False):
        total = self.len_allocated_tokens.get(Evaluations.support, 0) + \
            self.len_allocated_tokens.get(Evaluations.oppose, 0)
        if exclude_reserved_tokens:
            return total - len([
                o for o in self.reserved_tokens if o in self.allocated_tokens
            ])
        return total

    def get_len_free_tokens(self, root=None, exclude_reserved_tokens=False):
        root = root or getSite()
        return self.get_len_tokens(root, exclude_reserved_tokens) - \
            self.get_len_evaluations(exclude_reserved_tokens)

    def has_token(self, obj=None, root=None):
        root = root or getSite()
        obj_oid = get_oid(obj, None)
        if obj_oid and obj_oid in self.reserved_tokens:
            return obj_oid not in self.allocated_tokens

        return self.get_len_free_tokens(root, True) > 0

    def add_token(self, obj, evaluation_type, root=None):
        if self.has_token(obj, root):
            self.allocated_tokens[get_oid(obj)] = evaluation_type
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] += 1

    def remove_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid in self.allocated_tokens:
            evaluation_type = self.allocated_tokens.pop(obj_oid)
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] -= 1

    def add_reserved_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid not in self.reserved_tokens:
            self.reserved_tokens.append(obj_oid)

    def remove_reserved_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid in self.reserved_tokens:
            self.reserved_tokens.remove(obj_oid)

    def evaluated_objs(self, evaluation_type=None):
        if evaluation_type:
            return [
                get_obj(key) for value, key in self.allocated_tokens.byValue(
                    evaluation_type)
            ]

        return [get_obj(key) for key in self.allocated_tokens.keys()]

    def evaluated_objs_ids(self, evaluation_type=None):
        if evaluation_type:
            return [
                key for value, key in self.allocated_tokens.byValue(
                    evaluation_type)
            ]

        return list(self.allocated_tokens.keys())

    def init_contents_organizations(self):
        novaideo_catalog = find_catalog('novaideo')
        dace_catalog = find_catalog('dace')
        organizations_index = novaideo_catalog['organizations']
        object_authors_index = novaideo_catalog['object_authors']
        object_provides_index = dace_catalog['object_provides']
        query = object_authors_index.any([get_oid(self)]) & \
            object_provides_index.any(
                [Iidea.__identifier__, IProposal.__identifier__]) & \
            organizations_index.any([0])

        for entity in query.execute().all():
            entity.init_organization()
            entity.reindex()

    def set_read_date(self, channel, date):
        self._read_at[get_oid(channel)] = date

    def get_read_date(self, channel):
        return self._read_at.get(get_oid(channel),
                                 datetime.datetime.now(tz=pytz.UTC))

    def get_channel(self, user):
        all_channels = list(self.channels)
        all_channels.extend(list(getattr(user, 'channels', [])))
        for channel in all_channels:
            if user in channel.members and self in channel.members:
                return channel

        return None

    def addtoproperty(self, name, value, moving=None):
        super(Person, self).addtoproperty(name, value, moving)
        if name == 'selections':
            value.len_selections = getattr(value, 'len_selections', 0)
            value.len_selections += 1

    def delfromproperty(self, name, value, moving=None):
        super(Person, self).delfromproperty(name, value, moving)
        if name == 'selections':
            value.len_selections = getattr(value, 'len_selections', 0)
            if value.len_selections > 0:
                value.len_selections -= 1

    def set_title(self):
        if getattr(self, 'pseudonym', ''):
            self.title = self.pseudonym
        else:
            self.title = getattr(self, 'first_name', '') + ' ' + \
                getattr(self, 'last_name', '')

    def add_note(self, user, context, note, date, time_constant):
        self._notes[date] = (get_oid(user), get_oid(context), note)
        self.calculate_confidence_index(time_constant)

    def get_questions(self, user):
        if user is self:
            return self.questions + getattr(self.mask, 'questions', [])

        return self.questions

    def get_ideas(self, user):
        if user is self:
            return self.ideas + getattr(self.mask, 'ideas', [])

        return self.ideas

    def get_working_groups(self, user):
        if user is self:
            return self.working_groups + getattr(self.mask, 'working_groups',
                                                 [])

        return self.working_groups

    @property
    def proposals(self):
        return [wg.proposal for wg in self.working_groups]

    def get_proposals(self, user):
        if user is self:
            return self.proposals + getattr(self.mask, 'proposals', [])

        return self.proposals

    @property
    def contacts(self):
        return [s for s in self.selections if isinstance(s, Person)]

    @property
    def participations(self):
        result = [
            p for p in list(self.proposals) if any(s in p.state for s in [
                'amendable', 'open to a working group', 'votes for publishing',
                'votes for amendments'
            ])
        ]
        return result

    def get_participations(self, user):
        if user is self:
            return self.participations + getattr(self.mask, 'participations',
                                                 [])

        return self.participations

    @property
    def contents(self):
        result = [i for i in list(self.ideas) if i is i.current_version]
        result.extend(self.proposals)
        result.extend(self.questions)
        result.extend(self.challenges)
        result.extend(self.events)
        return result

    def get_contents(self, user):
        if user is self:
            return self.contents + getattr(self.mask, 'contents', [])

        return self.contents

    @property
    def active_working_groups(self):
        return [p.working_group for p in self.participations]

    def get_active_working_groups(self, user):
        if user is self:
            return self.active_working_groups + getattr(
                self.mask, 'active_working_groups', [])

        return self.active_working_groups

    def get_wg_participations(self, user):
        if user is self:
            return self.wg_participations + getattr(self.mask,
                                                    'wg_participations', [])

        return self.wg_participations

    @property
    def is_published(self):
        return 'active' in self.state

    @property
    def managed_organization(self):
        return get_objects_with_role(user=self, role='OrganizationResponsible')

    def get_confidence_index(self):
        return getattr(self, 'confidence_index', 0)

    def reindex(self):
        super(Person, self).reindex()
        root = getSite()
        self.__access_keys__ = PersistentList(generate_access_keys(self, root))

    def get_picture_url(self, kind, default):
        if self.picture:
            img = getattr(self.picture, kind, None)
            if img:
                return img.url

        return default

    def get_more_contents_criteria(self):
        "return specific query, filter values"
        return None, None

    def set_organization(self, organization):
        current_organization = self.organization
        if organization:
            if current_organization is not organization:
                is_manager = current_organization and has_role(
                    ('OrganizationResponsible', current_organization),
                    self,
                    ignore_superiors=True)
                if current_organization and is_manager:
                    revoke_roles(
                        self,
                        (('OrganizationResponsible', current_organization), ))

                self.setproperty('organization', organization)
        elif current_organization:
            is_manager = has_role(
                ('OrganizationResponsible', current_organization),
                self,
                ignore_superiors=True)
            if is_manager:
                revoke_roles(
                    self,
                    (('OrganizationResponsible', current_organization), ))

            self.delfromproperty('organization', current_organization)

    @property
    def all_alerts(self):
        novaideo_catalog = find_catalog('novaideo')
        dace_catalog = find_catalog('dace')
        alert_keys_index = novaideo_catalog['alert_keys']
        alert_exclude_keys_index = novaideo_catalog['alert_exclude_keys']
        object_provides_index = dace_catalog['object_provides']
        exclude = [str(get_oid(self))]
        if self.mask:
            exclude.append(str(get_oid(self.mask)))

        query = object_provides_index.any([IAlert.__identifier__]) & \
            alert_keys_index.any(self.get_alerts_keys()) & \
            alert_exclude_keys_index.notany(exclude)
        return query.execute()

    @property
    def alerts(self):
        old_alerts = [get_oid(a) for a in self.old_alerts]
        result = self.all_alerts

        def exclude(result_set, docids):
            filtered_ids = list(result_set.ids)
            for _id in docids:
                if _id in docids and _id in filtered_ids:
                    filtered_ids.remove(_id)

            return result_set.__class__(filtered_ids, len(filtered_ids),
                                        result_set.resolver)

        return exclude(result, old_alerts)

    def get_alerts_keys(self):
        result = ['all', str(get_oid(self))]
        if self.mask:
            result.append(str(get_oid(self.mask)))

        return result

    def get_alerts(self, alerts=None, kind=None, subject=None, **kwargs):
        if alerts is None:
            alerts = self.alerts

        if kind:
            alerts = [a for a in alerts if a.is_kind_of(kind)]

        if subject:
            alerts = [a for a in alerts if subject in a.subjects]

        if kwargs:
            alerts = [a for a in alerts if a.has_args(**kwargs)]

        return alerts

    def calculate_confidence_index(self, time_constant):
        now = datetime.datetime.utcnow().timestamp()
        notes = np.array([v[2] for v in self._notes.values()])
        dates = np.array([int(t.timestamp()) for t in self._notes.keys()])
        time_c = time_constant * 86400
        confidence_index = np.sum(
            np.dot(notes, np.exp(-np.log(2) * (now - dates) / time_c)))
        self.confidence_index = round(confidence_index, 1)

    @property
    def user_groups(self):
        groups = list(self.groups)
        if self.organization:
            groups.append(self.organization)

        if self.mask:
            groups.append(self.mask)

        return groups

    @property
    def user_locale(self):
        locale = getattr(self, 'locale', None)
        if not locale:
            locale = getSite(self).locale

        return locale

    def _init_mask(self, root):
        if not self.mask:
            mask = Mask()
            root.addtoproperty('masks', mask)
            self.setproperty('mask', mask)

    def get_mask(self, root=None):
        root = root if root else getSite()
        if not getattr(root, 'anonymisation', False):
            return self

        self._init_mask(root)
        return self.mask

    def add_submission(self, obj):
        now = datetime.datetime.now(tz=pytz.UTC)
        self._submited_at[now] = get_oid(obj)

    def add_report(self, obj):
        now = datetime.datetime.now(tz=pytz.UTC)
        self._reported_at[now] = get_oid(obj)

    def can_submit_idea(self, root=None):
        root = root if root else getSite()
        now = datetime.datetime.now(tz=pytz.UTC)
        monday = datetime.datetime.combine((now - datetime.timedelta(days=7)),
                                           datetime.time(0,
                                                         0,
                                                         0,
                                                         tzinfo=pytz.UTC))
        return len(self._submited_at.values(min=monday, max=now)) < getattr(
            root, 'nb_submission_maxi', 3)

    def can_report(self, root=None):
        root = root if root else getSite()
        now = datetime.datetime.now(tz=pytz.UTC)
        monday = datetime.datetime.combine((now - datetime.timedelta(days=7)),
                                           datetime.time(0,
                                                         0,
                                                         0,
                                                         tzinfo=pytz.UTC))
        return len(self._reported_at.values(min=monday, max=now)) < getattr(
            root, 'nb_reports_maxi', 3)
예제 #4
0
파일: person.py 프로젝트: ecreall/nova-ideo
class Person(User, SearchableEntity, CorrelableEntity, Debatable):
    """Person class"""

    type_title = _('Person')
    icon = 'icon glyphicon glyphicon-user' #'icon novaideo-icon icon-user'
    templates = {'default': 'novaideo:views/templates/person_result.pt',
                 'bloc': 'novaideo:views/templates/person_bloc.pt',
                 'small': 'novaideo:views/templates/small_person_result.pt',
                 'popover': 'novaideo:views/templates/person_popover.pt',
                 'card': 'novaideo:views/templates/person_card.pt',
                 'header': 'novaideo:views/templates/person_header.pt',}
    default_picture = 'novaideo:static/images/user100.png'
    name = renamer()
    tokens = CompositeMultipleProperty('tokens')
    tokens_ref = SharedMultipleProperty('tokens_ref')
    organization = SharedUniqueProperty('organization', 'members')
    picture = CompositeUniqueProperty('picture')
    cover_picture = CompositeUniqueProperty('cover_picture')
    ideas = SharedMultipleProperty('ideas', 'author')
    selections = SharedMultipleProperty('selections')
    working_groups = SharedMultipleProperty('working_groups', 'members')
    old_alerts = SharedMultipleProperty('old_alerts')
    following_channels = SharedMultipleProperty('following_channels', 'members')
    folders = SharedMultipleProperty('folders', 'author')
    questions = SharedMultipleProperty('questions', 'author')
    challenges = SharedMultipleProperty('challenges', 'author')
    mask = SharedUniqueProperty('mask', 'member')

    def __init__(self, **kwargs):
        super(Person, self).__init__(**kwargs)
        kwargs.pop('password', None)
        self.set_data(kwargs)
        self.set_title()
        self.last_connection = datetime.datetime.now(tz=pytz.UTC)
        self._read_at = OOBTree()
        self.guide_tour_data = PersistentDict({})
        self.allocated_tokens = OOBTree()
        self.len_allocated_tokens = PersistentDict({})
        self.reserved_tokens = PersistentList([])

    def __setattr__(self, name, value):
        super(Person, self).__setattr__(name, value)
        if name == 'organization' and value:
            self.init_contents_organizations()

    def get_len_tokens(self, root=None, exclude_reserved_tokens=False):
        root = root or getSite()
        return root.tokens_mini if exclude_reserved_tokens \
            else root.tokens_mini + len(self.reserved_tokens)

    def get_len_evaluations(self, exclude_reserved_tokens=False):
        total = self.len_allocated_tokens.get(Evaluations.support, 0) + \
            self.len_allocated_tokens.get(Evaluations.oppose, 0)
        if exclude_reserved_tokens:
            return total - len([o for o in self.reserved_tokens
                                if o in self.allocated_tokens])
        return  total

    def get_len_free_tokens(self, root=None, exclude_reserved_tokens=False):
        root = root or getSite()
        return self.get_len_tokens(root, exclude_reserved_tokens) - \
            self.get_len_evaluations(exclude_reserved_tokens)

    def has_token(self, obj=None, root=None):
        root = root or getSite()
        obj_oid = get_oid(obj, None)
        if obj_oid and obj_oid in self.reserved_tokens:
            return obj_oid not in self.allocated_tokens

        return self.get_len_free_tokens(root, True)>0

    def add_token(self, obj, evaluation_type, root=None):
        if self.has_token(obj, root):
            self.allocated_tokens[get_oid(obj)] = evaluation_type
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] += 1

    def remove_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid in self.allocated_tokens:
            evaluation_type = self.allocated_tokens.pop(obj_oid)
            self.len_allocated_tokens.setdefault(evaluation_type, 0)
            self.len_allocated_tokens[evaluation_type] -= 1

    def add_reserved_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid not in self.reserved_tokens:
            self.reserved_tokens.append(obj_oid)

    def remove_reserved_token(self, obj):
        obj_oid = get_oid(obj)
        if obj_oid in self.reserved_tokens:
            self.reserved_tokens.remove(obj_oid)

    def evaluated_objs(self, evaluation_type=None):
        if evaluation_type:
            return [get_obj(key) for value, key
                    in self.allocated_tokens.byValue(evaluation_type)]
        
        return [get_obj(key) for key
                in self.allocated_tokens.keys()]

    def evaluated_objs_ids(self, evaluation_type=None):
        if evaluation_type:
            return [key for value, key
                    in self.allocated_tokens.byValue(evaluation_type)]
        
        return list(self.allocated_tokens.keys())

    def init_contents_organizations(self):
        novaideo_catalog = find_catalog('novaideo')
        dace_catalog = find_catalog('dace')
        organizations_index = novaideo_catalog['organizations']
        object_authors_index = novaideo_catalog['object_authors']
        object_provides_index = dace_catalog['object_provides']
        query = object_authors_index.any([get_oid(self)]) & \
            object_provides_index.any(
                [Iidea.__identifier__, IProposal.__identifier__]) & \
            organizations_index.any([0])

        for entity in query.execute().all():
            entity.init_organization()
            entity.reindex()

    def set_read_date(self, channel, date):
        self._read_at[get_oid(channel)] = date

    def get_read_date(self, channel):
        return self._read_at.get(
            get_oid(channel), datetime.datetime.now(tz=pytz.UTC))

    def get_channel(self, user):
        all_channels = list(self.channels)
        all_channels.extend(list(getattr(user, 'channels', [])))
        for channel in all_channels:
            if user in channel.members and self in channel.members:
                return channel

        return None

    def addtoproperty(self, name, value, moving=None):
        super(Person, self).addtoproperty(name, value, moving)
        if name == 'selections':
            value.len_selections = getattr(value, 'len_selections', 0)
            value.len_selections += 1

    def delfromproperty(self, name, value, moving=None):
        super(Person, self).delfromproperty(name, value, moving)
        if name == 'selections':
            value.len_selections = getattr(value, 'len_selections', 0)
            if value.len_selections > 0:
                value.len_selections -= 1

    def set_title(self):
        self.title = getattr(self, 'first_name', '') + ' ' + \
                     getattr(self, 'last_name', '')

    def get_questions(self, user):
        if user is self:
            return self.questions + getattr(self.mask, 'questions', [])
        
        return self.questions

    def get_ideas(self, user):
        if user is self:
            return self.ideas + getattr(self.mask, 'ideas', [])
        
        return self.ideas

    def get_working_groups(self, user):
        if user is self:
            return self.working_groups + getattr(self.mask, 'working_groups', [])
        
        return self.working_groups

    @property
    def proposals(self):
        return [wg.proposal for wg in self.working_groups]

    def get_proposals(self, user):
        if user is self:
            return self.proposals + getattr(self.mask, 'proposals', [])
        
        return self.proposals

    @property
    def contacts(self):
        return [s for s in self.selections if isinstance(s, Person)]

    @property
    def participations(self):
        result = [p for p in list(self.proposals)
                  if any(s in p.state for s
                         in ['amendable',
                             'open to a working group',
                             'votes for publishing',
                             'votes for amendments'])]
        return result

    def get_participations(self, user):
        if user is self:
            return self.participations + getattr(self.mask, 'participations', [])
        
        return self.participations

    @property
    def contents(self):
        result = [i for i in list(self.ideas) if i is i.current_version]
        result.extend(self.proposals)
        result.extend(self.questions)
        result.extend(self.challenges)
        return result

    def get_contents(self, user):
        if user is self:
            return self.contents + getattr(self.mask, 'contents', [])
        
        return self.contents

    @property
    def active_working_groups(self):
        return [p.working_group for p in self.participations]

    def get_active_working_groups(self, user):
        if user is self:
            return self.active_working_groups + getattr(self.mask, 'active_working_groups', [])
        
        return self.active_working_groups

    @property
    def is_published(self):
        return 'active' in self.state

    @property
    def managed_organization(self):
        return get_objects_with_role(user=self, role='OrganizationResponsible')

    def reindex(self):
        super(Person, self).reindex()
        root = getSite()
        self.__access_keys__ = PersistentList(generate_access_keys(
            self, root))

    def get_picture_url(self, kind, default):
        if self.picture:
            img = getattr(self.picture, kind, None)
            if img:
                return img.url

        return default

    def get_more_contents_criteria(self):
        "return specific query, filter values"
        return None, None

    def set_organization(self, organization):
        current_organization = self.organization
        if organization:
            if current_organization is not organization:
                is_manager = current_organization and has_role(
                    ('OrganizationResponsible', current_organization), self,
                    ignore_superiors=True)
                if current_organization and is_manager:
                    revoke_roles(
                        self,
                        (('OrganizationResponsible', current_organization),))

                self.setproperty('organization', organization)
        elif current_organization:
            is_manager = has_role(
                ('OrganizationResponsible', current_organization), self,
                ignore_superiors=True)
            if is_manager:
                revoke_roles(
                    self,
                    (('OrganizationResponsible', current_organization),))

            self.delfromproperty('organization', current_organization)

    @property
    def all_alerts(self):
        novaideo_catalog = find_catalog('novaideo')
        dace_catalog = find_catalog('dace')
        alert_keys_index = novaideo_catalog['alert_keys']
        alert_exclude_keys_index = novaideo_catalog['alert_exclude_keys']
        object_provides_index = dace_catalog['object_provides']
        exclude = [str(get_oid(self))]
        if self.mask:
            exclude.append(str(get_oid(self.mask)))

        query = object_provides_index.any([IAlert.__identifier__]) & \
            alert_keys_index.any(self.get_alerts_keys()) & \
            alert_exclude_keys_index.notany(exclude)
        return query.execute()

    @property
    def alerts(self):
        old_alerts = [get_oid(a) for a in self.old_alerts]
        result = self.all_alerts

        def exclude(result_set, docids):
            filtered_ids = list(result_set.ids)
            for _id in docids:
                if _id in docids and _id in filtered_ids:
                    filtered_ids.remove(_id)

            return result_set.__class__(
                filtered_ids, len(filtered_ids), result_set.resolver)

        return exclude(result, old_alerts)

    def get_alerts_keys(self):
        result = ['all', str(get_oid(self))]
        if self.mask:
            result.append(str(get_oid(self.mask)))

        return result

    def get_alerts(self, alerts=None, kind=None,
                   subject=None, **kwargs):
        if alerts is None:
            alerts = self.alerts

        if kind:
            alerts = [a for a in alerts
                      if a.is_kind_of(kind)]

        if subject:
            alerts = [a for a in alerts
                      if subject in a.subjects]

        if kwargs:
            alerts = [a for a in alerts
                      if a.has_args(**kwargs)]

        return alerts

    @property
    def user_groups(self):
        groups = list(self.groups)
        if self.organization:
            groups.append(self.organization)

        if self.mask:
            groups.append(self.mask)

        return groups

    @property
    def user_locale(self):
        locale = getattr(self, 'locale', None)
        if not locale:
            locale = getSite(self).locale

        return locale

    def _init_mask(self, root):
        if not self.mask:
            mask = Mask()
            root.addtoproperty('masks', mask)
            self.setproperty('mask', mask)

    def get_mask(self, root=None):
        root = root if root else getSite()
        if not getattr(root, 'anonymisation', False):
            return self

        self._init_mask(root)
        return self.mask