-
Notifications
You must be signed in to change notification settings - Fork 46
/
helper.py
148 lines (132 loc) · 5.7 KB
/
helper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import requests
import json
from django.http import HttpResponse
from django.shortcuts import HttpResponseRedirect, reverse, render
from django.contrib import messages
from django.utils import timezone
from project.models import ActiveIssue
SUCCESS, FAILED = 1, 2
def safe_hit_url(url, payload=None, headers=None, timeout=10):
"""
Function to safely HIT an API with all exceptions being handled.
"""
org = "Github"
try:
r = requests.get(url, params=payload, headers=headers, timeout=timeout)
print(f"\n\nHeaders are: {r.request.headers}")
try:
response_data = r.json()
return {
"status": SUCCESS,
"data": response_data
}
except json.decoder.JSONDecodeError:
error_str = f"Internal Server Error: Could not fetch data. Probably {org} Server is down. Try again!"
return {
"status": FAILED,
"message": error_str,
}
except requests.exceptions.ConnectTimeout:
error_str = f"ConnectTimeout: Could not connect to {org} server. Check your Internet Connection and Try Again!"
return {
"status": FAILED,
"message": error_str,
}
except requests.exceptions.ReadTimeout:
error_str = f"ReadTimeout: Connected to {org} server but it took too long to respond. Try Again!"
return {
"status": FAILED,
"message": error_str,
}
except requests.exceptions.ConnectionError:
error_str = f"ConnectTimeout: Could not connect to {org} server. Check your Internet Connection and Try Again!"
return {
"status": FAILED,
"message": error_str,
}
def complete_profile_required(func):
"""
A decorator which checks if the profile is complete or not.
In case the profile is not complete, user is directed to Complete Profile Page.
:param func:
:return:
"""
def wrapper(*args, **kwargs):
request = args[0]
user = request.user
if user.is_authenticated and (not user.userprofile.is_complete):
return HttpResponseRedirect(reverse('complete_profile'))
return func(*args, **kwargs)
return wrapper
def check_issue_time_limit(func):
"""
A decorator which checks if the issue time limit is complete or not.
:param func:
:return:
"""
def wrapper(*args, **kwargs):
request = args[0]
user = request.user
issue_pk = kwargs.get('issue_pk')
if issue_pk is None:
active_issue_pk = kwargs.get('active_issue_pk')
username = kwargs.get('username')
if active_issue_pk is None:
if username is None:
return HttpResponse(
"Now, this is something which is unhandled. Copy the URL and Report to the Team "
"Now.")
else:
if username == user.username: # Visiting own profile
active_issue_qs = ActiveIssue.objects.filter(contributor=user)
for active_issue in active_issue_qs:
if is_deadline_passed(active_issue): # Deadline Crossed
messages.warning(request, f"Deadline Crossed For Issue: {active_issue.issue}")
active_issue.delete()
return func(*args, **kwargs)
else:
active_issue_qs = ActiveIssue.objects.filter(pk=active_issue_pk, contributor=user)
if active_issue_qs:
active_issue = active_issue_qs[0]
if is_deadline_passed(active_issue): # Deadline Crossed
active_issue.delete()
# TODO: ISSUE: set a message i.e. "Dead Crossed" here and redirect to user profile and show this
# message
messages.warning(request, f"Deadline Crossed For Issue: {active_issue.issue}")
return HttpResponseRedirect(reverse('user_profile',kwargs={'username': username}))
else:
return func(*args, **kwargs)
else:
# TODO: ISSUE: Redirect to 404 page
return render(request, '404.html')
else:
# Some operation regarding this issue is taking place
active_issue_qs = ActiveIssue.objects.filter(issue=issue_pk)
for active_issue in active_issue_qs:
if is_deadline_passed(active_issue): # Deadline
messages.warning(request, f"Deadline Crossed For Issue: {active_issue.issue}")
active_issue.delete()
return func(*args, **kwargs)
return wrapper
def is_deadline_passed(active_issue):
current_time = timezone.now()
deadline = active_issue.assigned_at + timezone.timedelta(days=active_issue.issue.get_issue_days_limit())
time_delta = (deadline - current_time)
total_seconds = time_delta.total_seconds()
if total_seconds <= 0: # Deadline Crossed
return True
return False
# Fetches all the issues(PRs included) both Open and Closed
def fetch_all_issues(uri, project_name, headers):
issues = {'data': []}
page = 0
while True:
page += 1
url = f"{uri}{project_name}/issues?per_page=100&state=all&page={page}" # All PR's and Issues
response = safe_hit_url(url=url, headers=headers)
if response['status'] == SUCCESS:
if len(response['data']) == 0: # No results from this and further page numbers
break
else:
issues['data'].extend(response['data'])
return issues