def get_group_clusters(self, user, sort_by_activity=False): clusters = [] projects = list(CosinnusProject.objects.get_for_user(user)) societies = list(CosinnusSociety.objects.get_for_user(user)) group_ct = ContentType.objects.get_for_model( get_cosinnus_group_model()) if sort_by_activity: group_last_visited_qs = LastVisitedObject.objects.filter( user=user, content_type=group_ct, portal=CosinnusPortal.get_current()) # a dict of group-id -> datetime group_last_visited = dict( group_last_visited_qs.values_list('object_id', 'visited')) else: group_last_visited = {} default_date = now() - relativedelta(years=100) class AttrList(list): last_visited = None for society in societies: if society.slug in get_default_user_group_slugs(): continue # the most recent visit time to any project or society in the cluster most_recent_dt = group_last_visited.get(society.id, default_date) items = AttrList([DashboardItem(society, is_emphasized=True)]) for i in range(len(projects) - 1, -1, -1): project = projects[i] if project.parent == society: items.append(DashboardItem(project)) projects.pop(i) project_dt = group_last_visited.get( project.id, default_date) most_recent_dt = project_dt if project_dt > most_recent_dt else most_recent_dt items.last_visited = most_recent_dt clusters.append(items) # add unclustered projects as own cluster for proj in projects: items = AttrList([DashboardItem(proj)]) items.last_visited = group_last_visited.get(proj.id, default_date) clusters.append(items) # sort clusters by last_visited if sort_by_activity: clusters = sorted(clusters, key=lambda cluster: cluster.last_visited, reverse=True) return clusters
def mark_visited(self, user): """ Creates or updates a `LastVisited` object for this object and the given user """ if not user.is_authenticated: return None try: from cosinnus.models.user_dashboard import DashboardItem from cosinnus.models.group import CosinnusPortal ct = self.get_content_type_for_last_visited() visit = get_object_or_None(LastVisitedObject, content_type=ct, object_id=self.id, user=user, portal=CosinnusPortal.get_current()) if visit is None: visit = LastVisitedObject(content_type=ct, object_id=self.id, user=user, portal=CosinnusPortal.get_current()) visit.visited = now() visit.item_data = DashboardItem(self) visit.save() return visit except Exception as e: logger.exception( 'An unknown error occured while saving the last_visited visit! Exception in extra.', extra={'exception': force_text(e)}) return None
def get_data(self, *kwargs): idea_ct = ContentType.objects.get_for_model(CosinnusIdea) likeobjects = LikeObject.objects.filter(user=self.request.user, content_type=idea_ct, liked=True) liked_ideas_ids = likeobjects.values_list('object_id', flat=True) liked_ideas = CosinnusIdea.objects.all_in_portal().filter( id__in=liked_ideas_ids) ideas = [DashboardItem(idea) for idea in liked_ideas] return {'items': ideas}
def get_items_from_queryset(self, queryset): """ Returns a list of converted item data from the queryset """ if self.show_recent: # the `item_data` field already contains the JSON of `DashboardItem` items = list(queryset.values_list('item_data', flat=True)) else: items = [ DashboardItem(item, user=self.request.user) for item in list(queryset) ] return items
def get_items_from_dataset(self, dataset): """ Returns a list of converted item data from the ES result""" items = [] for doc in dataset['documents']: item = DashboardItem() item['icon'] = 'fa-file-text' try: item['text'] = escape(doc['info']['file']) item['subtext'] = escape(doc['info']['dir']) except KeyError: continue # cloud_file.download_url for a direct download or cloud_file.url for a link into Nextcloud item['url'] = f"{settings.COSINNUS_CLOUD_NEXTCLOUD_URL}{doc['link']}" items.append(item) return items
def get_data(self, *kwargs): profile_ct = ContentType.objects.get_for_model( get_user_profile_model()) exclude_ids = [profile_ct.id] liked = LikeObject.objects.filter( user=self.request.user, starred=True).exclude(content_type_id__in=exclude_ids) objects = [] for like in liked: ct = ContentType.objects.get_for_id(like.content_type.id) obj = ct.get_object_for_this_type(pk=like.object_id) dashboard_item = DashboardItem(obj) dashboard_item['id'] = obj.id dashboard_item['ct'] = obj.get_content_type() objects.append(dashboard_item) return {'items': objects}
def get_data(self, *kwargs): profile_ct = ContentType.objects.get_for_model( get_user_profile_model()) likeobjects = LikeObject.objects.filter(user=self.request.user, content_type=profile_ct, starred=True) liked_users_ids = likeobjects.values_list('object_id', flat=True) liked_users = get_user_profile_model().objects.filter( id__in=liked_users_ids, user__is_active=True) users = [] for user in liked_users: dashboard_item = DashboardItem(user) dashboard_item['id'] = user.id dashboard_item['ct'] = user.get_content_type() users.append(dashboard_item) return {'items': users}
def get_data(self, *kwargs): followed = LikeObject.objects.filter(user=self.request.user, followed=True) objects = [] for follow in followed: ct = ContentType.objects.get_for_id(follow.content_type.id) obj = ct.get_object_for_this_type(pk=follow.object_id) # filter inactive groups if type(obj) is get_cosinnus_group_model() or issubclass( obj.__class__, get_cosinnus_group_model()): if not obj.is_active: continue dashboard_item = DashboardItem(obj) dashboard_item['id'] = obj.id dashboard_item['ct'] = obj.get_content_type() objects.append(dashboard_item) return {'items': objects}
def get_group_clusters(self, user, sort_by_activity=False): clusters = [] # collect map of last visited groups group_ct = ContentType.objects.get_for_model( get_cosinnus_group_model()) if sort_by_activity: group_last_visited_qs = LastVisitedObject.objects.filter( user=user, content_type=group_ct, portal=CosinnusPortal.get_current()) # a dict of group-id -> datetime group_last_visited = dict( group_last_visited_qs.values_list('object_id', 'visited')) else: group_last_visited = {} default_date = now() - relativedelta(years=100) # collect and sort user projects and societies lists projects = list(CosinnusProject.objects.get_for_user(user)) societies = list(CosinnusSociety.objects.get_for_user(user)) # sort sub items by last_visited or name if sort_by_activity: projects = sorted(projects, key=lambda project: group_last_visited.get( project.id, default_date), reverse=True) societies = sorted(societies, key=lambda society: group_last_visited.get( society.id, default_date), reverse=True) else: projects = sorted(projects, key=sort_key_strcoll_attr('name')) societies = sorted(societies, key=sort_key_strcoll_attr('name')) # sort projects into their societies clusters, society clusters are always displayed first for society in societies: if society.slug in get_default_user_group_slugs(): continue # the most recent visit time to any project or society in the cluster most_recent_dt = group_last_visited.get(society.id, default_date) items_projects = [] for i in range(len(projects) - 1, -1, -1): project = projects[i] if project.parent == society: items_projects.insert(0, DashboardItem( project)) # prepend because of reversed order projects.pop(i) project_dt = group_last_visited.get( project.id, default_date) most_recent_dt = project_dt if project_dt > most_recent_dt else most_recent_dt items = [DashboardItem(society, is_emphasized=True) ] + items_projects clusters.append(items) # add unclustered projects as own cluster for proj in projects: items = [DashboardItem(proj)] clusters.append(items) return clusters
def render_item(self, item): """ Renders an item to a dashboard item dict """ return DashboardItem(item)
def get_data(self, **kwargs): has_more = False offset_timestamp = None if self.show_recent: # showing "last-visited" content, ordering by visit datetime ct = ContentType.objects.get_for_model(self.model) queryset = LastVisitedObject.objects.filter( content_type=ct, user=self.request.user, portal=CosinnusPortal.get_current()) queryset = queryset.order_by('-visited') # cut off at timestamp if given if self.offset_timestamp: offset_datetime = datetime_from_timestamp( self.offset_timestamp) queryset = queryset.filter(visited__lt=offset_datetime) # calculate has_more and new offset timestamp has_more = queryset.count() > self.page_size queryset = queryset[:self.page_size] # the `item_data` field already contains the JSON of `DashboardItem` items = list(queryset.values_list('item_data', flat=True)) queryset = list(queryset) if len(queryset) > 0: offset_timestamp = timestamp_from_datetime( queryset[-1].visited) else: # all content, ordered by creation date only_mine = True sort_key = '-created' queryset = self.fetch_queryset_for_user(self.model, self.request.user, sort_key=sort_key, only_mine=only_mine) if queryset is None: return { 'items': [], 'widget_title': '(error: %s)' % self.model.__name__ } # cut off at timestamp if given if self.offset_timestamp: offset_datetime = datetime_from_timestamp( self.offset_timestamp) queryset = queryset.filter(created__lt=offset_datetime) # calculate has_more and new offset timestamp has_more = queryset.count() > self.page_size queryset = list(queryset[:self.page_size]) if len(queryset) > 0: offset_timestamp = timestamp_from_datetime( queryset[-1].created) items = [ DashboardItem(item, user=self.request.user) for item in queryset ] return { 'items': items, 'widget_title': self.model._meta.verbose_name_plural, 'has_more': has_more, 'offset_timestamp': offset_timestamp, }
def cosinnus_menu_v2(context, template="cosinnus/v2/navbar/navbar.html"): """ Renders the new style navbar """ if 'request' not in context: raise ImproperlyConfigured("Current request missing in rendering " "context. Include 'django.core.context_processors.request' in the " "TEMPLATE_CONTEXT_PROCESSORS.") request = context['request'] user = request.user if user.is_authenticated: from cosinnus.views.user_dashboard import MyGroupsClusteredMixin from cosinnus.models.user_dashboard import DashboardItem def _escape_quotes(text): return text.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") if settings.COSINNUS_IDEAS_ENABLED: # "My Ideas" my_ideas = CosinnusIdea.objects.all_in_portal().filter(creator=user).order_by(Lower('title')) context['my_ideas_json_encoded'] = _escape_quotes(_json.dumps([DashboardItem(idea) for idea in my_ideas])) # "Followed Ideas" idea_content_type = ContentType.objects.get_for_model(CosinnusIdea) my_followed_ids = LikeObject.objects.filter(content_type=idea_content_type, user=user, followed=True).values_list('object_id', flat=True) my_followed_ideas = CosinnusIdea.objects.all_in_portal().filter(id__in=my_followed_ids).order_by(Lower('title')) my_followed_ideas = my_followed_ideas.exclude(creator=user) context['followed_ideas_json_encoded'] = _escape_quotes(_json.dumps([DashboardItem(idea) for idea in my_followed_ideas])) # "My Groups and Projects" context['group_clusters_json_encoded'] = _escape_quotes(_json.dumps(MyGroupsClusteredMixin().get_group_clusters(user))) # "Invitations" societies_invited = CosinnusSociety.objects.get_for_user_invited(request.user) projects_invited = CosinnusProject.objects.get_for_user_invited(request.user) groups_invited = [DashboardItem(group) for group in societies_invited] groups_invited += [DashboardItem(group) for group in projects_invited] context['groups_invited_json_encoded'] = _escape_quotes(_json.dumps(groups_invited)) context['groups_invited_count'] = len(groups_invited) membership_requests = [] membership_requests_count = 0 admined_group_ids = CosinnusGroup.objects.get_for_user_group_admin_pks(request.user) admined_groups = CosinnusGroup.objects.get_cached(pks=admined_group_ids) for admined_group in admined_groups: pending_ids = CosinnusGroupMembership.objects.get_pendings(group=admined_group) if len(pending_ids) > 0: membership_request_item = DashboardItem() membership_request_item['icon'] = 'fa-sitemap' if admined_group.type == CosinnusGroup.TYPE_SOCIETY else 'fa-group' membership_request_item['text'] = escape('%s (%d)' % (admined_group.name, len(pending_ids))) membership_request_item['url'] = group_aware_reverse('cosinnus:group-detail', kwargs={'group': admined_group}) + '#requests' membership_requests.append(membership_request_item) membership_requests_count += len(pending_ids) context['group_requests_json_encoded'] = _escape_quotes(_json.dumps(membership_requests)) context['group_requests_count'] = membership_requests_count attending_events = [] try: from cosinnus_event.models import Event, EventAttendance # noqa my_attendances_ids = EventAttendance.objects.filter(user=user, state__gt=EventAttendance.ATTENDANCE_NOT_GOING).values_list('event_id', flat=True) attending_events = Event.get_current_for_portal().filter(id__in=my_attendances_ids) attending_events = filter_tagged_object_queryset_for_user(attending_events, user) except: if settings.DEBUG: raise context['attending_events_json_encoded'] = _escape_quotes(_json.dumps([DashboardItem(event) for event in attending_events])) # TODO cache the dumped JSON strings? return render_to_string(template, context.flatten())