def get_data(self, **kwargs): queryset = self.get_queryset() # cut off at timestamp if given if self.offset_timestamp: offset_datetime = datetime_from_timestamp(self.offset_timestamp) filter_exp = {'%s__lt' % self.offset_model_field: offset_datetime} queryset = queryset.filter(**filter_exp) # calculate has_more and new offset timestamp has_more = queryset.count() > self.page_size queryset = queryset[:self.page_size] items = self.get_items_from_queryset(queryset) queryset = list(queryset) last_offset_timestamp = None if len(queryset) > 0: last_offset_timestamp = timestamp_from_datetime( getattr(queryset[-1], self.offset_model_field)) return { 'items': items, 'widget_title': self.model._meta.verbose_name_plural if self.model else None, 'has_more': has_more, 'offset_timestamp': last_offset_timestamp, }
def alerts_mark_seen(request, before_timestamp=None): """ Marks all NotificationAlerts of the current user as seen. @param before_timestamp: if kwarg is given, only marks alerts older than the given timestamp as seen. """ if request and not request.user.is_authenticated: return HttpResponseForbidden('Not authenticated') if not request.method == 'POST': return HttpResponseNotAllowed(['POST']) if before_timestamp is not None and not is_number(before_timestamp): return HttpResponseBadRequest('Malformed parameter: "before_timestamp"') if before_timestamp: before_timestamp = float(before_timestamp) before_dt = datetime_from_timestamp(before_timestamp) else: before_dt = now() unseen_alerts = NotificationAlert.objects.filter( portal=CosinnusPortal.get_current(), user=request.user, last_event_at__lte=before_dt, seen=False ) unseen_alerts.update(seen=True) return HttpResponse('ok')
def get_queryset(self): alerts_qs = NotificationAlert.objects.filter( portal=CosinnusPortal.get_current(), user=self.request.user ) # retrieve number of unseen alerts from ALL alerts (before pagination) unless we're loading "more..." paged items self.unseen_count = -1 if not self.offset_timestamp: unseen_aggr = alerts_qs.aggregate(seen_count=Count(Case(When(seen=False, then=1)))) self.unseen_count = unseen_aggr.get('seen_count', 0) if self.newer_than_timestamp: after_dt = datetime_from_timestamp(self.newer_than_timestamp) alerts_qs = alerts_qs.filter(last_event_at__gt=after_dt) return alerts_qs
def _mix_items_from_querysets(self, *streams): """ Will zip items from multiple querysts (each for a single model) into a single item list, while retainining an overall sort-order. Will peek all of the querysets and pick the next lowest-sorted item (honoring the given offset), until enough items for the page size are collected, or all querysets are exhausted. """ reverse = '-' in self.sort_key # apply timestamp offset if self.offset_timestamp: offset_datetime = datetime_from_timestamp(self.offset_timestamp) streams = [ stream.filter( **{'%s__lt' % self.sort_key_natural: offset_datetime}) for stream in streams ] if not getattr(settings, 'COSINNUS_V2_DASHBOARD_USE_NAIVE_FETCHING', False): queryset_iterator = QuerysetLazyCombiner(streams, self.sort_key_natural, math.ceil(self.page_size / 2.0), reverse=reverse) items = list(itertools.islice(queryset_iterator, self.page_size)) else: logger.warn( 'Using naive queryset picking! Performance may suffer in production!' ) # naive just takes `page_size` items from each stream, then sorts and takes first `page_size` items cut_streams = [stream[:self.page_size] for stream in streams] items = sorted( itertools.chain(*cut_streams), key=lambda item: getattr(item, self.sort_key_natural), reverse=reverse) # placeholder items = items[:self.page_size] return items
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, }