#!/usr/bin/env python3 import sys import os import os.path import re import time import json import subprocess from optparse import OptionParser from urllib.request import urlopen, Request from urllib.error import URLError, HTTPError 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: req = Request("http://ytmnd.com/users/" + ytmnd_name + "/sites", headers={'User-Agent': 'Mozilla/5.0'}) with urlopen(req) as response: ytmnd_html = response.read().decode('utf-8').splitlines() except (URLError, HTTPError) 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: req = Request("http://" + domain + ".ytmnd.com", headers={'User-Agent': 'Mozilla/5.0'}) with urlopen(req) as response: ytmnd_html = response.read().decode('utf-8') 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) req = Request("http://" + domain + ".ytmnd.com/info/" + ytmnd_id + "/json", headers={'User-Agent': 'Mozilla/5.0'}) with urlopen(req) as response: ytmnd_info = json.load(response) except (URLError, HTTPError) 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("