Skip to content

Commit 4bfc776

Browse files
committedFeb 25, 2025··
Added model repo sync script
1 parent b07e1f6 commit 4bfc776

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed
 

‎tools/sync-to-github.py

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#! /usr/bin/env python3
2+
import os
3+
import requests
4+
import hashlib
5+
from typing import List, Dict
6+
import sys
7+
8+
# Configuration
9+
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", "").strip() # Add .strip() to remove whitespace
10+
REPO_OWNER = "nomadkaraoke"
11+
REPO_NAME = "python-audio-separator"
12+
RELEASE_TAG = "model-configs"
13+
14+
HEADERS = {"Authorization": f"Bearer {GITHUB_TOKEN}", "Accept": "application/vnd.github.v3+json"}
15+
16+
17+
def debug_request(url: str, headers: dict, response: requests.Response):
18+
"""Debug helper to print request and response details."""
19+
print("\n=== Debug Information ===")
20+
print(f"Request URL: {url}")
21+
print(f"Request Headers: {headers}")
22+
print(f"Response Status: {response.status_code}")
23+
print(f"Response Headers: {dict(response.headers)}")
24+
print(f"Response Body: {response.text[:500]}...") # First 500 chars of response
25+
print("=======================\n")
26+
27+
28+
def get_release_assets() -> List[Dict]:
29+
"""Get all assets from the specified release."""
30+
url = f"https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/releases/tags/{RELEASE_TAG}"
31+
print(f"\nDebug: Using token: {GITHUB_TOKEN[:4]}...{GITHUB_TOKEN[-4:]}") # Show first/last 4 chars
32+
print(f"Debug: Requesting URL: {url}")
33+
print(f"Debug: Headers: {HEADERS}")
34+
35+
response = requests.get(url, headers=HEADERS)
36+
debug_request(url, HEADERS, response)
37+
38+
if response.status_code != 200:
39+
print(f"Error getting release: {response.status_code}")
40+
return []
41+
42+
release_data = response.json()
43+
return release_data.get("assets", [])
44+
45+
46+
def list_local_files() -> List[str]:
47+
"""List all files in the current directory (excluding directories)."""
48+
return [f for f in os.listdir(".") if os.path.isfile(f)]
49+
50+
51+
def calculate_file_hash(filepath: str) -> str:
52+
"""Calculate SHA256 hash of a file."""
53+
sha256_hash = hashlib.sha256()
54+
with open(filepath, "rb") as f:
55+
for byte_block in iter(lambda: f.read(4096), b""):
56+
sha256_hash.update(byte_block)
57+
return sha256_hash.hexdigest()
58+
59+
60+
def upload_asset(release_id: int, filepath: str):
61+
"""Upload a file as a release asset."""
62+
upload_url = f"https://uploads.github.com/repos/{REPO_OWNER}/{REPO_NAME}/releases/{release_id}/assets"
63+
64+
filename = os.path.basename(filepath)
65+
headers = {"Authorization": f"Bearer {GITHUB_TOKEN}", "Content-Type": "application/octet-stream"}
66+
67+
params = {"name": filename}
68+
69+
with open(filepath, "rb") as f:
70+
response = requests.post(upload_url, headers=headers, params=params, data=f)
71+
72+
if response.status_code == 201:
73+
print(f"Successfully uploaded {filename}")
74+
else:
75+
print(f"Failed to upload {filename}: {response.status_code}")
76+
print(response.text)
77+
78+
79+
def download_asset(asset: Dict):
80+
"""Download a release asset to the local directory."""
81+
filename = asset["name"]
82+
download_url = asset["browser_download_url"]
83+
84+
print(f"Downloading {filename}...")
85+
response = requests.get(download_url, headers=HEADERS, stream=True)
86+
87+
if response.status_code == 200:
88+
with open(filename, "wb") as f:
89+
for chunk in response.iter_content(chunk_size=8192):
90+
f.write(chunk)
91+
print(f"Successfully downloaded {filename}")
92+
else:
93+
print(f"Failed to download {filename}: {response.status_code}")
94+
95+
96+
def main():
97+
if not GITHUB_TOKEN:
98+
print("Please set GITHUB_TOKEN environment variable")
99+
sys.exit(1)
100+
101+
print(f"Debug: Script starting with token length: {len(GITHUB_TOKEN)}")
102+
print(f"Debug: Token characters: {[ord(c) for c in GITHUB_TOKEN]}")
103+
print(f"Debug: Token first/last chars: {GITHUB_TOKEN[:4]}...{GITHUB_TOKEN[-4:]}")
104+
105+
# Get release ID first
106+
url = f"https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/releases/tags/{RELEASE_TAG}"
107+
response = requests.get(url, headers=HEADERS)
108+
if response.status_code != 200:
109+
print(f"Error getting release: {response.status_code}")
110+
return
111+
112+
release_id = response.json()["id"]
113+
114+
# Get existing assets
115+
existing_assets = get_release_assets()
116+
existing_filenames = {asset["name"] for asset in existing_assets}
117+
118+
# Get local files
119+
local_files = list_local_files()
120+
121+
print("\nExisting release assets:")
122+
for asset in existing_assets:
123+
print(f"- {asset['name']} ({asset['size']} bytes)")
124+
125+
# Add download option
126+
print("\nOptions:")
127+
print("1. Upload new files")
128+
print("2. Download all missing files")
129+
print("3. Exit")
130+
131+
choice = input("\nEnter your choice (1-3): ")
132+
133+
if choice == "1":
134+
# Original upload logic
135+
files_to_upload = []
136+
for local_file in local_files:
137+
if local_file not in existing_filenames:
138+
print(f"- {local_file}")
139+
files_to_upload.append(local_file)
140+
141+
if files_to_upload:
142+
files_with_size = [(f, os.path.getsize(f)) for f in files_to_upload]
143+
files_with_size.sort(key=lambda x: x[1])
144+
145+
print("\nFiles to upload (in order):")
146+
for file, size in files_with_size:
147+
print(f"- {file} ({size / 1024 / 1024:.2f} MB)")
148+
149+
response = input("\nDo you want to upload these files? (y/n): ")
150+
if response.lower() == "y":
151+
for file, _ in files_with_size:
152+
upload_asset(release_id, file)
153+
else:
154+
print("\nNo new files to upload.")
155+
156+
elif choice == "2":
157+
# Download missing files
158+
files_to_download = []
159+
for asset in existing_assets:
160+
if asset["name"] not in local_files:
161+
files_to_download.append(asset)
162+
163+
if files_to_download:
164+
print("\nFiles to download:")
165+
for asset in files_to_download:
166+
print(f"- {asset['name']} ({asset['size'] / 1024 / 1024:.2f} MB)")
167+
168+
response = input("\nDo you want to download these files? (y/n): ")
169+
if response.lower() == "y":
170+
for asset in files_to_download:
171+
download_asset(asset)
172+
else:
173+
print("\nNo files to download. Local directory is in sync.")
174+
175+
176+
if __name__ == "__main__":
177+
main()

0 commit comments

Comments
 (0)
Please sign in to comment.