Spaces:
Running
Running
| #! /usr/bin/env python3 | |
| import os | |
| import requests | |
| import hashlib | |
| from typing import List, Dict | |
| import sys | |
| # Configuration | |
| GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", "").strip() # Add .strip() to remove whitespace | |
| REPO_OWNER = "nomadkaraoke" | |
| REPO_NAME = "python-audio-separator" | |
| RELEASE_TAG = "model-configs" | |
| HEADERS = {"Authorization": f"Bearer {GITHUB_TOKEN}", "Accept": "application/vnd.github.v3+json"} | |
| def debug_request(url: str, headers: dict, response: requests.Response): | |
| """Debug helper to print request and response details.""" | |
| print("\n=== Debug Information ===") | |
| print(f"Request URL: {url}") | |
| print(f"Request Headers: {headers}") | |
| print(f"Response Status: {response.status_code}") | |
| print(f"Response Headers: {dict(response.headers)}") | |
| print(f"Response Body: {response.text[:500]}...") # First 500 chars of response | |
| print("=======================\n") | |
| def get_release_assets() -> List[Dict]: | |
| """Get all assets from the specified release.""" | |
| url = f"https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/releases/tags/{RELEASE_TAG}" | |
| print(f"\nDebug: Using token: {GITHUB_TOKEN[:4]}...{GITHUB_TOKEN[-4:]}") # Show first/last 4 chars | |
| print(f"Debug: Requesting URL: {url}") | |
| print(f"Debug: Headers: {HEADERS}") | |
| response = requests.get(url, headers=HEADERS) | |
| debug_request(url, HEADERS, response) | |
| if response.status_code != 200: | |
| print(f"Error getting release: {response.status_code}") | |
| return [] | |
| release_data = response.json() | |
| return release_data.get("assets", []) | |
| def list_local_files() -> List[str]: | |
| """List all files in the current directory (excluding directories).""" | |
| return [f for f in os.listdir(".") if os.path.isfile(f)] | |
| def calculate_file_hash(filepath: str) -> str: | |
| """Calculate SHA256 hash of a file.""" | |
| sha256_hash = hashlib.sha256() | |
| with open(filepath, "rb") as f: | |
| for byte_block in iter(lambda: f.read(4096), b""): | |
| sha256_hash.update(byte_block) | |
| return sha256_hash.hexdigest() | |
| def upload_asset(release_id: int, filepath: str): | |
| """Upload a file as a release asset.""" | |
| upload_url = f"https://uploads.github.com/repos/{REPO_OWNER}/{REPO_NAME}/releases/{release_id}/assets" | |
| filename = os.path.basename(filepath) | |
| headers = {"Authorization": f"Bearer {GITHUB_TOKEN}", "Content-Type": "application/octet-stream"} | |
| params = {"name": filename} | |
| with open(filepath, "rb") as f: | |
| response = requests.post(upload_url, headers=headers, params=params, data=f) | |
| if response.status_code == 201: | |
| print(f"Successfully uploaded {filename}") | |
| else: | |
| print(f"Failed to upload {filename}: {response.status_code}") | |
| print(response.text) | |
| def download_asset(asset: Dict): | |
| """Download a release asset to the local directory.""" | |
| filename = asset["name"] | |
| download_url = asset["browser_download_url"] | |
| print(f"Downloading {filename}...") | |
| response = requests.get(download_url, headers=HEADERS, stream=True) | |
| if response.status_code == 200: | |
| with open(filename, "wb") as f: | |
| for chunk in response.iter_content(chunk_size=8192): | |
| f.write(chunk) | |
| print(f"Successfully downloaded {filename}") | |
| else: | |
| print(f"Failed to download {filename}: {response.status_code}") | |
| def main(): | |
| if not GITHUB_TOKEN: | |
| print("Please set GITHUB_TOKEN environment variable") | |
| sys.exit(1) | |
| print(f"Debug: Script starting with token length: {len(GITHUB_TOKEN)}") | |
| print(f"Debug: Token characters: {[ord(c) for c in GITHUB_TOKEN]}") | |
| print(f"Debug: Token first/last chars: {GITHUB_TOKEN[:4]}...{GITHUB_TOKEN[-4:]}") | |
| # Get release ID first | |
| url = f"https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/releases/tags/{RELEASE_TAG}" | |
| response = requests.get(url, headers=HEADERS) | |
| if response.status_code != 200: | |
| print(f"Error getting release: {response.status_code}") | |
| return | |
| release_id = response.json()["id"] | |
| # Get existing assets | |
| existing_assets = get_release_assets() | |
| existing_filenames = {asset["name"] for asset in existing_assets} | |
| # Get local files | |
| local_files = list_local_files() | |
| print("\nExisting release assets:") | |
| for asset in existing_assets: | |
| print(f"- {asset['name']} ({asset['size']} bytes)") | |
| # Add download option | |
| print("\nOptions:") | |
| print("1. Upload new files") | |
| print("2. Download all missing files") | |
| print("3. Exit") | |
| choice = input("\nEnter your choice (1-3): ") | |
| if choice == "1": | |
| # Original upload logic | |
| files_to_upload = [] | |
| for local_file in local_files: | |
| if local_file not in existing_filenames: | |
| print(f"- {local_file}") | |
| files_to_upload.append(local_file) | |
| if files_to_upload: | |
| files_with_size = [(f, os.path.getsize(f)) for f in files_to_upload] | |
| files_with_size.sort(key=lambda x: x[1]) | |
| print("\nFiles to upload (in order):") | |
| for file, size in files_with_size: | |
| print(f"- {file} ({size / 1024 / 1024:.2f} MB)") | |
| response = input("\nDo you want to upload these files? (y/n): ") | |
| if response.lower() == "y": | |
| for file, _ in files_with_size: | |
| upload_asset(release_id, file) | |
| else: | |
| print("\nNo new files to upload.") | |
| elif choice == "2": | |
| # Download missing files | |
| files_to_download = [] | |
| for asset in existing_assets: | |
| if asset["name"] not in local_files: | |
| files_to_download.append(asset) | |
| if files_to_download: | |
| print("\nFiles to download:") | |
| for asset in files_to_download: | |
| print(f"- {asset['name']} ({asset['size'] / 1024 / 1024:.2f} MB)") | |
| response = input("\nDo you want to download these files? (y/n): ") | |
| if response.lower() == "y": | |
| for asset in files_to_download: | |
| download_asset(asset) | |
| else: | |
| print("\nNo files to download. Local directory is in sync.") | |
| if __name__ == "__main__": | |
| main() | |