ultralytics-actions 0.0.44__py3-none-any.whl → 0.0.46__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- actions/__init__.py +1 -1
- actions/first_interaction.py +3 -3
- actions/utils/__init__.py +2 -1
- actions/utils/common_utils.py +68 -58
- {ultralytics_actions-0.0.44.dist-info → ultralytics_actions-0.0.46.dist-info}/METADATA +1 -1
- ultralytics_actions-0.0.46.dist-info/RECORD +15 -0
- ultralytics_actions-0.0.44.dist-info/RECORD +0 -15
- {ultralytics_actions-0.0.44.dist-info → ultralytics_actions-0.0.46.dist-info}/LICENSE +0 -0
- {ultralytics_actions-0.0.44.dist-info → ultralytics_actions-0.0.46.dist-info}/WHEEL +0 -0
- {ultralytics_actions-0.0.44.dist-info → ultralytics_actions-0.0.46.dist-info}/entry_points.txt +0 -0
- {ultralytics_actions-0.0.44.dist-info → ultralytics_actions-0.0.46.dist-info}/top_level.txt +0 -0
actions/__init__.py
CHANGED
actions/first_interaction.py
CHANGED
@@ -298,7 +298,7 @@ def get_first_interaction_response(event, issue_type: str, title: str, body: str
|
|
298
298
|
3. For questions:
|
299
299
|
- Provide as much context as possible about your question
|
300
300
|
- Include any research you've already done on the topic
|
301
|
-
- Specify which parts of the [documentation](https://docs.ultralytics.com), if any, you've already consulted
|
301
|
+
- Specify which parts of the [documentation](https://docs.ultralytics.com/), if any, you've already consulted
|
302
302
|
|
303
303
|
Please make sure you've searched existing {issue_type}s to avoid duplicates. If you need to add any additional information, please comment on this {issue_type}.
|
304
304
|
|
@@ -311,12 +311,12 @@ Thank you for your contribution to improving our project!
|
|
311
311
|
- ✅ **Define a Purpose**: Clearly explain the purpose of your fix or feature in your PR description, and link to any [relevant issues](https://github.com/{event.repository}/issues). Ensure your commit messages are clear, concise, and adhere to the project's conventions.
|
312
312
|
- ✅ **Synchronize with Source**: Confirm your PR is synchronized with the `{event.repository}` `main` branch. If it's behind, update it by clicking the 'Update branch' button or by running `git pull` and `git merge main` locally.
|
313
313
|
- ✅ **Ensure CI Checks Pass**: Verify all Ultralytics [Continuous Integration (CI)](https://docs.ultralytics.com/help/CI/) checks are passing. If any checks fail, please address the issues.
|
314
|
-
- ✅ **Update Documentation**: Update the relevant [documentation](https://docs.ultralytics.com) for any new or modified features.
|
314
|
+
- ✅ **Update Documentation**: Update the relevant [documentation](https://docs.ultralytics.com/) for any new or modified features.
|
315
315
|
- ✅ **Add Tests**: If applicable, include or update tests to cover your changes, and confirm that all tests are passing.
|
316
316
|
- ✅ **Sign the CLA**: Please ensure you have signed our [Contributor License Agreement](https://docs.ultralytics.com/help/CLA/) if this is your first Ultralytics PR by writing "I have read the CLA Document and I sign the CLA" in a new message.
|
317
317
|
- ✅ **Minimize Changes**: Limit your changes to the **minimum** necessary for your bug fix or feature addition. _"It is not daily increase but daily decrease, hack away the unessential. The closer to the source, the less wastage there is."_ — Bruce Lee
|
318
318
|
|
319
|
-
For more guidance, please refer to our [Contributing Guide](https://docs.ultralytics.com/help/contributing). Don’t hesitate to leave a comment if you have any questions. Thank you for contributing to Ultralytics! 🚀
|
319
|
+
For more guidance, please refer to our [Contributing Guide](https://docs.ultralytics.com/help/contributing/). Don’t hesitate to leave a comment if you have any questions. Thank you for contributing to Ultralytics! 🚀
|
320
320
|
"""
|
321
321
|
|
322
322
|
if issue_type == "pull request":
|
actions/utils/__init__.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
-
from .common_utils import remove_html_comments
|
3
|
+
from .common_utils import REQUESTS_HEADERS, remove_html_comments
|
4
4
|
from .github_utils import (
|
5
5
|
GITHUB_API_URL,
|
6
6
|
Action,
|
@@ -11,6 +11,7 @@ from .openai_utils import get_completion
|
|
11
11
|
|
12
12
|
__all__ = (
|
13
13
|
"GITHUB_API_URL",
|
14
|
+
"REQUESTS_HEADERS",
|
14
15
|
"Action",
|
15
16
|
"check_pypi_version",
|
16
17
|
"get_completion",
|
actions/utils/common_utils.py
CHANGED
@@ -7,22 +7,24 @@ from urllib import parse
|
|
7
7
|
|
8
8
|
import requests
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
"""
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
""
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
10
|
+
REQUESTS_HEADERS = {
|
11
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
|
12
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
13
|
+
"Accept-Language": "en-US,en;q=0.9,es;q=0.8,zh-CN;q=0.7,zh;q=0.6",
|
14
|
+
"Accept-Encoding": "gzip, deflate, br, zstd",
|
15
|
+
"sec-ch-ua": '"Chromium";v="132", "Google Chrome";v="132", "Not_A Brand";v="99"',
|
16
|
+
"sec-ch-ua-mobile": "?0",
|
17
|
+
"sec-ch-ua-platform": '"macOS"',
|
18
|
+
"Sec-Fetch-Site": "none",
|
19
|
+
"Sec-Fetch-Mode": "navigate",
|
20
|
+
"Sec-Fetch-User": "?1",
|
21
|
+
"Sec-Fetch-Dest": "document",
|
22
|
+
"Referer": "https://www.google.com/",
|
23
|
+
"Origin": "https://www.google.com/",
|
24
|
+
}
|
25
|
+
|
26
|
+
URL_IGNORE_LIST = frozenset(
|
27
|
+
{
|
26
28
|
"localhost",
|
27
29
|
"127.0.0",
|
28
30
|
":5000",
|
@@ -36,16 +38,43 @@ def is_url(url, check=True, max_attempts=3, timeout=2):
|
|
36
38
|
"example",
|
37
39
|
"mailto:",
|
38
40
|
"github.com", # ignore GitHub links that may be private repos
|
39
|
-
"kaggle.com", # blocks automated header requests
|
40
|
-
"reddit.com", # blocks automated header requests
|
41
41
|
"linkedin.com",
|
42
42
|
"twitter.com",
|
43
43
|
"x.com",
|
44
44
|
"storage.googleapis.com", # private GCS buckets
|
45
|
-
|
45
|
+
}
|
46
|
+
)
|
47
|
+
|
48
|
+
URL_PATTERN = re.compile(
|
49
|
+
r"\[([^]]+)]\((.*?)(?=\)(?:\s|$))\)" # Markdown links with lookahead for space/end
|
50
|
+
r"|"
|
51
|
+
r"(" # Start capturing group for plaintext URLs
|
52
|
+
r"(?:https?://)?" # Optional http:// or https://
|
53
|
+
r"(?:www\.)?" # Optional www.
|
54
|
+
r"(?:[\w.-]+)?" # Optional domain name and subdomains
|
55
|
+
r"\.[a-zA-Z]{2,}" # TLD
|
56
|
+
r"(?:/[^\s\"'\]]*)?" # Optional path
|
57
|
+
r")"
|
58
|
+
)
|
59
|
+
|
60
|
+
|
61
|
+
def remove_html_comments(body: str) -> str:
|
62
|
+
"""Removes HTML comments from a string using regex pattern matching."""
|
63
|
+
return re.sub(r"<!--.*?-->", "", body, flags=re.DOTALL).strip()
|
64
|
+
|
65
|
+
|
66
|
+
def clean_url(url):
|
67
|
+
"""Remove extra characters from URL strings."""
|
68
|
+
for _ in range(3):
|
69
|
+
url = str(url).strip('"').strip("'").rstrip(".,:;!?`\\").replace(".git@main", "").replace("git+", "")
|
70
|
+
return url
|
71
|
+
|
72
|
+
|
73
|
+
def is_url(url, session=None, check=True, max_attempts=3, timeout=2):
|
74
|
+
"""Check if string is URL and optionally verify it exists."""
|
46
75
|
try:
|
47
76
|
# Check allow list
|
48
|
-
if any(x in url for x in
|
77
|
+
if any(x in url for x in URL_IGNORE_LIST):
|
49
78
|
return True
|
50
79
|
|
51
80
|
# Check structure
|
@@ -54,31 +83,20 @@ def is_url(url, check=True, max_attempts=3, timeout=2):
|
|
54
83
|
if not result.scheme or not partition[0] or not partition[2]:
|
55
84
|
return False
|
56
85
|
|
57
|
-
# Check response
|
58
86
|
if check:
|
59
|
-
|
60
|
-
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
|
61
|
-
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
62
|
-
"Accept-Language": "en-US,en;q=0.9,es;q=0.8,zh-CN;q=0.7,zh;q=0.6",
|
63
|
-
"Accept-Encoding": "gzip, deflate, br, zstd",
|
64
|
-
"sec-ch-ua": '"Chromium";v="132", "Google Chrome";v="132", "Not_A Brand";v="99"',
|
65
|
-
"sec-ch-ua-mobile": "?0",
|
66
|
-
"sec-ch-ua-platform": '"macOS"',
|
67
|
-
"Sec-Fetch-Site": "none",
|
68
|
-
"Sec-Fetch-Mode": "navigate",
|
69
|
-
"Sec-Fetch-User": "?1",
|
70
|
-
"Sec-Fetch-Dest": "document",
|
71
|
-
"Referer": "https://www.google.com/",
|
72
|
-
"Origin": "https://www.google.com/",
|
73
|
-
}
|
87
|
+
requester = session or requests
|
74
88
|
bad_codes = {404, 410, 500, 502, 503, 504}
|
89
|
+
kwargs = {"timeout": timeout, "allow_redirects": True}
|
90
|
+
if not session:
|
91
|
+
kwargs["headers"] = REQUESTS_HEADERS
|
92
|
+
|
75
93
|
for attempt in range(max_attempts):
|
76
94
|
try:
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
return
|
95
|
+
# Try HEAD first, then GET if needed
|
96
|
+
for method in (requester.head, requester.get):
|
97
|
+
if method(url, stream=method == requester.get, **kwargs).status_code not in bad_codes:
|
98
|
+
return True
|
99
|
+
return False
|
82
100
|
except Exception:
|
83
101
|
if attempt == max_attempts - 1: # last attempt
|
84
102
|
return False
|
@@ -91,28 +109,16 @@ def is_url(url, check=True, max_attempts=3, timeout=2):
|
|
91
109
|
|
92
110
|
def check_links_in_string(text, verbose=True, return_bad=False):
|
93
111
|
"""Process a given text, find unique URLs within it, and check for any 404 errors."""
|
94
|
-
pattern = (
|
95
|
-
r"\[([^\]]+)\]\(([^)]+)\)" # Matches Markdown links [text](url)
|
96
|
-
r"|"
|
97
|
-
r"(" # Start capturing group for plaintext URLs
|
98
|
-
r"(?:https?://)?" # Optional http:// or https://
|
99
|
-
r"(?:www\.)?" # Optional www.
|
100
|
-
r"(?:[\w.-]+)?" # Optional domain name and subdomains
|
101
|
-
r"\.[a-zA-Z]{2,}" # TLD
|
102
|
-
r"(?:/[^\s\"')\]]*)?" # Optional path
|
103
|
-
r")"
|
104
|
-
)
|
105
|
-
# all_urls.extend([url for url in match if url and parse.urlparse(url).scheme])
|
106
112
|
all_urls = []
|
107
|
-
for md_text, md_url, plain_url in
|
113
|
+
for md_text, md_url, plain_url in URL_PATTERN.findall(text):
|
108
114
|
url = md_url or plain_url
|
109
115
|
if url and parse.urlparse(url).scheme:
|
110
116
|
all_urls.append(url)
|
111
117
|
|
112
118
|
urls = set(map(clean_url, all_urls)) # remove extra characters and make unique
|
113
|
-
|
114
|
-
|
115
|
-
bad_urls = [url for url, valid in zip(urls, executor.map(lambda x: not is_url(x,
|
119
|
+
with requests.Session() as session, ThreadPoolExecutor(max_workers=16) as executor:
|
120
|
+
session.headers.update(REQUESTS_HEADERS)
|
121
|
+
bad_urls = [url for url, valid in zip(urls, executor.map(lambda x: not is_url(x, session), urls)) if valid]
|
116
122
|
|
117
123
|
passing = not bad_urls
|
118
124
|
if verbose and not passing:
|
@@ -122,4 +128,8 @@ def check_links_in_string(text, verbose=True, return_bad=False):
|
|
122
128
|
|
123
129
|
|
124
130
|
if __name__ == "__main__":
|
125
|
-
|
131
|
+
url = "https://ultralytics.com/images/bus.jpg"
|
132
|
+
string = f"This is a string with a [Markdown link]({url}) inside it."
|
133
|
+
|
134
|
+
print(f"is_url(): {is_url(url)}")
|
135
|
+
print(f"check_links_in_string(): {check_links_in_string(string)}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: ultralytics-actions
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.46
|
4
4
|
Summary: Ultralytics Actions for GitHub automation and PR management.
|
5
5
|
Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>
|
6
6
|
Maintainer-email: Ultralytics <hello@ultralytics.com>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
actions/__init__.py,sha256=ayOOJ0aHxao_KGb0rwJcpBCECN5nzyxr-Y8lg-s1OwE,742
|
2
|
+
actions/first_interaction.py,sha256=Oosw3GlXObF4RxYJG8haIjKXSV4MAx_uPXfMdRKY5qA,17851
|
3
|
+
actions/summarize_pr.py,sha256=Pfcm6ArfZfcMme48FcCGNmMwrFFlsG0czifhXHDKAlY,11166
|
4
|
+
actions/summarize_release.py,sha256=2D1IIeS4xrQNEJER3HItm5u9XvTL8hwGX_jWD2S8q1Y,8455
|
5
|
+
actions/update_markdown_code_blocks.py,sha256=DN6rrDw2VHXUTetrrg1SHlYDco9iaGOfQBKFORqbCBI,6362
|
6
|
+
actions/utils/__init__.py,sha256=WStdEAYROVnF0nubEOmrFLrejkRiMXIefA5O1ckfcFs,476
|
7
|
+
actions/utils/common_utils.py,sha256=2HFUz3bCMvzr9X0zqkOwJKWKddNdtYFEILsAMUrLHGI,4846
|
8
|
+
actions/utils/github_utils.py,sha256=0h0Hz2tgUta61Ymn9YggRXBZ7aZdF5krKnX7Tj9jqRU,7068
|
9
|
+
actions/utils/openai_utils.py,sha256=U7DjxTdFGdhmWSE4_KIg1yPQdtrfG4GkbNZCgMw4_1Q,1822
|
10
|
+
ultralytics_actions-0.0.46.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
11
|
+
ultralytics_actions-0.0.46.dist-info/METADATA,sha256=hpvH9Ch2NhuhcTcLvUv6GOmr-pQFL0w6qSKAUhRGW5g,10561
|
12
|
+
ultralytics_actions-0.0.46.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
13
|
+
ultralytics_actions-0.0.46.dist-info/entry_points.txt,sha256=GowvOFplj0C7JmsjbKcbpgLpdf2r921pcaOQkAHWZRA,378
|
14
|
+
ultralytics_actions-0.0.46.dist-info/top_level.txt,sha256=5apM5x80QlJcGbACn1v3fkmIuL1-XQCKcItJre7w7Tw,8
|
15
|
+
ultralytics_actions-0.0.46.dist-info/RECORD,,
|
@@ -1,15 +0,0 @@
|
|
1
|
-
actions/__init__.py,sha256=hIhJBdHAJFF5RjLVqpEhHB5ahmlGCV4aqLSqkdqr4NA,742
|
2
|
-
actions/first_interaction.py,sha256=YKW7pPFrG-IxzvRoR4UYe0i8ehQdavwNSf7TzuQEAlA,17848
|
3
|
-
actions/summarize_pr.py,sha256=Pfcm6ArfZfcMme48FcCGNmMwrFFlsG0czifhXHDKAlY,11166
|
4
|
-
actions/summarize_release.py,sha256=2D1IIeS4xrQNEJER3HItm5u9XvTL8hwGX_jWD2S8q1Y,8455
|
5
|
-
actions/update_markdown_code_blocks.py,sha256=DN6rrDw2VHXUTetrrg1SHlYDco9iaGOfQBKFORqbCBI,6362
|
6
|
-
actions/utils/__init__.py,sha256=Jc--odEZWBrQmgI9C9rPdKIJNj8YW-mCJV71VWQyMCA,434
|
7
|
-
actions/utils/common_utils.py,sha256=jcMtuFERmZXvDOUW6YclFNclIssxw3w7E7ilI68RpxU,4970
|
8
|
-
actions/utils/github_utils.py,sha256=0h0Hz2tgUta61Ymn9YggRXBZ7aZdF5krKnX7Tj9jqRU,7068
|
9
|
-
actions/utils/openai_utils.py,sha256=U7DjxTdFGdhmWSE4_KIg1yPQdtrfG4GkbNZCgMw4_1Q,1822
|
10
|
-
ultralytics_actions-0.0.44.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
11
|
-
ultralytics_actions-0.0.44.dist-info/METADATA,sha256=hgyNZCI6KfkpzkSVh5O77x9P7CdLMZT2DSIjBTD0Gp4,10561
|
12
|
-
ultralytics_actions-0.0.44.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
13
|
-
ultralytics_actions-0.0.44.dist-info/entry_points.txt,sha256=GowvOFplj0C7JmsjbKcbpgLpdf2r921pcaOQkAHWZRA,378
|
14
|
-
ultralytics_actions-0.0.44.dist-info/top_level.txt,sha256=5apM5x80QlJcGbACn1v3fkmIuL1-XQCKcItJre7w7Tw,8
|
15
|
-
ultralytics_actions-0.0.44.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{ultralytics_actions-0.0.44.dist-info → ultralytics_actions-0.0.46.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|