mirror of
https://github.com/PlaneQuery/OpenAirframes.git
synced 2026-06-27 14:59:56 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a2880904e5 |
@@ -0,0 +1,21 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"contributor_name": "applesauce123",
|
||||||
|
"contributor_uuid": "2981c3ee-8712-5f96-84bf-732eda515a3f",
|
||||||
|
"creation_timestamp": "2026-02-13T16:58:21.863525+00:00",
|
||||||
|
"registration_number": "N12345",
|
||||||
|
"tags": {
|
||||||
|
"internet": "starlink"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"contributor_name": "applesauce123",
|
||||||
|
"contributor_uuid": "2981c3ee-8712-5f96-84bf-732eda515a3f",
|
||||||
|
"creation_timestamp": "2026-02-13T16:58:21.863525+00:00",
|
||||||
|
"tags": {
|
||||||
|
"internet": "viasat",
|
||||||
|
"owner": "John Doe"
|
||||||
|
},
|
||||||
|
"transponder_code_hex": "ABC123"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -61,6 +61,9 @@
|
|||||||
"icao_aircraft_type": {
|
"icao_aircraft_type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"internet": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"manufacturer_icao": {
|
"manufacturer_icao": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -79,6 +82,9 @@
|
|||||||
"operator_icao": {
|
"operator_icao": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"serial_number": {
|
"serial_number": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,12 +23,6 @@ gh run list \
|
|||||||
"repos/$REPO/actions/runs/$run_id/artifacts" \
|
"repos/$REPO/actions/runs/$run_id/artifacts" \
|
||||||
--jq '.artifacts[] | select(.name | test("^openairframes_adsb-[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{4}-[0-9]{2}-[0-9]{2}$")) | .name' | while read -r artifact_name; do
|
--jq '.artifacts[] | select(.name | test("^openairframes_adsb-[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{4}-[0-9]{2}-[0-9]{2}$")) | .name' | while read -r artifact_name; do
|
||||||
|
|
||||||
# Check if artifact directory already exists and has files
|
|
||||||
if [ -d "downloads/adsb_artifacts/$artifact_name" ] && [ -n "$(ls -A "downloads/adsb_artifacts/$artifact_name" 2>/dev/null)" ]; then
|
|
||||||
echo " Skipping (already exists): $artifact_name"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " Downloading: $artifact_name"
|
echo " Downloading: $artifact_name"
|
||||||
gh run download "$run_id" \
|
gh run download "$run_id" \
|
||||||
--repo "$REPO" \
|
--repo "$REPO" \
|
||||||
|
|||||||
@@ -129,32 +129,13 @@ def fetch_releases(version_date: str) -> list:
|
|||||||
return releases
|
return releases
|
||||||
|
|
||||||
|
|
||||||
def download_asset(asset_url: str, file_path: str, expected_size: int | None = None) -> bool:
|
def download_asset(asset_url: str, file_path: str) -> bool:
|
||||||
"""Download a single release asset with size verification.
|
"""Download a single release asset."""
|
||||||
|
|
||||||
Args:
|
|
||||||
asset_url: URL to download from
|
|
||||||
file_path: Local path to save to
|
|
||||||
expected_size: Expected file size in bytes (for verification)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if download succeeded and size matches (if provided), False otherwise
|
|
||||||
"""
|
|
||||||
os.makedirs(os.path.dirname(file_path) or OUTPUT_DIR, exist_ok=True)
|
os.makedirs(os.path.dirname(file_path) or OUTPUT_DIR, exist_ok=True)
|
||||||
|
|
||||||
# Check if file exists and has correct size
|
|
||||||
if os.path.exists(file_path):
|
if os.path.exists(file_path):
|
||||||
if expected_size is not None:
|
print(f"[SKIP] {file_path} already downloaded.")
|
||||||
actual_size = os.path.getsize(file_path)
|
return True
|
||||||
if actual_size == expected_size:
|
|
||||||
print(f"[SKIP] {file_path} already downloaded and verified ({actual_size} bytes).")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"[WARN] {file_path} exists but size mismatch (expected {expected_size}, got {actual_size}). Re-downloading.")
|
|
||||||
os.remove(file_path)
|
|
||||||
else:
|
|
||||||
print(f"[SKIP] {file_path} already downloaded.")
|
|
||||||
return True
|
|
||||||
|
|
||||||
max_retries = 2
|
max_retries = 2
|
||||||
retry_delay = 30
|
retry_delay = 30
|
||||||
@@ -172,21 +153,7 @@ def download_asset(asset_url: str, file_path: str, expected_size: int | None = N
|
|||||||
if not chunk:
|
if not chunk:
|
||||||
break
|
break
|
||||||
file.write(chunk)
|
file.write(chunk)
|
||||||
|
print(f"Saved {file_path}")
|
||||||
# Verify file size if expected_size was provided
|
|
||||||
if expected_size is not None:
|
|
||||||
actual_size = os.path.getsize(file_path)
|
|
||||||
if actual_size != expected_size:
|
|
||||||
print(f"[ERROR] Size mismatch for {file_path}: expected {expected_size} bytes, got {actual_size} bytes")
|
|
||||||
os.remove(file_path)
|
|
||||||
if attempt < max_retries:
|
|
||||||
print(f"Waiting {retry_delay} seconds before retry")
|
|
||||||
time.sleep(retry_delay)
|
|
||||||
continue
|
|
||||||
return False
|
|
||||||
print(f"Saved {file_path} ({actual_size} bytes, verified)")
|
|
||||||
else:
|
|
||||||
print(f"Saved {file_path}")
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
print(f"Failed to download {asset_url}: {response.status} {response.msg}")
|
print(f"Failed to download {asset_url}: {response.status} {response.msg}")
|
||||||
@@ -260,6 +227,7 @@ def extract_split_archive(file_paths: list, extract_dir: str) -> bool:
|
|||||||
stdin=cat_proc.stdout,
|
stdin=cat_proc.stdout,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
|
check=True
|
||||||
)
|
)
|
||||||
cat_proc.stdout.close()
|
cat_proc.stdout.close()
|
||||||
cat_stderr = cat_proc.stderr.read().decode() if cat_proc.stderr else ""
|
cat_stderr = cat_proc.stderr.read().decode() if cat_proc.stderr else ""
|
||||||
@@ -268,24 +236,6 @@ def extract_split_archive(file_paths: list, extract_dir: str) -> bool:
|
|||||||
if cat_stderr:
|
if cat_stderr:
|
||||||
print(f"cat stderr: {cat_stderr}")
|
print(f"cat stderr: {cat_stderr}")
|
||||||
|
|
||||||
tar_stderr = result.stderr.decode() if result.stderr else ""
|
|
||||||
if result.returncode != 0:
|
|
||||||
# GNU tar exits non-zero for format issues that BSD tar silently
|
|
||||||
# tolerates (e.g. trailing junk after the last valid entry).
|
|
||||||
# Check whether files were actually extracted before giving up.
|
|
||||||
extracted_items = os.listdir(extract_dir)
|
|
||||||
if extracted_items:
|
|
||||||
print(f"[WARN] tar exited {result.returncode} but extracted "
|
|
||||||
f"{len(extracted_items)} items — treating as success")
|
|
||||||
if tar_stderr:
|
|
||||||
print(f"tar stderr: {tar_stderr}")
|
|
||||||
else:
|
|
||||||
print(f"Failed to extract split archive (tar exit {result.returncode})")
|
|
||||||
if tar_stderr:
|
|
||||||
print(f"tar stderr: {tar_stderr}")
|
|
||||||
shutil.rmtree(extract_dir, ignore_errors=True)
|
|
||||||
return False
|
|
||||||
|
|
||||||
print(f"Successfully extracted archive to {extract_dir}")
|
print(f"Successfully extracted archive to {extract_dir}")
|
||||||
|
|
||||||
# Delete tar files immediately after extraction
|
# Delete tar files immediately after extraction
|
||||||
@@ -302,9 +252,11 @@ def extract_split_archive(file_paths: list, extract_dir: str) -> bool:
|
|||||||
print(f"Disk space after tar deletion: {free_gb:.1f}GB free")
|
print(f"Disk space after tar deletion: {free_gb:.1f}GB free")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except subprocess.CalledProcessError as e:
|
||||||
|
stderr_output = e.stderr.decode() if e.stderr else ""
|
||||||
print(f"Failed to extract split archive: {e}")
|
print(f"Failed to extract split archive: {e}")
|
||||||
shutil.rmtree(extract_dir, ignore_errors=True)
|
if stderr_output:
|
||||||
|
print(f"tar stderr: {stderr_output}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -77,9 +77,8 @@ def download_and_extract(version_date: str) -> str | None:
|
|||||||
for asset in use_assets:
|
for asset in use_assets:
|
||||||
asset_name = asset["name"]
|
asset_name = asset["name"]
|
||||||
asset_url = asset["browser_download_url"]
|
asset_url = asset["browser_download_url"]
|
||||||
asset_size = asset.get("size") # Get expected file size
|
|
||||||
file_path = os.path.join(OUTPUT_DIR, asset_name)
|
file_path = os.path.join(OUTPUT_DIR, asset_name)
|
||||||
if download_asset(asset_url, file_path, expected_size=asset_size):
|
if download_asset(asset_url, file_path):
|
||||||
downloaded_files.append(file_path)
|
downloaded_files.append(file_path)
|
||||||
|
|
||||||
if not downloaded_files:
|
if not downloaded_files:
|
||||||
|
|||||||
@@ -246,20 +246,6 @@ def process_submission(
|
|||||||
if schema_updated:
|
if schema_updated:
|
||||||
schema_note = f"\n**Schema Updated:** Added new tags: `{', '.join(new_tags)}`\n"
|
schema_note = f"\n**Schema Updated:** Added new tags: `{', '.join(new_tags)}`\n"
|
||||||
|
|
||||||
# Truncate JSON preview to stay under GitHub's 65536 char body limit
|
|
||||||
max_json_preview = 50000
|
|
||||||
if len(content_json) > max_json_preview:
|
|
||||||
# Show first few entries as a preview
|
|
||||||
preview_entries = submissions[:10]
|
|
||||||
preview_json = json.dumps(preview_entries, indent=2, sort_keys=True)
|
|
||||||
json_section = (
|
|
||||||
f"### Submissions (showing 10 of {len(submissions)})\n"
|
|
||||||
f"```json\n{preview_json}\n```\n\n"
|
|
||||||
f"*Full submission ({len(submissions)} entries, {len(content_json):,} chars) is in the committed file.*"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
json_section = f"### Submissions\n```json\n{content_json}\n```"
|
|
||||||
|
|
||||||
pr_body = f"""## Community Submission
|
pr_body = f"""## Community Submission
|
||||||
|
|
||||||
Adds {len(submissions)} submission(s) from @{author_username}.
|
Adds {len(submissions)} submission(s) from @{author_username}.
|
||||||
@@ -271,7 +257,10 @@ Closes #{issue_number}
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{json_section}"""
|
### Submissions
|
||||||
|
```json
|
||||||
|
{content_json}
|
||||||
|
```"""
|
||||||
|
|
||||||
pr = create_pull_request(
|
pr = create_pull_request(
|
||||||
title=f"Community submission: {filename}",
|
title=f"Community submission: {filename}",
|
||||||
|
|||||||
Reference in New Issue
Block a user