Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
jefer94 committed Dec 16, 2024
1 parent 4a64a12 commit 47ac8db
Show file tree
Hide file tree
Showing 18 changed files with 733 additions and 111 deletions.
2 changes: 1 addition & 1 deletion breathecode/admissions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,7 @@ def get(self, request, syllabus_id, version, academy_id):
week_number = math.ceil(cumulative_days / class_days_per_week)
if "technologies" not in day:
day["technologies"] = []

if lang == "es":
writer.writerow(
[
Expand Down
4 changes: 1 addition & 3 deletions breathecode/assessment/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,15 +300,13 @@ def save(self, *args, **kwargs):
self.token = binascii.hexlify(os.urandom(20)).decode()

_instance = super().save(*args, **kwargs)

# Answer is being closed
if is_creating or self.status != self._old_status:
signals.userassessment_status_updated.send_robust(instance=self, sender=self.__class__)

return _instance



def get_score(self):

total_score = 0
Expand Down
1 change: 1 addition & 0 deletions breathecode/assessment/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ class HookUserAssessmentSerializer(serpy.Serializer):
created_at = serpy.Field()

summary = serpy.MethodField()

def get_summary(self, obj):
total_score, last_one = obj.get_score()

Expand Down
17 changes: 5 additions & 12 deletions breathecode/assignments/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import os

import requests
from capyc.rest_framework.exceptions import ValidationException
from task_manager.core.exceptions import AbortTask

from breathecode.admissions.models import CohortUser
from capyc.rest_framework.exceptions import ValidationException

from .models import Task

Expand Down Expand Up @@ -134,19 +135,11 @@ def sync_cohort_tasks(cohort):
return synchronized


def task_is_valid_for_notifications(task: Task) -> bool:
if not task:
logger.error("Task not found")
return False

def validate_task_for_notifications(task: Task) -> bool:
if not task.cohort:
logger.error("Can't determine the student cohort")
return False
raise AbortTask("Can't determine the student cohort")

language = task.cohort.language.lower()

if language not in NOTIFICATION_STRINGS:
logger.error(f"The language {language} is not implemented in teacher_task_notification")
return False

return True
raise AbortTask(f"The language {language} is not implemented in teacher_task_notification")
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.db.models import Q
from django.utils import timezone

from breathecode.assignments import tasks
from breathecode.assignments.models import RepositoryDeletionOrder, RepositoryWhiteList, Task
from breathecode.authenticate.models import AcademyAuthSettings
from breathecode.monitoring.models import RepositorySubscription
Expand All @@ -18,8 +19,10 @@
class Command(BaseCommand):
help = "Clean data from marketing module"
github_url_pattern = re.compile(r"https?://github\.com/(?P<user>[^/\s]+)/(?P<repo>[^/\s]+)/?")
allowed_users = ["breatheco-de", "4GeeksAcademy", "4geeksacademy"]

def handle(self, *args, **options):

self.fill_whitelist()
self.purge_deletion_orders()
self.github()
Expand Down Expand Up @@ -135,6 +138,11 @@ def purge_deletion_orders(self):
break

for deletion_order in qs:
if deletion_order.repository_user not in self.allowed_users:
to_delete.append(deletion_order.id)
print("here")
continue

if RepositoryWhiteList.objects.filter(
provider=deletion_order.provider,
repository_user__iexact=deletion_order.repository_user,
Expand All @@ -158,6 +166,7 @@ def delete_github_repositories(self):
status=RepositoryDeletionOrder.Status.PENDING,
created_at__lte=timezone.now() - relativedelta(months=2),
),
repository_user__in=self.allowed_users,
provider=RepositoryDeletionOrder.Provider.GITHUB,
)[:100]

Expand Down Expand Up @@ -291,6 +300,7 @@ def collect_transferred_orders(self):

while True:
qs = RepositoryDeletionOrder.objects.filter(
repository_user__in=self.allowed_users,
provider=RepositoryDeletionOrder.Provider.GITHUB,
status=RepositoryDeletionOrder.Status.TRANSFERRING,
created_at__gt=timezone.now(),
Expand Down Expand Up @@ -321,28 +331,43 @@ def transfer_ownership(self):

while True:
qs = RepositoryDeletionOrder.objects.filter(
repository_user__in=self.allowed_users,
provider=RepositoryDeletionOrder.Provider.GITHUB,
status=RepositoryDeletionOrder.Status.PENDING,
created_at__gt=timezone.now(),
).exclude(id__in=ids)[:100]

print(-1111)
if qs.count() == 0:
break

print(2222)

for deletion_order in qs:
ids.append(deletion_order.id)

try:
print(1111)
if self.github_client.repo_exists(
owner=deletion_order.repository_user, repo=deletion_order.repository_name
):
print(3333)
new_owner = self.get_username(deletion_order.repository_user, deletion_order.repository_name)
if not new_owner:
continue

print(4444)

self.github_client.transfer_repo(repo=deletion_order.repository_name, new_owner=new_owner)
deletion_order.status = RepositoryDeletionOrder.Status.TRANSFERRING
deletion_order.save()

print(5555)

tasks.send_repository_deletion_notification.delay(deletion_order.id, new_owner)

print(6666, tasks.send_repository_deletion_notification.delay)

except Exception as e:
deletion_order.status = RepositoryDeletionOrder.Status.ERROR
deletion_order.status_text = str(e)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import re
from typing import Any, Optional

from django.core.management.base import BaseCommand

from breathecode.assignments import tasks
from breathecode.assignments.models import RepositoryDeletionOrder
from breathecode.authenticate.models import AcademyAuthSettings
from breathecode.services.github import Github


class Command(BaseCommand):
help = "Clean data from marketing module"
github_url_pattern = re.compile(r"https?://github\.com/(?P<user>[^/\s]+)/(?P<repo>[^/\s]+)/?")

def handle(self, *args, **options):
self.github()

def github(self):
processed = set()
for settings in AcademyAuthSettings.objects.filter(
github_owner__isnull=False, github_owner__credentialsgithub__isnull=False
).exclude(github_username=""):
self.github_client = Github(
org=settings.github_username, token=settings.github_owner.credentialsgithub.token
)

key = (settings.github_username, settings.github_owner.id)
if key in processed:
continue

processed.add(key)
allowed_users = ["breatheco-de", "4GeeksAcademy", "4geeksacademy"]

items = RepositoryDeletionOrder.objects.filter(provider=RepositoryDeletionOrder.Provider.GITHUB)
for deletion_order in items:
if deletion_order.repository_user not in allowed_users:
continue

new_owner = self.get_username(deletion_order.repository_user, deletion_order.repository_name)
if new_owner is None:
continue

tasks.send_repository_deletion_notification.delay(deletion_order.id, new_owner)

def check_path(self, obj: dict, *indexes: str) -> bool:
try:
value = obj
for index in indexes:
value = value[index]
return True
except Exception:
return False

def how_many_added_members(self, events: list[dict[str, Any]]) -> int:
return len(
[
event
for event in events
if self.check_path(event, "type")
and self.check_path(event, "payload", "action")
and event["type"] == "MemberEvent"
and event["payload"]["action"] == "added"
]
)

def get_username(self, owner: str, repo: str) -> Optional[str]:
r = repo
repo = repo.lower()
index = -1
for events in self.github_client.get_repo_events(owner, r):
index += 1
for event in events:
if self.check_path(event, "type") is False:
continue

if (
index == 0
and event["type"] == "MemberEvent"
and len(events) < 30
and self.check_path(event, "payload", "action")
and self.how_many_added_members(events) == 1
and self.check_path(event, "payload", "member", "login")
and event["payload"]["action"] == "added"
):
return event["payload"]["member"]["login"]

if (
event["type"] == "watchEvent"
and self.check_path(event, "actor", "login")
and event["actor"]["login"].replace("-", "").lower() in repo
):
return event["actor"]["login"]

if (
event["type"] == "MemberEvent"
and self.check_path(event, "payload", "member", "login")
and event["payload"]["member"]["login"].replace("-", "").lower() in repo
):
return event["payload"]["member"]["login"]

if (
event["type"] == "IssuesEvent"
and self.check_path(event, "payload", "assignee", "login")
and event["payload"]["assignee"]["login"].replace("-", "").lower() in repo
):
return event["payload"]["assignee"]["login"]

if (
self.check_path(event, "actor", "login")
and event["actor"]["login"].replace("-", "").lower() in repo
):
return event["actor"]["login"]
2 changes: 2 additions & 0 deletions breathecode/assignments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ def __init__(self, *args, **kwargs):
repository_user = models.CharField(max_length=256)
repository_name = models.CharField(max_length=256)

notified_at = models.DateTimeField(default=None, null=True, blank=True)

starts_transferring_at = models.DateTimeField(default=None, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
Expand Down
Loading

0 comments on commit 47ac8db

Please sign in to comment.