|
|
|
import os |
|
import urllib.parse |
|
import tempfile |
|
import shutil |
|
from huggingface_hub import login, upload_folder |
|
from modules.constants import HF_API_TOKEN, upload_file_types, model_extensions, image_extensions |
|
|
|
def generate_permalink(valid_files, base_url_external, permalink_viewer_url="surn-3d-viewer.hf.space"): |
|
""" |
|
Given a list of valid files, checks if they contain exactly 1 model file and 2 image files. |
|
Constructs and returns a permalink URL with query parameters if the criteria is met. |
|
Otherwise, returns None. |
|
""" |
|
model_link = None |
|
images_links = [] |
|
for f in valid_files: |
|
filename = os.path.basename(f) |
|
ext = os.path.splitext(filename)[1].lower() |
|
if ext in model_extensions: |
|
if model_link is None: |
|
model_link = f"{base_url_external}/{filename}" |
|
elif ext in image_extensions: |
|
images_links.append(f"{base_url_external}/{filename}") |
|
if model_link and len(images_links) == 2: |
|
|
|
permalink_viewer_url = f"https:{permalink_viewer_url}/" |
|
params = {"3d": model_link, "hm": images_links[0], "image": images_links[1]} |
|
query_str = urllib.parse.urlencode(params) |
|
return f"{permalink_viewer_url}?{query_str}" |
|
return None |
|
|
|
def generate_permalink_from_urls(model_url, hm_url, img_url, permalink_viewer_url="surn-3d-viewer.hf.space"): |
|
""" |
|
Constructs and returns a permalink URL with query string parameters for the viewer. |
|
Each parameter is passed separately so that the image positions remain consistent. |
|
|
|
Parameters: |
|
model_url (str): Processed URL for the 3D model. |
|
hm_url (str): Processed URL for the height map image. |
|
img_url (str): Processed URL for the main image. |
|
permalink_viewer_url (str): The base viewer URL. |
|
|
|
Returns: |
|
str: The generated permalink URL. |
|
""" |
|
import urllib.parse |
|
params = {"3d": model_url, "hm": hm_url, "image": img_url} |
|
query_str = urllib.parse.urlencode(params) |
|
return f"https://{permalink_viewer_url}/?{query_str}" |
|
|
|
def upload_files_to_repo(files, repo_id, folder_name, create_permalink=False, repo_type="dataset", permalink_viewer_url="surn-3d-viewer.hf.space"): |
|
""" |
|
Uploads multiple files to a Hugging Face repository using a batch upload approach via upload_folder. |
|
|
|
Parameters: |
|
files (list): A list of file paths (str) to upload. |
|
repo_id (str): The repository ID on Hugging Face for storage, e.g. "Surn/Storage". |
|
folder_name (str): The subfolder within the repository where files will be saved. |
|
create_permalink (bool): If True and if exactly three files are uploaded (1 model and 2 images), |
|
returns a single permalink to the project with query parameters. |
|
Otherwise, returns individual permalinks for each file. |
|
repo_type (str): Repository type ("space", "dataset", etc.). Default is "dataset". |
|
|
|
Returns: |
|
If create_permalink is True and files match the criteria: |
|
tuple: (response, permalink) where response is the output of the batch upload |
|
and permalink is the URL string (with fully qualified file paths) for the project. |
|
Otherwise: |
|
list: A list of tuples (response, permalink) for each file. |
|
""" |
|
|
|
login(token=HF_API_TOKEN) |
|
|
|
valid_files = [] |
|
|
|
|
|
folder_name = folder_name.rstrip("/") |
|
|
|
|
|
for f in files: |
|
file_name = f if isinstance(f, str) else f.name if hasattr(f, "name") else None |
|
if file_name is None: |
|
continue |
|
ext = os.path.splitext(file_name)[1].lower() |
|
if ext in upload_file_types: |
|
valid_files.append(f) |
|
|
|
if not valid_files: |
|
return [] |
|
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
for file_path in valid_files: |
|
filename = os.path.basename(file_path) |
|
dest_path = os.path.join(temp_dir, filename) |
|
shutil.copy(file_path, dest_path) |
|
|
|
|
|
|
|
response = upload_folder( |
|
folder_path=temp_dir, |
|
repo_id=repo_id, |
|
repo_type=repo_type, |
|
path_in_repo=folder_name, |
|
commit_message="Batch upload files" |
|
) |
|
|
|
|
|
|
|
|
|
base_url_external = f"https://huggingface.co/datasets/{repo_id}/resolve/main/{folder_name}" |
|
individual_links = [] |
|
for file_path in valid_files: |
|
filename = os.path.basename(file_path) |
|
link = f"{base_url_external}/{filename}" |
|
individual_links.append(link) |
|
|
|
|
|
|
|
if create_permalink and len(valid_files) == 3: |
|
permalink = generate_permalink(valid_files, base_url_external, permalink_viewer_url) |
|
if permalink: |
|
return response, permalink |
|
|
|
|
|
return [(response, link) for link in individual_links] |
|
|