Skip to content

Commit a3013af

Browse files
committed
Refactor the integrations module organization #350
Signed-off-by: tdruez <[email protected]>
1 parent 833713a commit a3013af

File tree

6 files changed

+110
-84
lines changed

6 files changed

+110
-84
lines changed

workflow/integrations/__init__.py

Lines changed: 28 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,69 +6,31 @@
66
# See https://aboutcode.org for more information about AboutCode FOSS projects.
77
#
88

9-
from django.conf import settings
10-
11-
import requests
12-
13-
DEJACODE_SITE_URL = settings.SITE_URL.rstrip("/")
14-
15-
16-
class BaseIntegration:
17-
"""Base class for managing issue tracker integrations from DejaCode requests."""
18-
19-
default_timeout = 10
20-
21-
def __init__(self, dataspace):
22-
if not dataspace:
23-
raise ValueError("Dataspace must be provided.")
24-
self.dataspace = dataspace
25-
self.session = self.get_session()
26-
27-
def get_session(self):
28-
session = requests.Session()
29-
session.headers.update(self.get_headers())
30-
return session
31-
32-
def get_headers(self):
33-
"""
34-
Return authentication headers specific to the integration.
35-
Must be implemented in subclasses.
36-
"""
37-
raise NotImplementedError
38-
39-
@staticmethod
40-
def make_issue_title(request):
41-
return f"[DEJACODE] {request.title}"
42-
43-
@staticmethod
44-
def make_issue_body(request):
45-
request_url = f"{DEJACODE_SITE_URL}{request.get_absolute_url()}"
46-
label_fields = [
47-
("📝 Request Template", request.request_template),
48-
("📦 Product Context", request.product_context),
49-
("📌 Applies To", request.content_object),
50-
("🙋 Submitted By", request.requester),
51-
("👤 Assigned To", request.assignee),
52-
("🚨 Priority", request.priority),
53-
("🗒️ Notes", request.notes),
54-
("🔗️ DejaCode URL", request_url),
55-
]
56-
57-
lines = []
58-
for label, value in label_fields:
59-
if value:
60-
lines.append(f"### {label}\n{value}")
61-
62-
lines.append("----")
63-
64-
for question in request.get_serialized_data_as_list():
65-
label = question.get("label")
66-
value = question.get("value")
67-
input_type = question.get("input_type")
68-
69-
if input_type == "BooleanField":
70-
value = "Yes" if str(value).lower() in ("1", "true", "yes") else "No"
71-
72-
lines.append(f"### {label}\n{value}")
73-
74-
return "\n\n".join(lines)
9+
from workflow.integrations.base import BaseIntegration
10+
from workflow.integrations.github import GitHubIntegration
11+
from workflow.integrations.gitlab import GitLabIntegration
12+
from workflow.integrations.jira import JiraIntegration
13+
14+
__all__ = [
15+
"BaseIntegration",
16+
"GitHubIntegration",
17+
"GitLabIntegration",
18+
"JiraIntegration",
19+
]
20+
21+
22+
def get_class_for_tracker(issue_tracker_id):
23+
if "github.com" in issue_tracker_id:
24+
return GitHubIntegration
25+
elif "gitlab.com" in issue_tracker_id:
26+
return GitLabIntegration
27+
elif "atlassian.net" in issue_tracker_id:
28+
return JiraIntegration
29+
30+
31+
def get_class_for_platform(platform):
32+
return {
33+
"github": GitHubIntegration,
34+
"gitlab": GitLabIntegration,
35+
"jira": JiraIntegration,
36+
}.get(platform)

workflow/integrations/base.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# DejaCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: AGPL-3.0-only
5+
# See https://github.com/aboutcode-org/dejacode for support or download.
6+
# See https://aboutcode.org for more information about AboutCode FOSS projects.
7+
#
8+
9+
from django.conf import settings
10+
11+
import requests
12+
13+
DEJACODE_SITE_URL = settings.SITE_URL.rstrip("/")
14+
15+
16+
class BaseIntegration:
17+
"""Base class for managing issue tracker integrations from DejaCode requests."""
18+
19+
default_timeout = 10
20+
21+
def __init__(self, dataspace):
22+
if not dataspace:
23+
raise ValueError("Dataspace must be provided.")
24+
self.dataspace = dataspace
25+
self.session = self.get_session()
26+
27+
def get_session(self):
28+
session = requests.Session()
29+
session.headers.update(self.get_headers())
30+
return session
31+
32+
def get_headers(self):
33+
"""
34+
Return authentication headers specific to the integration.
35+
Must be implemented in subclasses.
36+
"""
37+
raise NotImplementedError
38+
39+
@staticmethod
40+
def make_issue_title(request):
41+
return f"[DEJACODE] {request.title}"
42+
43+
@staticmethod
44+
def make_issue_body(request):
45+
request_url = f"{DEJACODE_SITE_URL}{request.get_absolute_url()}"
46+
label_fields = [
47+
("📝 Request Template", request.request_template),
48+
("📦 Product Context", request.product_context),
49+
("📌 Applies To", request.content_object),
50+
("🙋 Submitted By", request.requester),
51+
("👤 Assigned To", request.assignee),
52+
("🚨 Priority", request.priority),
53+
("🗒️ Notes", request.notes),
54+
("🔗️ DejaCode URL", request_url),
55+
]
56+
57+
lines = []
58+
for label, value in label_fields:
59+
if value:
60+
lines.append(f"### {label}\n{value}")
61+
62+
lines.append("----")
63+
64+
for question in request.get_serialized_data_as_list():
65+
label = question.get("label")
66+
value = question.get("value")
67+
input_type = question.get("input_type")
68+
69+
if input_type == "BooleanField":
70+
value = "Yes" if str(value).lower() in ("1", "true", "yes") else "No"
71+
72+
lines.append(f"### {label}\n{value}")
73+
74+
return "\n\n".join(lines)

workflow/integrations/github.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from urllib.parse import urlparse
1010

11-
from workflow.integrations import BaseIntegration
11+
from workflow.integrations.base import BaseIntegration
1212

1313
GITHUB_API_URL = "https://api.github.com"
1414

workflow/integrations/gitlab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from urllib.parse import quote
1010
from urllib.parse import urlparse
1111

12-
from workflow.integrations import BaseIntegration
12+
from workflow.integrations.base import BaseIntegration
1313

1414
GITLAB_API_URL = "https://gitlab.com/api/v4"
1515

workflow/integrations/jira.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import re
1111
from urllib.parse import urlparse
1212

13-
from workflow.integrations import BaseIntegration
13+
from workflow.integrations.base import BaseIntegration
1414

1515
JIRA_API_PATH = "/rest/api/3"
1616

workflow/models.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@
3939
from dje.models import HistoryDateFieldsMixin
4040
from dje.models import HistoryFieldsMixin
4141
from dje.models import get_unsecured_manager
42-
from workflow.integrations.github import GitHubIntegration
43-
from workflow.integrations.gitlab import GitLabIntegration
44-
from workflow.integrations.jira import JiraIntegration
42+
from workflow import integrations
4543
from workflow.notification import request_comment_slack_payload
4644
from workflow.notification import request_slack_payload
4745

@@ -139,12 +137,7 @@ def icon_css_class(self):
139137

140138
@property
141139
def integration_class(self):
142-
if self.platform == self.Platform.GITHUB:
143-
return GitHubIntegration
144-
elif self.platform == self.Platform.GITLAB:
145-
return GitLabIntegration
146-
elif self.platform == self.Platform.JIRA:
147-
return JiraIntegration
140+
return integrations.get_class_for_platform(self.platform)
148141

149142

150143
class RequestQuerySet(DataspacedQuerySet):
@@ -626,12 +619,9 @@ def handle_integrations(self):
626619
if not issue_tracker_id:
627620
return
628621

629-
if "github.com" in issue_tracker_id:
630-
GitHubIntegration(dataspace=self.dataspace).sync(request=self)
631-
elif "gitlab.com" in issue_tracker_id:
632-
GitLabIntegration(dataspace=self.dataspace).sync(request=self)
633-
elif "atlassian.net" in issue_tracker_id:
634-
JiraIntegration(dataspace=self.dataspace).sync(request=self)
622+
integration_class = integrations.get_class_for_tracker(issue_tracker_id)
623+
if integration_class:
624+
integration_class(dataspace=self.dataspace).sync(request=self)
635625

636626

637627
@receiver(models.signals.post_delete, sender=Request)

0 commit comments

Comments
 (0)