""" SOYBOORU IMAGE SPAMMER - Scattered across your screen! Pure Python stdlib - no installs needed. Uses Edge headless to bypass Cloudflare + render React SPA. Press SPACE to stop. """ import subprocess, re, os, sys, time, random, tempfile, urllib.request, tkinter as tk # ═══════════════ CONFIG ═══════════════ EDGE = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" MAX_IMAGES = 30 MIN_SIZE = 150 MAX_SIZE = 500 MIN_DELAY_MS = 350 MAX_DELAY_MS = 700 # ═══════════════════════════════════════ def edge_render(url, wait_ms=10000): """Use Edge headless to render a page and return DOM HTML.""" try: r = subprocess.run( [EDGE, "--headless=new", "--disable-gpu", "--no-sandbox", "--dump-dom", f"--virtual-time-budget={wait_ms}", url], capture_output=True, timeout=45 ) return r.stdout.decode("utf-8", errors="replace") except Exception as e: print(f" Edge error: {e}") return "" def extract_post_ids(html): """Pull post IDs from rendered soybooru DOM.""" ids = set() for m in re.finditer(r'/api/booru/posts/(\d+)/(?:image|thumbnail|file)', html): ids.add(m.group(1)) for m in re.finditer(r'/post/view/(\d+)', html): ids.add(m.group(1)) for m in re.finditer(r'"id"\s*:\s*(\d{4,7})', html): ids.add(m.group(1)) return list(ids) def download_image(post_id, dest): """Download a post's image file. Returns path or None.""" url = f"https://soybooru.com/api/booru/posts/{post_id}/file" try: req = urllib.request.Request(url, headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Referer": "https://soybooru.com/", }) with urllib.request.urlopen(req, timeout=15) as resp: data = resp.read() if len(data) < 1000: return None ct = resp.headers.get("Content-Type", "") ext = ".gif" if "gif" in ct else ".png" if "png" in ct else ".ppm" path = os.path.join(dest, f"{post_id}{ext}") with open(path, "wb") as f: f.write(data) return path except: return None def load_photo(path): """Load an image into a tkinter PhotoImage. Tries GIF, PNG, then PPM fallback.""" try: return tk.PhotoImage(file=path) except: pass # If it's a PNG/GIF that tkinter can't read, try converting via raw bytes try: with open(path, "rb") as f: header = f.read(8) # Check if PNG if header[:4] == b'\x89PNG': # tkinter on 8.6+ should handle PNG - skip pass except: pass return None def photo_subsample(photo, target_w, target_h): """Scale a PhotoImage to roughly target_w x target_h using subsample.""" orig_w = photo.width() orig_h = photo.height() if orig_w == 0 or orig_h == 0: return photo, orig_w, orig_h # Calculate subsample factor (integer, min 1) sx = max(1, orig_w // target_w) sy = max(1, orig_h // target_h) s = max(sx, sy) if s <= 1: return photo, orig_w, orig_h scaled = photo.subsample(s, s) return scaled, scaled.width(), scaled.height() # ══════════════════════════════════════════════════ # PHASE 1: Scrape gallery # ══════════════════════════════════════════════════ print("=== SOYBOORU IMAGE SPAMMER ===") print("Loading gallery via Edge headless...") print() all_ids = set() pages = [ ("Gallery 1", "https://soybooru.com/booru?q=category:gallery"), ("Gallery 2", "https://soybooru.com/booru?q=category:gallery&page=2"), ("Gallery 3", "https://soybooru.com/booru?q=category:gallery&page=3"), ] for name, url in pages: print(f" {name}...") html = edge_render(url, wait_ms=10000) ids = extract_post_ids(html) print(f" -> {len(ids)} posts") all_ids.update(ids) if len(all_ids) >= MAX_IMAGES * 2: break time.sleep(0.5) all_ids = list(all_ids) random.shuffle(all_ids) print(f"\n Total unique posts: {len(all_ids)}") # ══════════════════════════════════════════════════ # PHASE 2: Download images # ══════════════════════════════════════════════════ print("\nDownloading images...") tmp = tempfile.mkdtemp(prefix="soyspam_") downloaded = [] # list of (path, original_w, original_h) for pid in all_ids: if len(downloaded) >= MAX_IMAGES: break p = download_image(pid, tmp) if p: downloaded.append(p) print(f" [{len(downloaded)}/{MAX_IMAGES}] Post {pid}") if not downloaded: print("\n No images downloaded! Exiting.") sys.exit(1) print(f"\n {len(downloaded)} images ready.\n") # ══════════════════════════════════════════════════ # PHASE 3: Spam them scattered across the screen # ══════════════════════════════════════════════════ print("SPAMMING! Press SPACE or ESC to stop.\n") root = tk.Tk() root.title("soyspam") root.attributes("-topmost", True) root.configure(bg="black") root.overrideredirect(True) root.keypreview = True sw = root.winfo_screenwidth() sh = root.winfo_screenheight() root.geometry(f"{sw}x{sh}+0+0") canvas = tk.Canvas(root, width=sw, height=sh, bg="black", highlightthickness=0) canvas.pack(fill="both", expand=True) # Keep references so GC doesn't eat them photo_refs = [] running = True def quit_spam(e=None): global running running = False root.destroy() root.bind("", lambda e: quit_spam() if e.keysym in ("space", "Escape") else None) root.focus_force() def spawn_one(): """Place one random image at a random position.""" if not running or not downloaded: return path = random.choice(downloaded) try: photo = load_photo(path) if photo is None: return orig_w = photo.width() orig_h = photo.height() # Pick a target size between MIN_SIZE and MAX_SIZE target = random.randint(MIN_SIZE, MAX_SIZE) # Scale down if image is bigger than target if orig_w > target or orig_h > target: show_photo, show_w, show_h = photo_subsample(photo, target, target) else: show_photo, show_w, show_h = photo, orig_w, orig_h photo_refs.append(show_photo) # Random position (keep on screen) x = random.randint(0, max(0, sw - show_w)) y = random.randint(0, max(0, sh - show_h)) canvas.create_image(x, y, anchor="nw", image=show_photo) canvas.update() except Exception: pass if running: delay = random.randint(MIN_DELAY_MS, MAX_DELAY_MS) root.after(delay, spawn_one) # Kick it off - stagger a few for i in range(5): root.after(i * 200, spawn_one) try: root.mainloop() except: pass # ══════════════════════════════════════════════════ # CLEANUP # ══════════════════════════════════════════════════ print("Stopped! Cleaning up temp files...") for p in downloaded: try: os.remove(p) except: pass try: os.rmdir(tmp) except: pass print("Done.")