Skip to content

Bugfix/aaradhyaberi07/issue 91/bug codeforces updater for list #135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
6 changes: 6 additions & 0 deletions codedigger/lists/cron.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from codedigger.settings import EMAIL_HOST_USER
from codeforces.api import user_status
from user.exception import ValidationException
from .solved_update import UpdateforUserCodeforces


def cron_codeforces(user):
Expand Down Expand Up @@ -43,6 +44,11 @@ def cron_codeforces(user):
continue


def cron_codeforces_all_users(limit):
for ele in User.objects.all():
UpdateforUserCodeforces(ele, limit)


def cron_uva(user):
if user is None:
return
Expand Down
7 changes: 7 additions & 0 deletions codedigger/lists/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,10 @@ class EnrollInListSerializer(serializers.Serializer):

class Meta:
fields = ('slug', )


class UpdateCodeforcesForUserSerializer(serializers.Serializer):
limit = serializers.IntegerField(required=False)

class Meta:
fields = ('limit', )
154 changes: 154 additions & 0 deletions codedigger/lists/solved_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,157 @@ def atcoder_scraper_check(user, prob):
check = soup.find_all("span", {"class": "label label-success"})
if check:
Solved.objects.create(user=user, problem=prob)


def UpdateforUserCodeforces(user, limit):
# limit should either be None, or be an integer greater than or equal to 1.
if user is None:
return (False, "Given User object cannot be None")
cf_handle = Profile.objects.get(owner=user).codeforces
if cf_handle == None:
return (False, "cf_handle cannot be None.")
try:
submission_user = user_status(cf_handle)
except ValidationException:
return (False, "Not able to fetch submission data from codeforces.")
for ele in submission_user:
if 'verdict' not in ele or 'contestId' not in ele or ele[
'verdict'] != 'OK':
continue
prob_id = str(ele['problem']['contestId']) + str(
ele['problem']['index'])
prob = Problem.objects.filter(prob_id=prob_id, platform='F')
if not prob.exists():
continue
solve, created = Solved.objects.get_or_create(user=user,
problem=prob[0])
if not created and limit != None:
limit -= 1
if limit <= 0:
break
continue
return (True,
"Submission data for the given user has been saved successfully.")


def UpdateforUserCodechef(user, limit):
if user is None:
return (False, "Given User object cannot be None")
codechef_handle = Profile.objects.get(owner=user).codechef
if codechef_handle is None:
return (False, "codechef_handle cannot be None.")
url = 'https://www.codechef.com/users/' + str(codechef_handle)
res = requests.get(url)
soup = bs4.BeautifulSoup(res.content, 'html.parser')
problems_solved = soup.find(
'section', {'class': 'rating-data-section problems-solved'})
if problems_solved is None:
return (
True,
"Submission data for the given user has been saved successfully.")
if problems_solved.find('h5').text == 'Fully Solved (0)':
return (
True,
"Submission data for the given user has been saved successfully.")
for ele in problems_solved.find('article').find_all('a'):
prob = Problem.objects.filter(prob_id=ele.text, platform='C')
if not prob.exists():
continue
solve, created = Solved.objects.get_or_create(problem=prob[0],
user=user)
if not created and limit != None:
limit -= 1
if limit <= 0:
break
continue
return (True,
"Submission data for the given user has been saved successfully.")


def UpdateforUserAtcoder(user, limit):
if user is None:
return (False, "Given User object cannot be None")
atcoder_handle = Profile.objects.get(owner=user).atcoder
if atcoder_handle is None:
return (False, "atcoder_handle cannot be None.")
url = 'https://kenkoooo.com/atcoder/atcoder-api/results?user=' + atcoder_handle
req = requests.get(url)
if req.status_code != 200:
return (False, "User with the given handle does not exist.")
req = req.json()
sorted_req = sorted(req, key=lambda k: k['epoch_second'], reverse=True)
for ele in sorted_req:
if ele['result'] != "AC":
continue
prob = Problem.objects.filter(prob_id=ele['problem_id'], platform='A')
if not prob.exists():
continue
solve, created = Solved.objects.get_or_create(user=user,
problem=prob[0])
if not created and limit != None:
limit -= 1
if limit <= 0:
break
continue
return (True,
"Submission data for the given user has been saved successfully.")


def UpdateforUserSpoj(user, limit):
if user is None:
return (False, "Given User object cannot be None")
spoj_handle = Profile.objects.get(owner=user).spoj
if spoj_handle == None:
return (False, "spoj_handle cannot be None.")
url = 'https://www.spoj.com/users/' + spoj_handle
res = requests.get(url)
soup = bs4.BeautifulSoup(res.content, 'html.parser')
problems = soup.find('table', {'class': 'table table-condensed'})
if problems is None:
return (
True,
"Submission data for the given user has been saved successfully.")
for ele in problems.find_all('td'):
if ele.text == "":
continue
prob = Problem.objects.filter(prob_id=ele.text, platform='S')
if not prob.exists():
continue
solve, created = Solved.objects.get_or_create(problem=prob[0],
user=user)
if not created and limit != None:
limit -= 1
if limit <= 0:
break
continue
return (True,
"Submission data for the given user has been saved successfully.")


def UpdateforUserUva(user, limit):
if user is None:
return (False, "Given User object cannot be None")
uva_id = Profile.objects.get(owner=user).uva_id
if uva_id is None:
return (False, "uva_id cannot be None.")
url1 = "https://uhunt.onlinejudge.org/api/subs-user/" + str(uva_id)
req1 = requests.get(url1)
if req1.status_code != 200:
return (False, "User with the given UVA-ID does not exist")
req1 = req1.json()
sorted_req1 = sorted(req1['subs'], key=lambda k: k[4], reverse=True)
for ele in sorted_req1:
if str(ele[2]) != '90':
continue
prob = Problem.objects.filter(prob_id=str(ele[1]), platform='U')
if not prob.exists():
continue
solve, created = Solved.objects.get_or_create(user=user,
problem=prob[0])
if not created and limit != None:
limit -= 1
if limit <= 0:
break
continue
return (True,
"Submission data for the given user has been saved successfully.")
4 changes: 4 additions & 0 deletions codedigger/lists/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
SearchUserlistView,
ListGetView,
EnrollListView,
UpdateForUserView,
testing)

urlpatterns = [
Expand Down Expand Up @@ -65,6 +66,9 @@
path('enroll-list/', EnrollListView.as_view(), name='enroll-list'),
path('userlists', SearchUserlistView.as_view(), name='userlist-search'),
path('user/<str:username>', ListGetView.as_view(), name='user-list'),
path('update/<str:platform>/',
UpdateForUserView.as_view(),
name='update-codeforces'),
# path('<str:slug>/stats', ListStats.as_view(), name='list-stats'),
path('<str:slug>/stats/standing',
UserStandingStats.as_view(),
Expand Down
45 changes: 44 additions & 1 deletion codedigger/lists/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
GetUserlistSerializer, EditUserlistSerializer,
CreateUserlistSerializer, ProblemSerializer,
UserlistAddSerializer, AddProblemsAdminSerializer,
EnrollInListSerializer)
EnrollInListSerializer,
UpdateCodeforcesForUserSerializer)
from codeforces.api import user_status
from .solved_update import (UpdateforUserCodeforces, UpdateforUserAtcoder,
UpdateforUserCodechef, UpdateforUserSpoj,
UpdateforUserUva, EnrollInListSerializer)
from django.db.models import Q, Subquery, Count
from user.permissions import *
from user.exception import *
Expand Down Expand Up @@ -818,6 +823,44 @@ def post(self, request, *args, **kwargs):
status=status.HTTP_201_CREATED)


class UpdatesForUserView(generics.GenericAPIView):
permission_classes = [AuthenticatedActivated]
serializer_class = UpdateCodeforcesForUserSerializer

def post(self, request, *args, **kwargs):
curr_user = self.request.user
data = request.data
platform = self.kwargs['platform']
username = data.get("username", None)
limit = data.get("limit", None)
if curr_user and curr_user.is_staff and username:
curr_user = User.objects.get(username=username)
if platform == 'F':
returned_status, returned_response = UpdateforUserCodeforces(
curr_user, limit)
if platform == 'C':
returned_status, returned_response = UpdateforUserCodechef(
curr_user, limit)
if platform == 'A':
returned_status, returned_response = UpdateforUserAtcoder(
curr_user, limit)
if platform == 'S':
returned_status, returned_response = UpdateforUserSpoj(
curr_user, limit)
if platform == 'U':
returned_status, returned_response = UpdateforUserUva(
curr_user, limit)
if returned_status:
return response.Response(
{
'status': 'OK',
'result': returned_response
},
status=status.HTTP_200_OK)
else:
return ValidationException(returned_response)


def testing(request):
updater()
return JsonResponse({'status': 'OK'})