Spaces:
Sleeping
Sleeping
generate safe file name
Browse files
app.py
CHANGED
|
@@ -20,6 +20,7 @@ from huggingface_hub import HfApi, HfFolder, create_repo
|
|
| 20 |
from huggingface_hub.utils import RepositoryNotFoundError
|
| 21 |
from huggingface_hub.hf_api import RepoFile
|
| 22 |
import tempfile
|
|
|
|
| 23 |
|
| 24 |
# Create FastAPI app
|
| 25 |
app = FastAPI(title="Image Uploader")
|
|
@@ -474,6 +475,18 @@ def delete_from_hf_and_local(filename):
|
|
| 474 |
return local_success or hf_success
|
| 475 |
|
| 476 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 477 |
@app.post("/upload/")
|
| 478 |
async def upload_image(
|
| 479 |
request: Request,
|
|
@@ -538,24 +551,24 @@ async def upload_image(
|
|
| 538 |
if not is_valid_image(extension):
|
| 539 |
continue # Skip non-image files
|
| 540 |
|
| 541 |
-
# Preserve original filename in metadata
|
| 542 |
original_filename = file.filename
|
| 543 |
|
| 544 |
-
# Generate a
|
| 545 |
-
|
| 546 |
|
| 547 |
# Read file content for upload
|
| 548 |
file.file.seek(0)
|
| 549 |
file_content = await file.read()
|
| 550 |
|
| 551 |
# Save file to both local storage and Hugging Face
|
| 552 |
-
upload_success = upload_to_hf_and_local(file_content,
|
| 553 |
|
| 554 |
if not upload_success:
|
| 555 |
continue # Skip to next file if upload failed
|
| 556 |
|
| 557 |
# Save hashtags and original filename
|
| 558 |
-
add_hashtags_to_image(
|
| 559 |
|
| 560 |
# For base64 encoding
|
| 561 |
base64_encoded = base64.b64encode(file_content).decode("utf-8")
|
|
@@ -571,7 +584,7 @@ async def upload_image(
|
|
| 571 |
}.get(extension, 'application/octet-stream')
|
| 572 |
|
| 573 |
# Get direct image URL using Space URL if available
|
| 574 |
-
image_url = f"/static/uploads/{
|
| 575 |
|
| 576 |
# Full URL for embedding
|
| 577 |
if (
|
|
@@ -579,21 +592,23 @@ async def upload_image(
|
|
| 579 |
and HF_USERNAME
|
| 580 |
and os.environ.get("ENV", "development") == "production"
|
| 581 |
):
|
| 582 |
-
full_url = f"https://{HF_USERNAME.lower()}-{SPACE_NAME}.hf.space/static/uploads/{
|
| 583 |
else:
|
| 584 |
-
full_url = f"{request.base_url}static/uploads/{
|
| 585 |
-
|
| 586 |
-
results.append(
|
| 587 |
-
|
| 588 |
-
|
| 589 |
-
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
|
| 596 |
-
|
|
|
|
|
|
|
| 597 |
|
| 598 |
if len(results) == 1:
|
| 599 |
return results[0]
|
|
@@ -660,17 +675,17 @@ async def upload_with_replace(
|
|
| 660 |
del metadata[old_filename]
|
| 661 |
save_image_metadata(metadata)
|
| 662 |
|
| 663 |
-
# Generate a
|
| 664 |
-
|
| 665 |
|
| 666 |
# Upload to both local storage and Hugging Face
|
| 667 |
-
upload_success = upload_to_hf_and_local(file_content,
|
| 668 |
|
| 669 |
if not upload_success:
|
| 670 |
continue # Skip to next file if upload failed
|
| 671 |
|
| 672 |
# Save hashtags and original filename
|
| 673 |
-
add_hashtags_to_image(
|
| 674 |
|
| 675 |
# For base64 encoding
|
| 676 |
base64_encoded = base64.b64encode(file_content).decode("utf-8")
|
|
@@ -686,7 +701,7 @@ async def upload_with_replace(
|
|
| 686 |
}.get(extension, 'application/octet-stream')
|
| 687 |
|
| 688 |
# Get direct image URL using Space URL if available
|
| 689 |
-
image_url = f"/static/uploads/{
|
| 690 |
|
| 691 |
# Full URL for embedding
|
| 692 |
if (
|
|
@@ -694,21 +709,23 @@ async def upload_with_replace(
|
|
| 694 |
and HF_USERNAME
|
| 695 |
and os.environ.get("ENV", "development") == "production"
|
| 696 |
):
|
| 697 |
-
full_url = f"https://{HF_USERNAME.lower()}-{SPACE_NAME}.hf.space/static/uploads/{
|
| 698 |
else:
|
| 699 |
-
full_url = f"{request.base_url}static/uploads/{
|
| 700 |
-
|
| 701 |
-
results.append(
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
|
|
|
|
|
|
| 712 |
|
| 713 |
if len(results) == 1:
|
| 714 |
return results[0]
|
|
|
|
| 20 |
from huggingface_hub.utils import RepositoryNotFoundError
|
| 21 |
from huggingface_hub.hf_api import RepoFile
|
| 22 |
import tempfile
|
| 23 |
+
import time
|
| 24 |
|
| 25 |
# Create FastAPI app
|
| 26 |
app = FastAPI(title="Image Uploader")
|
|
|
|
| 475 |
return local_success or hf_success
|
| 476 |
|
| 477 |
|
| 478 |
+
def generate_safe_filename(original_filename):
|
| 479 |
+
"""Generate a safe filename that preserves the original name but avoids collisions."""
|
| 480 |
+
# Extract base name and extension
|
| 481 |
+
base_name, extension = os.path.splitext(original_filename)
|
| 482 |
+
# Remove invalid characters from base name
|
| 483 |
+
safe_base = "".join(c for c in base_name if c.isalnum() or c in "-_. ")
|
| 484 |
+
safe_base = safe_base.replace(" ", "_")
|
| 485 |
+
# Add timestamp to ensure uniqueness
|
| 486 |
+
timestamp = int(time.time() * 1000)
|
| 487 |
+
return f"{safe_base}_{timestamp}{extension}"
|
| 488 |
+
|
| 489 |
+
|
| 490 |
@app.post("/upload/")
|
| 491 |
async def upload_image(
|
| 492 |
request: Request,
|
|
|
|
| 551 |
if not is_valid_image(extension):
|
| 552 |
continue # Skip non-image files
|
| 553 |
|
| 554 |
+
# Preserve original filename in metadata
|
| 555 |
original_filename = file.filename
|
| 556 |
|
| 557 |
+
# Generate a safe filename that preserves the original name
|
| 558 |
+
safe_filename = generate_safe_filename(original_filename)
|
| 559 |
|
| 560 |
# Read file content for upload
|
| 561 |
file.file.seek(0)
|
| 562 |
file_content = await file.read()
|
| 563 |
|
| 564 |
# Save file to both local storage and Hugging Face
|
| 565 |
+
upload_success = upload_to_hf_and_local(file_content, safe_filename)
|
| 566 |
|
| 567 |
if not upload_success:
|
| 568 |
continue # Skip to next file if upload failed
|
| 569 |
|
| 570 |
# Save hashtags and original filename
|
| 571 |
+
add_hashtags_to_image(safe_filename, hashtag_list, original_filename)
|
| 572 |
|
| 573 |
# For base64 encoding
|
| 574 |
base64_encoded = base64.b64encode(file_content).decode("utf-8")
|
|
|
|
| 584 |
}.get(extension, 'application/octet-stream')
|
| 585 |
|
| 586 |
# Get direct image URL using Space URL if available
|
| 587 |
+
image_url = f"/static/uploads/{safe_filename}" # Local URL
|
| 588 |
|
| 589 |
# Full URL for embedding
|
| 590 |
if (
|
|
|
|
| 592 |
and HF_USERNAME
|
| 593 |
and os.environ.get("ENV", "development") == "production"
|
| 594 |
):
|
| 595 |
+
full_url = f"https://{HF_USERNAME.lower()}-{SPACE_NAME}.hf.space/static/uploads/{safe_filename}"
|
| 596 |
else:
|
| 597 |
+
full_url = f"{request.base_url}static/uploads/{safe_filename}"
|
| 598 |
+
|
| 599 |
+
results.append(
|
| 600 |
+
{
|
| 601 |
+
"success": True,
|
| 602 |
+
"file_name": safe_filename,
|
| 603 |
+
"original_filename": original_filename,
|
| 604 |
+
"file_url": image_url,
|
| 605 |
+
"full_url": full_url,
|
| 606 |
+
"embed_html": f'<img src="{full_url}" alt="{original_filename}" />',
|
| 607 |
+
"base64_data": f"data:{mime_type};base64,{base64_encoded[:20]}...{base64_encoded[-20:]}",
|
| 608 |
+
"base64_embed": f'<img src="data:{mime_type};base64,{base64_encoded}" alt="{original_filename}" />',
|
| 609 |
+
"hashtags": hashtag_list,
|
| 610 |
+
}
|
| 611 |
+
)
|
| 612 |
|
| 613 |
if len(results) == 1:
|
| 614 |
return results[0]
|
|
|
|
| 675 |
del metadata[old_filename]
|
| 676 |
save_image_metadata(metadata)
|
| 677 |
|
| 678 |
+
# Generate a safe filename that preserves the original name
|
| 679 |
+
safe_filename = generate_safe_filename(original_filename)
|
| 680 |
|
| 681 |
# Upload to both local storage and Hugging Face
|
| 682 |
+
upload_success = upload_to_hf_and_local(file_content, safe_filename)
|
| 683 |
|
| 684 |
if not upload_success:
|
| 685 |
continue # Skip to next file if upload failed
|
| 686 |
|
| 687 |
# Save hashtags and original filename
|
| 688 |
+
add_hashtags_to_image(safe_filename, hashtag_list, original_filename)
|
| 689 |
|
| 690 |
# For base64 encoding
|
| 691 |
base64_encoded = base64.b64encode(file_content).decode("utf-8")
|
|
|
|
| 701 |
}.get(extension, 'application/octet-stream')
|
| 702 |
|
| 703 |
# Get direct image URL using Space URL if available
|
| 704 |
+
image_url = f"/static/uploads/{safe_filename}" # Local URL
|
| 705 |
|
| 706 |
# Full URL for embedding
|
| 707 |
if (
|
|
|
|
| 709 |
and HF_USERNAME
|
| 710 |
and os.environ.get("ENV", "development") == "production"
|
| 711 |
):
|
| 712 |
+
full_url = f"https://{HF_USERNAME.lower()}-{SPACE_NAME}.hf.space/static/uploads/{safe_filename}"
|
| 713 |
else:
|
| 714 |
+
full_url = f"{request.base_url}static/uploads/{safe_filename}"
|
| 715 |
+
|
| 716 |
+
results.append(
|
| 717 |
+
{
|
| 718 |
+
"success": True,
|
| 719 |
+
"file_name": safe_filename,
|
| 720 |
+
"original_filename": original_filename,
|
| 721 |
+
"file_url": image_url,
|
| 722 |
+
"full_url": full_url,
|
| 723 |
+
"embed_html": f'<img src="{full_url}" alt="{original_filename}" />',
|
| 724 |
+
"base64_data": f"data:{mime_type};base64,{base64_encoded[:20]}...{base64_encoded[-20:]}",
|
| 725 |
+
"base64_embed": f'<img src="data:{mime_type};base64,{base64_encoded}" alt="{original_filename}" />',
|
| 726 |
+
"hashtags": hashtag_list,
|
| 727 |
+
}
|
| 728 |
+
)
|
| 729 |
|
| 730 |
if len(results) == 1:
|
| 731 |
return results[0]
|