Deadmon's picture
Rename app.py to app1.py
29d5ab1 verified
import os
import requests
import zipfile
import gradio as gr
import shutil
from PIL import Image
# Configuration
API_URL = "https://porn-pictures-api.p.rapidapi.com/pornstars/{gender}/{page}"
API_HEADERS = {
"x-rapidapi-key": "2dcd4142a4msh0d39ff26a5b144cp1e8703jsndf67b0582674",
"x-rapidapi-host": "porn-pictures-api.p.rapidapi.com"
}
OUTPUT_DIR = "downloaded_images" # Base output folder
IMAGES_DIR = os.path.join(OUTPUT_DIR, "images") # Subfolder for downloaded images
ZIP_FILE = os.path.join(OUTPUT_DIR, "images.zip") # Path for the output ZIP file
# Ensure output directory exists
os.makedirs(OUTPUT_DIR, exist_ok=True)
def fetch_image_urls(gender, num_images):
"""Fetch image URLs from the API based on gender and desired number of images."""
image_urls = []
page = 1
items_per_page = 40 # From the response, each page has 40 items
while len(image_urls) < num_images:
url = API_URL.format(gender=gender.lower(), page=page)
try:
response = requests.get(url, headers=API_HEADERS)
response.raise_for_status() # Raise an error for bad status codes
data = response.json()
if "result" not in data or not data["result"]:
break # No more data to fetch
for item in data["result"]:
if len(image_urls) >= num_images:
break
image_urls.append(item["picture"])
page += 1
except Exception as e:
print(f"Error fetching page {page}: {e}")
break
return image_urls[:num_images]
def download_images(image_urls):
"""Download images from the provided URLs and save to IMAGES_DIR."""
if os.path.exists(IMAGES_DIR):
shutil.rmtree(IMAGES_DIR) # Clear previous contents
os.makedirs(IMAGES_DIR, exist_ok=True)
downloaded_count = 0
image_paths = []
for idx, url in enumerate(image_urls, 1):
try:
response = requests.get(url, stream=True)
response.raise_for_status()
image_path = os.path.join(IMAGES_DIR, f"img{idx}.jpg")
with open(image_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
# Verify the image
Image.open(image_path).verify()
downloaded_count += 1
image_paths.append(image_path)
print(f"Downloaded {idx}/{len(image_urls)}: {url}")
except Exception as e:
print(f"Error downloading {url}: {e}")
return downloaded_count, image_paths
def create_zip_file(selected_image_paths):
"""Create a ZIP file of the selected images."""
if os.path.exists(ZIP_FILE):
os.remove(ZIP_FILE) # Remove previous ZIP
with zipfile.ZipFile(ZIP_FILE, 'w', zipfile.ZIP_DEFLATED) as zipf:
for image_path in selected_image_paths:
arcname = os.path.relpath(image_path, OUTPUT_DIR)
zipf.write(image_path, arcname)
return ZIP_FILE
def process_and_display(gender, num_images):
"""Fetch and download images, then prepare data for display."""
num_images = int(num_images) # Convert dropdown selection to integer
if num_images > 24:
num_images = 24 # Limit to 24 images to fit 6 rows of 4
# Fetch image URLs
image_urls = fetch_image_urls(gender, num_images)
if not image_urls:
return "Failed to fetch image URLs.", None, None, None
# Download images
downloaded_count, image_paths = download_images(image_urls)
if downloaded_count == 0:
return "No images were successfully downloaded.", None, None, None
return f"Successfully downloaded {downloaded_count}/{num_images} images. Select images to include in ZIP below.", None, image_paths, image_paths
def process_zip_submission(image_paths, *checkbox_states):
"""Create a ZIP file based on the selected images."""
if not image_paths:
return "No images available to process.", None
selected_image_paths = [image_paths[i] for i, state in enumerate(checkbox_states) if state]
if not selected_image_paths:
return "No images selected for ZIP.", None
zip_path = create_zip_file(selected_image_paths)
return f"ZIP file created with {len(selected_image_paths)} images at {zip_path}", zip_path
# Gradio Interface
with gr.Blocks(title="Image Downloader") as demo:
gr.Markdown("### Select Parameters to Download Images")
gender_input = gr.Dropdown(
label="Category (Gender, Race, Hair Color, Body Type) - Select or Type Custom",
choices=["female", "male", "nonbinary", "black", "latino", "asian", "white", "mixed",
"redhead", "blonde", "brunette", "blackhair", "bald", "bbw", "curvy",
"slim", "muscular", "thick"],
value="female",
allow_custom_value=True
)
num_images_input = gr.Dropdown(
label="Number of Images (Max 24)",
choices=["4", "8", "12", "16", "20", "24"], # Multiples of 4 up to 24
value="4"
)
download_button = gr.Button("Fetch and Display Images")
gr.Markdown("### Download Status")
status_output = gr.Textbox(label="Status", interactive=False)
gr.Markdown("### Download Your Images")
zip_output = gr.File(label="Download ZIP", visible=False)
gr.Markdown("### Image Gallery (Click Thumbnails to View Full Size)")
image_paths_state = gr.State() # Store image paths for later use
# Define constants for grid layout
IMAGES_PER_ROW = 4
MAX_ROWS = 6 # 6 rows of 4 = 24 images max
TOTAL_IMAGES = IMAGES_PER_ROW * MAX_ROWS # 24 images max
# Create image and checkbox components in a strict 4-per-row grid
image_outputs = []
checkbox_outputs = []
for row in range(MAX_ROWS):
with gr.Row():
for col in range(IMAGES_PER_ROW):
idx = row * IMAGES_PER_ROW + col
with gr.Column(min_width=150): # Set a minimum width to force layout
image_output = gr.Image(
label=f"Image {idx+1}",
visible=False,
height=150,
width=150
)
checkbox_output = gr.Checkbox(
label=f"Include in ZIP",
value=True,
visible=False
)
image_outputs.append(image_output)
checkbox_outputs.append(checkbox_output)
gr.Markdown("### Submit Selections")
submit_button = gr.Button("Create ZIP of Selected Images")
def on_download(gender, num_images):
status, zip_path, image_paths, _ = process_and_display(gender, num_images)
if image_paths:
# Update image and checkbox components for the downloaded images
updates = {
status_output: status,
zip_output: gr.File(value=None, visible=False), # Hide ZIP initially
image_paths_state: image_paths
}
for i in range(TOTAL_IMAGES):
if i < len(image_paths):
updates[image_outputs[i]] = gr.Image(
value=image_paths[i],
visible=True,
label=f"Image {i+1}",
width=150,
height=150
)
updates[checkbox_outputs[i]] = gr.Checkbox(
value=True,
visible=True,
label=f"Include in ZIP"
)
else:
updates[image_outputs[i]] = gr.Image(value=None, visible=False)
updates[checkbox_outputs[i]] = gr.Checkbox(value=False, visible=False)
return updates
return {
status_output: status,
zip_output: gr.File(visible=False),
image_paths_state: None,
**{image_outputs[i]: gr.Image(value=None, visible=False) for i in range(TOTAL_IMAGES)},
**{checkbox_outputs[i]: gr.Checkbox(value=False, visible=False) for i in range(TOTAL_IMAGES)}
}
def on_submit(image_paths, *checkbox_states):
status, zip_path = process_zip_submission(image_paths, *checkbox_states)
return {
status_output: status,
zip_output: gr.File(value=zip_path, visible=True) if zip_path else gr.File(visible=False)
}
download_button.click(
fn=on_download,
inputs=[gender_input, num_images_input],
outputs=[status_output, zip_output, image_paths_state] + image_outputs + checkbox_outputs
)
submit_button.click(
fn=on_submit,
inputs=[image_paths_state] + checkbox_outputs,
outputs=[status_output, zip_output]
)
demo.launch()