예제 #1
0
파일: docs.py 프로젝트: slafs/sentry
def client_guide(request, organization, project, platform):
    if platform not in PLATFORM_LIST:
        return HttpResponseRedirect(reverse('sentry'))

    template = 'sentry/partial/client_config/%s.html' % (platform, )

    context = {
        'platform': platform,
        'platform_title': PLATFORM_TITLES.get(platform, platform.title()),
        'organization': organization,
        'team': project.team,
        'project': project,
        'page': 'client_help_%s' % (PLATFORM_ROOTS.get(platform, platform), ),
        'SUBSECTION': 'projects',
        'SECTION': 'team',
    }
    context.update(get_key_context(request.user, project))

    if request.is_ajax():
        return render_to_response(template, context, request)

    context['template'] = render_to_string(template, context, request)

    return render_to_response('sentry/projects/docs/client_config.html',
                              context, request)
예제 #2
0
def load_data(platform):
    json_path = os.path.join(DATA_ROOT, 'samples', '%s.json' % (platform.encode('utf-8'),))

    if not os.path.exists(json_path):
        return

    with open(json_path) as fp:
        data = json.loads(fp.read())

    data['platform'] = platform
    data['message'] = 'This is an example %s exception' % (
        PLATFORM_TITLES.get(platform, platform.title()),)
    data['sentry.interfaces.User'] = {
        "username": "******",
        "id": "1671",
        "email": "*****@*****.**"
    }
    data['tags'] = [
        ('foo', 'bar'),
        ('version', '1.0'),
    ]
    data['sentry.interfaces.Http'] = {
        "cookies": {},
        "url": "http://example.com/foo",
        "headers": {
            "Referer": "http://example.com",
            "User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"
        },
        "env": {},
        "query_string": "",
        "data": {},
        "method": "GET"
    }

    return data
예제 #3
0
def load_data(platform, default=None):
    data = None
    for platform in (platform, default):
        if platform is None:
            continue

        json_path = os.path.join(DATA_ROOT, 'samples',
                                 '%s.json' % (platform.encode('utf-8'), ))

        if not os.path.exists(json_path):
            continue

        with open(json_path) as fp:
            data = json.loads(fp.read())
            break

    if data is None:
        return

    data['platform'] = platform
    data['message'] = 'This is an example %s exception' % (PLATFORM_TITLES.get(
        platform, platform.title()), )
    data['sentry.interfaces.User'] = {
        "username": "******",
        "id": "1671",
        "email": "*****@*****.**"
    }
    data['extra'] = {
        'session': {
            'foo': 'bar',
        },
        'results': [1, 2, 3, 4, 5],
        'emptyList': [],
        'emptyMap': {},
    }
    data['modules'] = {
        'my.package': '1.0.0',
    }
    data['sentry.interfaces.Http'] = {
        "cookies": 'foo=bar;biz=baz',
        "url": "http://example.com/foo",
        "headers": {
            "Referer":
            "http://example.com",
            "Content-Type":
            "application/json",
            "User-Agent":
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"
        },
        "env": {
            'ENV': 'prod',
        },
        "query_string": "foo=bar",
        "data": '{"hello": "world"}',
        "method": "GET"
    }

    return data
예제 #4
0
def load_data(platform, default=None):
    data = None
    for platform in (platform, default):
        if platform is None:
            continue

        json_path = os.path.join(DATA_ROOT, 'samples', '%s.json' % (platform.encode('utf-8'),))

        if not os.path.exists(json_path):
            continue

        with open(json_path) as fp:
            data = json.loads(fp.read())
            break

    if data is None:
        return

    data['platform'] = platform
    data['message'] = 'This is an example %s exception' % (
        PLATFORM_TITLES.get(platform, platform.title()),)
    data['sentry.interfaces.User'] = {
        "username": "******",
        "id": "1671",
        "email": "*****@*****.**"
    }
    data['extra'] = {
        'session': {
            'foo': 'bar',
        },
        'results': [1, 2, 3, 4, 5],
        'emptyList': [],
        'emptyMap': {},
    }
    data['modules'] = {
        'my.package': '1.0.0',
    }
    data['sentry.interfaces.Http'] = {
        "cookies": 'foo=bar;biz=baz',
        "url": "http://example.com/foo",
        "headers": {
            "Referer": "http://example.com",
            "Content-Type": "application/json",
            "User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"
        },
        "env": {
            'ENV': 'prod',
        },
        "query_string": "foo=bar",
        "data": '{"hello": "world"}',
        "method": "GET"
    }

    return data
예제 #5
0
    def get(self, request, platform, project_list, selected_project):
        if platform not in PLATFORM_LIST:
            raise Http404

        template = "sentry/partial/client_config/%s.html" % (platform,)

        context = self.get_context_data(request, project_list, selected_project)
        context.update({"platform": platform, "platform_title": PLATFORM_TITLES.get(platform, platform.title())})

        context["template"] = render_to_string(template, context, request)

        return self.respond("sentry/help/platform_details.html", context)
예제 #6
0
    def get(self, request, platform, project_list, selected_project):
        if platform not in PLATFORM_LIST:
            raise Http404

        template = 'sentry/partial/client_config/%s.html' % (platform,)

        context = self.get_context_data(request, project_list, selected_project)
        context.update({
            'platform': platform,
            'platform_title': PLATFORM_TITLES.get(platform, platform.title()),
        })

        context['template'] = render_to_string(template, context, request)

        return render_to_response('sentry/help/platform_details.html', context, request)
예제 #7
0
def load_data(platform, default=None):
    data = None
    for platform in (platform, default):
        if platform is None:
            continue

        json_path = os.path.join(DATA_ROOT, 'samples',
                                 '%s.json' % (platform.encode('utf-8'), ))

        if not os.path.exists(json_path):
            continue

        with open(json_path) as fp:
            data = json.loads(fp.read())
            break

    if data is None:
        return

    data['platform'] = platform
    data['message'] = 'This is an example %s exception' % (PLATFORM_TITLES.get(
        platform, platform.title()), )
    data['sentry.interfaces.User'] = {
        "username": "******",
        "id": "1671",
        "email": "*****@*****.**"
    }
    data['tags'] = [
        ('foo', 'bar'),
        ('version', '1.0'),
    ]
    data['sentry.interfaces.Http'] = {
        "cookies": {},
        "url": "http://example.com/foo",
        "headers": {
            "Referer":
            "http://example.com",
            "User-Agent":
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"
        },
        "env": {},
        "query_string": "",
        "data": {},
        "method": "GET"
    }

    return data
    def get(self, request, platform, project_list, selected_project):
        if platform not in PLATFORM_LIST:
            raise Http404

        template = 'sentry/partial/client_config/%s.html' % (platform, )

        context = self.get_context_data(request, project_list,
                                        selected_project)
        context.update({
            'platform':
            platform,
            'platform_title':
            PLATFORM_TITLES.get(platform, platform.title()),
        })

        context['template'] = render_to_string(template, context, request)

        return self.respond('sentry/help/platform_details.html', context)
예제 #9
0
def create_sample_event(project, platform=None):
    if not platform:
        platform = project.platform

    if not platform:
        return

    platform = PLATFORM_ROOTS.get(platform, platform)

    json_path = os.path.join(DATA_ROOT, 'samples',
                             '%s.json' % (platform.encode('utf-8'), ))

    if not os.path.exists(json_path):
        return

    with open(json_path) as fp:
        data = json.loads(fp.read())

    data['platform'] = platform
    data['message'] = 'This is an example %s exception' % (PLATFORM_TITLES.get(
        platform, platform.title()), )
    data['sentry.interfaces.User'] = {
        "username": "******",
        "id": "1671",
        "email": "*****@*****.**"
    }
    data['sentry.interfaces.Http'] = {
        "cookies": {},
        "url": "http://example.com/foo",
        "headers": {
            "Referer":
            "http://example.com",
            "User-Agent":
            "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"
        },
        "env": {},
        "query_string": "",
        "data": {},
        "method": "GET"
    }
    data = Group.objects.normalize_event_data(data)
    return Group.objects.save_data(project.id, data, raw=True)
예제 #10
0
파일: docs.py 프로젝트: MSylvia/sentry
def client_guide(request, project, platform):
    if platform not in PLATFORM_LIST:
        return HttpResponseRedirect(reverse('sentry'))

    template = 'sentry/partial/client_config/%s.html' % (platform,)

    context = {
        'platform': platform,
        'platform_title': PLATFORM_TITLES.get(platform, platform.title()),
        'project': project,
        'page': 'client_help_%s' % (PLATFORM_ROOTS.get(platform, platform),),
        'SECTION': 'settings',
    }
    context.update(get_key_context(request.user, project))

    if request.is_ajax():
        return render_to_response(template, context, request)

    context['template'] = render_to_string(template, context, request)

    return render_to_response('sentry/projects/docs/client_config.html', context, request)
예제 #11
0
def create_sample_event(project, platform=None):
    if not platform:
        platform = project.platform

    if not platform:
        return

    platform = PLATFORM_ROOTS.get(platform, platform)

    json_path = os.path.join(DATA_ROOT, 'samples', '%s.json' % (platform.encode('utf-8'),))

    if not os.path.exists(json_path):
        return

    with open(json_path) as fp:
        data = json.loads(fp.read())

    data['platform'] = platform
    data['message'] = 'This is an example %s exception' % (
        PLATFORM_TITLES.get(platform, platform.title()),)
    data['sentry.interfaces.User'] = {
        "username": "******",
        "id": "1671",
        "email": "*****@*****.**"
    }
    data['sentry.interfaces.Http'] = {
        "cookies": {},
        "url": "http://example.com/foo",
        "headers": {
            "Referer": "http://example.com",
            "User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"
        },
        "env": {},
        "query_string": "",
        "data": {},
        "method": "GET"
    }
    data = Group.objects.normalize_event_data(data)
    return Group.objects.save_data(project.id, data, raw=True)
예제 #12
0
class Project(Model):
    """
    Projects are permission based namespaces which generally
    are the top level entry point for all data.

    A project may be owned by only a single team, and may or may not
    have an owner (which is thought of as a project creator).
    """
    PLATFORM_CHOICES = tuple((p, PLATFORM_TITLES.get(p, p.title()))
                             for p in PLATFORM_LIST) + (('other', 'Other'), )

    slug = models.SlugField(null=True)
    name = models.CharField(max_length=200)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL,
                              related_name="sentry_owned_project_set",
                              null=True)
    team = models.ForeignKey(Team, null=True)
    public = models.BooleanField(default=False)
    date_added = models.DateTimeField(default=timezone.now)
    status = BoundedPositiveIntegerField(default=0,
                                         choices=(
                                             (STATUS_VISIBLE, _('Visible')),
                                             (STATUS_HIDDEN, _('Hidden')),
                                         ),
                                         db_index=True)
    platform = models.CharField(max_length=32,
                                choices=PLATFORM_CHOICES,
                                null=True)

    objects = ProjectManager(cache_fields=[
        'pk',
        'slug',
    ])

    class Meta:
        unique_together = (('team', 'slug'), )

    __repr__ = sane_repr('team_id', 'slug', 'owner_id')

    def __unicode__(self):
        return u'%s (%s)' % (self.name, self.slug)

    def save(self, *args, **kwargs):
        if not self.slug:
            slugify_instance(self, self.name, team=self.team)
        super(Project, self).save(*args, **kwargs)

    def delete(self):
        # This handles cascades properly
        # TODO: this doesn't clean up the index
        for model in (TagKey, TagValue, GroupTagKey, GroupTag,
                      GroupCountByMinute, ProjectCountByMinute, Activity,
                      EventMapping, Event, Group):
            logging.info('Removing %r objects where project=%s', model,
                         self.id)
            has_results = True
            while has_results:
                has_results = False
                for obj in model.objects.filter(project=self)[:1000]:
                    obj.delete()
                    has_results = True
        super(Project, self).delete()

    def get_absolute_url(self):
        return absolute_uri(
            reverse('sentry-stream', args=[self.team.slug, self.slug]))

    def merge_to(self, project):
        if not isinstance(project, Project):
            project = Project.objects.get_from_cache(pk=project)

        for group in Group.objects.filter(project=self):
            try:
                other = Group.objects.get(
                    project=project,
                    logger=group.logger,
                    culprit=group.culprit,
                    checksum=group.checksum,
                )
            except Group.DoesNotExist:
                group.update(project=project)
                for model in (Event, GroupTag, GroupCountByMinute):
                    model.objects.filter(project=self,
                                         group=group).update(project=project)
            else:
                Event.objects.filter(group=group).update(group=other)

                for obj in GroupTag.objects.filter(group=group):
                    obj2, created = GroupTag.objects.get_or_create(
                        project=project,
                        group=group,
                        key=obj.key,
                        value=obj.value,
                        defaults={'times_seen': obj.times_seen})
                    if not created:
                        obj2.update(times_seen=F('times_seen') +
                                    obj.times_seen)

                for obj in GroupCountByMinute.objects.filter(group=group):
                    obj2, created = GroupCountByMinute.objects.get_or_create(
                        project=project,
                        group=group,
                        date=obj.date,
                        defaults={
                            'times_seen': obj.times_seen,
                            'time_spent_total': obj.time_spent_total,
                            'time_spent_count': obj.time_spent_count,
                        })
                    if not created:
                        obj2.update(
                            times_seen=F('times_seen') + obj.times_seen,
                            time_spent_total=F('time_spent_total') +
                            obj.time_spent_total,
                            time_spent_count=F('time_spent_count') +
                            obj.time_spent_count,
                        )

        for fv in TagValue.objects.filter(project=self):
            TagValue.objects.get_or_create(project=project,
                                           key=fv.key,
                                           value=fv.value)
            fv.delete()
        self.delete()

    def is_default_project(self):
        return str(self.id) == str(settings.SENTRY_PROJECT) or str(
            self.slug) == str(settings.SENTRY_PROJECT)

    def get_tags(self):
        if not hasattr(self, '_tag_cache'):
            tags = ProjectOption.objects.get_value(self, 'tags', None)
            if tags is None:
                tags = TagKey.objects.all_keys(self)
            self._tag_cache = [t for t in tags if not t.startswith('sentry:')]
        return self._tag_cache

    # TODO: Make these a mixin
    def update_option(self, *args, **kwargs):
        return ProjectOption.objects.set_value(self, *args, **kwargs)

    def get_option(self, *args, **kwargs):
        return ProjectOption.objects.get_value(self, *args, **kwargs)
예제 #13
0
파일: project.py 프로젝트: slafs/sentry
class Project(Model):
    """
    Projects are permission based namespaces which generally
    are the top level entry point for all data.
    """
    PLATFORM_CHOICES = tuple((p, PLATFORM_TITLES.get(p, p.title()))
                             for p in PLATFORM_LIST) + (('other', 'Other'), )

    slug = models.SlugField(null=True)
    name = models.CharField(max_length=200)
    organization = models.ForeignKey('sentry.Organization')
    team = models.ForeignKey('sentry.Team')
    public = models.BooleanField(default=False)
    date_added = models.DateTimeField(default=timezone.now)
    status = BoundedPositiveIntegerField(default=0,
                                         choices=(
                                             (STATUS_VISIBLE, _('Active')),
                                             (STATUS_HIDDEN, _('Hidden')),
                                         ),
                                         db_index=True)
    platform = models.CharField(max_length=32,
                                choices=PLATFORM_CHOICES,
                                null=True)

    objects = ProjectManager(cache_fields=[
        'pk',
        'slug',
    ])

    class Meta:
        app_label = 'sentry'
        db_table = 'sentry_project'
        unique_together = (('team', 'slug'), ('organization', 'slug'))

    __repr__ = sane_repr('team_id', 'slug')

    def __unicode__(self):
        return u'%s (%s)' % (self.name, self.slug)

    def save(self, *args, **kwargs):
        if not self.slug:
            slugify_instance(self, self.name, organization=self.organization)
        super(Project, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return absolute_uri(
            reverse('sentry-stream', args=[self.organization.slug, self.slug]))

    def merge_to(self, project):
        from sentry.models import (Group, GroupTagValue, Event, TagValue)

        if not isinstance(project, Project):
            project = Project.objects.get_from_cache(pk=project)

        for group in Group.objects.filter(project=self):
            try:
                other = Group.objects.get(
                    project=project,
                    checksum=group.checksum,
                )
            except Group.DoesNotExist:
                group.update(project=project)
                for model in (Event, GroupTagValue):
                    model.objects.filter(project=self,
                                         group=group).update(project=project)
            else:
                Event.objects.filter(group=group).update(group=other)

                for obj in GroupTagValue.objects.filter(group=group):
                    obj2, created = GroupTagValue.objects.get_or_create(
                        project=project,
                        group=group,
                        key=obj.key,
                        value=obj.value,
                        defaults={'times_seen': obj.times_seen})
                    if not created:
                        obj2.update(times_seen=F('times_seen') +
                                    obj.times_seen)

        for fv in TagValue.objects.filter(project=self):
            TagValue.objects.get_or_create(project=project,
                                           key=fv.key,
                                           value=fv.value)
            fv.delete()
        self.delete()

    def is_internal_project(self):
        for value in (settings.SENTRY_FRONTEND_PROJECT,
                      settings.SENTRY_PROJECT):
            if str(self.id) == str(value) or str(self.slug) == str(value):
                return True
        return False

    def get_tags(self, with_internal=True):
        from sentry.models import TagKey

        if not hasattr(self, '_tag_cache'):
            tags = self.get_option('tags', None)
            if tags is None:
                tags = [
                    t for t in TagKey.objects.all_keys(self)
                    if with_internal or not t.startswith('sentry:')
                ]
            self._tag_cache = tags
        return self._tag_cache

    # TODO: Make these a mixin
    def update_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.set_value(self, *args, **kwargs)

    def get_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.get_value(self, *args, **kwargs)

    def delete_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.unset_value(self, *args, **kwargs)

    def has_access(self, user, access=None):
        from sentry.models import OrganizationMember

        queryset = OrganizationMember.objects.filter(
            Q(teams=self.team) | Q(has_global_access=True),
            user__is_active=True,
            user=user,
            organization=self.organization,
        )
        if access is not None:
            queryset = queryset.filter(type__lte=access)

        return queryset.exists()

    def get_audit_log_data(self):
        return {
            'slug': self.slug,
            'name': self.name,
            'status': self.status,
            'public': self.public,
            'platform': self.platform,
        }
예제 #14
0
파일: models.py 프로젝트: Supy/sentry
class Project(Model):
    """
    Projects are permission based namespaces which generally
    are the top level entry point for all data.

    A project may be owned by only a single team, and may or may not
    have an owner (which is thought of as a project creator).
    """
    PLATFORM_CHOICES = tuple((p, PLATFORM_TITLES.get(p, p.title()))
                             for p in PLATFORM_LIST) + (('other', 'Other'), )

    slug = models.SlugField(unique=True, null=True)
    name = models.CharField(max_length=200)
    owner = models.ForeignKey(User,
                              related_name="sentry_owned_project_set",
                              null=True)
    team = models.ForeignKey(Team, null=True)
    public = models.BooleanField(
        default=settings.ALLOW_PUBLIC_PROJECTS and settings.PUBLIC)
    date_added = models.DateTimeField(default=timezone.now)
    status = models.PositiveIntegerField(default=0,
                                         choices=(
                                             (STATUS_VISIBLE, 'Visible'),
                                             (STATUS_HIDDEN, 'Hidden'),
                                         ),
                                         db_index=True)
    platform = models.CharField(max_length=32,
                                choices=PLATFORM_CHOICES,
                                null=True)

    objects = ProjectManager(cache_fields=[
        'pk',
        'slug',
    ])

    __repr__ = sane_repr('slug', 'owner_id')

    def save(self, *args, **kwargs):
        if not self.slug:
            slugify_instance(self, self.name)
        super(Project, self).save(*args, **kwargs)

    def delete(self):
        # This hadles cascades properly
        # TODO: this doesnt clean up the index
        for model in (Event, Group, FilterValue, MessageFilterValue,
                      MessageCountByMinute):
            model.objects.filter(project=self).delete()
        super(Project, self).delete()

    def merge_to(self, project):
        if not isinstance(project, Project):
            project = Project.objects.get_from_cache(pk=project)

        for group in Group.objects.filter(project=self):
            try:
                other = Group.objects.get(
                    project=project,
                    logger=group.logger,
                    culprit=group.culprit,
                    checksum=group.checksum,
                )
            except Group.DoesNotExist:
                group.update(project=project)
                for model in (Event, MessageFilterValue, MessageCountByMinute):
                    model.objects.filter(project=self,
                                         group=group).update(project=project)
            else:
                Event.objects.filter(group=group).update(group=other)

                for obj in MessageFilterValue.objects.filter(group=group):
                    obj2, created = MessageFilterValue.objects.get_or_create(
                        project=project,
                        group=group,
                        key=obj.key,
                        value=obj.value,
                        defaults={'times_seen': obj.times_seen})
                    if not created:
                        obj2.update(times_seen=F('times_seen') +
                                    obj.times_seen)

                for obj in MessageCountByMinute.objects.filter(group=group):
                    obj2, created = MessageCountByMinute.objects.get_or_create(
                        project=project,
                        group=group,
                        date=obj.date,
                        defaults={
                            'times_seen': obj.times_seen,
                            'time_spent_total': obj.time_spent_total,
                            'time_spent_count': obj.time_spent_count,
                        })
                    if not created:
                        obj2.update(
                            times_seen=F('times_seen') + obj.times_seen,
                            time_spent_total=F('time_spent_total') +
                            obj.time_spent_total,
                            time_spent_count=F('time_spent_count') +
                            obj.time_spent_count,
                        )

        for fv in FilterValue.objects.filter(project=self):
            FilterValue.objects.get_or_create(project=project,
                                              key=fv.key,
                                              value=fv.value)
            fv.delete()
        self.delete()

    def is_default_project(self):
        return str(self.id) == str(settings.PROJECT) or str(self.slug) == str(
            settings.PROJECT)

    def get_tags(self):
        if not hasattr(self, '_tag_cache'):
            tags = ProjectOption.objects.get_value(self, 'tags', None)
            if tags is None:
                tags = FilterKey.objects.all_keys(self)
            self._tag_cache = tags
        return self._tag_cache
예제 #15
0
class Project(Model):
    """
    Projects are permission based namespaces which generally
    are the top level entry point for all data.

    A project may be owned by only a single team, and may or may not
    have an owner (which is thought of as a project creator).
    """
    PLATFORM_CHOICES = tuple((p, PLATFORM_TITLES.get(p, p.title()))
                             for p in PLATFORM_LIST) + (('other', 'Other'), )

    slug = models.SlugField(null=True)
    name = models.CharField(max_length=200)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL,
                              related_name="sentry_owned_project_set",
                              null=True)
    team = models.ForeignKey('sentry.Team', null=True)
    public = models.BooleanField(default=False)
    date_added = models.DateTimeField(default=timezone.now)
    status = BoundedPositiveIntegerField(default=0,
                                         choices=(
                                             (STATUS_VISIBLE, _('Visible')),
                                             (STATUS_HIDDEN, _('Hidden')),
                                         ),
                                         db_index=True)
    platform = models.CharField(max_length=32,
                                choices=PLATFORM_CHOICES,
                                null=True)

    objects = ProjectManager(cache_fields=[
        'pk',
        'slug',
    ])

    class Meta:
        app_label = 'sentry'
        db_table = 'sentry_project'
        unique_together = (('team', 'slug'), )

    __repr__ = sane_repr('team_id', 'slug', 'owner_id')

    def __unicode__(self):
        return u'%s (%s)' % (self.name, self.slug)

    def save(self, *args, **kwargs):
        if not self.slug:
            slugify_instance(self, self.name, team=self.team)
        super(Project, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return absolute_uri(
            reverse('sentry-stream', args=[self.team.slug, self.slug]))

    def merge_to(self, project):
        from sentry.models import (Group, GroupTagValue, Event, TagValue)

        if not isinstance(project, Project):
            project = Project.objects.get_from_cache(pk=project)

        for group in Group.objects.filter(project=self):
            try:
                other = Group.objects.get(
                    project=project,
                    checksum=group.checksum,
                )
            except Group.DoesNotExist:
                group.update(project=project)
                for model in (Event, GroupTagValue):
                    model.objects.filter(project=self,
                                         group=group).update(project=project)
            else:
                Event.objects.filter(group=group).update(group=other)

                for obj in GroupTagValue.objects.filter(group=group):
                    obj2, created = GroupTagValue.objects.get_or_create(
                        project=project,
                        group=group,
                        key=obj.key,
                        value=obj.value,
                        defaults={'times_seen': obj.times_seen})
                    if not created:
                        obj2.update(times_seen=F('times_seen') +
                                    obj.times_seen)

        for fv in TagValue.objects.filter(project=self):
            TagValue.objects.get_or_create(project=project,
                                           key=fv.key,
                                           value=fv.value)
            fv.delete()
        self.delete()

    def is_internal_project(self):
        for value in (settings.SENTRY_FRONTEND_PROJECT,
                      settings.SENTRY_PROJECT):
            if str(self.id) == str(value) or str(self.slug) == str(value):
                return True
        return False

    def get_tags(self):
        from sentry.models import TagKey

        if not hasattr(self, '_tag_cache'):
            tags = self.get_option('tags', None)
            if tags is None:
                tags = [
                    t for t in TagKey.objects.all_keys(self)
                    if not t.startswith('sentry:')
                ]
            self._tag_cache = tags
        return self._tag_cache

    # TODO: Make these a mixin
    def update_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.set_value(self, *args, **kwargs)

    def get_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.get_value(self, *args, **kwargs)
예제 #16
0
class Project(Model):
    """
    Projects are permission based namespaces which generally
    are the top level entry point for all data.
    """
    PLATFORM_CHOICES = tuple((p, PLATFORM_TITLES.get(p, p.title()))
                             for p in PLATFORM_LIST) + (('other', 'Other'), )

    slug = models.SlugField(null=True)
    name = models.CharField(max_length=200)
    organization = FlexibleForeignKey('sentry.Organization')
    team = FlexibleForeignKey('sentry.Team')
    public = models.BooleanField(default=False)
    date_added = models.DateTimeField(default=timezone.now)
    status = BoundedPositiveIntegerField(
        default=0,
        choices=(
            (ProjectStatus.VISIBLE, _('Active')),
            (ProjectStatus.PENDING_DELETION, _('Pending Deletion')),
            (ProjectStatus.DELETION_IN_PROGRESS, _('Deletion in Progress')),
        ),
        db_index=True)

    objects = ProjectManager(cache_fields=[
        'pk',
        'slug',
    ])

    class Meta:
        app_label = 'sentry'
        db_table = 'sentry_project'
        unique_together = (('team', 'slug'), ('organization', 'slug'))

    __repr__ = sane_repr('team_id', 'slug')

    def __unicode__(self):
        return u'%s (%s)' % (self.name, self.slug)

    def save(self, *args, **kwargs):
        if not self.slug:
            lock_key = 'slug:project'
            with Lock(lock_key):
                slugify_instance(self,
                                 self.name,
                                 organization=self.organization)
            super(Project, self).save(*args, **kwargs)
        else:
            super(Project, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return absolute_uri(
            reverse('sentry-stream', args=[self.organization.slug, self.slug]))

    def merge_to(self, project):
        from sentry.models import (Group, GroupTagValue, Event, TagValue)

        if not isinstance(project, Project):
            project = Project.objects.get_from_cache(pk=project)

        for group in Group.objects.filter(project=self):
            try:
                other = Group.objects.get(project=project, )
            except Group.DoesNotExist:
                group.update(project=project)
                for model in (Event, GroupTagValue):
                    model.objects.filter(project=self,
                                         group=group).update(project=project)
            else:
                Event.objects.filter(group=group).update(group=other)

                for obj in GroupTagValue.objects.filter(group=group):
                    obj2, created = GroupTagValue.objects.get_or_create(
                        project=project,
                        group=group,
                        key=obj.key,
                        value=obj.value,
                        defaults={'times_seen': obj.times_seen})
                    if not created:
                        obj2.update(times_seen=F('times_seen') +
                                    obj.times_seen)

        for fv in TagValue.objects.filter(project=self):
            TagValue.objects.get_or_create(project=project,
                                           key=fv.key,
                                           value=fv.value)
            fv.delete()
        self.delete()

    def is_internal_project(self):
        for value in (settings.SENTRY_FRONTEND_PROJECT,
                      settings.SENTRY_PROJECT):
            if str(self.id) == str(value) or str(self.slug) == str(value):
                return True
        return False

    def get_tags(self, with_internal=True):
        from sentry.models import TagKey

        if not hasattr(self, '_tag_cache'):
            tags = self.get_option('tags', None)
            if tags is None:
                tags = [
                    t for t in TagKey.objects.all_keys(self)
                    if with_internal or not t.startswith('sentry:')
                ]
            self._tag_cache = tags
        return self._tag_cache

    # TODO: Make these a mixin
    def update_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.set_value(self, *args, **kwargs)

    def get_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.get_value(self, *args, **kwargs)

    def delete_option(self, *args, **kwargs):
        from sentry.models import ProjectOption

        return ProjectOption.objects.unset_value(self, *args, **kwargs)

    @property
    def member_set(self):
        from sentry.models import OrganizationMember
        return self.organization.member_set.filter(
            Q(organizationmemberteam__team=self.team)
            | Q(has_global_access=True),
            user__is_active=True,
        ).exclude(id__in=OrganizationMember.objects.filter(
            organizationmemberteam__is_active=False,
            organizationmemberteam__team=self.team,
        ).values('id')).distinct()

    def has_access(self, user, access=None):
        from sentry.models import AuthIdentity, OrganizationMember

        warnings.warn('Project.has_access is deprecated.', DeprecationWarning)

        queryset = self.member_set.filter(user=user)

        if access is not None:
            queryset = queryset.filter(type__lte=access)

        try:
            member = queryset.get()
        except OrganizationMember.DoesNotExist:
            return False

        try:
            auth_identity = AuthIdentity.objects.get(
                auth_provider__organization=self.organization_id,
                user=member.user_id,
            )
        except AuthIdentity.DoesNotExist:
            return True

        return auth_identity.is_valid(member)

    def get_audit_log_data(self):
        return {
            'slug': self.slug,
            'name': self.name,
            'status': self.status,
            'public': self.public,
        }

    def get_full_name(self):
        if self.team.name not in self.name:
            return '%s %s' % (self.team.name, self.name)
        return self.name