Skip to content

Commit 4f421fe

Browse files
committed
build_parameters.py: use local cache and server cache to get files
1 parent 967eea9 commit 4f421fe

1 file changed

Lines changed: 110 additions & 10 deletions

File tree

build_parameters.py

Lines changed: 110 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import sys
3737
import time # noqa: F401
3838
from html.parser import HTMLParser
39+
from urllib.parse import quote
3940

4041
import requests
4142

@@ -44,6 +45,15 @@
4445
parser.add_argument("--ardupilotRepoFolder", dest='gitFolder', default="../ardupilot", help="Ardupilot git folder. ")
4546
parser.add_argument("--destination", dest='destFolder', default="../../../../new_params_mversion", help="Parameters*.rst destination folder.") # noqa: E501
4647
parser.add_argument('--vehicle', dest='single_vehicle', help="If you just want to copy to one vehicle, you can do this. Otherwise it will work for all vehicles (Copter, Plane, Rover, AntennaTracker, Sub, Blimp)") # noqa: E501
48+
49+
DEFAULT_CACHE_TIME = 6 * 3600
50+
51+
# Get the directory where this script is located
52+
script_dir = os.path.dirname(os.path.abspath(__file__))
53+
default_http_request_cache_dir = os.path.join(script_dir, '.cache')
54+
55+
parser.add_argument("--cache-dir", dest='cache_dir', default=default_http_request_cache_dir,
56+
help="Directory to cache HTTP responses")
4757
args = parser.parse_args()
4858

4959

@@ -94,6 +104,102 @@ def format(self, record):
94104
})
95105

96106

107+
def fetch_url_with_cache(url, cache_dir=None):
108+
"""Fetch URL content with caching to avoid repeated downloads."""
109+
if cache_dir is None:
110+
cache_dir = args.cache_dir
111+
112+
os.makedirs(cache_dir, exist_ok=True)
113+
114+
# Create cache filename from URL
115+
cache_filename = quote(url, safe='') + '.cache'
116+
cache_path = os.path.join(cache_dir, cache_filename)
117+
cache_meta_path = cache_path + '.meta'
118+
119+
def load_cached_content():
120+
with open(cache_path, 'r', encoding='utf-8') as f:
121+
return f.read()
122+
123+
def load_cache_metadata():
124+
if not os.path.exists(cache_meta_path):
125+
return {}
126+
try:
127+
with open(cache_meta_path, 'r', encoding='utf-8') as f:
128+
return json.load(f)
129+
except OSError:
130+
return {}
131+
132+
def save_cache(content, response):
133+
with open(cache_path, 'w', encoding='utf-8') as f:
134+
f.write(content)
135+
136+
metadata = {}
137+
etag = response.headers.get('ETag')
138+
last_modified = response.headers.get('Last-Modified')
139+
if etag:
140+
metadata['etag'] = etag
141+
if last_modified:
142+
metadata['last_modified'] = last_modified
143+
if metadata:
144+
with open(cache_meta_path, 'w', encoding='utf-8') as f:
145+
json.dump(metadata, f)
146+
147+
def refresh_cache_mtime():
148+
try:
149+
os.utime(cache_path, None)
150+
except OSError:
151+
pass
152+
153+
if os.path.exists(cache_path):
154+
cache_age = time.time() - os.path.getmtime(cache_path)
155+
if cache_age < DEFAULT_CACHE_TIME:
156+
debug(f"Using cached content for {url}")
157+
return load_cached_content()
158+
159+
cache_metadata = {}
160+
headers = {}
161+
if os.path.exists(cache_path):
162+
cache_metadata = load_cache_metadata()
163+
if cache_metadata.get('etag'):
164+
headers['If-None-Match'] = cache_metadata['etag']
165+
if cache_metadata.get('last_modified'):
166+
headers['If-Modified-Since'] = cache_metadata['last_modified']
167+
168+
if headers:
169+
try:
170+
debug(f"HEAD checking server for {url}")
171+
head_response = session.head(url, timeout=30, headers=headers, allow_redirects=True)
172+
if head_response.status_code == 304:
173+
debug(f"Cache still valid for {url}")
174+
refresh_cache_mtime()
175+
return load_cached_content()
176+
177+
head_response.raise_for_status()
178+
if (head_response.headers.get('ETag') == cache_metadata.get('etag') and
179+
head_response.headers.get('Last-Modified') == cache_metadata.get('last_modified')):
180+
debug(f"Server metadata unchanged for {url}, using local cache")
181+
refresh_cache_mtime()
182+
return load_cached_content()
183+
except requests.RequestException as e:
184+
debug(f"HEAD request failed for {url}: {e}")
185+
# Fallback to GET if the HEAD request is unsupported or fails.
186+
187+
try:
188+
debug(f"Fetching full content from {url}")
189+
response = session.get(url, timeout=30, allow_redirects=True)
190+
response.raise_for_status()
191+
content = response.text
192+
except requests.RequestException as e:
193+
error(f"Failed to fetch {url}: {e}")
194+
if os.path.exists(cache_path):
195+
debug(f"Using stale cached content for {url}")
196+
return load_cached_content()
197+
raise
198+
199+
save_cache(content, response)
200+
return content
201+
202+
97203
def run_git(cmd, cwd=None, check=True, max_retries=3):
98204
"""Run git command with retry logic for lock conflicts"""
99205
if cwd is None:
@@ -406,9 +512,7 @@ def handle_starttag(self, tag, attrs):
406512
try:
407513
debug(f"Fetching {firmware_url}{vehicle}")
408514

409-
response = session.get(firmware_url + vehicle, timeout=30)
410-
response.raise_for_status()
411-
content = response.text
515+
content = fetch_url_with_cache(firmware_url + vehicle)
412516
html_parser.feed(content)
413517
except Exception as e:
414518
error(f"Vehicles folders list download error: {e}")
@@ -460,9 +564,7 @@ def handle_starttag(self, tag, attrs):
460564
try:
461565
debug(f"Fetching {url}")
462566

463-
response = session.get(url, timeout=30)
464-
response.raise_for_status()
465-
content = response.text
567+
content = fetch_url_with_cache(url)
466568
html_parser.feed(content)
467569
except Exception as e:
468570
error(f"Board folders list download error: {e}")
@@ -483,11 +585,9 @@ def fetch_commit_hash(version_link, board, file):
483585
progress(f"Processing link...\t{fetch_link}")
484586

485587
try:
486-
response = session.get(fetch_link, timeout=30)
487-
response.raise_for_status()
488-
fecth_response = response.text
588+
fetch_response = fetch_url_with_cache(fetch_link)
489589

490-
commit_details = fecth_response.split("\n")
590+
commit_details = fetch_response.split("\n")
491591
commit_hash = commit_details[0][7:]
492592
# version = commit_details[6] the sizes cary
493593
version = commit_details.pop(-2)

0 commit comments

Comments
 (0)