|
2 | 2 |
|
3 | 3 | import logging |
4 | 4 | import re |
5 | | -from datetime import datetime |
6 | 5 | from functools import lru_cache |
7 | 6 | from html import escape as escape_html |
8 | 7 | from urllib.parse import urljoin |
9 | 8 |
|
10 | 9 | import requests |
11 | 10 | import yaml |
12 | | -from django.conf import settings |
13 | | -from django.core.exceptions import ValidationError |
14 | | -from django.utils import timezone |
15 | | -from github import Github |
16 | 11 | from lxml import html |
17 | 12 | from requests.exceptions import RequestException |
18 | 13 |
|
|
21 | 16 | logger = logging.getLogger(__name__) |
22 | 17 |
|
23 | 18 |
|
24 | | -ISSUES_INDEX = 5 |
25 | | -GITHUB_COM_INDEX = 2 |
26 | | -MIN_PARTS_LENGTH = 4 |
27 | | - |
28 | | -DEADLINE_FORMAT_ERROR = "Invalid deadline format. Use YYYY-MM-DD or YYYY-MM-DD HH:MM." |
29 | | -DEADLINE_FUTURE_ERROR = "Deadline must be in the future." |
30 | | -FETCH_ISSUE_ERROR = "Failed to fetch issue from GitHub: {error}" |
31 | | -INVALID_ISSUE_LINK_FORMAT = "Invalid GitHub issue link format." |
32 | | -ISSUE_LINK_ERROR = "Issue link must belong to an OWASP repository." |
33 | | -PRICE_POSITIVE_ERROR = "Price must be a positive value." |
34 | | -PRICE_VALID_ERROR = "Price must be a valid number." |
35 | | - |
36 | | - |
37 | 19 | def escape(content): |
38 | 20 | """Escape HTML content.""" |
39 | 21 | return escape_html(content, quote=False) |
@@ -83,48 +65,6 @@ def get_news_data(limit=10, timeout=30): |
83 | 65 | return items |
84 | 66 |
|
85 | 67 |
|
86 | | -def get_or_create_issue(issue_link): |
87 | | - """Fetch or create an Issue instance from the GitHub API.""" |
88 | | - from apps.github.models.issue import Issue |
89 | | - from apps.github.models.repository import Repository |
90 | | - from apps.github.models.user import User |
91 | | - |
92 | | - logger.info("Fetching or creating issue for link: %s", issue_link) |
93 | | - |
94 | | - # Extract repository owner, repo name, and issue number from the issue link |
95 | | - # Example: https://github.com/OWASP/Nest/issues/XYZ |
96 | | - parts = issue_link.strip("/").split("/") |
97 | | - if ( |
98 | | - len(parts) < MIN_PARTS_LENGTH |
99 | | - or parts[GITHUB_COM_INDEX] != "github.com" |
100 | | - or parts[ISSUES_INDEX] != "issues" |
101 | | - ): |
102 | | - raise ValidationError(INVALID_ISSUE_LINK_FORMAT) |
103 | | - |
104 | | - try: |
105 | | - return Issue.objects.get(url=issue_link) |
106 | | - except Issue.DoesNotExist: |
107 | | - pass |
108 | | - |
109 | | - github_client = Github(settings.GITHUB_TOKEN) |
110 | | - issue_number = int(parts[6]) |
111 | | - owner = parts[3] |
112 | | - repo_name = parts[4] |
113 | | - |
114 | | - try: |
115 | | - # Fetch the repository and issue from GitHub |
116 | | - gh_repo = github_client.get_repo(f"{owner}/{repo_name}") |
117 | | - gh_issue = gh_repo.get_issue(issue_number) |
118 | | - repository = Repository.objects.get(name=repo_name) |
119 | | - author = User.objects.get(login=gh_issue.user.login) |
120 | | - |
121 | | - # Update or create the issue in the database |
122 | | - return Issue.update_data(gh_issue, author=author, repository=repository) |
123 | | - except Exception as e: |
124 | | - logger.exception("Failed to fetch issue from GitHub: %s") |
125 | | - raise ValidationError(FETCH_ISSUE_ERROR.format(error=e)) from e |
126 | | - |
127 | | - |
128 | 68 | @lru_cache |
129 | 69 | def get_staff_data(timeout=30): |
130 | 70 | """Get staff data.""" |
@@ -192,43 +132,3 @@ def strip_markdown(text): |
192 | 132 | """Strip markdown formatting.""" |
193 | 133 | slack_link_pattern = re.compile(r"<(https?://[^|]+)\|([^>]+)>") |
194 | 134 | return slack_link_pattern.sub(r"\2 (\1)", text).replace("*", "") |
195 | | - |
196 | | - |
197 | | -def validate_deadline(deadline_str): |
198 | | - """Validate that the deadline is in a valid datetime format.""" |
199 | | - try: |
200 | | - # Try parsing the deadline in YYYY-MM-DD format |
201 | | - deadline = datetime.strptime(deadline_str, "%Y-%m-%d").replace( |
202 | | - tzinfo=timezone.get_current_timezone() |
203 | | - ) |
204 | | - except ValueError: |
205 | | - try: |
206 | | - # Try parsing the deadline in YYYY-MM-DD HH:MM format |
207 | | - deadline = datetime.strptime(deadline_str, "%Y-%m-%d %H:%M").replace( |
208 | | - tzinfo=timezone.get_current_timezone() |
209 | | - ) |
210 | | - except ValueError as e: |
211 | | - raise ValidationError(DEADLINE_FORMAT_ERROR) from e |
212 | | - |
213 | | - if deadline < timezone.now(): |
214 | | - raise ValidationError(DEADLINE_FUTURE_ERROR) |
215 | | - |
216 | | - return deadline |
217 | | - |
218 | | - |
219 | | -def validate_github_issue_link(issue_link): |
220 | | - """Validate that the issue link belongs to a valid OWASP-related repository.""" |
221 | | - if not issue_link.startswith("https://github.com/OWASP"): |
222 | | - raise ValidationError(ISSUE_LINK_ERROR) |
223 | | - return issue_link |
224 | | - |
225 | | - |
226 | | -def validate_price(price): |
227 | | - """Validate that the price is a positive float value.""" |
228 | | - try: |
229 | | - price = float(price) |
230 | | - if price <= 0: |
231 | | - raise ValidationError(PRICE_POSITIVE_ERROR) |
232 | | - except ValueError as e: |
233 | | - raise ValidationError(PRICE_VALID_ERROR) from e |
234 | | - return price |
0 commit comments