ultralytics-actions 0.0.66__py3-none-any.whl → 0.0.68__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/utils/__init__.py +11 -2
- actions/utils/common_utils.py +34 -21
- {ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/METADATA +1 -1
- {ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/RECORD +9 -9
- {ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/WHEEL +0 -0
- {ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/entry_points.txt +0 -0
- {ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/licenses/LICENSE +0 -0
- {ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/top_level.txt +0 -0
actions/__init__.py
CHANGED
actions/utils/__init__.py
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
-
from .common_utils import
|
3
|
+
from .common_utils import (
|
4
|
+
REDIRECT_END_IGNORE_LIST,
|
5
|
+
REDIRECT_START_IGNORE_LIST,
|
6
|
+
REQUESTS_HEADERS,
|
7
|
+
URL_IGNORE_LIST,
|
8
|
+
allow_redirect,
|
9
|
+
remove_html_comments,
|
10
|
+
)
|
4
11
|
from .github_utils import GITHUB_API_URL, Action, check_pypi_version, ultralytics_actions_info
|
5
12
|
from .openai_utils import get_completion
|
6
13
|
|
@@ -8,8 +15,10 @@ __all__ = (
|
|
8
15
|
"GITHUB_API_URL",
|
9
16
|
"REQUESTS_HEADERS",
|
10
17
|
"URL_IGNORE_LIST",
|
11
|
-
"
|
18
|
+
"REDIRECT_START_IGNORE_LIST",
|
19
|
+
"REDIRECT_END_IGNORE_LIST",
|
12
20
|
"Action",
|
21
|
+
"allow_redirect",
|
13
22
|
"check_pypi_version",
|
14
23
|
"get_completion",
|
15
24
|
"remove_html_comments",
|
actions/utils/common_utils.py
CHANGED
@@ -20,15 +20,14 @@ REQUESTS_HEADERS = {
|
|
20
20
|
"Sec-Fetch-Mode": "navigate",
|
21
21
|
"Sec-Fetch-User": "?1",
|
22
22
|
"Sec-Fetch-Dest": "document",
|
23
|
-
"Referer": "https://www.google.com/",
|
24
|
-
"Origin": "https://www.google.com/",
|
25
23
|
}
|
26
24
|
BAD_HTTP_CODES = frozenset(
|
27
25
|
{
|
28
|
-
|
26
|
+
204, # No content
|
29
27
|
# 403, # Forbidden - client lacks permission to access the resource (commented as works in browser typically)
|
30
28
|
404, # Not Found - requested resource doesn't exist
|
31
29
|
405, # Method Not Allowed - HTTP method not supported for this endpoint
|
30
|
+
406, # Not Acceptable - server can't generate response matching client's acceptable headers
|
32
31
|
410, # Gone - resource permanently removed
|
33
32
|
500, # Internal Server Error - server encountered an error
|
34
33
|
502, # Bad Gateway - upstream server sent invalid response
|
@@ -58,10 +57,24 @@ URL_IGNORE_LIST = { # use a set (not frozenset) to update with possible private
|
|
58
57
|
"(", # breaks pattern matches
|
59
58
|
"api.", # ignore api endpoints
|
60
59
|
}
|
61
|
-
|
60
|
+
REDIRECT_START_IGNORE_LIST = frozenset(
|
62
61
|
{
|
63
62
|
"{", # possible f-string
|
64
63
|
"}", # possible f-string
|
64
|
+
"https://youtu.be",
|
65
|
+
"bit.ly",
|
66
|
+
"ow.ly",
|
67
|
+
"shields.io",
|
68
|
+
"badge",
|
69
|
+
"ultralytics.com/actions",
|
70
|
+
"ultralytics.com/bilibili",
|
71
|
+
"ultralytics.com/images",
|
72
|
+
"app.gong.io/call?",
|
73
|
+
"docs.openvino.ai",
|
74
|
+
}
|
75
|
+
)
|
76
|
+
REDIRECT_END_IGNORE_LIST = frozenset(
|
77
|
+
{
|
65
78
|
"/es/",
|
66
79
|
"/us/",
|
67
80
|
"en-us",
|
@@ -77,20 +90,11 @@ REDIRECT_IGNORE_LIST = frozenset(
|
|
77
90
|
"login",
|
78
91
|
"consent",
|
79
92
|
"verify",
|
80
|
-
"badge",
|
81
|
-
"shields.io",
|
82
|
-
"bit.ly",
|
83
|
-
"ow.ly",
|
84
|
-
"https://youtu.be/",
|
85
93
|
"latex.codecogs.com",
|
86
94
|
"svg.image",
|
87
95
|
"?view=azureml",
|
88
96
|
"?utm_",
|
89
97
|
"redirect",
|
90
|
-
"ultralytics.com/actions",
|
91
|
-
"ultralytics.com/bilibili",
|
92
|
-
"ultralytics.com/images",
|
93
|
-
"app.gong.io/call?",
|
94
98
|
"https://code.visualstudio.com/", # errors
|
95
99
|
"?rdt=", # problems with reddit redirecting to https://www.reddit.com/r/ultralytics/?rdt=48616
|
96
100
|
"objects.githubusercontent.com", # Prevent replacement with temporary signed GitHub asset URLs
|
@@ -121,10 +125,16 @@ def clean_url(url):
|
|
121
125
|
return url
|
122
126
|
|
123
127
|
|
124
|
-
def allow_redirect(
|
128
|
+
def allow_redirect(start="", end=""):
|
125
129
|
"""Check if URL should be skipped based on simple rules."""
|
126
|
-
|
127
|
-
|
130
|
+
start_lower = start.lower()
|
131
|
+
end_lower = end.lower()
|
132
|
+
return (
|
133
|
+
end
|
134
|
+
and end.startswith("https://")
|
135
|
+
and not any(item in end_lower for item in REDIRECT_END_IGNORE_LIST)
|
136
|
+
and not any(item in start_lower for item in REDIRECT_START_IGNORE_LIST)
|
137
|
+
)
|
128
138
|
|
129
139
|
|
130
140
|
def brave_search(query, api_key, count=5):
|
@@ -141,7 +151,7 @@ def brave_search(query, api_key, count=5):
|
|
141
151
|
return [result.get("url") for result in results if result.get("url")]
|
142
152
|
|
143
153
|
|
144
|
-
def is_url(url, session=None, check=True, max_attempts=3, timeout=
|
154
|
+
def is_url(url, session=None, check=True, max_attempts=3, timeout=3, return_url=False, redirect=False):
|
145
155
|
"""Check if string is URL and optionally verify it exists, with fallback for GitHub repos."""
|
146
156
|
try:
|
147
157
|
# Check allow list
|
@@ -165,7 +175,7 @@ def is_url(url, session=None, check=True, max_attempts=3, timeout=2, return_url=
|
|
165
175
|
# Try HEAD first, then GET if needed
|
166
176
|
for method in (requester.head, requester.get):
|
167
177
|
response = method(url, stream=method == requester.get, **kwargs)
|
168
|
-
if redirect and allow_redirect(response.url):
|
178
|
+
if redirect and allow_redirect(start=url, end=response.url):
|
169
179
|
url = response.url
|
170
180
|
if response.status_code not in BAD_HTTP_CODES:
|
171
181
|
return (True, url) if return_url else True
|
@@ -200,6 +210,7 @@ def check_links_in_string(text, verbose=True, return_bad=False, replace=False):
|
|
200
210
|
|
201
211
|
with requests.Session() as session, ThreadPoolExecutor(max_workers=64) as executor:
|
202
212
|
session.headers.update(REQUESTS_HEADERS)
|
213
|
+
session.cookies = requests.cookies.RequestsCookieJar()
|
203
214
|
results = list(executor.map(lambda x: is_url(x[1], session, return_url=True, redirect=True), urls))
|
204
215
|
bad_urls = [url for (title, url), (valid, redirect) in zip(urls, results) if not valid]
|
205
216
|
|
@@ -212,14 +223,16 @@ def check_links_in_string(text, verbose=True, return_bad=False, replace=False):
|
|
212
223
|
for (title, url), (valid, redirect) in zip(urls, results):
|
213
224
|
# Handle invalid URLs with Brave search
|
214
225
|
if not valid and brave_api_key:
|
215
|
-
|
226
|
+
query = f"{(redirect or url)[:200]} {title[:199]}"
|
227
|
+
if search_urls := brave_search(query, brave_api_key, count=3):
|
216
228
|
best_url = search_urls[0]
|
217
229
|
for alt_url in search_urls:
|
218
230
|
if is_url(alt_url, session):
|
219
231
|
best_url = alt_url
|
220
232
|
break
|
221
|
-
|
222
|
-
|
233
|
+
if url != best_url:
|
234
|
+
replacements[url] = best_url
|
235
|
+
modified_text = modified_text.replace(url, best_url)
|
223
236
|
# Handle redirects for valid URLs
|
224
237
|
elif valid and redirect and redirect != url:
|
225
238
|
replacements[url] = redirect
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ultralytics-actions
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.68
|
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>
|
@@ -1,15 +1,15 @@
|
|
1
|
-
actions/__init__.py,sha256=
|
1
|
+
actions/__init__.py,sha256=JRXgdKfSoTN4UJEHO2P9prHZYIHPLBQo9hbiRD1WC20,742
|
2
2
|
actions/first_interaction.py,sha256=1_WvQHCi5RWaSfyi49ClF2Zk_3CKGjFnZqz6FlxPRAc,17868
|
3
3
|
actions/summarize_pr.py,sha256=BKttOq-MGaanVaChLU5B1ewKUA8K6S05Cy3FQtyRmxU,11681
|
4
4
|
actions/summarize_release.py,sha256=tov6qsYGC68lfobvkwVyoWZBGtJ598G0m097n4Ydzvo,8472
|
5
5
|
actions/update_markdown_code_blocks.py,sha256=9PL7YIQfApRNAa0que2hYHv7umGZTZoHlblesB0xFj4,8587
|
6
|
-
actions/utils/__init__.py,sha256=
|
7
|
-
actions/utils/common_utils.py,sha256=
|
6
|
+
actions/utils/__init__.py,sha256=ZE0RmC9qOCt9TUhvORd6uVhbxOKVFWJDobR454v55_M,682
|
7
|
+
actions/utils/common_utils.py,sha256=YRdEz8qluwzCZfWgqXNmyhKqNhdxNMpoHhGaHUD4AaM,11013
|
8
8
|
actions/utils/github_utils.py,sha256=-F--JgxtXE0fSPMFEzakz7iZilp-vonzLiyXfg0b17Y,7117
|
9
9
|
actions/utils/openai_utils.py,sha256=qQbmrJpOUANxSMf7inDSgPIwgf0JHD1fWZuab-y2W6g,2942
|
10
|
-
ultralytics_actions-0.0.
|
11
|
-
ultralytics_actions-0.0.
|
12
|
-
ultralytics_actions-0.0.
|
13
|
-
ultralytics_actions-0.0.
|
14
|
-
ultralytics_actions-0.0.
|
15
|
-
ultralytics_actions-0.0.
|
10
|
+
ultralytics_actions-0.0.68.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
11
|
+
ultralytics_actions-0.0.68.dist-info/METADATA,sha256=CpcyV3LeuvtCpvOAzycM_EwA3Gsnq190EPQQuTZ3vUw,10923
|
12
|
+
ultralytics_actions-0.0.68.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
13
|
+
ultralytics_actions-0.0.68.dist-info/entry_points.txt,sha256=GowvOFplj0C7JmsjbKcbpgLpdf2r921pcaOQkAHWZRA,378
|
14
|
+
ultralytics_actions-0.0.68.dist-info/top_level.txt,sha256=5apM5x80QlJcGbACn1v3fkmIuL1-XQCKcItJre7w7Tw,8
|
15
|
+
ultralytics_actions-0.0.68.dist-info/RECORD,,
|
File without changes
|
{ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/entry_points.txt
RENAMED
File without changes
|
{ultralytics_actions-0.0.66.dist-info → ultralytics_actions-0.0.68.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
File without changes
|