您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Download your saved posts or directly posts from your feed with support for Direct links (png, jpg, gif, mp4...), (Gypcat kinda), Redgify, Imgur (Only when supplied with an API key)
// ==UserScript== // @name Reddit Downloader // @namespace https://github.com/felixire/Reddit-Downloader // @version 0.2.4 // @description Download your saved posts or directly posts from your feed with support for Direct links (png, jpg, gif, mp4...), (Gypcat kinda), Redgify, Imgur (Only when supplied with an API key) // @author felixire // @match https://www.reddit.com/* // @match https://reddit.com/* // @match https://www.old.reddit.com/* // @match https://old.reddit.com/* // @match https://www.new.reddit.com/* // @match https://new.reddit.com/* // @require https://gf.qytechs.cn/scripts/28536-gm-config/code/GM_config.js?version=184529 // @grant GM_download // @grant GM_notification // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // ==/UserScript== const DEBUG = false; let _LastDownloadedID = GM_getValue('LastDownloaded', ''); let _IsOnUserPage = false; //#region Helpers function wait(ms) { return new Promise(res => setTimeout(res, ms)); } function randomName(length = 16) { let chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; let name = ''; for (let index = 0; index < length; index++) { let ind = Math.floor(Math.random() * chars.length); name += chars.charAt(ind); } return name; } function waitForElements(selectors, timeout = 1000) { return new Promise(async (res, rej) => { let time = 0; if (!Array.isArray(selectors)) selectors = [selectors]; let eles = []; selectors.forEach(async (sel, i) => { let ele = document.querySelector(sel.trim()); while (ele == null || ele == undefined) { if (time >= timeout) { //console.error("Timed out while waiting for: " + sel); rej("Timed out while waiting for: " + sel); return; } time += 10; await wait(10); ele = document.querySelector(sel); } eles.push(ele); if (i == (selectors.length - 1)) res(eles); return; }); }) } function createNotification(title, text) { GM_notification({ title, text, timeout: 5000 }) } function isOldReddit(){ return new Promise((res) => { if (window.location.href.includes('old.reddit.com')){ res(true); return true; } if (window.location.href.includes('new.reddit.com')){ res(false); return false; } //Old page waitForElements('.redesign-beta-optin', 5000) .then(() => { res(true); return true; }).catch(() => {}) //New page waitForElements('#SHORTCUT_FOCUSABLE_DIV', 5000) .then(() => { res(false); return false; }).catch(() => {}) }) } //#endregion //#region Supported Downloaders class DownloadSite { constructor() { } checkSupport(href) { throw new Error('NOT IMPLEMENTD!'); } async downloadImages(info, folder = '') { return new Promise(async res => { let url = this._removeParams(info.url); let links = await this.getDownloadLinks(url); if (!Array.isArray(links)) links = [links]; if (links.length > 1) await this._downloadBulk(links, folder, `${randomName()}`); else await this._downloadBulk(links, folder); // if(links.length > 1) // else // this._download(links[0], folder); res(); }); } /** * @return {Promise<Array<string>>} */ getDownloadLinks(href) { throw new Error('NOT IMPLEMENTD!'); } _getExtension(href) { return href.replace(/.*\./, ''); } _getParams(href) { return href.match(/\?.*/gim); } _removeAmpSymbols(href) { return href.replace(/amp;/gim, ''); } _removeParams(href) { return href.replace(/\?.*/gim, ''); } async _downloadBulk(links, folder = '', locationAppend = '') { return new Promise(async res => { for (let index = 0; index < links.length; index++) { const url = links[index]; const params = this._getParams(url); const pureUrl = this._removeParams(url); const name = (links.length > 1 ? `[${index}]` : '') + `${randomName()}`; this._download({ url: url, folder, locationAppend, name, extension: this._getExtension(pureUrl) }); await wait(100); } res(); }) } //_download(url, folder='', name=randomName(), locationAppend=''){ _download(infos) { let folder = ((infos.folder != '' && infos.folder != null && infos.folder != undefined && infos.folder != '') ? `/${infos.folder}` : ''); let locationAppend = ((infos.locationAppend != null && infos.locationAppend != undefined && infos.locationAppend != '') ? `/${infos.locationAppend}` : ''); let name = (infos.name != '' && infos.name != null && infos.name != undefined) ? `/${infos.name}` : '/' + randomName(); let downloadLocation = GM_config.get('download_location').substr(-1) == '/' ? GM_config.get('download_location').slice(0, -1) : GM_config.get('download_location'); let details = { url: infos.url, name: downloadLocation + folder + locationAppend + name + '.' + infos.extension, saveAs: false } GM_download(details); } } class DirectDownload extends DownloadSite { constructor() { super(); this.supportedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'gifv', 'mp4', 'mp3']; } checkSupport(href) { return this.supportedExtensions.includes(this._getExtension(href)); } getDownloadLinks(href) { if (href.endsWith('.gifv')) href = href.replace('gifv', 'mp4'); return [href]; } } class RedditGallery extends DownloadSite { constructor() { super(); } async downloadImages(info, folder) { return new Promise(async res => { let postJSON = await window.RedditDownloader._getPostData(info.og_url); let media_metadata = postJSON[0].data.children[0].data.media_metadata; if (media_metadata == null || media_metadata == undefined) { media_metadata = postJSON[0].data.children[0].data.crosspost_parent_list[0].media_metadata; } let media_keys = Object.keys(media_metadata); let links = []; for (let i = 0; i < media_keys.length; i++) { const key = media_keys[i]; const url = media_metadata[key].s.u; links.push(this._removeAmpSymbols(url)); } if (!Array.isArray(links)) links = [links]; if (links.length > 1) await this._downloadBulk(links, folder, `${randomName()}`); else await this._downloadBulk(links, folder); // if(links.length > 1) // else{ // let infos = {} // this._download(links[0], folder); // } res(); }); } checkSupport(href) { console.log('-----------------') console.log(href.includes('reddit.com/gallery/')); return (href.includes('reddit.com/gallery/')); } } class Imgur extends DownloadSite { constructor() { super(); this._ApiEndpoint = 'https://api.imgur.com/3/'; } checkSupport(href) { return (href.includes('imgur.com/') && !href.includes('i.imgur.com/')); } getDownloadLinks(href) { let id = href.replace(/.*\//igm, ''); let isAlbum = href.replace(/.*imgur.com\//igm, '').startsWith('a'); return isAlbum ? this.getAlbumLinks(id) : this.getGalleryLinks(id); } getGalleryLinks(galleryID) { return new Promise((res, rej) => { if (!GM_config.get('imgur_client_id')) { rej('NO CLIENT ID!'); return; } fetch(this._ApiEndpoint + `gallery/${galleryID}/images?client_id=${GM_config.get('imgur_client_id')}`) .then(body => body.text()) .then(text => { let data = JSON.parse(text); if (data.data.images == undefined) { res([]); return; } let links = data.data.images.reduce((a, c) => { console.log(a, c); a.push(c.link); return a; }, []); console.log(links) res(links); }); }) } getAlbumLinks(albumID) { return new Promise((res, rej) => { if (!GM_config.get('imgur_client_id')) { rej('NO CLIENT ID!'); return; } fetch(this._ApiEndpoint + `album/${albumID}/images?client_id=${GM_config.get('imgur_client_id')}`) .then(body => body.text()) .then(text => { let data = JSON.parse(text); let links = data.data.reduce((a, c) => { a.push(c.link); return a; }, []); res(links); }); }) } } class Gfycat extends DownloadSite { constructor() { super(); } checkSupport(href) { return (href.includes('//gfycat.com/') || href.includes('www.gfycat.com/')); } getDownloadLinks(href) { //media => oembed => thumbnail_url //https://thumbs.gfycat.com/<ID>-size_restricted.gif return href.replace('thumbs', 'giant').replace('-size_restricted.gif', '.mp4'); } } class Redgifs extends DownloadSite { constructor() { super(); this.gypcatList = [ 'aardvark', 'aardwolf', 'abalone', 'abyssiniancat', 'abyssiniangroundhornbill', 'acaciarat', 'achillestang', 'acornbarnacle', 'acornweevil', 'acornwoodpecker', 'acouchi', 'adamsstaghornedbeetle', 'addax', 'adder', 'adeliepenguin', 'admiralbutterfly', 'adouri', 'aegeancat', 'affenpinscher', 'afghanhound', 'africanaugurbuzzard', 'africanbushviper', 'africancivet', 'africanclawedfrog', 'africanelephant', 'africanfisheagle', 'africangoldencat', 'africangroundhornbill', 'africanharrierhawk', 'africanhornbill', 'africanjacana', 'africanmolesnake', 'africanparadiseflycatcher', 'africanpiedkingfisher', 'africanporcupine', 'africanrockpython', 'africanwildcat', 'africanwilddog', 'agama', 'agouti', 'aidi', 'airedale', 'airedaleterrier', 'akitainu', 'alabamamapturtle', 'alaskajingle', 'alaskanhusky', 'alaskankleekai', 'alaskanmalamute', 'albacoretuna', 'albatross', 'albertosaurus', 'albino', 'aldabratortoise', 'allensbigearedbat', 'alleycat', 'alligator', 'alligatorgar', 'alligatorsnappingturtle', 'allosaurus', 'alpaca', 'alpinegoat', 'alpineroadguidetigerbeetle', 'altiplanochinchillamouse', 'amazondolphin', 'amazonparrot', 'amazontreeboa', 'amberpenshell', 'ambushbug', 'americanalligator', 'americanavocet', 'americanbadger', 'americanbittern', 'americanblackvulture', 'americanbobtail', 'americanbulldog', 'americancicada', 'americancrayfish', 'americancreamdraft', 'americancrocodile', 'americancrow', 'americancurl', 'americangoldfinch', 'americanindianhorse', 'americankestrel', 'americanlobster', 'americanmarten', 'americanpainthorse', 'americanquarterhorse', 'americanratsnake', 'americanredsquirrel', 'americanriverotter', 'americanrobin', 'americansaddlebred', 'americanshorthair', 'americantoad', 'americanwarmblood', 'americanwigeon', 'americanwirehair', 'amethystgemclam', 'amethystinepython', 'amethystsunbird', 'ammonite', 'amoeba', 'amphibian', 'amphiuma', 'amurminnow', 'amurratsnake', 'amurstarfish', 'anaconda', 'anchovy', 'andalusianhorse', 'andeancat', 'andeancockoftherock', 'andeancondor', 'anemone', 'anemonecrab', 'anemoneshrimp', 'angelfish', 'angelwingmussel', 'anglerfish', 'angora', 'angwantibo', 'anhinga', 'ankole', 'ankolewatusi', 'annashummingbird', 'annelid', 'annelida', 'anole', 'anophelesmosquito', 'ant', 'antarcticfurseal', 'antarcticgiantpetrel', 'antbear', 'anteater', 'antelope', 'antelopegroundsquirrel', 'antipodesgreenparakeet', 'antlion', 'anura', 'aoudad', 'apatosaur', 'ape', 'aphid', 'apisdorsatalaboriosa', 'aplomadofalcon', 'appaloosa', 'aquaticleech', 'arabianhorse', 'arabianoryx', 'arabianwildcat', 'aracari', 'arachnid', 'arawana', 'archaeocete', 'archaeopteryx', 'archerfish', 'arcticduck', 'arcticfox', 'arctichare', 'arcticseal', 'arcticwolf', 'argali', 'argentinehornedfrog', 'argentineruddyduck', 'argusfish', 'arieltoucan', 'arizonaalligatorlizard', 'arkshell', 'armadillo', 'armedcrab', 'armednylonshrimp', 'armyant', 'armyworm', 'arrowana', 'arrowcrab', 'arrowworm', 'arthropods', 'aruanas', 'asianconstablebutterfly', 'asiandamselfly', 'asianelephant', 'asianlion', 'asianpiedstarling', 'asianporcupine', 'asiansmallclawedotter', 'asiantrumpetfish', 'asianwaterbuffalo', 'asiaticgreaterfreshwaterclam', 'asiaticlesserfreshwaterclam', 'asiaticmouflon', 'asiaticwildass', 'asp', 'ass', 'assassinbug', 'astarte', 'astrangiacoral', 'atlanticblackgoby', 'atlanticbluetang', 'atlanticridleyturtle', 'atlanticsharpnosepuffer', 'atlanticspadefish', 'atlasmoth', 'attwatersprairiechicken', 'auk', 'auklet', 'aurochs', 'australiancattledog', 'australiancurlew', 'australianfreshwatercrocodile', 'australianfurseal', 'australiankelpie', 'australiankestrel', 'australianshelduck', 'australiansilkyterrier', 'austrianpinscher', 'avians', 'avocet', 'axisdeer', 'axolotl', 'ayeaye', 'aztecant', 'azurevase', 'azurevasesponge', 'azurewingedmagpie', 'babirusa', 'baboon', 'backswimmer', 'bactrian', 'badger', 'bagworm', 'baiji', 'baldeagle', 'baleenwhale', 'balloonfish', 'ballpython', 'bandicoot', 'bangeltiger', 'bantamrooster', 'banteng', 'barasinga', 'barasingha', 'barb', 'barbet', 'barebirdbat', 'barnacle', 'barnowl', 'barnswallow', 'barracuda', 'basenji', 'basil', 'basilisk', 'bass', 'bassethound', 'bat', 'bats', 'beagle', 'bear', 'beardedcollie', 'beardeddragon', 'beauceron', 'beaver', 'bedbug', 'bedlingtonterrier', 'bee', 'beetle', 'bellfrog', 'bellsnake', 'belugawhale', 'bengaltiger', 'bergerpicard', 'bernesemountaindog', 'betafish', 'bettong', 'bichonfrise', 'bighorn', 'bighornedsheep', 'bighornsheep', 'bigmouthbass', 'bilby', 'billygoat', 'binturong', 'bird', 'birdofparadise', 'bison', 'bittern', 'blackandtancoonhound', 'blackbear', 'blackbird', 'blackbuck', 'blackcrappie', 'blackfish', 'blackfly', 'blackfootedferret', 'blacklab', 'blacklemur', 'blackmamba', 'blacknorwegianelkhound', 'blackpanther', 'blackrhino', 'blackrussianterrier', 'blackwidowspider', 'blesbok', 'blobfish', 'blowfish', 'blueandgoldmackaw', 'bluebird', 'bluebottle', 'bluebottlejellyfish', 'bluebreastedkookaburra', 'bluefintuna', 'bluefish', 'bluegill', 'bluejay', 'bluemorphobutterfly', 'blueshark', 'bluet', 'bluetickcoonhound', 'bluetonguelizard', 'bluewhale', 'boa', 'boaconstrictor', 'boar', 'bobcat', 'bobolink', 'bobwhite', 'boilweevil', 'bongo', 'bonobo', 'booby', 'bordercollie', 'borderterrier', 'borer', 'borzoi', 'boto', 'boubou', 'boutu', 'bovine', 'brahmanbull', 'brahmancow', 'brant', 'bream', 'brocketdeer', 'bronco', 'brontosaurus', 'brownbear', 'brownbutterfly', 'bubblefish', 'buck', 'buckeyebutterfly', 'budgie', 'bufeo', 'buffalo', 'bufflehead', 'bug', 'bull', 'bullfrog', 'bullmastiff', 'bumblebee', 'bunny', 'bunting', 'burro', 'bushbaby', 'bushsqueaker', 'bustard', 'butterfly', 'buzzard', 'caecilian', 'caiman', 'caimanlizard', 'calf', 'camel', 'canadagoose', 'canary', 'canine', 'canvasback', 'capeghostfrog', 'capybara', 'caracal', 'cardinal', 'caribou', 'carp', 'carpenterant', 'cassowary', 'cat', 'catbird', 'caterpillar', 'catfish', 'cats', 'cattle', 'caudata', 'cavy', 'centipede', 'cero', 'chafer', 'chameleon', 'chamois', 'chanticleer', 'cheetah', 'chevrotain', 'chick', 'chickadee', 'chicken', 'chihuahua', 'chimneyswift', 'chimpanzee', 'chinchilla', 'chinesecrocodilelizard', 'chipmunk', 'chital', 'chrysalis', 'chrysomelid', 'chuckwalla', 'chupacabra', 'cicada', 'cirriped', 'civet', 'clam', 'cleanerwrasse', 'clingfish', 'clownanemonefish', 'clumber', 'coati', 'cob', 'cobra', 'cock', 'cockatiel', 'cockatoo', 'cockerspaniel', 'cockroach', 'cod', 'coelacanth', 'collardlizard', 'collie', 'colt', 'comet', 'commabutterfly', 'commongonolek', 'conch', 'condor', 'coney', 'conure', 'cony', 'coot', 'cooter', 'copepod', 'copperbutterfly', 'copperhead', 'coqui', 'coral', 'cormorant', 'cornsnake', 'corydorascatfish', 'cottonmouth', 'cottontail', 'cougar', 'cow', 'cowbird', 'cowrie', 'coyote', 'coypu', 'crab', 'crane', 'cranefly', 'crayfish', 'creature', 'cricket', 'crocodile', 'crocodileskink', 'crossbill', 'crow', 'crownofthornsstarfish', 'crustacean', 'cub', 'cuckoo', 'cur', 'curassow', 'curlew', 'cuscus', 'cusimanse', 'cuttlefish', 'cutworm', 'cygnet', 'dachshund', 'daddylonglegs', 'dairycow', 'dalmatian', 'damselfly', 'danishswedishfarmdog', 'darklingbeetle', 'dartfrog', 'darwinsfox', 'dassie', 'dassierat', 'davidstiger', 'deer', 'deermouse', 'degu', 'degus', 'deinonychus', 'desertpupfish', 'devilfish', 'deviltasmanian', 'diamondbackrattlesnake', 'dikdik', 'dikkops', 'dingo', 'dinosaur', 'diplodocus', 'dipper', 'discus', 'dobermanpinscher', 'doctorfish', 'dodo', 'dodobird', 'doe', 'dog', 'dogfish', 'dogwoodclubgall', 'dogwoodtwigborer', 'dolphin', 'donkey', 'dorado', 'dore', 'dorking', 'dormouse', 'dotterel', 'douglasfirbarkbeetle', 'dove', 'dowitcher', 'drafthorse', 'dragon', 'dragonfly', 'drake', 'drever', 'dromaeosaur', 'dromedary', 'drongo', 'duck', 'duckbillcat', 'duckbillplatypus', 'duckling', 'dugong', 'duiker', 'dungbeetle', 'dungenesscrab', 'dunlin', 'dunnart', 'dutchshepherddog', 'dutchsmoushond', 'dwarfmongoose', 'dwarfrabbit', 'eagle', 'earthworm', 'earwig', 'easternglasslizard', 'easternnewt', 'easteuropeanshepherd', 'eastrussiancoursinghounds', 'eastsiberianlaika', 'echidna', 'eel', 'eelelephant', 'eeve', 'eft', 'egg', 'egret', 'eider', 'eidolonhelvum', 'ekaltadeta', 'eland', 'electriceel', 'elephant', 'elephantbeetle', 'elephantseal', 'elk', 'elkhound', 'elver', 'emeraldtreeskink', 'emperorpenguin', 'emperorshrimp', 'emu', 'englishpointer', 'englishsetter', 'equestrian', 'equine', 'erin', 'ermine', 'erne', 'eskimodog', 'esok', 'estuarinecrocodile', 'ethiopianwolf', 'europeanfiresalamander', 'europeanpolecat', 'ewe', 'eyas', 'eyelashpitviper', 'eyra', 'fairybluebird', 'fairyfly', 'falcon', 'fallowdeer', 'fantail', 'fanworms', 'fattaileddunnart', 'fawn', 'feline', 'fennecfox', 'ferret', 'fiddlercrab', 'fieldmouse', 'fieldspaniel', 'finch', 'finnishspitz', 'finwhale', 'fireant', 'firebelliedtoad', 'firecrest', 'firefly', 'fish', 'fishingcat', 'flamingo', 'flatcoatretriever', 'flatfish', 'flea', 'flee', 'flicker', 'flickertailsquirrel', 'flies', 'flounder', 'fluke', 'fly', 'flycatcher', 'flyingfish', 'flyingfox', 'flyinglemur', 'flyingsquirrel', 'foal', 'fossa', 'fowl', 'fox', 'foxhound', 'foxterrier', 'frenchbulldog', 'freshwatereel', 'frigatebird', 'frilledlizard', 'frillneckedlizard', 'fritillarybutterfly', 'frog', 'frogmouth', 'fruitbat', 'fruitfly', 'fugu', 'fulmar', 'funnelweaverspider', 'furseal', 'gadwall', 'galago', 'galah', 'galapagosalbatross', 'galapagosdove', 'galapagoshawk', 'galapagosmockingbird', 'galapagospenguin', 'galapagossealion', 'galapagostortoise', 'gallinule', 'gallowaycow', 'gander', 'gangesdolphin', 'gannet', 'gar', 'gardensnake', 'garpike', 'gartersnake', 'gaur', 'gavial', 'gazelle', 'gecko', 'geese', 'gelada', 'gelding', 'gemsbok', 'gemsbuck', 'genet', 'gentoopenguin', 'gerbil', 'gerenuk', 'germanpinscher', 'germanshepherd', 'germanshorthairedpointer', 'germanspaniel', 'germanspitz', 'germanwirehairedpointer', 'gharial', 'ghostshrimp', 'giantschnauzer', 'gibbon', 'gilamonster', 'giraffe', 'glassfrog', 'globefish', 'glowworm', 'gnat', 'gnatcatcher', 'gnu', 'goa', 'goat', 'godwit', 'goitered', 'goldeneye', 'goldenmantledgroundsquirrel', 'goldenretriever', 'goldfinch', 'goldfish', 'gonolek', 'goose', 'goosefish', 'gopher', 'goral', 'gordonsetter', 'gorilla', 'goshawk', 'gosling', 'gossamerwingedbutterfly', 'gourami', 'grackle', 'grasshopper', 'grassspider', 'grayfox', 'grayling', 'grayreefshark', 'graysquirrel', 'graywolf', 'greatargus', 'greatdane', 'greathornedowl', 'greatwhiteshark', 'grebe', 'greendarnerdragonfly', 'greyhounddog', 'grison', 'grizzlybear', 'grosbeak', 'groundbeetle', 'groundhog', 'grouper', 'grouse', 'grub', 'grunion', 'guanaco', 'guernseycow', 'guillemot', 'guineafowl', 'guineapig', 'gull', 'guppy', 'gypsymoth', 'gyrfalcon', 'hackee', 'haddock', 'hadrosaurus', 'hagfish', 'hairstreak', 'hairstreakbutterfly', 'hake', 'halcyon', 'halibut', 'halicore', 'hamadryad', 'hamadryas', 'hammerheadbird', 'hammerheadshark', 'hammerkop', 'hamster', 'hanumanmonkey', 'hapuka', 'hapuku', 'harborporpoise', 'harborseal', 'hare', 'harlequinbug', 'harpseal', 'harpyeagle', 'harrier', 'harrierhawk', 'hart', 'hartebeest', 'harvestmen', 'harvestmouse', 'hatchetfish', 'hawaiianmonkseal', 'hawk', 'hectorsdolphin', 'hedgehog', 'heifer', 'hellbender', 'hen', 'herald', 'herculesbeetle', 'hermitcrab', 'heron', 'herring', 'heterodontosaurus', 'hind', 'hippopotamus', 'hoatzin', 'hochstettersfrog', 'hog', 'hogget', 'hoiho', 'hoki', 'homalocephale', 'honeybadger', 'honeybee', 'honeycreeper', 'honeyeater', 'hookersealion', 'hoopoe', 'hornbill', 'hornedtoad', 'hornedviper', 'hornet', 'hornshark', 'horse', 'horsechestnutleafminer', 'horsefly', 'horsemouse', 'horseshoebat', 'horseshoecrab', 'hound', 'housefly', 'hoverfly', 'howlermonkey', 'huemul', 'huia', 'human', 'hummingbird', 'humpbackwhale', 'husky', 'hydatidtapeworm', 'hydra', 'hyena', 'hylaeosaurus', 'hypacrosaurus', 'hypsilophodon', 'hyracotherium', 'hyrax', 'iaerismetalmark', 'ibadanmalimbe', 'iberianbarbel', 'iberianchiffchaff', 'iberianemeraldlizard', 'iberianlynx', 'iberianmidwifetoad', 'iberianmole', 'iberiannase', 'ibex', 'ibis', 'ibisbill', 'ibizanhound', 'iceblueredtopzebra', 'icefish', 'icelandgull', 'icelandichorse', 'icelandicsheepdog', 'ichidna', 'ichneumonfly', 'ichthyosaurs', 'ichthyostega', 'icterinewarbler', 'iggypops', 'iguana', 'iguanodon', 'illadopsis', 'ilsamochadegu', 'imago', 'impala', 'imperatorangel', 'imperialeagle', 'incatern', 'inchworm', 'indianabat', 'indiancow', 'indianelephant', 'indianglassfish', 'indianhare', 'indianjackal', 'indianpalmsquirrel', 'indianpangolin', 'indianrhinoceros', 'indianringneckparakeet', 'indianrockpython', 'indianskimmer', 'indianspinyloach', 'indigobunting', 'indigowingedparrot', 'indochinahogdeer', 'indochinesetiger', 'indri', 'indusriverdolphin', 'inexpectatumpleco', 'inganue', 'insect', 'intermediateegret', 'invisiblerail', 'iraniangroundjay', 'iridescentshark', 'iriomotecat', 'irishdraughthorse', 'irishredandwhitesetter', 'irishsetter', 'irishterrier', 'irishwaterspaniel', 'irishwolfhound', 'irrawaddydolphin', 'irukandjijellyfish', 'isabellineshrike', 'isabellinewheatear', 'islandcanary', 'islandwhistler', 'isopod', 'italianbrownbear', 'italiangreyhound', 'ivorybackedwoodswallow', 'ivorybilledwoodpecker', 'ivorygull', 'izuthrush', 'jabiru', 'jackal', 'jackrabbit', 'jaeger', 'jaguar', 'jaguarundi', 'janenschia', 'japanesebeetle', 'javalina', 'jay', 'jellyfish', 'jenny', 'jerboa', 'joey', 'johndory', 'juliabutterfly', 'jumpingbean', 'junco', 'junebug', 'kagu', 'kakapo', 'kakarikis', 'kangaroo', 'karakul', 'katydid', 'kawala', 'kentrosaurus', 'kestrel', 'kid', 'killdeer', 'killerwhale', 'killifish', 'kingbird', 'kingfisher', 'kinglet', 'kingsnake', 'kinkajou', 'kiskadee', 'kissingbug', 'kite', 'kitfox', 'kitten', 'kittiwake', 'kitty', 'kiwi', 'koala', 'koalabear', 'kob', 'kodiakbear', 'koi', 'komododragon', 'koodoo', 'kookaburra', 'kouprey', 'krill', 'kronosaurus', 'kudu', 'kusimanse', 'labradorretriever', 'lacewing', 'ladybird', 'ladybug', 'lamb', 'lamprey', 'langur', 'lark', 'larva', 'laughingthrush', 'lcont', 'leafbird', 'leafcutterant', 'leafhopper', 'leafwing', 'leech', 'lemming', 'lemur', 'leonberger', 'leopard', 'leopardseal', 'leveret', 'lhasaapso', 'lice', 'liger', 'lightningbug', 'limpet', 'limpkin', 'ling', 'lion', 'lionfish', 'littlenightmonkeys', 'lizard', 'llama', 'lobo', 'lobster', 'locust', 'loggerheadturtle', 'longhorn', 'longhornbeetle', 'longspur', 'loon', 'lorikeet', 'loris', 'louse', 'lovebird', 'lowchen', 'lunamoth', 'lungfish', 'lynx', 'lynxÂ', 'macaque', 'macaw', 'macropod', 'madagascarhissingroach', 'maggot', 'magpie', 'maiasaura', 'majungatholus', 'malamute', 'mallard', 'maltesedog', 'mamba', 'mamenchisaurus', 'mammal', 'mammoth', 'manatee', 'mandrill', 'mangabey', 'manta', 'mantaray', 'mantid', 'mantis', 'mantisray', 'manxcat', 'mara', 'marabou', 'marbledmurrelet', 'mare', 'marlin', 'marmoset', 'marmot', 'marten', 'martin', 'massasauga', 'massospondylus', 'mastiff', 'mastodon', 'mayfly', 'meadowhawk', 'meadowlark', 'mealworm', 'meerkat', 'megalosaurus', 'megalotomusquinquespinosus', 'megaraptor', 'merganser', 'merlin', 'metalmarkbutterfly', 'metamorphosis', 'mice', 'microvenator', 'midge', 'milksnake', 'milkweedbug', 'millipede', 'minibeast', 'mink', 'minnow', 'mite', 'moa', 'mockingbird', 'mole', 'mollies', 'mollusk', 'molly', 'monarch', 'mongoose', 'mongrel', 'monkey', 'monkfishÂ', 'monoclonius', 'montanoceratops', 'moorhen', 'moose', 'moray', 'morayeel', 'morpho', 'mosasaur', 'mosquito', 'moth', 'motmot', 'mouflon', 'mountaincat', 'mountainlion', 'mouse', 'mouse / mice', 'mousebird', 'mudpuppy', 'mule', 'mullet', 'muntjac', 'murrelet', 'muskox', 'muskrat', 'mussaurus', 'mussel', 'mustang', 'mutt', 'myna', 'mynah', 'myotisÂ', 'nabarlek', 'nag', 'naga', 'nagapies', 'nakedmolerat', 'nandine', 'nandoo', 'nandu', 'narwhal', 'narwhale', 'natterjacktoad', 'nauplius', 'nautilus', 'needlefish', 'needletail', 'nematode', 'nene', 'neonblueguppy', 'neonbluehermitcrab', 'neondwarfgourami', 'neonrainbowfish', 'neonredguppy', 'neontetra', 'nerka', 'nettlefish', 'newfoundlanddog', 'newt', 'newtnutria', 'nightcrawler', 'nighthawk', 'nightheron', 'nightingale', 'nightjar', 'nijssenissdwarfchihlid', 'nilgai', 'ninebandedarmadillo', 'noctilio', 'noctule', 'noddy', 'noolbenger', 'northerncardinals', 'northernelephantseal', 'northernflyingsquirrel', 'northernfurseal', 'northernhairynosedwombat', 'northernpike', 'northernseahorse', 'northernspottedowl', 'norwaylobster', 'norwayrat', 'nubiangoat', 'nudibranch', 'numbat', 'nurseshark', 'nutcracker', 'nuthatch', 'nutria', 'nyala', 'nymph', 'ocelot', 'octopus', 'okapi', 'olingo', 'olm', 'opossum', 'orangutan', 'orca', 'oregonsilverspotbutterfly', 'oriole', 'oropendola', 'oropendula', 'oryx', 'osprey', 'ostracod', 'ostrich', 'otter', 'ovenbird', 'owl', 'owlbutterfly', 'ox', 'oxen', 'oxpecker', 'oyster', 'ozarkbigearedbat', 'pacaÂ', 'pachyderm', 'pacificparrotlet', 'paddlefish', 'paintedladybutterfly', 'panda', 'pangolin', 'panther', 'paperwasp', 'papillon', 'parakeet', 'parrot', 'partridge', 'peacock', 'peafowl', 'peccary', 'pekingese', 'pelican', 'pelicinuspetrel', 'penguin', 'perch', 'peregrinefalcon', 'pewee', 'phalarope', 'pharaohhound', 'pheasant', 'phoebe', 'phoenix', 'pig', 'pigeon', 'piglet', 'pika', 'pike', 'pikeperchÂ', 'pilchard', 'pinemarten', 'pinkriverdolphin', 'pinniped', 'pintail', 'pipistrelle', 'pipit', 'piranha', 'pitbull', 'pittabird', 'plainsqueaker', 'plankton', 'planthopper', 'platypus', 'plover', 'polarbear', 'polecat', 'polliwog', 'polyp', 'polyturator', 'pomeranian', 'pondskater', 'pony', 'pooch', 'poodle', 'porcupine', 'porpoise', 'portuguesemanofwar', 'possum', 'prairiedog', 'prawn', 'prayingmantid', 'prayingmantis', 'primate', 'pronghorn', 'pseudodynerusquadrisectus', 'ptarmigan', 'pterodactyls', 'pterosaurs', 'puffer', 'pufferfish', 'puffin', 'pug', 'pullet', 'puma', 'pupa', 'pupfish', 'puppy', 'purplemarten', 'pussycat', 'pygmy', 'python', 'quadrisectus', 'quagga', 'quahog', 'quail', 'queenalexandrasbirdwing', 'queenalexandrasbirdwingbutterfly', 'queenant', 'queenbee', 'queenconch', 'queenslandgrouper', 'queenslandheeler', 'queensnake', 'quelea', 'quetzal', 'quetzalcoatlus', 'quillback', 'quinquespinosus', 'quokka', 'quoll', 'rabbit', 'rabidsquirrel', 'raccoon', 'racer', 'racerunner', 'ragfish', 'rail', 'rainbowfish', 'rainbowlorikeet', 'rainbowtrout', 'ram', 'raptors', 'rasbora', 'rat', 'ratfish', 'rattail', 'rattlesnake', 'raven', 'ray', 'redhead', 'redheadedwoodpecker', 'redpoll', 'redstart', 'redtailedhawk', 'reindeer', 'reptile', 'reynard', 'rhea', 'rhesusmonkey', 'rhino', 'rhinoceros', 'rhinocerosbeetle', 'rhodesianridgeback', 'ringtailedlemur', 'ringworm', 'riograndeescuerzo', 'roach', 'roadrunner', 'roan', 'robberfly', 'robin', 'rockrat', 'rodent', 'roebuck', 'roller', 'rook', 'rooster', 'rottweiler', 'sable', 'sableantelope', 'sablefishÂ', 'saiga', 'sakimonkey', 'salamander', 'salmon', 'saltwatercrocodile', 'sambar', 'samoyeddog', 'sandbarshark', 'sanddollar', 'sanderling', 'sandpiper', 'sapsucker', 'sardine', 'sawfish', 'scallop', 'scarab', 'scarletibis', 'scaup', 'schapendoes', 'schipperke', 'schnauzer', 'scorpion', 'scoter', 'screamer', 'seabird', 'seagull', 'seahog', 'seahorse', 'seal', 'sealion', 'seamonkey', 'seaslug', 'seaurchin', 'senegalpython', 'seriema', 'serpent', 'serval', 'shark', 'shearwater', 'sheep', 'sheldrake', 'shelduck', 'shibainu', 'shihtzu', 'shorebird', 'shoveler', 'shrew', 'shrike', 'shrimp', 'siamang', 'siamesecat', 'siberiantiger', 'sidewinder', 'sifaka', 'silkworm', 'silverfish', 'silverfox', 'silversidefish', 'siskin', 'skimmer', 'skink', 'skipper', 'skua', 'skunk', 'skylark', 'sloth', 'slothbear', 'slug', 'smelts', 'smew', 'snail', 'snake', 'snipe', 'snoutbutterfly', 'snowdog', 'snowgeese', 'snowleopard', 'snowmonkey', 'snowyowl', 'sockeyesalmon', 'solenodon', 'solitaire', 'songbird', 'sora', 'southernhairnosedwombat', 'sow', 'spadefoot', 'sparrow', 'sphinx', 'spider', 'spidermonkey', 'spiketail', 'spittlebug', 'sponge', 'spoonbill', 'spotteddolphin', 'spreadwing', 'springbok', 'springpeeper', 'springtail', 'squab', 'squamata', 'squeaker', 'squid', 'squirrel', 'stag', 'stagbeetle', 'stallion', 'starfish', 'starling', 'steed', 'steer', 'stegosaurus', 'stickinsect', 'stickleback', 'stilt', 'stingray', 'stinkbug', 'stinkpot', 'stoat', 'stonefly', 'stork', 'stud', 'sturgeon', 'sugarglider', 'sulphurbutterfly', 'sunbear', 'sunbittern', 'sunfish', 'swallow', 'swallowtail', 'swallowtailbutterfly', 'swan', 'swellfish', 'swift', 'swordfish', 'tadpole', 'tahr', 'takin', 'tamarin', 'tanager', 'tapaculo', 'tapeworm', 'tapir', 'tarantula', 'tarpan', 'tarsier', 'taruca', 'tasmaniandevil', 'tasmaniantiger', 'tattler', 'tayra', 'teal', 'tegus', 'teledu', 'tench', 'tenrec', 'termite', 'tern', 'terrapin', 'terrier', 'thoroughbred', 'thrasher', 'thrip', 'thrush', 'thunderbird', 'thylacine', 'tick', 'tiger', 'tigerbeetle', 'tigermoth', 'tigershark', 'tilefish', 'tinamou', 'titi', 'titmouse', 'toad', 'toadfish', 'tomtitÂ', 'topi', 'tortoise', 'toucan', 'towhee', 'tragopan', 'treecreeper', 'trex', 'triceratops', 'trogon', 'trout', 'trumpeterbird', 'trumpeterswan', 'tsetsefly', 'tuatara', 'tuna', 'turaco', 'turkey', 'turnstone', 'turtle', 'turtledove', 'uakari', 'ugandakob', 'uintagroundsquirrel', 'ulyssesbutterfly', 'umbrellabird', 'umbrette', 'unau', 'ungulate', 'unicorn', 'upupa', 'urchin', 'urial', 'uromastyxmaliensis', 'uromastyxspinipes', 'urson', 'urubu', 'urus', 'urutu', 'urva', 'utahprairiedog', 'vampirebat', 'vaquita', 'veery', 'velociraptor', 'velvetcrab', 'velvetworm', 'venomoussnake', 'verdin', 'vervet', 'viceroybutterfly', 'vicuna', 'viper', 'viperfish', 'vipersquid', 'vireo', 'virginiaopossum', 'vixen', 'vole', 'volvox', 'vulpesvelox', 'vulpesvulpes', 'vulture', 'walkingstick', 'wallaby', 'wallaroo', 'walleye', 'walrus', 'warbler', 'warthog', 'wasp', 'waterboatman', 'waterbuck', 'waterbuffalo', 'waterbug', 'waterdogs', 'waterdragons', 'watermoccasin', 'waterstrider', 'waterthrush', 'wattlebird', 'watussi', 'waxwing', 'weasel', 'weaverbird', 'weevil', 'westafricanantelope', 'whale', 'whapuku', 'whelp', 'whimbrel', 'whippet', 'whippoorwill', 'whitebeakeddolphin', 'whiteeye', 'whitepelican', 'whiterhino', 'whitetaileddeer', 'whitetippedreefshark', 'whooper', 'whoopingcrane', 'widgeon', 'widowspider', 'wildcat', 'wildebeast', 'wildebeest', 'willet', 'wireworm', 'wisent', 'wobbegongshark', 'wolf', 'wolfspider', 'wolverine', 'wombat', 'woodborer', 'woodchuck', 'woodcock', 'woodnymphbutterfly', 'woodpecker', 'woodstorks', 'woollybearcaterpillar', 'worm', 'wrasse', 'wreckfish', 'wren', 'wrenchbird', 'wryneck', 'wuerhosaurus', 'wyvern', 'xanclomys', 'xanthareel', 'xantus', 'xantusmurrelet', 'xeme', 'xenarthra', 'xenoposeidon', 'xenops', 'xenopterygii', 'xenopus', 'xenotarsosaurus', 'xenurine', 'xenurusunicinctus', 'xerus', 'xiaosaurus', 'xinjiangovenator', 'xiphias', 'xiphiasgladius', 'xiphosuran', 'xoloitzcuintli', 'xoni', 'xrayfish', 'xraytetra', 'xuanhanosaurus', 'xuanhuaceratops', 'xuanhuasaurus', 'yaffle', 'yak', 'yapok', 'yardant', 'yearling', 'yellowbelliedmarmot', 'yellowbellylizard', 'yellowhammer', 'yellowjacket', 'yellowlegs', 'yellowthroat', 'yellowwhitebutterfly', 'yeti', 'ynambu', 'yorkshireterrier', 'yosemitetoad', 'yucker', 'zander', 'zanzibardaygecko', 'zebra', 'zebradove', 'zebrafinch', 'zebrafish', 'zebralongwingbutterfly', 'zebraswallowtailbutterfly', 'zebratailedlizard', 'zebu', 'zenaida', 'zeren', 'zethusspinipes', 'zethuswasp', 'zigzagsalamander', 'zonetailedpigeon', 'zooplankton', 'zopilote', 'zorilla', 'abandoned', 'able', 'absolute', 'academic', 'acceptable', 'acclaimed', 'accomplished', 'accurate', 'aching', 'acidic', 'acrobatic', 'adorable', 'adventurous', 'babyish', 'back', 'bad', 'baggy', 'bare', 'barren', 'basic', 'beautiful', 'belated', 'beloved', 'calculating', 'calm', 'candid', 'canine', 'capital', 'carefree', 'careful', 'careless', 'caring', 'cautious', 'cavernous', 'celebrated', 'charming', 'damaged', 'damp', 'dangerous', 'dapper', 'daring', 'dark', 'darling', 'dazzling', 'dead', 'deadly', 'deafening', 'dear', 'dearest', 'each', 'eager', 'early', 'earnest', 'easy', 'easygoing', 'ecstatic', 'edible', 'educated', 'fabulous', 'failing', 'faint', 'fair', 'faithful', 'fake', 'familiar', 'famous', 'fancy', 'fantastic', 'far', 'faraway', 'farflung', 'faroff', 'gargantuan', 'gaseous', 'general', 'generous', 'gentle', 'genuine', 'giant', 'giddy', 'gigantic', 'hairy', 'half', 'handmade', 'handsome', 'handy', 'happy', 'happygolucky', 'hard', 'icky', 'icy', 'ideal', 'idealistic', 'identical', 'idiotic', 'idle', 'idolized', 'ignorant', 'ill', 'illegal', 'jaded', 'jagged', 'jampacked', 'kaleidoscopic', 'keen', 'lame', 'lanky', 'large', 'last', 'lasting', 'late', 'lavish', 'lawful', 'mad', 'madeup', 'magnificent', 'majestic', 'major', 'male', 'mammoth', 'married', 'marvelous', 'naive', 'narrow', 'nasty', 'natural', 'naughty', 'obedient', 'obese', 'oblong', 'oblong', 'obvious', 'occasional', 'oily', 'palatable', 'pale', 'paltry', 'parallel', 'parched', 'partial', 'passionate', 'past', 'pastel', 'peaceful', 'peppery', 'perfect', 'perfumed', 'quaint', 'qualified', 'radiant', 'ragged', 'rapid', 'rare', 'rash', 'raw', 'recent', 'reckless', 'rectangular', 'sad', 'safe', 'salty', 'same', 'sandy', 'sane', 'sarcastic', 'sardonic', 'satisfied', 'scaly', 'scarce', 'scared', 'scary', 'scented', 'scholarly', 'scientific', 'scornful', 'scratchy', 'scrawny', 'second', 'secondary', 'secondhand', 'secret', 'selfassured', 'selfish', 'selfreliant', 'sentimental', 'talkative', 'tall', 'tame', 'tan', 'tangible', 'tart', 'tasty', 'tattered', 'taut', 'tedious', 'teeming', 'ugly', 'ultimate', 'unacceptable', 'unaware', 'uncomfortable', 'uncommon', 'unconscious', 'understated', 'unequaled', 'vacant', 'vague', 'vain', 'valid', 'wan', 'warlike', 'warm', 'warmhearted', 'warped', 'wary', 'wasteful', 'watchful', 'waterlogged', 'watery', 'wavy', 'yawning', 'yearly', 'zany', 'false', 'active', 'actual', 'adept', 'admirable', 'admired', 'adolescent', 'adorable', 'adored', 'advanced', 'affectionate', 'afraid', 'aged', 'aggravating', 'beneficial', 'best', 'better', 'bewitched', 'big', 'bighearted', 'biodegradable', 'bitesized', 'bitter', 'black', 'cheap', 'cheerful', 'cheery', 'chief', 'chilly', 'chubby', 'circular', 'classic', 'clean', 'clear', 'clearcut', 'clever', 'close', 'closed', 'decent', 'decimal', 'decisive', 'deep', 'defenseless', 'defensive', 'defiant', 'deficient', 'definite', 'definitive', 'delayed', 'delectable', 'delicious', 'elaborate', 'elastic', 'elated', 'elderly', 'electric', 'elegant', 'elementary', 'elliptical', 'embarrassed', 'fast', 'fat', 'fatal', 'fatherly', 'favorable', 'favorite', 'fearful', 'fearless', 'feisty', 'feline', 'female', 'feminine', 'few', 'fickle', 'gifted', 'giving', 'glamorous', 'glaring', 'glass', 'gleaming', 'gleeful', 'glistening', 'glittering', 'hardtofind', 'harmful', 'harmless', 'harmonious', 'harsh', 'hasty', 'hateful', 'haunting', 'illfated', 'illinformed', 'illiterate', 'illustrious', 'imaginary', 'imaginative', 'immaculate', 'immaterial', 'immediate', 'immense', 'impassioned', 'jaunty', 'jealous', 'jittery', 'key', 'kind', 'lazy', 'leading', 'leafy', 'lean', 'left', 'legal', 'legitimate', 'light', 'masculine', 'massive', 'mature', 'meager', 'mealy', 'mean', 'measly', 'meaty', 'medical', 'mediocre', 'nautical', 'near', 'neat', 'necessary', 'needy', 'odd', 'oddball', 'offbeat', 'offensive', 'official', 'old', 'periodic', 'perky', 'personal', 'pertinent', 'pesky', 'pessimistic', 'petty', 'phony', 'physical', 'piercing', 'pink', 'pitiful', 'plain', 'quarrelsome', 'quarterly', 'ready', 'real', 'realistic', 'reasonable', 'red', 'reflecting', 'regal', 'regular', 'separate', 'serene', 'serious', 'serpentine', 'several', 'severe', 'shabby', 'shadowy', 'shady', 'shallow', 'shameful', 'shameless', 'sharp', 'shimmering', 'shiny', 'shocked', 'shocking', 'shoddy', 'short', 'shortterm', 'showy', 'shrill', 'shy', 'sick', 'silent', 'silky', 'tempting', 'tender', 'tense', 'tepid', 'terrible', 'terrific', 'testy', 'thankful', 'that', 'these', 'uneven', 'unfinished', 'unfit', 'unfolded', 'unfortunate', 'unhappy', 'unhealthy', 'uniform', 'unimportant', 'unique', 'valuable', 'vapid', 'variable', 'vast', 'velvety', 'weak', 'wealthy', 'weary', 'webbed', 'wee', 'weekly', 'weepy', 'weighty', 'weird', 'welcome', 'welldocumented', 'yellow', 'zealous', 'aggressive', 'agile', 'agitated', 'agonizing', 'agreeable', 'ajar', 'alarmed', 'alarming', 'alert', 'alienated', 'alive', 'all', 'altruistic', 'blackandwhite', 'bland', 'blank', 'blaring', 'bleak', 'blind', 'blissful', 'blond', 'blue', 'blushing', 'cloudy', 'clueless', 'clumsy', 'cluttered', 'coarse', 'cold', 'colorful', 'colorless', 'colossal', 'comfortable', 'common', 'compassionate', 'competent', 'complete', 'delightful', 'delirious', 'demanding', 'dense', 'dental', 'dependable', 'dependent', 'descriptive', 'deserted', 'detailed', 'determined', 'devoted', 'different', 'embellished', 'eminent', 'emotional', 'empty', 'enchanted', 'enchanting', 'energetic', 'enlightened', 'enormous', 'filthy', 'fine', 'finished', 'firm', 'first', 'firsthand', 'fitting', 'fixed', 'flaky', 'flamboyant', 'flashy', 'flat', 'flawed', 'flawless', 'flickering', 'gloomy', 'glorious', 'glossy', 'glum', 'golden', 'good', 'goodnatured', 'gorgeous', 'graceful', 'healthy', 'heartfelt', 'hearty', 'heavenly', 'heavy', 'hefty', 'helpful', 'helpless', 'impartial', 'impeccable', 'imperfect', 'imperturbable', 'impish', 'impolite', 'important', 'impossible', 'impractical', 'impressionable', 'impressive', 'improbable', 'joint', 'jolly', 'jovial', 'kindhearted', 'kindly', 'lighthearted', 'likable', 'likely', 'limited', 'limp', 'limping', 'linear', 'lined', 'liquid', 'medium', 'meek', 'mellow', 'melodic', 'memorable', 'menacing', 'merry', 'messy', 'metallic', 'mild', 'negative', 'neglected', 'negligible', 'neighboring', 'nervous', 'new', 'oldfashioned', 'only', 'open', 'optimal', 'optimistic', 'opulent', 'plaintive', 'plastic', 'playful', 'pleasant', 'pleased', 'pleasing', 'plump', 'plush', 'pointed', 'pointless', 'poised', 'polished', 'polite', 'political', 'queasy', 'querulous', 'reliable', 'relieved', 'remarkable', 'remorseful', 'remote', 'repentant', 'required', 'respectful', 'responsible', 'silly', 'silver', 'similar', 'simple', 'simplistic', 'sinful', 'single', 'sizzling', 'skeletal', 'skinny', 'sleepy', 'slight', 'slim', 'slimy', 'slippery', 'slow', 'slushy', 'small', 'smart', 'smoggy', 'smooth', 'smug', 'snappy', 'snarling', 'sneaky', 'sniveling', 'snoopy', 'thick', 'thin', 'third', 'thirsty', 'this', 'thorny', 'thorough', 'those', 'thoughtful', 'threadbare', 'united', 'unkempt', 'unknown', 'unlawful', 'unlined', 'unlucky', 'unnatural', 'unpleasant', 'unrealistic', 'venerated', 'vengeful', 'verifiable', 'vibrant', 'vicious', 'wellgroomed', 'wellinformed', 'welllit', 'wellmade', 'welloff', 'welltodo', 'wellworn', 'wet', 'which', 'whimsical', 'whirlwind', 'whispered', 'yellowish', 'zesty', 'amazing', 'ambitious', 'ample', 'amused', 'amusing', 'anchored', 'ancient', 'angelic', 'angry', 'anguished', 'animated', 'annual', 'another', 'antique', 'bogus', 'boiling', 'bold', 'bony', 'boring', 'bossy', 'both', 'bouncy', 'bountiful', 'bowed', 'complex', 'complicated', 'composed', 'concerned', 'concrete', 'confused', 'conscious', 'considerate', 'constant', 'content', 'conventional', 'cooked', 'cool', 'cooperative', 'difficult', 'digital', 'diligent', 'dim', 'dimpled', 'dimwitted', 'direct', 'disastrous', 'discrete', 'disfigured', 'disgusting', 'disloyal', 'dismal', 'enraged', 'entire', 'envious', 'equal', 'equatorial', 'essential', 'esteemed', 'ethical', 'euphoric', 'flimsy', 'flippant', 'flowery', 'fluffy', 'fluid', 'flustered', 'focused', 'fond', 'foolhardy', 'foolish', 'forceful', 'forked', 'formal', 'forsaken', 'gracious', 'grand', 'grandiose', 'granular', 'grateful', 'grave', 'gray', 'great', 'greedy', 'green', 'hidden', 'hideous', 'high', 'highlevel', 'hilarious', 'hoarse', 'hollow', 'homely', 'impure', 'inborn', 'incomparable', 'incompatible', 'incomplete', 'inconsequential', 'incredible', 'indelible', 'indolent', 'inexperienced', 'infamous', 'infantile', 'joyful', 'joyous', 'jubilant', 'klutzy', 'knobby', 'little', 'live', 'lively', 'livid', 'loathsome', 'lone', 'lonely', 'long', 'milky', 'mindless', 'miniature', 'minor', 'minty', 'miserable', 'miserly', 'misguided', 'misty', 'mixed', 'next', 'nice', 'nifty', 'nimble', 'nippy', 'orange', 'orderly', 'ordinary', 'organic', 'ornate', 'ornery', 'poor', 'popular', 'portly', 'posh', 'positive', 'possible', 'potable', 'powerful', 'powerless', 'practical', 'precious', 'present', 'prestigious', 'questionable', 'quick', 'repulsive', 'revolving', 'rewarding', 'rich', 'right', 'rigid', 'ringed', 'ripe', 'sociable', 'soft', 'soggy', 'solid', 'somber', 'some', 'sophisticated', 'sore', 'sorrowful', 'soulful', 'soupy', 'sour', 'spanish', 'sparkling', 'sparse', 'specific', 'spectacular', 'speedy', 'spherical', 'spicy', 'spiffy', 'spirited', 'spiteful', 'splendid', 'spotless', 'spotted', 'spry', 'thrifty', 'thunderous', 'tidy', 'tight', 'timely', 'tinted', 'tiny', 'tired', 'torn', 'total', 'unripe', 'unruly', 'unselfish', 'unsightly', 'unsteady', 'unsung', 'untidy', 'untimely', 'untried', 'victorious', 'vigilant', 'vigorous', 'villainous', 'violet', 'white', 'whole', 'whopping', 'wicked', 'wide', 'wideeyed', 'wiggly', 'wild', 'willing', 'wilted', 'winding', 'windy', 'young', 'zigzag', 'anxious', 'any', 'apprehensive', 'appropriate', 'apt', 'arctic', 'arid', 'aromatic', 'artistic', 'ashamed', 'assured', 'astonishing', 'athletic', 'brave', 'breakable', 'brief', 'bright', 'brilliant', 'brisk', 'broken', 'bronze', 'brown', 'bruised', 'coordinated', 'corny', 'corrupt', 'costly', 'courageous', 'courteous', 'crafty', 'crazy', 'creamy', 'creative', 'creepy', 'criminal', 'crisp', 'dirty', 'disguised', 'dishonest', 'dismal', 'distant', 'distant', 'distinct', 'distorted', 'dizzy', 'dopey', 'downright', 'dreary', 'even', 'evergreen', 'everlasting', 'every', 'evil', 'exalted', 'excellent', 'excitable', 'exemplary', 'exhausted', 'forthright', 'fortunate', 'fragrant', 'frail', 'frank', 'frayed', 'free', 'french', 'frequent', 'fresh', 'friendly', 'frightened', 'frightening', 'frigid', 'gregarious', 'grim', 'grimy', 'gripping', 'grizzled', 'gross', 'grotesque', 'grouchy', 'grounded', 'honest', 'honorable', 'honored', 'hopeful', 'horrible', 'hospitable', 'hot', 'huge', 'infatuated', 'inferior', 'infinite', 'informal', 'innocent', 'insecure', 'insidious', 'insignificant', 'insistent', 'instructive', 'insubstantial', 'judicious', 'juicy', 'jumbo', 'knotty', 'knowing', 'knowledgeable', 'longterm', 'loose', 'lopsided', 'lost', 'loud', 'lovable', 'lovely', 'loving', 'modern', 'modest', 'moist', 'monstrous', 'monthly', 'monumental', 'moral', 'mortified', 'motherly', 'motionless', 'nocturnal', 'noisy', 'nonstop', 'normal', 'notable', 'noted', 'original', 'other', 'our', 'outgoing', 'outlandish', 'outlying', 'precious', 'pretty', 'previous', 'pricey', 'prickly', 'primary', 'prime', 'pristine', 'private', 'prize', 'probable', 'productive', 'profitable', 'quickwitted', 'quiet', 'quintessential', 'roasted', 'robust', 'rosy', 'rotating', 'rotten', 'rough', 'round', 'rowdy', 'square', 'squeaky', 'squiggly', 'stable', 'staid', 'stained', 'stale', 'standard', 'starchy', 'stark', 'starry', 'steel', 'steep', 'sticky', 'stiff', 'stimulating', 'stingy', 'stormy', 'straight', 'strange', 'strict', 'strident', 'striking', 'striped', 'strong', 'studious', 'stunning', 'tough', 'tragic', 'trained', 'traumatic', 'treasured', 'tremendous', 'tremendous', 'triangular', 'tricky', 'trifling', 'trim', 'untrue', 'unused', 'unusual', 'unwelcome', 'unwieldy', 'unwilling', 'unwitting', 'unwritten', 'upbeat', 'violent', 'virtual', 'virtuous', 'visible', 'winged', 'wiry', 'wise', 'witty', 'wobbly', 'woeful', 'wonderful', 'wooden', 'woozy', 'wordy', 'worldly', 'worn', 'youthful', 'attached', 'attentive', 'attractive', 'austere', 'authentic', 'authorized', 'automatic', 'avaricious', 'average', 'aware', 'awesome', 'awful', 'awkward', 'bubbly', 'bulky', 'bumpy', 'buoyant', 'burdensome', 'burly', 'bustling', 'busy', 'buttery', 'buzzing', 'critical', 'crooked', 'crowded', 'cruel', 'crushing', 'cuddly', 'cultivated', 'cultured', 'cumbersome', 'curly', 'curvy', 'cute', 'cylindrical', 'doting', 'double', 'downright', 'drab', 'drafty', 'dramatic', 'dreary', 'droopy', 'dry', 'dual', 'dull', 'dutiful', 'excited', 'exciting', 'exotic', 'expensive', 'experienced', 'expert', 'extralarge', 'extraneous', 'extrasmall', 'extroverted', 'frilly', 'frivolous', 'frizzy', 'front', 'frosty', 'frozen', 'frugal', 'fruitful', 'full', 'fumbling', 'functional', 'funny', 'fussy', 'fuzzy', 'growing', 'growling', 'grown', 'grubby', 'gruesome', 'grumpy', 'guilty', 'gullible', 'gummy', 'humble', 'humiliating', 'humming', 'humongous', 'hungry', 'hurtful', 'husky', 'intelligent', 'intent', 'intentional', 'interesting', 'internal', 'international', 'intrepid', 'ironclad', 'irresponsible', 'irritating', 'itchy', 'jumpy', 'junior', 'juvenile', 'known', 'kooky', 'kosher', 'low', 'loyal', 'lucky', 'lumbering', 'luminous', 'lumpy', 'lustrous', 'luxurious', 'mountainous', 'muddy', 'muffled', 'multicolored', 'mundane', 'murky', 'mushy', 'musty', 'muted', 'mysterious', 'noteworthy', 'novel', 'noxious', 'numb', 'nutritious', 'nutty', 'onerlooked', 'outrageous', 'outstanding', 'oval', 'overcooked', 'overdue', 'overjoyed', 'profuse', 'proper', 'proud', 'prudent', 'punctual', 'pungent', 'puny', 'pure', 'purple', 'pushy', 'putrid', 'puzzled', 'puzzling', 'quirky', 'quixotic', 'quizzical', 'royal', 'rubbery', 'ruddy', 'rude', 'rundown', 'runny', 'rural', 'rusty', 'stupendous', 'stupid', 'sturdy', 'stylish', 'subdued', 'submissive', 'substantial', 'subtle', 'suburban', 'sudden', 'sugary', 'sunny', 'super', 'superb', 'superficial', 'superior', 'supportive', 'surefooted', 'surprised', 'suspicious', 'svelte', 'sweaty', 'sweet', 'sweltering', 'swift', 'sympathetic', 'trivial', 'troubled', 'trusting', 'trustworthy', 'trusty', 'truthful', 'tubby', 'turbulent', 'twin', 'upright', 'upset', 'urban', 'usable', 'used', 'useful', 'useless', 'utilized', 'utter', 'vital', 'vivacious', 'vivid', 'voluminous', 'worried', 'worrisome', 'worse', 'worst', 'worthless', 'worthwhile', 'worthy', 'wrathful', 'wretched', 'writhing', 'wrong', 'wry', 'yummy', 'true', 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fractal', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrod', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslateblue', 'lightslategray', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumforestgreen', 'mediumgoldenrod', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'navyblue', 'oldlace', 'olive', 'olivedrab', 'opaque', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'transparent', 'turquoise', 'violet', 'violetred', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen' ] } checkSupport(href) { return (href.includes('//redgifs.com/') || href.includes('www.redgifs.com/')); } capatilizeWords(word) { let words = []; let remaing = word; let ind = 0; while (remaing.length > 0 && ind <= remaing.length) { let word = remaing.slice(0, ++ind); if (this.gypcatList.includes(word)) { remaing = remaing.slice(ind); words.push(word); ind = 0; } } return words.map(val => val[0].toUpperCase() + val.slice(1)).join(''); } getDownloadLinks(href) { //media => oembed => thumbnail_url //https://thcf2.redgifs.com/<ID>.mp4 //https://redgifs.com/watch/<ID> let words = href.split('/'); let cWords = this.capatilizeWords(words[words.length - 1]); let url = words.slice(0, words.length - 1); url = url.join('/').replace('www.', '').replace('/watch', '').replace('redgifs', 'thcf2.redgifs') + '/' + cWords + '.mp4' return url; } } const _SupportedSites = [new DirectDownload(), new RedditGallery(), new Imgur(), new Gfycat(), new Redgifs()]; //#endregion //#region Downloader Class class BaseRedditClass { constructor() { } _getSavedPostsData(after = null) { return new Promise((res, rej) => { let username; if (_IsOnUserPage) { username = document.location.href.split('/'); username = username[username.indexOf('user') + 1]; } else if (GM_config.get('reddit_username') != '') { username = _RedditUsername; } fetch(`${window.location.origin}/user/${username}/saved/.json?limit=20${after != null ? '&after=' + after : ''}`) .then(resp => resp.text()) .then(text => res(JSON.parse(text))); }) } _getPostData(url) { return new Promise((res, rej) => { fetch(`${url}/.json`) .then(resp => resp.text()) .then(text => res(JSON.parse(text))); }) } _parseData(data) { return { id: data.data.name, url: data.data.url, og_url: `https://www.reddit.com${data.data.permalink}`, subreddit: data.data.subreddit } } _getFilterArray() { return new Promise((res, rej) => { let str = GM_config.get('create_for_filter'); let arr = str.split(',').map(val => val.trim()); res(arr); }); } async downloadSingle(info, filter = null) { return new Promise(async (res, rej) => { if (filter == null) filter = await this._getFilterArray(); const url = info.url; if (url == undefined) { rej(); return; }; for (let index = 0; index < _SupportedSites.length; index++) { const site = _SupportedSites[index]; if (site.checkSupport(url)) { let folder = null; if (GM_config.get('create_subreddit_folder')) { if (!GM_config.get('create_only_for_selected') || filter.includes(info.subreddit)) { folder = info.subreddit; } } await site.downloadImages(info, folder); await wait(20); break; } } res(); }) } async downloadAll() { console.log('DOWNLOADING!'); //_SupportedSites.forEach(downloader => { // downloader.checkSupport() //}) //Before = newly added to page so page 1 => when using an id you go up the list //Thats why you use Before as Paramter //^^^ Screw that shit am i right //resp.data.after => Pagnation //resp.data.children[].data.name => ID //resp.data.children[].data.url => url //resp.data.children[].data.subreddit => subreddit let running = true; let after = null; let postInfos = []; let first = true; let stopAt = _LastDownloadedID; let filter = await this._getFilterArray(); while (running) { let data = (await this._getSavedPostsData(after)).data; after = data.after; if (after == null || after == 'null') running = false; for (let index = 0; index < data.children.length; index++) { const postData = data.children[index]; const info = this._parseData(postData); if (info.id == stopAt) { running = false; break; } if (first) { first = false; _LastDownloadedID = info.id; GM_setValue('LastDownloaded', info.id); } postInfos.push(info); } } let tmp_title = document.title; for (let index = 0; index < postInfos.length; index++) { document.title = `${index+1}/${postInfos.length}`; const info = postInfos[index]; await this.downloadSingle(info, filter).catch(() => { console.error("Failed to download image!") }); /*const url = info.url; //console.log(`Downloading ${index+1}/${links.length} - ${url}`); if(url == undefined) continue; for (let index = 0; index < _SupportedSites.length; index++) { const site = _SupportedSites[index]; if(site.checkSupport(url)){ let folder = null; if(GM_config.get('create_subreddit_folder')){ if(!GM_config.get('create_only_for_selected') || filter.includes(info.subreddit)){ folder = info.subreddit; } } await site.downloadImages(url, folder); await wait(20); break; } }*/ } createNotification('Reddit Downloader', `Finished downloading ${postInfos.length} Posts!`); document.title = tmp_title; } } class RedditDownloader extends BaseRedditClass { constructor() { super(); //this.addSavedDownloadButton(); //this.addSettingsButton(); this.pageUpdateChecker(); } addSavedDownloadButton() { let aEles = document.querySelectorAll('a'); for (let index = 0; index < aEles.length; index++) { const x = aEles[index]; if (x.innerText.toLowerCase().indexOf('overview') > -1) { console.log(x); let className = x.className; let btn = document.createElement('a'); btn.className = className + ' download'; btn.innerText = 'DOWNLOAD'; btn.onclick = () => { this.downloadAll() }; x.parentNode.appendChild(btn); return true; } } return false; } async addPostDownloadButton() { return new Promise(async (res, rej) => { let postEles = [...document.querySelectorAll('.Post')]; let commentButton = document.querySelector('.icon-comment'); if (commentButton == null || commentButton == undefined) { rej(); return; } let buttonClassName = commentButton.parentElement.parentElement.className; for (let i = 0; i < postEles.length; i++) { const post = postEles[i]; if (post.classList.contains('TMP_DOWNLOAD_ADDED') || post.querySelector('a[Reddit_Downloader="download"]') != null || post.classList.contains('promotedvideolink') || post == undefined) continue; //console.log(post); const link = post.querySelector('a[data-click-id="body"]'); let url; if (link == undefined || link == null) { if (window.location.href.includes('comments')) { url = window.location.href; if (post.children.length < 1 || post.children[0].getAttribute('data-test-id') != 'post-content') continue; } else { continue; } } else { url = link.href } post.classList.add('TMP_DOWNLOAD_ADDED') //TODO clean this shit up let dwnBTN = document.createElement('a'); dwnBTN.className = buttonClassName; dwnBTN.innerText = 'DOWNLOAD'; dwnBTN.setAttribute('Reddit_Downloader', 'download') dwnBTN.onclick = () => { console.log(`Getting Data from post: ${url}`); this._getPostData(url) .then(data => { if (!document.body.contains(post)) { rej(); return; } const info = this._parseData(data[0].data.children[0]); this.downloadSingle(info); }) }; post.querySelector('.icon-comment').parentElement.parentElement.parentNode.appendChild(dwnBTN); // promises.push(this._getPostData(url) // .then(data => { // if(!document.body.contains(post)){ // rej(); // return; // } // const info = this._parseData(data[0].data.children[0]); // // TODO clean this shit up // let dwnBTN = document.createElement('a'); // dwnBTN.className = buttonClassName; // dwnBTN.innerText = 'DOWNLOAD'; // dwnBTN.setAttribute('Reddit_Downloader', 'download') // dwnBTN.onclick = () => this.downloadSingle(info); // post.querySelector('.icon-comment').parentElement.parentElement.parentNode.appendChild(dwnBTN); // }).catch(() => {})); } res(); // Promise.all(promises).then(values => { // res(); // }) }) } async addSettingsButton() { waitForElements('#change-username-tooltip-id', 5000) .then(parent => { let chatButton = parent[0].children[0]; let settingsButton = chatButton.cloneNode(true); settingsButton.setAttribute('title', 'Reddit Downloader Settings'); settingsButton.querySelector('a').href = '#'; settingsButton.querySelector('a').onclick = () => { GM_config.open(); }; //settingsButton.querySelector('svg').setAttribute('viewBox', '0 0 24 24'); settingsButton.querySelector('i').className = "icon icon-settings" //Icon link: https://iconmonstr.com/gear-1-svg/ //settingsButton.querySelector('path').setAttribute('d', 'M24 13.616v-3.232c-1.651-.587-2.694-.752-3.219-2.019v-.001c-.527-1.271.1-2.134.847-3.707l-2.285-2.285c-1.561.742-2.433 1.375-3.707.847h-.001c-1.269-.526-1.435-1.576-2.019-3.219h-3.232c-.582 1.635-.749 2.692-2.019 3.219h-.001c-1.271.528-2.132-.098-3.707-.847l-2.285 2.285c.745 1.568 1.375 2.434.847 3.707-.527 1.271-1.584 1.438-3.219 2.02v3.232c1.632.58 2.692.749 3.219 2.019.53 1.282-.114 2.166-.847 3.707l2.285 2.286c1.562-.743 2.434-1.375 3.707-.847h.001c1.27.526 1.436 1.579 2.019 3.219h3.232c.582-1.636.75-2.69 2.027-3.222h.001c1.262-.524 2.12.101 3.698.851l2.285-2.286c-.744-1.563-1.375-2.433-.848-3.706.527-1.271 1.588-1.44 3.221-2.021zm-12 2.384c-2.209 0-4-1.791-4-4s1.791-4 4-4 4 1.791 4 4-1.791 4-4 4z'); parent[0].appendChild(settingsButton); }) .catch(err => { this.addSettingsButton(); }); } async pageUpdateChecker() { let isAdded = false; let username = await this.getUsername(); while (true) { await wait(50); _IsOnUserPage = window.location.href.includes('reddit.com/user/' + username); if (true) { if(!_IsOnUserPage) isAdded = false; if (window.RedditDownloader != undefined) await window.RedditDownloader.addPostDownloadButton().catch(() => {}); } if (!isAdded && _IsOnUserPage) { if (window.RedditDownloader != undefined) { await wait(50); isAdded = window.RedditDownloader.addSavedDownloadButton(); } } } } async getUsername() { return new Promise(async (res, rej) => { let usernameEle = []; while (usernameEle == undefined || usernameEle == null || usernameEle.length == 0) { usernameEle = await waitForElements('#email-collection-tooltip-id', 5000); console.log("CALLED", usernameEle); } res(usernameEle[0].innerText.split('\n')[0]); }) } } class OldRedditDownloader extends BaseRedditClass { constructor() { super(); //this.addSavedDownloadButton(); this.addSettingsButton(); this.pageUpdateChecker(); } async addSavedDownloadButton() { return new Promise(async (res) => { waitForElements('.tabmenu') .then(ele => { let tabmenu = ele[0]; let downloadLi = document.createElement('li'); let downloadA = document.createElement('a'); downloadA.classList.add('choice'); downloadA.innerHTML = 'Download'; downloadA.style.cursor = 'pointer'; downloadA.onclick = () => { this.downloadAll(); } downloadLi.appendChild(downloadA); tabmenu.appendChild(downloadLi); }) .catch(() => { res(false); }) }) } async addPostDownloadButton() { return new Promise(async (res, rej) => { let postEles = [...document.querySelectorAll('.thing[data-subreddit-prefixed]')]; for (let index = 0; index < postEles.length; index++) { const post = postEles[index]; if (post.classList.contains('TMP_DOWNLOAD_ADDED') || post.querySelector('a[Reddit_Downloader="download"]') != null || post.classList.contains('promotedvideolink') || post == undefined) continue; const link = post.querySelector('a[data-event-action="comments"]'); let url = link; post.classList.add('TMP_DOWNLOAD_ADDED') const buttons = post.querySelector('.flat-list.buttons'); const downloadButtonLi = document.createElement('li'); downloadButtonLi.classList.add('download-button'); const downloadButtonA = document.createElement('a'); downloadButtonA.innerHTML = 'Download'; downloadButtonA.setAttribute('Reddit_Downloader', 'download'); downloadButtonA.onclick = () => { console.log(`Getting Data from post: ${url}`); this._getPostData(url) .then(data => { if (!document.body.contains(post)) { rej(); return; } const info = this._parseData(data[0].data.children[0]); this.downloadSingle(info); }) } downloadButtonLi.appendChild(downloadButtonA); buttons.appendChild(downloadButtonLi); } res(); }) } async addSettingsButton() { waitForElements('.tabmenu', 5000) .then(parent => { let tabmenu = parent[0]; let downloadLi = document.createElement('li'); let downloadA = document.createElement('a'); downloadA.classList.add('choice'); downloadA.innerHTML = 'RD-Settings'; downloadA.style.cursor = 'pointer'; downloadA.onclick = () => { GM_config.open(); } downloadLi.appendChild(downloadA); tabmenu.appendChild(downloadLi); }) .catch(() => { this.addSettingsButton(); }) } async pageUpdateChecker() { let isAdded = false; let username = await this.getUsername(); while (true) { await wait(50); _IsOnUserPage = window.location.href.includes('reddit.com/user/' + username); if (!_IsOnUserPage) { isAdded = false; if (window.RedditDownloader != undefined) await window.RedditDownloader.addPostDownloadButton().catch(() => {}); } if (!isAdded && _IsOnUserPage) { if (window.RedditDownloader != undefined) { await wait(50); isAdded = await window.RedditDownloader.addSavedDownloadButton(); } } } } async getUsername() { return new Promise(async (res, rej) => { let usernameEle = []; while (usernameEle == undefined || usernameEle == null || usernameEle.length == 0) { usernameEle = await waitForElements('.user', 5000); console.log("CALLED", usernameEle); } res(usernameEle[0].children[0].innerText.trim()); }) } } //#endregion (async () => { if (DEBUG) { //let imgur = new Imgur(); //await imgur.downloadImages('https://imgur.com/a/w0ouO'); //let direct = new DirectDownload(); //await direct.downloadImages('') //let redgif = new Redgifs(); //await redgif.downloadImages(''); } })() window.addEventListener('load', async () => { if (window.top != window.self) { return; } await wait(100); let oldReddit = await isOldReddit(); if (oldReddit) window.RedditDownloader = new OldRedditDownloader(); else{ window.RedditDownloader = new RedditDownloader(); } GM_config.init({ 'id': 'Reddit_Downloader', 'fields': { 'create_subreddit_folder': { 'label': 'Create a subreddit folder which stores all subreddit entries.', 'type': 'checkbox', 'default': false }, 'create_only_for_selected': { 'label': 'Create a folder only if it passes the filter.', 'type': 'checkbox', 'default': false }, 'create_for_filter': { 'label': 'The names of the subreddits to create a folder for. (comma seperated)', 'type': 'text', 'size': 9999999, 'default': '' }, 'reddit_username': { 'label': 'Your Reddit username. Not actually needed right now.', 'type': 'text', 'size': 9999999, 'default': '' }, 'imgur_client_id': { 'label': 'Your imgur Client ID. Incase you want to download imgur images/albums.', 'type': 'text', 'size': 9999999, 'default': '' }, 'download_location': { 'label': 'The download location of the files. Inside of your Downloads folder.', 'type': 'text', 'size': 9999999, 'default': 'Reddit/Stuff/Stuff/' } } }); GM_registerMenuCommand('Manage Settings', (() => { GM_config.open(); })); })
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址