Skip to content

Commit

Permalink
Revert "feat(github-growth): email nudge task (#55703)"
Browse files Browse the repository at this point in the history
This reverts commit c984fd2.

Co-authored-by: cathteng <70817427+cathteng@users.noreply.github.com>
  • Loading branch information
getsentry-bot and cathteng committed Sep 11, 2023
1 parent 21803c6 commit 22deb13
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 262 deletions.
120 changes: 61 additions & 59 deletions src/sentry/api/endpoints/organization_missing_org_members.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from django.db.models import Count, Q, QuerySet
from django.utils import timezone
from django_stubs_ext import WithAnnotations
from rest_framework import status
from rest_framework.request import Request
from rest_framework.response import Response
Expand All @@ -29,69 +28,73 @@

class MissingOrgMemberSerializer(Serializer):
def serialize(self, obj, attrs, user, **kwargs):
return {"email": obj.email, "externalId": obj.external_id, "commitCount": obj.commit__count}
return {"email": obj.email, "externalId": obj.external_id, "commitCount": obj.commit_count}


class MissingMembersPermission(OrganizationPermission):
scope_map = {"GET": ["org:write"]}


def _get_missing_organization_members(
organization: Organization, provider: str, integration_ids: Sequence[int]
) -> QuerySet[WithAnnotations[CommitAuthor]]:
member_emails = set(
organization.member_set.exclude(email=None).values_list("email", flat=True)
) | set(organization.member_set.exclude(user_email=None).values_list("user_email", flat=True))

nonmember_authors = CommitAuthor.objects.filter(organization_id=organization.id).exclude(
Q(email__in=member_emails) | Q(external_id=None)
)

org_repos = Repository.objects.filter(
provider="integrations:" + provider,
organization_id=organization.id,
integration_id__in=integration_ids,
).values_list("id", flat=True)
@region_silo_endpoint
class OrganizationMissingMembersEndpoint(OrganizationEndpoint):
publish_status = {
"GET": ApiPublishStatus.UNKNOWN,
}
permission_classes = (MissingMembersPermission,)

return (
nonmember_authors.filter(
commit__repository_id__in=set(org_repos),
commit__date_added__gte=timezone.now() - timedelta(days=30),
def _get_missing_members(
self, organization: Organization, provider: str, integration_ids: Sequence[int]
) -> QuerySet[CommitAuthor]:
member_emails = set(
organization.member_set.exclude(email=None).values_list("email", flat=True)
)
member_emails.update(
set(
organization.member_set.exclude(user_email=None).values_list(
"user_email", flat=True
)
)
)
nonmember_authors = CommitAuthor.objects.filter(organization_id=organization.id).exclude(
Q(email__in=member_emails) | Q(external_id=None)
)
.annotate(Count("commit"))
.order_by("-commit__count")
)


def _get_shared_email_domain(organization: Organization) -> str | None:
# if a member has user_email=None, then they have yet to accept an invite
org_owners = organization.get_members_with_org_roles(roles=[roles.get_top_dog().id]).exclude(
Q(user_email=None) | Q(user_email="")
)
org_repos = Repository.objects.filter(
provider="integrations:" + provider,
organization_id=organization.id,
integration_id__in=integration_ids,
).values_list("id", flat=True)

def _get_email_domain(email: str) -> str | None:
try:
domain = Address(addr_spec=email).domain
except Exception:
return None
return (
nonmember_authors.filter(
commit__repository_id__in=set(org_repos),
commit__date_added__gte=timezone.now() - timedelta(days=30),
)
.annotate(commit_count=Count("commit"))
.order_by("-commit_count")
)

return domain
def _get_shared_email_domain(self, organization) -> str | None:
# if a member has user_email=None, then they have yet to accept an invite
org_owners = organization.get_members_with_org_roles(
roles=[roles.get_top_dog().id]
).exclude(Q(user_email=None) | Q(user_email=""))

owner_email_domains = {_get_email_domain(owner.user_email) for owner in org_owners}
def _get_email_domain(email: str) -> str | None:
try:
domain = Address(addr_spec=email).domain
except Exception:
return None

# all owners have the same email domain
if len(owner_email_domains) == 1:
return owner_email_domains.pop()
return domain

return None
owner_email_domains = {_get_email_domain(owner.user_email) for owner in org_owners}

# all owners have the same email domain
if len(owner_email_domains) == 1:
return owner_email_domains.pop()

@region_silo_endpoint
class OrganizationMissingMembersEndpoint(OrganizationEndpoint):
publish_status = {
"GET": ApiPublishStatus.UNKNOWN,
}
permission_classes = (MissingMembersPermission,)
return None

def get(self, request: Request, organization: Organization) -> Response:
# ensure the organization has an integration with the commit feature
Expand All @@ -113,7 +116,7 @@ def provider_reducer(dict, integration):
provider_reducer, integrations, defaultdict(list)
)

shared_domain = _get_shared_email_domain(organization)
shared_domain = self._get_shared_email_domain(organization)

missing_org_members = []

Expand All @@ -122,22 +125,21 @@ def provider_reducer(dict, integration):
if integration_provider != "github":
continue

queryset = _get_missing_organization_members(
queryset = self._get_missing_members(
organization, integration_provider, integration_ids
)

if shared_domain:
queryset = queryset.filter(email__endswith=shared_domain)

if queryset.exists():
query = request.GET.get("query")
if query:
tokens = tokenize_query(query)
if "query" in tokens:
query_value = " ".join(tokens["query"])
queryset = queryset.filter(
Q(email__icontains=query_value) | Q(external_id__icontains=query_value)
)
query = request.GET.get("query")
if query:
tokens = tokenize_query(query)
if "query" in tokens:
query_value = " ".join(tokens["query"])
queryset = queryset.filter(
Q(email__icontains=query_value) | Q(external_id__icontains=query_value)
)

missing_members_for_integration = {
"integration": integration_provider,
Expand Down
11 changes: 0 additions & 11 deletions src/sentry/conf/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,6 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.tasks.files",
"sentry.tasks.groupowner",
"sentry.tasks.integrations",
"sentry.tasks.invite_missing_org_members",
"sentry.tasks.low_priority_symbolication",
"sentry.tasks.merge",
"sentry.tasks.options",
Expand Down Expand Up @@ -892,7 +891,6 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
Queue("performance.statistical_detector", routing_key="performance.statistical_detector"),
Queue("profiling.statistical_detector", routing_key="profiling.statistical_detector"),
CELERY_ISSUE_STATES_QUEUE,
Queue("nudge.invite_missing_org_members", routing_key="invite_missing_org_members"),
]

from celery.schedules import crontab
Expand Down Expand Up @@ -1047,15 +1045,6 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
),
"options": {"expires": 60 * 60 * 3},
},
"schedule-monthly-invite-missing-org-members": {
"task": "sentry.tasks.invite_missing_org_members.schedule_organizations",
"schedule": crontab(
minute=0,
hour=7,
day_of_month="1", # 00:00 PDT, 03:00 EDT, 7:00 UTC
),
"options": {"expires": 60 * 25},
},
"schedule-hybrid-cloud-foreign-key-jobs": {
"task": "sentry.tasks.deletion.hybrid_cloud.schedule_hybrid_cloud_foreign_key_jobs",
# Run every 15 minutes
Expand Down
70 changes: 0 additions & 70 deletions src/sentry/tasks/invite_missing_org_members.py

This file was deleted.

122 changes: 0 additions & 122 deletions tests/sentry/tasks/test_invite_missing_org_members.py

This file was deleted.

0 comments on commit 22deb13

Please sign in to comment.