# -*- coding: utf-8 -*- # Copyright (C) 2004-2005 Tristan Seligmann and Jonathan Jacobs # Copyright (C) 2012-2014 Bastian Kleineidam # Copyright (C) 2015-2016 Tobias Gruetzmacher from __future__ import absolute_import, division, print_function from ..util import quote from ..scraper import _ParserScraper from ..output import out # SmackJeeves is a crawlers nightmare - users are allowed to edit HTML # directly. Additionally, users use unescaped < characters sometimes, which # breaks the parse tree on libxml2 before 2.9.3... class SmackJeeves(_ParserScraper): ONLY_COMICS = '[contains(@href, "/comics/")]' prevSearch = ( '//a[@class="nav-prev"]' + ONLY_COMICS, '//a[img[re:test(@alt, "prev", "i")]]' + ONLY_COMICS, '//a[img[re:test(@src, "/(prev|back)")]]' + ONLY_COMICS, '//a[re:test(@title, "previous", "i")]' + ONLY_COMICS, '//a[re:test(text(), "prev|back", "i")]' + ONLY_COMICS, '//select[@class="jumpbox"]/preceding::a[1]' + ONLY_COMICS, ) nextSearch = ( '//a[@class="nav-next"]' + ONLY_COMICS, '//a[img[re:test(@alt, "next", "i")]]' + ONLY_COMICS, '//a[img[re:test(@src, "/next", "i")]]' + ONLY_COMICS, '//a[re:test(@title, "next", "i")]' + ONLY_COMICS, '//a[re:test(text(), "next", "i")]' + ONLY_COMICS, '//select[@class="jumpbox"]/following::a[1]' + ONLY_COMICS, ) imageSearch = ( '//img[@id="comic_image"]', '//div[@id="comic-image"]//img', '//img[@id="comic"]', '//div[@id="comicset"]/object/param[@name="movie"]/@value', ) broken_html_bugfix = True def __init__(self, name, host=None, sub=None, adult=False): super(SmackJeeves, self).__init__('SmackJeeves/' + name) if host: self.url = 'http://%s/comics/' % host else: self.url = 'http://%s.smackjeeves.com/comics/' % sub if adult: self.adult = True def starter(self): """Get start URL.""" start = self.url if self.adult: start = 'http://www.smackjeeves.com/mature.php?ref=' + quote(start) data = self.getPage(start) startimg = None if not self.shouldSkipUrl(start, data): startimg = self.fetchUrl(start, data, self.imageSearch) prevurl = self.fetchUrl(start, data, self.prevSearch) data = self.getPage(prevurl) previmg = None if not self.shouldSkipUrl(prevurl, data): previmg = self.fetchUrl(prevurl, data, self.imageSearch) if startimg and previmg and startimg == previmg: out.debug("Matching! %s %s" % (prevurl, self.name)) return prevurl else: return self.fetchUrl(prevurl, data, self.nextSearch) def namer(self, image_url, page_url): parts = page_url.split('/') name = parts[-2] num = parts[-3] return "%s_%s" % (name, num) def shouldSkipUrl(self, url, data): return data.xpath('//img[contains(@src, "/images/image_na.gif")]') @classmethod def getmodules(cls): return ( # do not edit anything below since these entries are generated from # scripts/smackjeeves.py # START AUTOUPDATE cls('20TimesKirby', sub='20xkirby'), cls('2Kingdoms', sub='2kingdoms'), cls('355Days', sub='355days'), cls('AB', sub='alistairandboggart', adult=True), cls('AceOfHearts', sub='aceof-hearts', adult=True), cls('ADoodleADay', sub='adoodleaday'), cls('AGirlAndHerShadow', sub='agirlandhershadow'), cls('AGirlontheServer', sub='girlontheserver'), cls('AKirbyKomic', sub='akirbykomic'), cls('ALaMode', sub='alamode'), cls('AlmostTouching', sub='almosttouching', adult=True), cls('ANGELOU', sub='angelou-esp'), cls('APTComic', sub='aptcomic'), cls('AQuestionOfCharacter', sub='aqoc'), cls('ASongforElise', sub='asongforelise', adult=True), cls('AYuriCollab', sub='ayuricollabbitches', adult=True), cls('Aarrevaara', sub='aarrevaara'), cls('AcidMonday', sub='acidmonday', adult=True), cls('Adalsysla', sub='adalsysla'), cls('AddictiveScience', sub='addictivescience'), cls('AdventuresofLumandFriends', sub='aolaf'), cls('AdventuresoftheWeird', sub='adventuresoftheweird'), cls('AetherTheories', sub='aethertheories'), cls('AgeoftheGray', sub='ageofthegray', adult=True), cls('AllInLOVE', sub='allinlove'), cls('AllStarHeroes', sub='allstarheroes'), cls('AloversRule', sub='aloversrule', adult=True), cls('AlwaysDamnedWebcomic', sub='alwaysdamned', adult=True), cls('AlwaysRainingHere', sub='alwaysraininghere'), cls('Amaravati', sub='amaravati'), cls('AmorVincitOmnia', sub='avo', adult=True), cls('AmsdenEstate', sub='monsterous'), cls('Anathemacomics', sub='anathema-comics'), cls('AngelGuardian', sub='angel-guardian'), cls('AnimalAdventures', sub='animaladventures'), cls('Animayhem', sub='animayhem'), cls('Anythingaboutnothing', host='www.anythingcomic.com'), cls('ArchportCityChronicles', sub='tjs'), cls('Area9', sub='area-9'), cls('AroundtheBlock', sub='aroundtheblock'), cls('ArtofAFantasy', sub='artofafantasy', adult=True), cls('AtArmsLength', sub='atarmslength'), cls('Atlaswebcomic', sub='atlaswebcomic'), cls('Autophobia', sub='autophobia', adult=True), cls('Aware', sub='aware'), cls('AwesomeSauce', sub='tdawesomesauce'), cls('AyaTakeo', sub='ayatakeo'), cls('BLDShortComics', sub='bldshortcomics'), cls('BabysittingFourDemons', sub='babysitting4demons'), cls('Babywhatsyoursign', sub='babywhatsyoursign'), cls('BadassRiz', sub='badassriz'), cls('BallandChain', sub='ballandchain'), cls('Bard', sub='barred'), cls('BassComicAdventures', sub='basscomicadventures'), cls('BattleSequence', sub='battlesequence'), cls('Bearhoney', sub='bear-honey'), cls('BearlyAbel', sub='bearlyabel'), cls('BeautifulLies', sub='beautiful-lies'), cls('BehindTheObsidianMirror', sub='obsidian-mirror', adult=True), cls('Behindtheglasscurtain', sub='g1ass'), cls('BeretCatComics', sub='beretcatcomics'), cls('Bestbrosforever', sub='bestbrosforever'), cls('Betovering', sub='betovering', adult=True), cls('BettencourtHotel', sub='bettencourt'), cls('BetweenLightandDark', sub='bld'), cls('BetweenWorlds', sub='betweenworlds', adult=True), cls('Betwin', sub='be-twin'), cls('BeyondTheOrdinary', sub='bto'), cls('BioRevelation', sub='biorevelation'), cls('Bl3', sub='bl3'), cls('BlackDragon', sub='blackdragon'), cls('BlackFridayRule', sub='blackfridayrule'), cls('BlackSheepcomic', sub='black-sheep'), cls('BlackandBlue', sub='black-and-blue'), cls('Blackdemon', sub='blackdemoncomics'), cls('BleachRedux', sub='bleachredux'), cls('BlindandBlue', sub='blindandblue'), cls('BloodhuntersBirthofavampire', sub='bloodhunters'), cls('BloomaPokemonConquestComic', sub='bloomconquest'), cls('BlueHair', sub='bluehair'), cls('BlueWell', host='www.bluewellcomic.com'), cls('BoilingPointofBrain', sub='bpob'), cls('BoogeyDancingMonkeyPot', sub='monkeypot'), cls('BreachofAgency', sub='breachofagency'), cls('BreakfastonaCliff', sub='boac'), cls('Burn', sub='burn'), cls('ByTheBook', sub='bythebook'), cls('CafeAmargo', sub='cafeamargo'), cls('CafeSuada', sub='cafesuada'), cls('Cambion', sub='cambion', adult=True), cls('CaptiveSoul', sub='captive-soul'), cls('Captured', sub='captured', adult=True), cls('CaravanaTaleofGodsandMen', sub='caravantale'), cls('Cataclysm', sub='cataclysm'), cls('Catnip', sub='catnipmanga', adult=True), cls('Cerintha', sub='cerintha'), cls('ChampionofChampions', sub='championofchampions'), cls('ChampionsandHeroesAgeofDragons', sub='championsandheroes'), cls('ChannelDDDNews', sub='dddnews'), cls('ChaosAdventuresII', sub='chaosadventuresii'), cls('ChaoticNation', sub='chaoticnation', adult=True), cls('Charaktermaske', sub='charaktermaske'), cls('Chatuplines', sub='chatuplines'), cls('CheneysGotaGun', sub='cheney'), cls('ChickenScratches', sub='chickenscratches'), cls('ChildrenoftheNight', sub='cotn'), cls('ChimiMouryou', sub='cmmr'), cls('ChocolatewithPepper', sub='chocolate-with-pepper'), cls('CityFolk', sub='cityfolk'), cls('ClairetheFlare', sub='clairetheflare'), cls('CleanCure', sub='cleanpluscure'), cls('ClockworkAtrium', host='www.clockwork-atrium.com'), cls('CloeRemembrance', sub='cloe'), cls('CockroachTheater', sub='cockroachtheater'), cls('Cogs', sub='cogs'), cls('ColorBlind', sub='cbcomic'), cls('ConventionalWisdom', sub='conventionalwisdom'), cls('CosmicDash', sub='cosmicdash'), cls('Cramberries', sub='cramberries'), cls('CrimsonWings', sub='crimson-wings'), cls('CrocodileTears', sub='crocodile-tears', adult=True), cls('CupofOlea', sub='cupofolea'), cls('CurseLineage', sub='curselineage'), cls('DBON', sub='dbondoujin'), cls('DEGAF', sub='degaf'), cls('DEMENTED', sub='demented', adult=True), cls('DaddysGirl', sub='daddysgirl'), cls('DanielleDark', sub='danielledark'), cls('Dasien', sub='dasien', adult=True), cls('DavidDoesntGetIt', sub='daviddoesntgetit'), cls('DeadtoDay', sub='deadtoday'), cls('DeathNoteIridescent', sub='dn-iridescent'), cls('DefyingGravityTheFourGreatGuardians', sub='defyinggravitycomic'), cls('DemonBattles', sub='demonbattles'), cls('DemonCat', sub='demoncat'), cls('DemonEater', sub='demoneater', adult=True), cls('DenizensAttention', sub='denizensattention'), cls('DevilsCake', sub='devilscake'), cls('DevotoMusicinHell', sub='devoto', adult=True), cls('Diaz', sub='diaz'), cls('Diexemor', sub='diexemor'), cls('DigimonSaviors', sub='digimonsaviors'), cls('DigimonTamersMiraiProject', sub='digimontamersmiraiproject'), cls('DigisRandomSpriteshack', sub='digisspriteshack'), cls('DigitalInsanity', sub='digitalinsanity'), cls('DoItYourself', sub='diy'), cls('Dontdie', sub='dontdie'), cls('DoodleBeans', sub='beans', adult=True), cls('DoodlingAround', sub='doodlingcomic'), cls('DoomsdayMyDear', host='www.doomsdaymydear.com'), cls('DragonKid', sub='dragonkid'), cls('Dragonet', sub='dragonet'), cls('DumpofManyPeople', sub='dumpofmanypeople'), cls('DungeonHordes', sub='dungeonhordes'), cls('EATATAU', sub='eatatau'), cls('EDepthAngel', sub='edepth'), cls('ERAConvergence', sub='convergence'), cls('ERAIbuki', sub='eraibuki'), cls('ERRORERROR', sub='errorerror'), cls('EidolonWhispersofEternity', sub='whispersofeternity'), cls('ElementalSpirits', sub='elementalspirits'), cls('EnkeltenKentta', sub='enkeltenkentta', adult=True), cls('Enthrall', sub='enthrall', adult=True), cls('Entreeuxdeux', sub='entreuxdeux'), cls('Entuthrie', sub='entuthrie', adult=True), cls('Eorah', sub='eorah', adult=True), cls('EozinKadonnutKuningas', sub='eozinkadonnutkuningas'), cls('EpicChaos', sub='epicchaos'), cls('Equsopia', sub='equsopia'), cls('EternalKnights', sub='eternalknights', adult=True), cls('EuphemisticEephus', sub='eephus'), cls('EvD', sub='ev-d'), cls('EvilPlan', host='evilplan.thewebcomic.com'), cls('ExperimentalMegaman', sub='ex90081'), cls('EyesofaDigimon', sub='eoad'), cls('FailureConfetti', sub='failureconfetti'), cls('FairyTaleRejects', host='fairytalerejects.thewebcomic.com', adult=True), cls('FaithlessDigitals', sub='faithlessdigitals'), cls('FalconersDailyStrips', sub='falcdaily'), cls('FallenAngelslove', sub='fallen-angels-love'), cls('FarOutMantic', sub='meteorflo'), cls('FarOutThere', sub='faroutthere'), cls('FatetheAnthologyofKaienandhisfuckingmagicfriends', sub='fatehoho'), cls('FemmeSchism', sub='femmeschism'), cls('FeralGentry', sub='feralgentry'), cls('FinalArcanum', sub='finalarcanum'), cls('FireredLisasReise', sub='lisasreise'), cls('FlyorFail', sub='flyorfail'), cls('ForcedSeduction', sub='forced-seduction'), cls('ForestHill', host='www.foresthillcomic.org'), cls('ForgettheDistance', sub='forgetthedistance', adult=True), cls('Fortheloveofabrokenstring', sub='fortheloveofabrokenstring'), cls('FramebyFrame', sub='frame-by-frame', adult=True), cls('FrenzyRedux', sub='theadventuresoffrenzy'), cls('FrobertTheDemon', sub='frobby'), cls('FromnowonImagirl', sub='fromnowonimagirl'), cls('FruitloopAndMrDownbeat', sub='fruitbeat'), cls('FullSpectrumTherapy', sub='fst', adult=True), cls('GamerCafe', sub='gamercafe'), cls('GamesPeoplePlayUpdatedWeekly', sub='gamespeopleplay'), cls('GardenofHearts', sub='gardenofhearts'), cls('GayBacon', sub='gaybacon'), cls('GayTimesWithRyanandJay', sub='gtwraj'), cls('GetUpandGo', sub='getupandgo', adult=True), cls('GigisNuzlockeRuns', sub='giginuzlocke'), cls('Gloomverse', sub='gloomverse'), cls('Gnoph', sub='gnoph'), cls('GoldenSunGenerationsAftermathVolume1', sub='gsgbtsyearone'), cls('GoldenSunGenerationsColossoVolume6', sub='gsgbtsyearthree'), cls('GoodGame', sub='goodgame'), cls('GoodnightMrsGoose', sub='goose'), cls('Grayscale', sub='grayscale', adult=True), cls('GuardianGhost', sub='guardianghost'), cls('GuardiansoftheGalaxialSpaceways', sub='ggs'), cls('HIPS', sub='hips', adult=True), cls('Habibahssong', sub='habibahsong'), cls('HarvestMoonParadiseFound', sub='paradisefound'), cls('HatShop', sub='hatshop'), cls('HatethePlayer', host='hatetheplayer.thewebcomic.com'), cls('Helix', sub='helix', adult=True), cls('HeltonShelton', sub='heltonshelton'), cls('HendrixAndJulian', sub='hendrixandjulian', adult=True), cls('Hephaestus', host='hephaestus.thewebcomic.com'), cls('HereBeVoodoo', sub='herebevoodoo', adult=True), cls('HiddenStrengthAWhiteNuzlocke', sub='hsnuzlocke'), cls('Hinata', sub='hinata'), cls('HitandMiss', sub='hitandmiss'), cls('Holocrash', sub='holocrash', adult=True), cls('HolyBlasphemy', sub='holyblasphemy'), cls('HolyCrap', sub='holycrap'), cls('HopeForABreeze', sub='h4ab'), cls('HouseofCraziness', sub='craziness'), cls('HurrocksFardel', sub='hurrocksfardel'), cls('Hybristorific', sub='hybristorific', adult=True), cls('IWishIggysWish', sub='i-wish-comic'), cls('IciVontLesMorts', sub='icivontlesmorts', adult=True), cls('InHouseHumor', sub='inhousehumor'), cls('Inchoatica', sub='inchoatica'), cls('Ingloriousbasterds', sub='ingloriousbasterds'), cls('Inhuman', sub='inhumancomic'), cls('InsideOuTAYuriTale', sub='insideout-a-yuri-tale'), cls('InspiredByADream', sub='inspiredbyadream'), cls('Intoxicated', sub='intoxicated', adult=True), cls('Itsan8BitWorldBlankWorld', sub='8bitblankworld'), cls('JackiesStory', sub='jackiestory'), cls('Jantar', sub='jantar'), cls('Jantarpol', sub='jantar-pl'), cls('Jason', sub='jasoncomic'), cls('JoeysAdventure', sub='joeysadventure'), cls('JourneyMan', sub='journeyman'), cls('JoyToTheWorld', sub='joytotheworld'), cls('June', sub='june'), cls('JustAnotherLife', sub='justanotherlife'), cls('JustCrazy', sub='justcrazy'), cls('Justmyluck', sub='justmyluck'), cls('KCNO', sub='kcno'), cls('KaitoShuno', sub='kaitoshuno', adult=True), cls('KasaKeira', sub='kasakeira'), cls('Katran', sub='katran'), cls('KazanatoFuneralPlanningService', sub='kazanato'), cls('KezroChroniclesPhantomOps', sub='phantomops'), cls('Kirbandfriendsshowcase', sub='kas'), cls('KirbiesoftheAlternateDimension', sub='kirbyaltdimension'), cls('KirbyAdventure', sub='kirbysadventure'), cls('KirbyDreamTeam', sub='kirbysdreamteam'), cls('KirbyFunfestTheOriginals', sub='kirbyfunfestold'), cls('KirbyTheDeeArmy', sub='kirbyandthedeearmy'), cls('KirbysDreamAdventure', sub='kirbyda'), cls('KirbysDreamlandAdventures', sub='kirbysdreamlandadventures'), cls('KissmeSnow', sub='kissmesnow'), cls('KissoftheDevil', sub='kissofthedevil'), cls('Knightface', sub='knightface', adult=True), cls('KnightsRequiem', sub='knightsrequiem'), cls('KojiX5', sub='kojix5'), cls('Kreetor', sub='kreetor'), cls('Kruptos', sub='kruptos'), cls('KuroNeko', sub='kuro-neko'), cls('KuronaFlutterandLylaSpamTime', sub='icantflyaplane'), cls('LOGOS', sub='logoscomic', adult=True), cls('LOKI', sub='loki'), cls('LastBlockStanding', sub='lastblockstanding'), cls('LastLivingSouls', sub='lastlivingsouls'), cls('LatchkeyKingdom', sub='latchkeykingdom'), cls('LavenderLegend', sub='lavenderlegend'), cls('LeCirquedObscure', sub='cirquedobscure'), cls('LedbyaMadMan', sub='ledbyamadman'), cls('LegendofZeldaAHerosStory', sub='aherosstory'), cls('LegendofZeldaStaffofPower', sub='loz-sop'), cls('LegendofZeldaTheEdgeandTheLight', sub='legendofzelda'), cls('LegendofZeldaTheWindWaker', sub='zeldawindwaker'), cls('LegendsofMobiusBookOne', sub='legendsofmobius-bookone'), cls('Lemongrass', sub='lemongrass'), cls('LesCendresdelHiver', sub='cendres'), cls('LetLoveRule', sub='letloverule'), cls('LethalDose', sub='lethaldosecomic', adult=True), cls('LetsBreakitforReals', sub='breaktehmentality'), cls('LicensedHeroes', sub='licensedheroes'), cls('LifeAsACutOut', host='lifeasacutout.thewebcomic.com'), cls('LifeAsItWas', sub='lifeasitwas'), cls('LifeLessOrdinary', sub='lifelessordinary', adult=True), cls('Lifeonpaper', sub='lifeonpaper'), cls('LightLovers', sub='lightlovers'), cls('LightwithinShadow', sub='lightwithinshadow'), cls('LilLevi', sub='lillevi'), cls('LiliBleu', sub='lilibleu'), cls('LondonUnderworld', sub='lunderworld'), cls('LostNova', sub='lostnova'), cls('LoveHarbor', sub='shipcentral'), cls('LoveMeLoveMyTeddyBear', sub='teddybear'), cls('LoveandIcecream', sub='lovexandxicecream'), cls('LoveroftheSunandMoon', sub='loverofthesunandmoon'), cls('LsEmpire', sub='l-empire'), cls('LuffinpuffandEric', sub='luffinpuff'), cls('LumasParadise', sub='luma'), cls('MUTE', sub='muterobot'), cls('MYth', sub='myth'), cls('MagicalGirlAlice', sub='magicalgirlalice'), cls('MagicalMisfits', sub='magicalmisfits'), cls('Magience', host='www.magience.co'), cls('Magipunk', sub='magipunk'), cls('Manifestedpart1', sub='manifested'), cls('MarXistemTWC', sub='marxistem'), cls('MarioandLuigiMisadventures', sub='mandladventures'), cls('MariosDayJob', sub='mariosjob'), cls('MariovsSonicvsMegaMan', sub='mvsvmm'), cls('MarsMind', sub='marsmind'), cls('Mascara', sub='mascara'), cls('MasqueradeWTTM', sub='masqueradewttm'), cls('MatildasSweetCakeCafe', sub='mscc', adult=True), cls('MaytheRainCome', sub='maytheraincome'), cls('Mazscara', sub='mazscara'), cls('MegaManBattleNetwork7', sub='mmbn7-twt'), cls('MegaManTales', sub='megamantales'), cls('MegaPain', sub='megapain'), cls('MelodyAndMacabre', sub='melodyandmacabre'), cls('MerirosvotSeikkailumerella', sub='merirosvotseikkailumerella'), cls('MetroJack', sub='metro-jack', adult=True), cls('MidnightPrince', sub='midnightprince'), cls('MineS', sub='mines'), cls('Minibot', sub='minibot'), cls('MinorActsofHeroism', host='www.minoractsofheroism.com'), cls('Missing', sub='missing'), cls('Missingversionfrancaise', sub='missingfr'), cls('MixupofallMixups', sub='mixupofmixups'), cls('MobianChaos', sub='mobianchaos'), cls('Mokepon', sub='mokepon'), cls('Monstar', host='monstar.thewebcomic.com'), cls('MoonValley', sub='moonvalley'), cls('MorphE', host='morphe.thewebcomic.com'), cls('Mortifer', sub='mortifer'), cls('MrFactory', sub='mrfactory'), cls('MyBoyfriendisaMobBoss', sub='mbmb', adult=True), cls('MyFakeHeart', sub='myfakeheart'), cls('MySistertheDragon', sub='sisterdragon'), cls('MySparklingPrincesama', sub='kiraouji'), cls('MyStereoBot', sub='mystereobot'), cls('MyTrollLife', sub='mytrolllife'), cls('MyTwoCentsPlusTax', sub='mtcpt'), cls('MysticanDreams', sub='mysticandreams'), cls('MythsofUnovaAWhiteNuzlockeRunHardMode', sub='mythsofunova'), cls('NIK', sub='nik'), cls('Nah', sub='thecomicformerlyknownasgenlab'), cls('Negligence', sub='negligence'), cls('NeoCrystalAdventures', sub='neocrystaladventures'), cls('NeonGlow', sub='neonglow'), cls('NevertheHero', sub='neverthehero'), cls('Nexus', sub='nexus'), cls('NiceKitty', sub='nicekitty'), cls('NighHeavenandHell', sub='oldnighheavenandhell', adult=True), cls('NightSpace', sub='nightspace'), cls('NissiesDragonPrincess', sub='drgnprincess'), cls('NixsFireRedNuzlocke', sub='nixnuzlocke'), cls('NoEnd', sub='no-end'), cls('NobleHeartsHiruandMerroug', sub='hiruandmerroug', adult=True), cls('NormalcyisforWimps', sub='normalcyisforwimps'), cls('NotyoursamI', sub='notyoursami', adult=True), cls('ObnoxiousHeroKun', sub='hero-kun', adult=True), cls('ObsidianHeart', sub='obsidianheart'), cls('October20th', host='www.october20comic.com'), cls('OddPlaceOddTime', sub='oddplaceoddtime'), cls('Ohman', sub='ohman'), cls('OldElastikid', sub='oldelastikid'), cls('OneRainyDay', sub='one-rainy-day', adult=True), cls('Onlyonelovesong', sub='onlyonelovesong'), cls('OperationTheater', sub='operation-theater'), cls('OriginBook1Codearth', sub='theoriginbooks'), cls('OurTimeinEden', sub='ourtimeineden'), cls('Outbreak', sub='xoutbreak'), cls('OutofKey', sub='outofkey'), cls('OverSync', sub='oversync'), cls('PMDExplorersofHeart', sub='pmd-explorers-of-heart'), cls('PMDTeamFirefox', sub='pmdteamfirefox'), cls('PMDVictoryFire', sub='victoryfire'), cls('PTO', sub='pto', adult=True), cls('Pahantekija', sub='pahantekija'), cls('Panacea', sub='panacea', adult=True), cls('PantsParty', sub='partypants'), cls('PanzerDragonandEnigmaCompleteEdition', sub='panzerdragonandenigma'), cls('Paradox', sub='paradoxcomic', adult=True), cls('Paripety', sub='paripety'), cls('Pause', sub='pause'), cls('PencilviewUpdatesMondayscough', sub='pencilview'), cls('Perinto', sub='perinto'), cls('PerplexingMagnoliaDisruption', sub='smgpmd'), cls('PeterPan', sub='peterpan'), cls('Phantomland', sub='phantomland'), cls('PhotoShootnarusasuDoujinshi', sub='photoshootnarusasu', adult=True), cls('PlasticKings', sub='plastickings'), cls('PlatonicBoyfriends', sub='platonicboyfriends'), cls('PlayTime', sub='dollysplaytime'), cls('PleasyBeMyBoytoy', sub='pleasebemyboytoy', adult=True), cls('PokeVenturous', sub='pokeventuras'), cls('PokemonBeta', sub='pokemonbeta'), cls('PokemonCrystalDoubleNuzlockeChallenge', sub='miinuzlocke'), cls('PokemonGleamingCrystal', sub='gleamingcrystal'), cls('PokemonLANDSKY', sub='landsky'), cls('PokemonMysteryDungeonTeamCrystal', sub='crystalmysterydungeon'), cls('PokemonParallel', sub='pokemon-parallel'), cls('PokemonSAKOHJU', sub='sakohju'), cls('PokemonnoRakuen', sub='pokemon-no-rakuen'), cls('Ponzi', sub='ponzi'), cls('PrettyMouth', sub='prettymouth'), cls('PrincessChroma', sub='princesschroma'), cls('ProfessorDolphinpresentsPokemon', sub='pdpp'), cls('ProjectCAPLimit', sub='imagecap'), cls('Puck', sub='puck'), cls('PullingYouUnder', sub='pullingyouunder', adult=True), cls('PulseandBolt', sub='pulse-bolt'), cls('PurpureaNoxa', sub='purpureanoxa', adult=True), cls('QueerQueen', sub='queerqueen'), cls('RANDOM', sub='randomthecomic'), cls('ROSIER', sub='rosier'), cls('RainbowMansion', sub='rainbow-mansion', adult=True), cls('RainLGBT', sub='rainlgbt'), cls('RainxSasori', sub='rainxsasori', adult=True), cls('RareCandyTreatment', host='www.rarecandytreatment.com'), cls('RavenWolf', sub='ravenwolf'), cls('RedVelvetRequiem', sub='rvr'), cls('Regina', sub='regina'), cls('ReidyandFriendsShowcase', sub='reidynfriends'), cls('RemoteAngel', sub='remoteangel'), cls('Replica', sub='replica', adult=True), cls('Respectable', sub='respectable', adult=True), cls('ReturntoEden', sub='rte'), cls('RiversideExtras', host='www.riversidecomics.co', adult=True), cls('RottenApple', sub='rottenapple'), cls('RoyalIcing', sub='royalicing'), cls('RuScrewed', host='ru-screwed', adult=True), cls('RubyNation', host='www.therubynation.com'), cls('RuderiQuest', sub='ruderi'), cls('RuneSpark', sub='runespark'), cls('RyuManwebcomicversion', sub='ryuman-web'), cls('SChIzO', sub='schizophrenic'), cls('SFCBlackjackBay', sub='blackjackbay'), cls('SFCForestofDreams', sub='sfcforestofdreams'), cls('SLightlyabOVeavErage', sub='slightlyaboveaverage', adult=True), cls('SOSRadio', sub='sosradio'), cls('SPRITEDHeroesofDobalia', sub='spritedhod'), cls('SUNRISESTORY', sub='sunrisestory'), cls('SabishiiGhost', sub='sabishiighost'), cls('SaintforRent', sub='saint-for-rent'), cls('SakuraDAY', sub='sakuraday'), cls('SakuraMishzo', sub='sakurazo', adult=True), cls('SalemUncommons', sub='salemuncommons'), cls('SallySprocketAndPistonPete', sub='ssnpp'), cls('SaltyKiss', sub='saltykiss'), cls('Saywhatyoumean', sub='saywhatyoumean'), cls('SchoolofRejectsSoRe', sub='sore'), cls('ScionsoftheSeraph', sub='scions', adult=True), cls('ScrappedProject', sub='scrappedproject'), cls('SecretPowerbk1', sub='secretpower1'), cls('SecretPowerbk2', sub='secretpower2'), cls('Seki', sub='se-ki', adult=True), cls('SenoireDelirium', sub='senoiredelirium'), cls('SeriousTimes', sub='serioustimes'), cls('Shameless', sub='shamelesscomic'), cls('ShamelessAdvertisements', sub='advertiseat'), cls('ShotoutofCanon', sub='akumathfs'), cls('ShroudofLight', sub='shroudoflight'), cls('Signifikat', sub='signifikat', adult=True), cls('SimonSues', sub='simonsues'), cls('SimpleBear', sub='simplebear'), cls('SimplySarah', sub='simplysarah'), cls('Sire', host='sire.thewebcomic.com'), cls('Skeptical', sub='skeptical'), cls('Slackmatic', sub='slackmatic'), cls('SlipstreamSingularity', sub='slipstreamsingularity'), cls('SmallPressAdventures', sub='smallpressadventures'), cls('SocksMittensandScarfs', sub='socksmitsscarfs'), cls('SomebodyShootMe', sub='somebodyshootme'), cls('SomethingLikeaPhenomenon', sub='somethinglikeaphenomenon', adult=True), cls('SonicAuthorAdventII', sub='saa2'), cls('SonicBoom', sub='sonic-boom'), cls('SonicClub', sub='sonicclub'), cls('SonicDashly', sub='sonicdashly'), cls('SonicFuture', sub='sonicfuture'), cls('SonicSchoolRedo', sub='sonicschoolredo'), cls('SonicUniverseAsk', sub='sonicuniverseask'), cls('SoulGuardian', sub='soulguardian'), cls('SouthernCross', host='southerncross.thewebcomic.com'), cls('SovereignTheMostAmazingComicEver', sub='mostamazingcomicever'), cls('SpaghettiAndMeatballs', sub='spaghettiandmeatballs', adult=True), cls('SparElricsextras', sub='sparextras'), cls('SparkStory', sub='sparkstory'), cls('Spellcross', sub='spellcross'), cls('SpiderWings', sub='spiderwings'), cls('SpursAndStripes', sub='spursandstripes', adult=True), cls('Spidersilk', sub='spidersilk'), cls('SplitScreen', sub='splitscreencomic', adult=True), cls('Spriterschaos', sub='spriterschaos'), cls('Sprytts', sub='sprytts'), cls('StarTrip', sub='startrip'), cls('Stay', sub='stay-comic', adult=True), cls('StellaInChrome', sub='stellainchrome'), cls('Stereophonic', host='stereophonic.thewebcomic.com'), cls('Storyofadamnedlove', sub='storyofadamnedlove'), cls('StrangersandFriends', sub='hemu'), cls('Striped', sub='striped', adult=True), cls('StuntRayWalterswish', sub='stuntray'), cls('SubjecttoChangeCollegeWoes', sub='subject-to-change'), cls('Sunfall', host='sunfall.thewebcomic.com'), cls('SunmeetsMoon', sub='sunmeetsmoon'), cls('SuperDimensionAfterTheHero', sub='afterthehero'), cls('SuperMarioBros3', sub='smb3'), cls('SuperMarjoBros', sub='marjobros'), cls('SupermassiveBlackHoleA', sub='smbhax'), cls('SurvivorFanCharacters', sub='sfc'), cls('SweetestPoison', sub='sweetestpoison'), cls('SwitchMechanism', sub='switchmechanism'), cls('Symbios', sub='symbios', adult=True), cls('TEN', sub='ten'), cls('TLAAOK', sub='tlaaok', adult=True), cls('TPTruePower', sub='truepower'), cls('TRIPP', sub='tripp'), cls('TaikiTheWebcomic', sub='taiki'), cls('TailsAdventureThroughTimeandOtherWorlds', sub='tailsadventure'), cls('TakingPicturesofStrangers', sub='darrenandkale', adult=True), cls('TalesfromAaronsWings', sub='tfaw'), cls('ThatWasntThereYesterday', sub='twty'), cls('The13thWorld', sub='the13thworld'), cls('TheAdventuresofBanjoZ', sub='abz-fancomic', adult=True), cls('TheAntihero', sub='antihero'), cls('TheArchipelago', sub='thearchipelago'), cls('TheAvianStories', sub='theavianstories'), cls('TheBattleInTheSky', sub='thebattleinthesky'), cls('TheBookofNosferatu', host='www.thebookofnosferatu.com'), cls('TheBrideoftheShark', sub='sameyome', adult=True), cls('TheBucket', sub='thebucket'), cls('TheCafedAlizee', sub='alizee'), cls('TheCavernofSecrets', sub='cavern'), cls('TheColony', sub='thecolony', adult=True), cls('TheContract', sub='the-contract'), cls('TheCrawl', sub='thecrawl'), cls('TheCurtandTonyShow', sub='thecurtandtonyshow'), cls('TheDarkAgeofMobius', sub='thedarkageofmobius'), cls('TheDarkLegacy', sub='tdlcomic'), cls('TheDemonicAdventuresofAngelWitchPita', sub='angelwitchpita', adult=True), cls('TheDestroyer', sub='heartless-destroyer', adult=True), cls('TheDragonandtheLemur', sub='dal', adult=True), cls('TheDreaming', sub='thedreaming'), cls('TheDrifter', sub='thedrifter', adult=True), cls('TheElectricRose', sub='electricrosecomic'), cls('TheForestofWhispers', sub='theforestofwhispers'), cls('TheGhostWithTheMost', sub='theghostwiththemost'), cls('TheGoldRiderofPern', sub='goldrider'), cls('TheGrayZone', sub='thegrayzone'), cls('TheHeadhunters', sub='headhunters'), cls('TheHeartofEarth', sub='heart-of-earth'), cls('TheHobbitbic', sub='hobbit'), cls('TheJosephComics', sub='josephcomics'), cls('TheKeyHotelEnding', sub='tekeyhotel'), cls('TheKeyToReality', sub='keytoreality'), cls('TheKwiddexProtocol', sub='kwiddexprotocol'), cls('TheLastBloodCafe', sub='lastbloodcafe'), cls('TheLegendaryQueen', sub='legendaryqueen', adult=True), cls('TheLifeofMagFlamequill', sub='lifeofmag'), cls('TheLoneSwordsman', sub='theloneswordsman'), cls('TheLostland', sub='thelostlandcomic'), cls('TheMegaManandSonicSpriteShowcase', sub='megamanshowcase'), cls('TheMoistTouch', sub='themoisttouch'), cls('TheNOMEDSEGA', sub='nomed'), cls('TheNightSurfers', sub='thenightsurfers'), cls('TheNocheComicSeries', sub='nochecomicseries', adult=True), cls('ThePirateBalthasar', sub='thepiratebalthasar'), cls('ThePremise', sub='thepremise'), cls('ThePrincessandtheGiant', sub='princess'), cls('ThePropertyofHate', sub='tpoh'), cls('TheReborn', sub='reborn'), cls('TheSearchforHenryJekyll', sub='thesearchforhenryjekyll'), cls('TheSilverLeague', sub='thesilverleague'), cls('TheSummerofBlakeSinclair', sub='blake-sinclair'), cls('TheTimeDog', sub='timedog'), cls('TheTytonNuzlockeChallengeEmeraldEdition', sub='tytonnuzlockeemerald'), cls('TheWastelands', sub='wastelands'), cls('TheWhiteTower', sub='thewhitetower'), cls('TheWinterCampaign', sub='winterc'), cls('TheYoshiHerd', sub='theyoshiherd'), cls('Theatrics', sub='theatrics'), cls('TheiaMania', sub='theia-mania'), cls('ThelaughingDeath', sub='thelaughingdeath'), cls('Themadman', sub='themadman'), cls('Theswordsmanandtheamnesiac', sub='tsata', adult=True), cls('ThiefCatcherRingTail', sub='tcringtail'), cls('ThinkBeforeYouThink', sub='thinkbeforeyouthink'), cls('ThornTopia', sub='tnt100'), cls('ThornsComic', sub='thornscomic'), cls('ThroughtheWonkyEye', sub='through-the-wonky-eye'), cls('TosiHuonoYaoiSarjis', sub='tosihuonoyaoisarjis', adult=True), cls('TotallyCrossover', sub='totallycrossover'), cls('TrainerWantstoFight', sub='twtf'), cls('TransUMan', sub='transuman', adult=True), cls('Transfusions', sub='transfusions'), cls('Troublenextdoor', sub='troublenextdoor'), cls('UglyBoysLove', sub='shounenai'), cls('Uglygame', sub='uglygame'), cls('UndertheDeadSkies', host='underthedeadskies.thewebcomic.com', adult=True), cls('UnicampaLapis', sub='ual'), cls('UpDown', sub='updown', adult=True), cls('UshalaatWorldsEnd', sub='ushala', adult=True), cls('VACANT', sub='vacant'), cls('Vacan7', sub='vacan7', adult=True), cls('VerloreGeleentheid', host='verlore.thewebcomic.com'), cls('Void', sub='vtgtahr', adult=True), cls('VoidMisadventures', sub='voidmisadventures'), cls('VoyageoftheBrokenPromise', sub='voyageofthebrokenpromise', adult=True), cls('WHATaboutSHADOWS', sub='was'), cls('WakeEcho', sub='echo'), cls('Wander', sub='wander'), cls('WantedDeadorDead', sub='wanteddeadordead'), cls('Wayfar', sub='wayfar'), cls('Waysoftheheart', sub='wayoftheheart'), cls('WeAreGolden', sub='wearegolden', adult=True), cls('WelcometoFreakshow', sub='welcometofreakshow'), cls('WelcometothePCA', sub='welcometothepca'), cls('WhatAboutLove', sub='whataboutlove', adult=True), cls('Whatisdeepinonesheart', sub='ones-mindt'), cls('WhenSheWasBad', sub='whenshewasbad'), cls('Whenweweresilent', sub='silence'), cls('WHOLE', sub='whole', adult=True), cls('WhereaboutsOfTime', sub='wot'), cls('WhiteHeart', sub='whiteheart', adult=True), cls('WhiteNoise', sub='white-noise'), cls('WildWingBoys', sub='wwb'), cls('WildWingBoysKoathArc', sub='wwbka'), cls('Wildflowers', sub='wildflowers'), cls('WingsOverEthereal', sub='wings-over-ethereal'), cls('WingsTurnedtoDust', sub='wingsturnedtodust'), cls('Wootlabs', host='wootlabs.thewebcomic.com'), cls('XXMoralityXx', sub='xxmoralityxx'), cls('YadotCakeShop', sub='yadotcakeshop', adult=True), cls('YamanaokiHighSchool', sub='yamanaokihs'), cls('YouAreTheReasonForTheEndOfTheWorld', sub='thereasonfortheendoftheworld'), cls('YoungCannibals', host='www.youngcannibals.net'), cls('ZaenWell', sub='zaenwell'), cls('ZeldaTheNewAdventureofLinkIIMajorasMask', sub='newlink'), cls('_A_', sub='a-the-stalker'), # END AUTOUPDATE )