Spaces:
Running
Running
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]
|