diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 77aebc1..0000000 --- a/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -*~ -typogra* -klasky* -alas* -ROY4L* -dnmyt* -directory* -CarlWinslows* -Coach* diff --git a/LICENSE b/LICENSE deleted file mode 100644 index ae2904b..0000000 --- a/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ - Jollo LNT license - Version 1 - February 2015 - - Copyright, 2015. JOLLO NET NA. - The Jollo IRC Network. - - Vu, fare wanderer, confronted with raw, programmatic instruction - dans la forme la plus pure. A hesitation, troubled to the terms - qui ce license affirme. Par un voyage du explorer le mechanisme - et ponder la fabrication. Voila! La remide: egress sans risque. - - Sans trace (Leave No Trace) via sept principales: - - 0. Modifique language en advance. L'Apposer Jollo LNT license - with copies en distribuer. - - 1. Non responsible pour neglige programme du problematique. - - 2. Non sympathie pour neglige programme du problematique. - - 3. Non permission l'modifique under any circumstance. - - 4. Non permission distribution under any circumstance. - - 5. Respect les programmatic instructions. - - 6. Non interfere avec l'harmonie d'une amitie. - - diff --git a/requirements.txt b/requirements.txt index fe96e16..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +0,0 @@ -httplib2==0.9 -simplejson==3.4.0 diff --git a/ytmnd.js b/ytmnd.js index 2a0a2cb..ad26f42 100644 --- a/ytmnd.js +++ b/ytmnd.js @@ -1,25 +1,42 @@ -(function(){ - var hasWebKit = ('webkitAudioContext' in window) && !('chrome' in window) - var context = new webkitAudioContext() - var request = new XMLHttpRequest() - var source - request.open('GET', url, true) - request.responseType = 'arraybuffer' - request.onload = function() { - context.decodeAudioData(request.response, function(response) { - (function loop(){ - if (source) { - source.start(0) - setTimeout(loop, source.buffer.duration * 1000 - (source.buffer.duration < 2 ? 0 : 60) ) +(function () { + var AudioContext = window.AudioContext || window.webkitAudioContext; + var context = new AudioContext(); + var request = new XMLHttpRequest(); + var source; + var buffer; + + request.open("GET", url, true); + request.responseType = "arraybuffer"; + + request.onload = function () { + context.decodeAudioData( + request.response, + function (response) { + buffer = response; + + function playBuffer() { + source = context.createBufferSource(); + source.buffer = buffer; + source.connect(context.destination); + + source.onended = function () { + playBuffer(); + }; + + source.start(0); } - else { - setTimeout(loop, 0) - } - source = context.createBufferSource() - source.connect(context.destination) - source.buffer = response - })() - }, function () { console.error('The request failed.') } ) - } - request.send() -})() + + playBuffer(); + }, + function (error) { + console.error("Audio decoding failed:", error); + }, + ); + }; + + request.onerror = function () { + console.error("Failed to load audio file"); + }; + + request.send(); +})(); diff --git a/ytmnd.py b/ytmnd.py index ade7b04..3e45f19 100755 --- a/ytmnd.py +++ b/ytmnd.py @@ -1,17 +1,19 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import sys import os import os.path import re import time -import urllib2 -import simplejson +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): + def __init__(self): self.user_mode = False self.media_only = False self.html_only = False @@ -20,64 +22,90 @@ class YTMND: self.print_json = False self.sleep = 5 - # Scrapes sites from the profile page, then fetches them def fetch_user(self, user): if user == "": - print("expecting one ytmnd name, got "+str(sys.argv)) + 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 - ytmnd_name = user - ytmnd_html = urllib2.urlopen("http://ytmnd.com/users/" + ytmnd_name + "/sites").readlines() - domains = [] - + for line in ytmnd_html: if 'profile_link' in line: expr = r"site_link\" href=\"http://(\S+).ytmn(d|sfw)?.com\"" - domain = re.search(expr,line).group(1) - domains.append(domain) + match = re.search(expr, line) + if match: + domain = match.group(1) + domains.append(domain) if self.json_only: if self.media_only: - os.system("mkdir -p %s" % user) + os.makedirs(user, exist_ok=True) os.chdir(user) parsed = [] for domain in domains: - parsed.append( self.fetch_ytmnd( domain ) ) + 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.system("mkdir -p %s" % user) + 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 ) + self.fetch_ytmnd(domain) os.chdir("..") - # Fetches a single subdomain def fetch_ytmnd(self, domain): if domain == "": - print("expecting one ytmnd name, got "+str(sys.argv)) - return + print("expecting one ytmnd name, got " + str(sys.argv)) + return None if not self.print_json: - print "fetching %s" % domain - if not self.sleep: + print("fetching %s" % domain) + if self.sleep: time.sleep(self.sleep) ytmnd_name = domain - ytmnd_html = urllib2.urlopen("http://" + domain + ".ytmnd.com").read() - expr = r"ytmnd.site_id = (\d+);" - ytmnd_id = re.search(expr,ytmnd_html).group(1) - ytmnd_info = simplejson.load(urllib2.urlopen("http://" + domain + ".ytmnd.com/info/" + ytmnd_id + "/json")) + 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 simplejson.dumps(ytmnd_info, sort_keys=True, indent=4 * ' ') + print(json.dumps(ytmnd_info, sort_keys=True, indent=4)) elif self.json_only: if self.media_only: self.fetch_media(ytmnd_info) @@ -92,28 +120,25 @@ class YTMND: return ytmnd_info - # Fetches the gif and mp3 for a post 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 = ytmnd_info['site']['sound']['alternates'].keys()[0] + 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'] - os.system("wget --quiet -O %s %s" % (domain + "." + gif_type, original_gif)) - os.system("wget --quiet -O %s %s" % (domain + "." + wav_type, original_wav)) + subprocess.run(["wget", "--quiet", "-O", f"{domain}.{gif_type}", original_gif]) + subprocess.run(["wget", "--quiet", "-O", f"{domain}.{wav_type}", original_wav]) - # Writes an html file emulating the ytmnd format def write_index(self, ytmnd_info): - - # print simplejson.dumps(ytmnd_info) + domain = ytmnd_info['site']['domain'] bgcolor = ytmnd_info['site']['background']['color'] title = ytmnd_info['site']['description'] @@ -122,93 +147,89 @@ class YTMND: 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 = ytmnd_info['site']['sound']['alternates'].keys()[0] + 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'] - fn = open(domain + ".html", 'w') - fn.write("\n") - fn.write("\n") - fn.write("%s\n" % title) - fn.write("\n") - fn.write("\n") + 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("