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)
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
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
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
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)
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)
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)
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)
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)
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)
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)
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, }
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
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)
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