// ==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://greasyfork.org/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();
}));
})