Exemplo n.º 1
0
    def post(self, request, group_id):
        group = Group.objects.get(
            id=group_id,
        )

        assert_perm(group, request.user, request.auth)

        now = timezone.now()

        group.resolved_at = now

        happened = Group.objects.filter(
            id=group.id,
        ).exclude(status=STATUS_RESOLVED).update(
            status=STATUS_RESOLVED,
            resolved_at=now,
        )

        if happened:
            create_or_update(
                Activity,
                project=group.project,
                group=group,
                type=Activity.SET_RESOLVED,
                user=request.user,
            )

        return Response()
Exemplo n.º 2
0
 def _set_bytes(self, id, data, ttl=None):
     create_or_update(Node,
                      id=id,
                      values={
                          "data": compress(data),
                          "timestamp": timezone.now()
                      })
Exemplo n.º 3
0
 def set(self, id, data, ttl=None):
     create_or_update(Node,
                      id=id,
                      values={
                          "data": data,
                          "timestamp": timezone.now()
                      })
Exemplo n.º 4
0
    def post(self, request, group_id):
        group = Group.objects.get(id=group_id)

        assert_perm(group, request.user, request.auth)

        serializer = GroupAssigneeSerializer(data=request.DATA)

        if serializer.is_valid():
            user = serializer.object.user
            now = timezone.now()

            assignee, created = GroupAssignee.objects.get_or_create(
                group=group, defaults={"project": group.project, "user": user, "date_added": now}
            )

            if not created:
                affected = (
                    GroupAssignee.objects.filter(group=group).exclude(user=user).update(user=user, date_added=now)
                )
            else:
                affected = True

            if affected:
                create_or_update(
                    Activity, project=group.project, group=group, type=Activity.ASSIGNED, user=request.user
                )

            return Response()

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemplo n.º 5
0
 def set(self, id, data, ttl=None):
     create_or_update(
         Node,
         id=id,
         values={
             'data': data,
             'timestamp': timezone.now(),
         },
     )
Exemplo n.º 6
0
 def set(self, id, data):
     create_or_update(
         Node,
         id=id,
         values={
             'data': data,
             'timestamp': timezone.now(),
         },
     )
Exemplo n.º 7
0
 def set(self, id, data):
     create_or_update(
         Node,
         id=id,
         defaults={
             'data': data,
             'timestamp': timezone.now(),
         },
     )
Exemplo n.º 8
0
 def set(self, id, data, ttl=None):
     create_or_update(Node,
                      id=id,
                      values={
                          "data": data,
                          "timestamp": timezone.now()
                      })
     cache_on_save = options.get("nodedata.cache-on-save")
     if cache_on_save:
         self._set_cache_item(id, data)
Exemplo n.º 9
0
    def handle(self, **options):
        page_path = os.path.join(DATA_ROOT, 'help_pages')
        for filename in os.listdir(page_path):
            file_path = os.path.join(page_path, filename)
            if not os.path.isfile(file_path):
                continue

            with open(file_path) as fp:
                content = fp.read()

            options, body = self.__split_content(content)

            print('Loading help page {key}'.format(
                key=filename,
            ))

            assert 'title' in options

            page, created = create_or_update(
                HelpPage,
                key=filename,
                values={
                    'title': options['title'],
                    'priority': options.get('priority', 50),
                    'content': body,
                }
            )
Exemplo n.º 10
0
    def handle(self, **options):
        page_path = os.path.join(DATA_ROOT, 'help_pages')
        for filename in os.listdir(page_path):
            file_path = os.path.join(page_path, filename)
            if not os.path.isfile(file_path):
                continue

            with open(file_path) as fp:
                content = fp.read()

            options, body = self.__split_content(content)

            print('Loading help page {key}'.format(key=filename, ))

            assert 'title' in options

            page, created = create_or_update(HelpPage,
                                             key=filename,
                                             values={
                                                 'title':
                                                 options['title'],
                                                 'priority':
                                                 options.get('priority', 50),
                                                 'content':
                                                 body,
                                             })
Exemplo n.º 11
0
    def post(self, request, group_id):
        group = Group.objects.get(
            id=group_id,
        )

        assert_perm(group, request.user, request.auth)

        serializer = GroupAssigneeSerializer(data=request.DATA)

        if serializer.is_valid():
            user = serializer.object.user
            now = timezone.now()

            assignee, created = GroupAssignee.objects.get_or_create(
                group=group,
                defaults={
                    'project': group.project,
                    'user': user,
                    'date_added': now,
                }
            )

            if not created:
                affected = GroupAssignee.objects.filter(
                    group=group,
                ).exclude(user=user).update(
                    user=user, date_added=now
                )
            else:
                affected = True

            if affected:
                create_or_update(
                    Activity,
                    project=group.project,
                    group=group,
                    type=Activity.ASSIGNED,
                    user=request.user,
                )

            return Response()

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemplo n.º 12
0
    def post(self, request, group_id):
        group = Group.objects.get(id=group_id, )

        assert_perm(group, request.user, request.auth)

        instance, created = create_or_update(GroupSeen,
                                             group=group,
                                             user=extract_lazy_object(
                                                 request.user),
                                             project=group.project,
                                             defaults={
                                                 'last_seen': timezone.now(),
                                             })
        if created:
            return Response(status=201)
        return Response(status=204)
Exemplo n.º 13
0
    def post(self, request, group_id):
        group = Group.objects.get(
            id=group_id,
        )

        assert_perm(group, request.user, request.auth)

        instance, created = create_or_update(
            GroupSeen,
            group=group,
            user=extract_lazy_object(request.user),
            project=group.project,
            defaults={
                'last_seen': timezone.now(),
            }
        )
        if created:
            return Response(status=201)
        return Response(status=204)
Exemplo n.º 14
0
def group(request, team, project, group, event_id=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    if event_id:
        event = get_object_or_404(group.event_set, id=event_id)
    else:
        event = group.get_latest_event() or Event()

    Event.objects.bind_nodes([event], 'data')

    # bind params to group in case they get hit
    event.group = group
    event.project = project

    if request.POST.get('o') == 'note' and request.user.is_authenticated():
        add_note_form = NewNoteForm(request.POST)
        if add_note_form.is_valid():
            add_note_form.save(event, request.user)
            return HttpResponseRedirect(request.path)
    else:
        add_note_form = NewNoteForm()

    activity_qs = Activity.objects.order_by('-datetime').select_related('user')
    # if event_id:
    #     activity_qs = activity_qs.filter(
    #         Q(event=event) | Q(event__isnull=True),
    #     )

    if project in Project.objects.get_for_user(request.user,
                                               team=team,
                                               superuser=False):
        # update that the user has seen this group
        create_or_update(GroupSeen,
                         group=group,
                         user=request.user,
                         project=project,
                         defaults={
                             'last_seen': timezone.now(),
                         })

    # filter out dupe activity items
    activity_items = set()
    activity = []
    for item in activity_qs.filter(group=group)[:20]:
        sig = (item.event_id, item.type, item.ident, item.user_id)
        # TODO: we could just generate a signature (hash(text)) for notes
        # so theres no special casing
        if item.type == Activity.NOTE:
            activity.append(item)
        elif sig not in activity_items:
            activity_items.add(sig)
            activity.append(item)

    activity.append(
        Activity(project=project,
                 group=group,
                 type=Activity.FIRST_SEEN,
                 datetime=group.first_seen))

    # trim to latest 5
    activity = activity[:7]

    seen_by = sorted(filter(lambda ls: ls[0] != request.user and ls[0].email, [
        (gs.user, gs.last_seen)
        for gs in GroupSeen.objects.filter(group=group).select_related('user')
    ]),
                     key=lambda ls: ls[1],
                     reverse=True)
    seen_by_extra = len(seen_by) - 5
    if seen_by_extra < 0:
        seen_by_extra = 0
    seen_by_faces = seen_by[:5]

    context = {
        'add_note_form': add_note_form,
        'page': 'details',
        'activity': activity,
        'seen_by': seen_by,
        'seen_by_faces': seen_by_faces,
        'seen_by_extra': seen_by_extra,
    }

    is_public = group_is_public(group, request.user)

    if is_public:
        template = 'sentry/groups/public_details.html'
        context['PROJECT_LIST'] = [project]
    else:
        template = 'sentry/groups/details.html'

    return render_with_group_context(group,
                                     template,
                                     context,
                                     request,
                                     event=event,
                                     is_public=is_public)
Exemplo n.º 15
0
def group(request, team, project, group, event_id=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    if event_id:
        event = get_object_or_404(group.event_set, id=event_id)
    else:
        event = group.get_latest_event() or Event()

    Event.objects.bind_nodes([event], "data")

    # bind params to group in case they get hit
    event.group = group
    event.project = project

    if request.POST.get("o") == "note" and request.user.is_authenticated():
        add_note_form = NewNoteForm(request.POST)
        if add_note_form.is_valid():
            add_note_form.save(event, request.user)
            return HttpResponseRedirect(request.path)
    else:
        add_note_form = NewNoteForm()

    if project in Project.objects.get_for_user(request.user, team=team, superuser=False):
        # update that the user has seen this group
        create_or_update(
            GroupSeen, group=group, user=request.user, project=project, defaults={"last_seen": timezone.now()}
        )

    activity_qs = Activity.objects.filter(group=group).order_by("-datetime").select_related("user")

    # filter out dupe activity items
    activity_items = set()
    activity = []
    for item in activity_qs[:20]:
        sig = (item.event_id, item.type, item.ident, item.user_id)
        # TODO: we could just generate a signature (hash(text)) for notes
        # so there's no special casing
        if item.type == Activity.NOTE:
            activity.append(item)
        elif sig not in activity_items:
            activity_items.add(sig)
            activity.append(item)

    activity.append(Activity(project=project, group=group, type=Activity.FIRST_SEEN, datetime=group.first_seen))

    # trim to latest 5
    activity = activity[:7]

    seen_by = sorted(
        filter(
            lambda ls: ls[0] != request.user and ls[0].email,
            [(gs.user, gs.last_seen) for gs in GroupSeen.objects.filter(group=group).select_related("user")],
        ),
        key=lambda ls: ls[1],
        reverse=True,
    )
    seen_by_extra = len(seen_by) - 5
    if seen_by_extra < 0:
        seen_by_extra = 0
    seen_by_faces = seen_by[:5]

    context = {
        "add_note_form": add_note_form,
        "page": "details",
        "activity": activity,
        "seen_by": seen_by,
        "seen_by_faces": seen_by_faces,
        "seen_by_extra": seen_by_extra,
    }

    is_public = group_is_public(group, request.user)

    if is_public:
        template = "sentry/groups/public_details.html"
        context["PROJECT_LIST"] = [project]
    else:
        template = "sentry/groups/details.html"

    return render_with_group_context(group, template, context, request, event=event, is_public=is_public)
Exemplo n.º 16
0
def group(request, team, project, group, event_id=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    if event_id:
        event = get_object_or_404(group.event_set, id=event_id)
    else:
        event = group.get_latest_event() or Event()

    # bind params to group in case they get hit
    event.group = group
    event.project = project

    if request.POST.get('o') == 'note' and request.user.is_authenticated():
        add_note_form = NewNoteForm(request.POST)
        if add_note_form.is_valid():
            activity = Activity.objects.create(
                group=group, event=event, project=project,
                type=Activity.NOTE, user=request.user,
                data=add_note_form.cleaned_data
            )
            activity.send_notification()
            return HttpResponseRedirect(request.path)
    else:
        add_note_form = NewNoteForm()

    activity_qs = Activity.objects.order_by('-datetime').select_related('user')
    if event:
        activity_qs = activity_qs.filter(
            Q(event=event) | Q(event__isnull=True),
        )

    if project in Project.objects.get_for_user(
            request.user, team=team, superuser=False):
        # update that the user has seen this group
        create_or_update(
            GroupSeen,
            group=group,
            user=request.user,
            project=project,
            defaults={
                'last_seen': timezone.now(),
            }
        )

    # filter out dupe activity items
    activity_items = set()
    activity = []
    for item in activity_qs.filter(group=group)[:20]:
        sig = (item.event_id, item.type, item.ident, item.user_id)
        # TODO: we could just generate a signature (hash(text)) for notes
        # so theres no special casing
        if item.type == Activity.NOTE:
            activity.append(item)
        elif sig not in activity_items:
            activity_items.add(sig)
            activity.append(item)

    activity.append(Activity(
        project=project, group=group, type=Activity.FIRST_SEEN,
        datetime=group.first_seen))

    # trim to latest 5
    activity = activity[:7]

    seen_by = sorted(filter(lambda ls: ls[0] != request.user and ls[0].email, [
        (gs.user, gs.last_seen)
        for gs in GroupSeen.objects.filter(
            group=group
        ).select_related('user')
    ]), key=lambda ls: ls[1], reverse=True)
    seen_by_extra = len(seen_by) - 5
    if seen_by_extra < 0:
        seen_by_extra = 0
    seen_by_faces = seen_by[:5]

    context = {
        'add_note_form': add_note_form,
        'page': 'details',
        'activity': activity,
        'seen_by': seen_by,
        'seen_by_faces': seen_by_faces,
        'seen_by_extra': seen_by_extra,
    }

    is_public = group_is_public(group, request.user)

    if is_public:
        template = 'sentry/groups/public_details.html'
        context['PROJECT_LIST'] = [project]
    else:
        template = 'sentry/groups/details.html'

    return render_with_group_context(
        group, template, context, request,
        event=event, is_public=is_public)
    def forwards(self, orm):
        from django.db.models import F
        from collections import defaultdict
        from sentry.db.models import create_or_update
        from sentry.utils.query import RangeQuerySetWrapper

        # We don't fully merge results because it's simply not worth it
        for group in RangeQuerySetWrapper(orm['sentry.Group'].objects.all()):

            # could be already migrated
            if not orm['sentry.Group'].objects.filter(id=group.id).exists():
                continue

            matches = list(orm['sentry.Group'].objects.exclude(id=group.id).filter(
                checksum=group.checksum, project=group.project))

            if not matches:
                continue

            print "Merging duplicate events for %r" % (group,)

            updates = defaultdict(int)
            updates.update({
                'first_seen': group.first_seen,
                'last_seen': group.last_seen,
                'active_at': group.active_at,
            })

            tag_updates = defaultdict(lambda: defaultdict(int))
            counts = defaultdict(lambda: defaultdict(int))
            for other in matches:
                # migrate events first
                orm['sentry.Event'].objects.filter(group=other).update(group=group)

                updates['times_seen'] += other.times_seen
                updates['users_seen'] += other.users_seen
                updates['time_spent_total'] += other.time_spent_total
                updates['time_spent_count'] += other.time_spent_count
                for datecol in ('active_at', 'last_seen', 'first_seen'):
                    val = getattr(other, datecol)
                    if val and updates[datecol]:
                        updates[datecol] = max(val, updates[datecol])
                    elif val:
                        updates[datecol] = val

                # determine missing tags
                for tag in RangeQuerySetWrapper(orm['sentry.MessageFilterValue'].objects.filter(group=other)):
                    key = tag_updates[(tag.key, tag.value)]
                    key['times_seen'] += other.times_seen
                    for datecol in ('last_seen', 'first_seen'):
                        val = getattr(other, datecol)
                        if val and updates[datecol]:
                            updates[datecol] = max(val, updates[datecol])
                        elif val:
                            updates[datecol] = val

                # determine counts
                for count in RangeQuerySetWrapper(orm['sentry.MessageCountByMinute'].objects.filter(group=other)):
                    key = counts[count.date]
                    key['times_seen'] += count.times_seen
                    key['time_spent_total'] += count.time_spent_total
                    key['time_spent_count'] += count.time_spent_count

            # migrate tags
            for (key, value), data in tag_updates.iteritems():
                defaults = {
                    'times_seen': F('times_seen') + data['times_seen'],
                }
                if 'last_seen' in data:
                    defaults['last_seen'] = data['last_seen']
                if 'first_seen' in data:
                    defaults['first_seen'] = data['first_seen']

                create_or_update(orm['sentry.MessageFilterValue'],
                    project=group.project,
                    group=group,
                    key=key,
                    value=value,
                    defaults=defaults
                )

            orm['sentry.MessageFilterValue'].objects.filter(group__in=matches).delete()

            # migrate counts
            for date, data in counts.iteritems():
                create_or_update(orm['sentry.MessageCountByMinute'],
                    project=group.project,
                    group=group,
                    date=date,
                    defaults={
                        'times_seen': F('times_seen') + data['times_seen'],
                        'time_spent_total': F('time_spent_total') + data['time_spent_total'],
                        'time_spent_count': F('time_spent_count') + data['time_spent_count'],
                    }
                )

            orm['sentry.MessageCountByMinute'].objects.filter(group__in=matches).delete()

            orm['sentry.Group'].objects.filter(id=group.id).update(
                times_seen=F('times_seen') + updates['times_seen'],
                users_seen=F('users_seen') + updates['user_seen'],
                time_spent_total=F('time_spent_total') + updates['time_spent_total'],
                time_spent_count=F('time_spent_count') + updates['time_spent_count'],
                last_seen=updates['last_seen'],
                first_seen=updates['first_seen'],
                active_at=updates['active_at'],
            )

            for other in matches:
                other.delete()
Exemplo n.º 18
0
    def forwards(self, orm):
        from django.db.models import F
        from collections import defaultdict
        from sentry.db.models import create_or_update
        from sentry.utils.query import RangeQuerySetWrapper

        # We don't fully merge results because it's simply not worth it
        for group in RangeQuerySetWrapper(orm['sentry.Group'].objects.all()):

            # could be already migrated
            if not orm['sentry.Group'].objects.filter(id=group.id).exists():
                continue

            matches = list(orm['sentry.Group'].objects.exclude(
                id=group.id).filter(checksum=group.checksum,
                                    project=group.project))

            if not matches:
                continue

            print "Merging duplicate events for %r" % (group, )

            updates = defaultdict(int)
            updates.update({
                'first_seen': group.first_seen,
                'last_seen': group.last_seen,
                'active_at': group.active_at,
            })

            tag_updates = defaultdict(lambda: defaultdict(int))
            counts = defaultdict(lambda: defaultdict(int))
            for other in matches:
                # migrate events first
                orm['sentry.Event'].objects.filter(group=other).update(
                    group=group)

                updates['times_seen'] += other.times_seen
                updates['users_seen'] += other.users_seen
                updates['time_spent_total'] += other.time_spent_total
                updates['time_spent_count'] += other.time_spent_count
                for datecol in ('active_at', 'last_seen', 'first_seen'):
                    val = getattr(other, datecol)
                    if val and updates[datecol]:
                        updates[datecol] = max(val, updates[datecol])
                    elif val:
                        updates[datecol] = val

                # determine missing tags
                for tag in RangeQuerySetWrapper(
                        orm['sentry.MessageFilterValue'].objects.filter(
                            group=other)):
                    key = tag_updates[(tag.key, tag.value)]
                    key['times_seen'] += other.times_seen
                    for datecol in ('last_seen', 'first_seen'):
                        val = getattr(other, datecol)
                        if val and updates[datecol]:
                            updates[datecol] = max(val, updates[datecol])
                        elif val:
                            updates[datecol] = val

                # determine counts
                for count in RangeQuerySetWrapper(
                        orm['sentry.MessageCountByMinute'].objects.filter(
                            group=other)):
                    key = counts[count.date]
                    key['times_seen'] += count.times_seen
                    key['time_spent_total'] += count.time_spent_total
                    key['time_spent_count'] += count.time_spent_count

            # migrate tags
            for (key, value), data in tag_updates.iteritems():
                defaults = {
                    'times_seen': F('times_seen') + data['times_seen'],
                }
                if 'last_seen' in data:
                    defaults['last_seen'] = data['last_seen']
                if 'first_seen' in data:
                    defaults['first_seen'] = data['first_seen']

                create_or_update(orm['sentry.MessageFilterValue'],
                                 project=group.project,
                                 group=group,
                                 key=key,
                                 value=value,
                                 defaults=defaults)

            orm['sentry.MessageFilterValue'].objects.filter(
                group__in=matches).delete()

            # migrate counts
            for date, data in counts.iteritems():
                create_or_update(
                    orm['sentry.MessageCountByMinute'],
                    project=group.project,
                    group=group,
                    date=date,
                    defaults={
                        'times_seen':
                        F('times_seen') + data['times_seen'],
                        'time_spent_total':
                        F('time_spent_total') + data['time_spent_total'],
                        'time_spent_count':
                        F('time_spent_count') + data['time_spent_count'],
                    })

            orm['sentry.MessageCountByMinute'].objects.filter(
                group__in=matches).delete()

            orm['sentry.Group'].objects.filter(id=group.id).update(
                times_seen=F('times_seen') + updates['times_seen'],
                users_seen=F('users_seen') + updates['user_seen'],
                time_spent_total=F('time_spent_total') +
                updates['time_spent_total'],
                time_spent_count=F('time_spent_count') +
                updates['time_spent_count'],
                last_seen=updates['last_seen'],
                first_seen=updates['first_seen'],
                active_at=updates['active_at'],
            )

            for other in matches:
                other.delete()
Exemplo n.º 19
0
def group(request, team, project, group, event_id=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    activity_qs = Activity.objects.order_by('-datetime').select_related('user')
    if event_id:
        event = get_object_or_404(group.event_set, id=event_id)
        activity_qs = activity_qs.filter(
            Q(event=event) | Q(event__isnull=True), )
    else:
        event = group.get_latest_event() or Event()

    # bind params to group in case they get hit
    event.group = group
    event.project = project

    if project in Project.objects.get_for_user(request.user,
                                               team=team,
                                               superuser=False):
        # update that the user has seen this group
        create_or_update(GroupSeen,
                         group=group,
                         user=request.user,
                         project=project,
                         defaults={
                             'last_seen': timezone.now(),
                         })

    # filter out dupe activity items
    activity_items = set()
    activity = []
    for item in activity_qs.filter(group=group)[:10]:
        sig = (item.event_id, item.type, item.ident, item.user_id)
        if sig not in activity_items:
            activity_items.add(sig)
            activity.append(item)

    # trim to latest 5
    activity = activity[:5]

    seen_by = sorted(filter(lambda ls: ls[0] != request.user and ls[0].email, [
        (gs.user, gs.last_seen)
        for gs in GroupSeen.objects.filter(group=group).select_related('user')
    ]),
                     key=lambda ls: ls[1],
                     reverse=True)
    seen_by_extra = len(seen_by) - 5
    if seen_by_extra < 0:
        seen_by_extra = 0
    seen_by_faces = seen_by[:5]

    context = {
        'page': 'details',
        'activity': activity,
        'seen_by': seen_by,
        'seen_by_faces': seen_by_faces,
        'seen_by_extra': seen_by_extra,
    }

    is_public = group_is_public(group, request.user)

    if is_public:
        template = 'sentry/groups/public_details.html'
        context['PROJECT_LIST'] = [project]
    else:
        template = 'sentry/groups/details.html'

    return render_with_group_context(group,
                                     template,
                                     context,
                                     request,
                                     event=event,
                                     is_public=is_public)
Exemplo n.º 20
0
def group_details(request, organization, project, group, event_id=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    if event_id:
        event = get_object_or_404(group.event_set, id=event_id)
    else:
        event = group.get_latest_event() or Event()

    Event.objects.bind_nodes([event], 'data')
    GroupMeta.objects.populate_cache([group])

    # bind params to group in case they get hit
    event.group = group
    event.project = project

    if request.POST.get('o') == 'note' and request.user.is_authenticated():
        add_note_form = NewNoteForm(request.POST)
        if add_note_form.is_valid():
            add_note_form.save(event, request.user)
            return HttpResponseRedirect(request.path)
    else:
        add_note_form = NewNoteForm()

    if request.user.is_authenticated() and project.has_access(request.user):
        # update that the user has seen this group
        try:
            create_or_update(
                GroupSeen,
                group=group,
                user=request.user,
                project=project,
                values={
                    'last_seen': timezone.now(),
                }
            )
        except DatabaseError as exc:
            logging.warn(unicode(exc), exc_info=True)

    activity_qs = Activity.objects.filter(
        group=group,
    ).order_by('-datetime').select_related('user')

    # filter out dupe activity items
    activity_items = set()
    activity = []
    for item in activity_qs[:20]:
        sig = (item.event_id, item.type, item.ident, item.user_id)
        # TODO: we could just generate a signature (hash(text)) for notes
        # so there's no special casing
        if item.type == Activity.NOTE:
            activity.append(item)
        elif sig not in activity_items:
            activity_items.add(sig)
            activity.append(item)

    activity.append(Activity(
        project=project, group=group, type=Activity.FIRST_SEEN,
        datetime=group.first_seen))

    # trim to latest 5
    activity = activity[:7]

    seen_by = sorted(filter(lambda ls: ls[0] != request.user and ls[0].email, [
        (gs.user, gs.last_seen)
        for gs in GroupSeen.objects.filter(
            group=group
        ).select_related('user')
    ]), key=lambda ls: ls[1], reverse=True)
    seen_by_extra = len(seen_by) - 5
    if seen_by_extra < 0:
        seen_by_extra = 0
    seen_by_faces = seen_by[:5]

    context = {
        'add_note_form': add_note_form,
        'page': 'details',
        'activity': activity,
        'seen_by': seen_by,
        'seen_by_faces': seen_by_faces,
        'seen_by_extra': seen_by_extra,
    }

    is_public = group_is_public(group, request.user)

    if is_public:
        template = 'sentry/groups/public_details.html'
        context['PROJECT_LIST'] = [project]
    else:
        template = 'sentry/groups/details.html'

    return render_with_group_context(
        group, template, context, request,
        event=event, is_public=is_public)
Exemplo n.º 21
0
def group(request, team, project, group, event_id=None):
    # It's possible that a message would not be created under certain
    # circumstances (such as a post_save signal failing)
    activity_qs = Activity.objects.order_by("-datetime").select_related("user")
    if event_id:
        event = get_object_or_404(group.event_set, id=event_id)
        activity_qs = activity_qs.filter(Q(event=event) | Q(event__isnull=True))
    else:
        event = group.get_latest_event() or Event()

    # bind params to group in case they get hit
    event.group = group
    event.project = project

    if project in Project.objects.get_for_user(request.user, team=team, superuser=False):
        # update that the user has seen this group
        create_or_update(
            GroupSeen, group=group, user=request.user, project=project, defaults={"last_seen": timezone.now()}
        )

    # filter out dupe activity items
    activity_items = set()
    activity = []
    for item in activity_qs.filter(group=group)[:10]:
        sig = (item.event_id, item.type, item.ident, item.user_id)
        if sig not in activity_items:
            activity_items.add(sig)
            activity.append(item)

    # trim to latest 5
    activity = activity[:5]

    seen_by = sorted(
        filter(
            lambda ls: ls[0] != request.user and ls[0].email,
            [(gs.user, gs.last_seen) for gs in GroupSeen.objects.filter(group=group).select_related("user")],
        ),
        key=lambda ls: ls[1],
        reverse=True,
    )
    seen_by_extra = len(seen_by) - 5
    if seen_by_extra < 0:
        seen_by_extra = 0
    seen_by_faces = seen_by[:5]

    context = {
        "page": "details",
        "activity": activity,
        "seen_by": seen_by,
        "seen_by_faces": seen_by_faces,
        "seen_by_extra": seen_by_extra,
    }

    is_public = group_is_public(group, request.user)

    if is_public:
        template = "sentry/groups/public_details.html"
        context["PROJECT_LIST"] = [project]
    else:
        template = "sentry/groups/details.html"

    return render_with_group_context(group, template, context, request, event=event, is_public=is_public)