#!/usr/bin/env python3 import sys import os import os.path import re import time import json import subprocess from optparse import OptionParser import requests from requests.exceptions import RequestException class YTMND: def __init__(self): self.user_mode = False self.media_only = False self.html_only = False self.json_only = False self.no_web_audio = False self.print_json = False self.sleep = 5 def fetch_user(self, user): if user == "": print("expecting one ytmnd name, got " + str(sys.argv)) return ytmnd_name = user try: response = requests.get("http://ytmnd.com/users/" + ytmnd_name + "/sites", headers={'User-Agent': 'Mozilla/5.0'}) response.raise_for_status() ytmnd_html = response.text.splitlines() except RequestException as e: print(f"Error fetching user page: {e}") return domains = [] for line in ytmnd_html: if 'profile_link' in line: expr = r"site_link\" href=\"http://(\S+).ytmn(d|sfw)?.com\"" match = re.search(expr, line) if match: domain = match.group(1) domains.append(domain) if self.json_only: if self.media_only: os.makedirs(user, exist_ok=True) os.chdir(user) parsed = [] for domain in domains: result = self.fetch_ytmnd(domain) if result: parsed.append(result) if self.media_only: os.chdir("..") self.write_json(ytmnd_name, parsed) else: print(">> found %d domains" % len(domains)) os.makedirs(user, exist_ok=True) os.chdir(user) if not self.no_web_audio: self.copy_ytmnd_js() for domain in domains: self.fetch_ytmnd(domain) os.chdir("..") def fetch_ytmnd(self, domain): if domain == "": print("expecting one ytmnd name, got " + str(sys.argv)) return None if not self.print_json: print("fetching %s" % domain) if self.sleep: time.sleep(self.sleep) ytmnd_name = domain try: response = requests.get("http://" + domain + ".ytmnd.com", headers={'User-Agent': 'Mozilla/5.0'}) response.raise_for_status() ytmnd_html = response.text expr = r"ytmnd.site_id = (\d+);" match = re.search(expr, ytmnd_html) if not match: print(f"Could not find site_id for {domain}") return None ytmnd_id = match.group(1) response = requests.get("http://" + domain + ".ytmnd.com/info/" + ytmnd_id + "/json", headers={'User-Agent': 'Mozilla/5.0'}) response.raise_for_status() ytmnd_info = response.json() except RequestException as e: print(f"Error fetching {domain}: {e}") return None if self.print_json: print(json.dumps(ytmnd_info, sort_keys=True, indent=4)) elif self.json_only: if self.media_only: self.fetch_media(ytmnd_info) return self.parse_json(ytmnd_info) elif self.media_only: self.fetch_media(ytmnd_info) elif self.html_only: self.write_index(ytmnd_info) else: self.fetch_media(ytmnd_info) self.write_index(ytmnd_info) return ytmnd_info def fetch_media(self, ytmnd_info): domain = ytmnd_info['site']['domain'] original_gif = ytmnd_info['site']['foreground']['url'] gif_type = original_gif.split(".")[-1] original_wav = ytmnd_info['site']['sound']['url'] wav_type = ytmnd_info['site']['sound']['type'] if 'alternates' in ytmnd_info['site']['sound']: key = list(ytmnd_info['site']['sound']['alternates'].keys())[0] value = ytmnd_info['site']['sound']['alternates'][key] if value['file_type'] != 'swf': original_wav = value['file_url'] wav_type = ytmnd_info['site']['sound']['file_type'] subprocess.run(["wget", "--quiet", "-O", f"{domain}.{gif_type}", original_gif]) subprocess.run(["wget", "--quiet", "-O", f"{domain}.{wav_type}", original_wav]) def write_index(self, ytmnd_info): domain = ytmnd_info['site']['domain'] bgcolor = ytmnd_info['site']['background']['color'] title = ytmnd_info['site']['description'] placement = ytmnd_info['site']['foreground']['placement'] original_gif = ytmnd_info['site']['foreground']['url'] gif_type = original_gif.split(".")[-1] wav_type = ytmnd_info['site']['sound']['type'] if 'alternates' in ytmnd_info['site']['sound']: key = list(ytmnd_info['site']['sound']['alternates'].keys())[0] value = ytmnd_info['site']['sound']['alternates'][key] if value['file_type'] != 'swf': original_wav = value['file_url'] wav_type = ytmnd_info['site']['sound']['file_type'] with open(domain + ".html", 'w', encoding='utf-8') as fn: fn.write("\n") fn.write("\n") fn.write("%s\n" % title) fn.write("\n") fn.write("\n") fn.write("\n") self.write_zoom_text(fn, ytmnd_info) if self.no_web_audio: fn.write("