From 20ab279cde44a83fb7d047cc5c440d6e293b4093 Mon Sep 17 00:00:00 2001 From: Tobias Gruetzmacher Date: Mon, 13 Feb 2017 01:46:49 +0100 Subject: [PATCH] Clean up SmackJeeves... Currently only covers already existing modules: Removed 11 broken modules, added 2 and tried to update comic names and the adult and endOfLife flags from their index. This isn't helped by the fact that their search seems to skip some comics... --- dosagelib/plugins/old.py | 13 ++ dosagelib/plugins/smackjeeves.py | 369 +++++++++++++++---------------- scripts/smackjeeves.py | 53 ++--- 3 files changed, 215 insertions(+), 220 deletions(-) diff --git a/dosagelib/plugins/old.py b/dosagelib/plugins/old.py index cf5fed481..8a933fbc3 100644 --- a/dosagelib/plugins/old.py +++ b/dosagelib/plugins/old.py @@ -398,8 +398,11 @@ class Removed(Scraper): cls('RedsPlanet'), cls('SmackJeeves/Aarrevaara'), cls('SmackJeeves/AchievementStuck'), + cls('SmackJeeves/AGirlAndHerShadow'), cls('SmackJeeves/Allthatglitters'), + cls('SmackJeeves/Anathemacomics'), cls('SmackJeeves/AngelBeast'), + cls('SmackJeeves/AwesomeSauce'), cls('SmackJeeves/BetweenWorlds'), cls('SmackJeeves/BeyondTemptation'), cls('SmackJeeves/Bloodyfairytale'), @@ -411,7 +414,12 @@ class Removed(Scraper): cls('SmackJeeves/Destinationunknown'), cls('SmackJeeves/DevilTrainee'), cls('SmackJeeves/DevilTraineeSpanish'), + cls('SmackJeeves/Diexemor'), cls('SmackJeeves/ElfenLiedDifferences'), + cls('SmackJeeves/EozinKadonnutKuningas'), + cls('SmackJeeves/EpicChaos'), + cls('SmackJeeves/EternalKnights'), + cls('SmackJeeves/EvD'), cls('SmackJeeves/FeathersPI'), cls('SmackJeeves/FireWire'), cls('SmackJeeves/FrogKing'), @@ -432,13 +440,17 @@ class Removed(Scraper): cls('SmackJeeves/LatchkeyKingdom'), cls('SmackJeeves/LoveTwister'), cls('SmackJeeves/MegaManiacs'), + cls('SmackJeeves/MerirosvotSeikkailumerella'), cls('SmackJeeves/MewsDynasty'), cls('SmackJeeves/MomthegamestorerippedusoffAGAIN'), cls('SmackJeeves/MoonlitDawnAMythicalTale'), + cls('SmackJeeves/MyBoyfriendisaMobBoss'), cls('SmackJeeves/NihilWandasJourney'), cls('SmackJeeves/OddContact'), cls('SmackJeeves/OneFrameGags'), cls('SmackJeeves/Paripety'), + cls('SmackJeeves/Perinto'), + cls('SmackJeeves/PlatonicBoyfriends'), cls('SmackJeeves/Plotlessnesses'), cls('SmackJeeves/PokemonGleamingCrystal', 'mis'), cls('SmackJeeves/PRAGUERACE'), @@ -455,6 +467,7 @@ class Removed(Scraper): cls('SmackJeeves/TheMewExperiment'), cls('SmackJeeves/TheRandomObscureFairyTaleNoOnesEverReallyHeardOf'), cls('SmackJeeves/TheSomewhereOther'), + cls('SmackJeeves/ThroughTheWonkyEye'), cls('SmackJeeves/TitleUnrelated'), cls('SmackJeeves/TotalPokemonIsland'), cls('SmackJeeves/TrillyAndSilly'), diff --git a/dosagelib/plugins/smackjeeves.py b/dosagelib/plugins/smackjeeves.py index bda1d023a..b3ef7e7ab 100644 --- a/dosagelib/plugins/smackjeeves.py +++ b/dosagelib/plugins/smackjeeves.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Copyright (C) 2004-2008 Tristan Seligmann and Jonathan Jacobs # Copyright (C) 2012-2014 Bastian Kleineidam -# Copyright (C) 2015-2016 Tobias Gruetzmacher +# Copyright (C) 2015-2017 Tobias Gruetzmacher from __future__ import absolute_import, division, print_function @@ -50,14 +50,14 @@ class SmackJeeves(_ParserScraper): broken_html_bugfix = True - def __init__(self, name, host=None, sub=None, adult=False): + def __init__(self, name, host=None, sub=None, adult=False, endOfLife=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 + self.adult = adult + self.endOfLife = endOfLife def starter(self): """Get start URL.""" @@ -93,56 +93,55 @@ class SmackJeeves(_ParserScraper): @classmethod def getmodules(cls): return ( - # do not edit anything below since these entries are generated from - # scripts/smackjeeves.py + # these would be generated by scripts/smackjeeves.py, but the sheer + # amount of comics on SmackJeeves makes that idea rather + # unattractive. If you add new comics, try to copy them from the + # output of that script... # START AUTOUPDATE cls('20TimesKirby', sub='20xkirby'), - cls('2Kingdoms', sub='2kingdoms'), + cls('2Kingdoms', sub='2kingdoms', endOfLife=True), cls('355Days', sub='355days'), + cls('_A_', sub='a-the-stalker', endOfLife=True), cls('AB', sub='alistairandboggart', adult=True), cls('AceOfHearts', sub='aceof-hearts'), - 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('AcidMonday', sub='acidmonday', adult=True), - cls('Adalsysla', sub='adalsysla'), + cls('Adalsysla', sub='adalsysla', endOfLife=True), cls('AddictiveScience', sub='addictivescience'), - cls('AdventuresofLumandFriends', sub='aolaf'), + cls('ADoodleADay', sub='adoodleaday'), + cls('AdventuresOfLumAndFriends', sub='aolaf'), cls('AdventuresoftheWeird', sub='adventuresoftheweird'), cls('AetherTheories', sub='aethertheories'), - cls('AgeoftheGray', sub='ageofthegray', adult=True), + cls('AgeOfTheGray', sub='ageofthegray'), + cls('AGirlOnTheServer', sub='girlontheserver'), + cls('AKirbyKomic', sub='akirbykomic'), + cls('ALaMode', sub='alamode'), cls('AllInLOVE', sub='allinlove'), cls('AllStarHeroes', sub='allstarheroes'), + cls('AlmostTouching', sub='almosttouching', adult=True), 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('ANGELOU', sub='angelou-esp'), cls('AnimalAdventures', sub='animaladventures'), cls('Animayhem', sub='animayhem'), - cls('Anythingaboutnothing', host='www.anythingcomic.com'), + cls('AnythingAboutNothing', host='www.anythingcomic.com'), + cls('APTComic', sub='aptcomic'), + cls('AQuestionOfCharacter', sub='aqoc'), cls('ArchportCityChronicles', sub='tjs'), cls('Area9', sub='area-9'), - cls('AroundtheBlock', sub='aroundtheblock'), - cls('ArtofAFantasy', sub='artofafantasy', adult=True), - cls('AtArmsLength', sub='atarmslength'), + cls('AroundTheBlock', sub='aroundtheblock'), + cls('ArtOfAFantasy', sub='artofafantasy', adult=True), + cls('ASongforElise', sub='asongforelise', adult=True), + cls('AtArmsLength', host='www.atarmslength.net'), cls('Atlaswebcomic', sub='atlaswebcomic'), - cls('Autophobia', sub='autophobia', adult=True), + cls('Autophobia', sub='autophobia'), cls('Aware', sub='aware'), - cls('AwesomeSauce', sub='tdawesomesauce'), cls('AyaTakeo', sub='ayatakeo'), - cls('BLDShortComics', sub='bldshortcomics'), + cls('AYuriCollab', sub='ayuricollabbitches', adult=True), cls('BabysittingFourDemons', sub='babysitting4demons'), cls('Babywhatsyoursign', sub='babywhatsyoursign'), cls('BadassRiz', sub='badassriz'), @@ -153,32 +152,33 @@ class SmackJeeves(_ParserScraper): cls('Bearhoney', sub='bear-honey'), cls('BearlyAbel', sub='bearlyabel'), cls('BeautifulLies', sub='beautiful-lies'), + cls('BehindTheGlassCurtain', sub='g1ass', endOfLife=True), 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('Betwin', sub='be-twin'), + cls('BettencourtHotel', sub='bettencourt', endOfLife=True), + cls('BetweenLightAndDark', sub='bld'), + cls('BeTwin', sub='be-twin', endOfLife=True), cls('BeyondTheOrdinary', sub='bto'), cls('BioRevelation', sub='biorevelation'), - cls('Bl3', sub='bl3'), + cls('Bl3', sub='bl3', endOfLife=True), + cls('BlackAndBlue', sub='black-and-blue', endOfLife=True), + cls('Blackdemon', sub='blackdemoncomics'), cls('BlackDragon', sub='blackdragon'), cls('BlackFridayRule', sub='blackfridayrule'), cls('BlackSheepcomic', sub='black-sheep'), - cls('BlackandBlue', sub='black-and-blue'), - cls('Blackdemon', sub='blackdemoncomics'), + cls('BLDShortComics', sub='bldshortcomics'), cls('BleachRedux', sub='bleachredux'), cls('BlindandBlue', sub='blindandblue'), - cls('BloodhuntersBirthofavampire', sub='bloodhunters'), - cls('BloomaPokemonConquestComic', sub='bloomconquest'), + cls('BloodhuntersBirthOfAVampire', sub='bloodhunters', endOfLife=True), + 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('BreachOfAgency', sub='breachofagency', endOfLife=True), + cls('BreakfastOnACliff', sub='boac'), cls('Burn', sub='burn'), cls('ByTheBook', sub='bythebook', adult=True), cls('CafeAmargo', sub='cafeamargo'), @@ -187,11 +187,11 @@ class SmackJeeves(_ParserScraper): cls('CaptiveSoul', sub='captive-soul'), cls('Captured', sub='captured', adult=True), cls('CaravanaTaleofGodsandMen', sub='caravantale'), - cls('Cataclysm', sub='cataclysm'), + cls('Cataclysm', sub='cataclysm', adult=True), cls('Catnip', sub='catnipmanga', adult=True), cls('Cerintha', sub='cerintha'), cls('ChampionofChampions', sub='championofchampions'), - cls('ChampionsandHeroesAgeofDragons', sub='championsandheroes'), + cls('ChampionsAndHeroesAgeOfDragons', sub='championsandheroes'), cls('ChannelDDDNews', sub='dddnews'), cls('ChaosAdventuresII', sub='chaosadventuresii'), cls('ChaoticNation', sub='chaoticnation', adult=True), @@ -199,14 +199,14 @@ class SmackJeeves(_ParserScraper): cls('Chatuplines', sub='chatuplines'), cls('CheneysGotaGun', sub='cheney'), cls('ChickenScratches', sub='chickenscratches'), - cls('ChildrenoftheNight', sub='cotn'), + cls('ChildrenOfTheNight', sub='cotn'), cls('ChimiMouryou', sub='cmmr'), cls('ChocolatewithPepper', sub='chocolate-with-pepper'), - cls('CityFolk', sub='cityfolk'), + cls('CityFolk', host='www.cityfolk.ca'), cls('ClairetheFlare', sub='clairetheflare'), cls('CleanCure', sub='cleanpluscure'), cls('ClockworkAtrium', host='www.clockwork-atrium.com'), - cls('CloeRemembrance', sub='cloe'), + cls('CloeRemembrance', sub='cloe', endOfLife=True), cls('CockroachTheater', sub='cockroachtheater'), cls('Cogs', sub='cogs'), cls('ColorBlind', sub='cbcomic'), @@ -215,18 +215,18 @@ class SmackJeeves(_ParserScraper): cls('Cramberries', sub='cramberries'), cls('CrimsonWings', sub='crimson-wings'), cls('CrocodileTears', sub='crocodile-tears', adult=True), - cls('CupofOlea', sub='cupofolea'), + 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('DBON', sub='dbondoujin'), cls('DeadtoDay', sub='deadtoday'), cls('DeathNoteIridescent', sub='dn-iridescent'), cls('DefyingGravityTheFourGreatGuardians', sub='defyinggravitycomic'), + cls('DEGAF', sub='degaf'), + cls('DEMENTED', sub='demented', adult=True), cls('DemonBattles', sub='demonbattles'), cls('DemonCat', sub='demoncat'), cls('DemonEater', sub='demoneater', adult=True), @@ -234,41 +234,37 @@ class SmackJeeves(_ParserScraper): 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('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('DragonKid', sub='dragonkid'), + cls('DreamCatcher', host='www.dreamcatchercomic.com'), 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('EidolonWhispersOfEternity', sub='whispersofeternity'), cls('ElementalSpirits', sub='elementalspirits'), cls('EnkeltenKentta', sub='enkeltenkentta', adult=True), cls('Enthrall', sub='enthrall', adult=True), - cls('Entreeuxdeux', sub='entreuxdeux'), + cls('EntreEuxDeux', sub='entreuxdeux', endOfLife=True), 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('ERAConvergence', sub='convergence', endOfLife=True), + cls('ERAIbuki', sub='eraibuki', endOfLife=True), + cls('ERRORERROR', sub='errorerror'), cls('EuphemisticEephus', sub='eephus'), - cls('EvD', sub='ev-d'), cls('EvilPlan', host='evilplan.thewebcomic.com'), cls('ExperimentalMegaman', sub='ex90081'), - cls('EyesofaDigimon', sub='eoad'), + cls('EyesOfADigimon', sub='eoad'), cls('FailureConfetti', sub='failureconfetti'), cls('FairyTaleRejects', sub='fairytalerejects', adult=True), cls('FaithlessDigitals', sub='faithlessdigitals'), @@ -284,7 +280,7 @@ class SmackJeeves(_ParserScraper): cls('FlyorFail', sub='flyorfail'), cls('ForcedSeduction', sub='forced-seduction'), cls('ForestHill', host='www.foresthillcomic.org'), - cls('ForgettheDistance', sub='forgetthedistance', adult=True), + cls('ForgetTheDistance', sub='forgetthedistance', adult=True), cls('Fortheloveofabrokenstring', sub='fortheloveofabrokenstring'), cls('FramebyFrame', sub='frame-by-frame', adult=True), cls('FrenzyRedux', sub='theadventuresoffrenzy'), @@ -296,50 +292,50 @@ class SmackJeeves(_ParserScraper): cls('GamesPeoplePlayUpdatedWeekly', sub='gamespeopleplay'), cls('GardenofHearts', sub='gardenofhearts'), cls('GayBacon', sub='gaybacon'), - cls('GayTimesWithRyanandJay', sub='gtwraj'), - cls('GetUpandGo', sub='getupandgo', adult=True), + cls('GayTimesWithRyanAndJay', sub='gtwraj'), + cls('GetUpAndGo', sub='getupandgo', adult=True), cls('GigisNuzlockeRuns', sub='giginuzlocke'), cls('Gloomverse', sub='gloomverse'), - cls('Gnoph', sub='gnoph'), + cls('Gnoph', sub='gnoph', endOfLife=True), cls('GoldenSunGenerationsAftermathVolume1', sub='gsgbtsyearone'), cls('GoldenSunGenerationsColossoVolume6', sub='gsgbtsyearthree'), - cls('GoodGame', sub='goodgame'), + cls('GoodGame', sub='goodgame', endOfLife=True), 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('HarvestMoonParadiseFound', sub='paradisefound', endOfLife=True), + cls('HateThePlayer', host='hatetheplayer.thewebcomic.com'), cls('HatShop', sub='hatshop'), - cls('HatethePlayer', host='hatetheplayer.thewebcomic.com'), - cls('Helix', sub='helix', adult=True), + cls('Helix', host='www.helixcomic.com'), 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('HIPS', sub='hips', adult=True), cls('HitandMiss', sub='hitandmiss'), - cls('Holocrash', sub='holocrash', adult=True), + cls('Holocrash', sub='holocrash', endOfLife=True), cls('HolyBlasphemy', sub='holyblasphemy'), cls('HolyCrap', sub='holycrap'), cls('HopeForABreeze', sub='h4ab'), - cls('HouseofCraziness', sub='craziness'), + 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('InHouseHumor', sub='inhousehumor'), cls('Inhuman', sub='inhumancomic'), cls('InsideOuTAYuriTale', sub='insideout-a-yuri-tale'), cls('InspiredByADream', sub='inspiredbyadream'), - cls('Itsan8BitWorldBlankWorld', sub='8bitblankworld'), + cls('ItsAn8BitWorldBlankWorld', sub='8bitblankworld'), + cls('IWishIggysWish', sub='i-wish-comic'), cls('JackiesStory', sub='jackiestory'), - cls('Jantar', sub='jantar'), cls('Jantarpol', sub='jantar-pl'), + cls('Jantar', sub='jantar'), cls('Jason', sub='jasoncomic'), cls('JoeysAdventure', sub='joeysadventure'), cls('JourneyMan', sub='journeyman'), @@ -348,91 +344,89 @@ class SmackJeeves(_ParserScraper): 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('KCNO', sub='kcno', endOfLife=True), 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('KirbyTheDeeArmy', sub='kirbyandthedeearmy', endOfLife=True), cls('KissmeSnow', sub='kissmesnow'), cls('KissoftheDevil', sub='kissofthedevil'), cls('Knightface', sub='knightface', adult=True), cls('KnightsRequiem', sub='knightsrequiem'), - cls('KojiX5', sub='kojix5'), + cls('KojiX5', sub='kojix5', endOfLife=True), cls('Kreetor', sub='kreetor'), - cls('Kruptos', sub='kruptos'), - cls('KuroNeko', sub='kuro-neko'), + cls('Kruptos', sub='kruptos', endOfLife=True), cls('KuronaFlutterandLylaSpamTime', sub='icantflyaplane'), - cls('LOGOS', sub='logoscomic', adult=True), - cls('LOKI', sub='loki'), + cls('KuroNeko', sub='kuro-neko'), cls('LastBlockStanding', sub='lastblockstanding'), - cls('LastLivingSouls', sub='lastlivingsouls'), + cls('LastLivingSouls', host='lastlivingsouls.thewebcomic.com'), 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('LegendOfZeldaAHerosStory', sub='aherosstory'), + cls('LegendOfZeldaStaffOfPower', sub='loz-sop'), + cls('LegendOfZeldaTheEdgeAndTheLight', sub='legendofzelda', endOfLife=True), + 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('LetLoveRule', sub='letloverule'), 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('LightLovers', sub='lightlovers', adult=True), cls('LightwithinShadow', sub='lightwithinshadow'), - cls('LilLevi', sub='lillevi'), cls('LiliBleu', sub='lilibleu'), + cls('LilLevi', sub='lillevi'), + cls('LOGOS', sub='logoscomic', adult=True), + cls('LOKI', sub='loki'), cls('LondonUnderworld', sub='lunderworld'), cls('LostNova', sub='lostnova'), + cls('LoveandIcecream', sub='lovexandxicecream'), 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('MarioVsSonicVsMegaMan', sub='mvsvmm', endOfLife=True), cls('MarsMind', sub='marsmind'), + cls('MarXistemTWC', sub='marxistem'), cls('Mascara', sub='mascara'), cls('MasqueradeWTTM', sub='masqueradewttm'), cls('MatildasSweetCakeCafe', sub='mscc', adult=True), - cls('MaytheRainCome', sub='maytheraincome'), + cls('MayTheRainCome', sub='maytheraincome', endOfLife=True), 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('Merceneiress', host='www.merceneiress.com'), cls('MetroJack', sub='metro-jack', adult=True), - cls('MidnightPrince', sub='midnightprince'), + cls('MidnightPrince', sub='midnightprince', adult=True), cls('MineS', sub='mines'), cls('Minibot', sub='minibot'), - cls('MinorActsofHeroism', host='www.minoractsofheroism.com'), + cls('MinorActsOfHeroism', host='www.minoractsofheroism.com'), cls('Missing', sub='missing'), cls('Missingversionfrancaise', sub='missingfr'), cls('MixupofallMixups', sub='mixupofmixups'), @@ -440,35 +434,36 @@ class SmackJeeves(_ParserScraper): cls('Mokepon', sub='mokepon'), cls('Monstar', host='monstar.thewebcomic.com'), cls('MoonValley', sub='moonvalley'), - cls('MorphE', host='morphe.thewebcomic.com'), + cls('MorphE', sub='morphe'), cls('Mortifer', sub='mortifer'), cls('MrFactory', sub='mrfactory'), - cls('MyBoyfriendisaMobBoss', sub='mbmb', adult=True), + cls('MUTE', sub='muterobot', endOfLife=True), cls('MyFakeHeart', sub='myfakeheart'), - cls('MySistertheDragon', sub='sisterdragon'), + cls('MySisterTheDragon', sub='sisterdragon', endOfLife=True), cls('MySparklingPrincesama', sub='kiraouji'), cls('MyStereoBot', sub='mystereobot'), + cls('MysticanDreams', sub='mysticandreams'), + cls('MythsOfUnovaAWhiteNuzlockeRunHardMode', sub='mythsofunova'), + cls('MYth', sub='myth'), 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('NeverTheHero', sub='neverthehero'), cls('Nexus', sub='nexus'), cls('NiceKitty', sub='nicekitty'), cls('NighHeavenandHell', sub='oldnighheavenandhell', adult=True), cls('NightSpace', sub='nightspace'), + cls('NIK', sub='nik'), cls('NissiesDragonPrincess', sub='drgnprincess'), cls('NixsFireRedNuzlocke', sub='nixnuzlocke'), - cls('NoEnd', sub='no-end'), cls('NobleHeartsHiruandMerroug', sub='hiruandmerroug', adult=True), + cls('NoEnd', sub='no-end'), cls('NormalcyisforWimps', sub='normalcyisforwimps'), cls('NotyoursamI', sub='notyoursami', adult=True), - cls('ObnoxiousHeroKun', sub='hero-kun', adult=True), + cls('ObnoxiousHerokun', sub='hero-kun', adult=True), cls('ObsidianHeart', sub='obsidianheart'), cls('October20th', host='www.october20comic.com'), cls('OddPlaceOddTime', sub='oddplaceoddtime'), @@ -478,14 +473,10 @@ class SmackJeeves(_ParserScraper): cls('Onlyonelovesong', sub='onlyonelovesong'), cls('OperationTheater', sub='operation-theater'), cls('OriginBook1Codearth', sub='theoriginbooks'), - cls('OurTimeinEden', sub='ourtimeineden'), + 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'), @@ -493,89 +484,88 @@ class SmackJeeves(_ParserScraper): cls('Paradox', sub='paradoxcomic', adult=True), 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('PhotoShootNarusasuDoujinshi', sub='photoshootnarusasu', adult=True), cls('PlasticKings', sub='plastickings'), - cls('PlatonicBoyfriends', sub='platonicboyfriends'), cls('PlayTime', sub='dollysplaytime'), cls('PleaseBeMyBoytoy', sub='pleasebemyboytoy'), - cls('PokeVenturous', sub='pokeventuras'), - cls('PokemonBeta', sub='pokemonbeta'), - cls('PokemonCrystalDoubleNuzlockeChallenge', sub='miinuzlocke'), + cls('PMDExplorersOfHeart', sub='pmd-explorers-of-heart'), + cls('PMDTeamFirefox', sub='pmdteamfirefox'), + cls('PMDVictoryFire', sub='victoryfire'), + cls('PokemonBeta', sub='pokemonbeta', endOfLife=True), + cls('PokemonCrystalDoubleNuzlockeChallenge', sub='miinuzlocke', endOfLife=True), cls('PokemonLANDSKY', sub='landsky'), cls('PokemonMysteryDungeonTeamCrystal', sub='crystalmysterydungeon'), + cls('PokemonNoRakuen', sub='pokemon-no-rakuen'), cls('PokemonParallel', sub='pokemon-parallel'), cls('PokemonSAKOHJU', sub='sakohju'), - cls('PokemonnoRakuen', sub='pokemon-no-rakuen'), + cls('Pokeventurous', sub='pokeventuras'), cls('Ponzi', sub='ponzi'), cls('PrettyMouth', sub='prettymouth'), cls('PrincessChroma', sub='princesschroma'), cls('ProfessorDolphinpresentsPokemon', sub='pdpp'), cls('ProjectCAPLimit', sub='imagecap'), + cls('PTO', sub='pto', adult=True), 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', host='rainbow-mansion.thewebcomic.com', adult=True), cls('RainLGBT', sub='rainlgbt'), - cls('RainxSasori', sub='rainxsasori', adult=True), + cls('RainxSasori', sub='rainxsasori', adult=True, endOfLife=True), + cls('RANDOM', sub='randomthecomic'), cls('RareCandyTreatment', host='www.rarecandytreatment.com'), cls('RavenWolf', sub='ravenwolf'), cls('RedVelvetRequiem', sub='rvr'), cls('Regina', sub='regina'), - cls('ReidyandFriendsShowcase', sub='reidynfriends'), + cls('ReidyAndFriendsShowcase', sub='reidynfriends'), cls('RemoteAngel', sub='remoteangel'), - cls('Replica', sub='replica', adult=True), - cls('Respectable', sub='respectable', adult=True), + cls('Replica', sub='replica', adult=True, endOfLife=True), + cls('Respectable', sub='respectable', adult=True, endOfLife=True), cls('ReturntoEden', sub='rte'), cls('RiversideExtras', host='www.riversidecomics.co'), + cls('ROSIER', sub='rosier'), cls('RottenApple', sub='rottenapple'), cls('RoyalIcing', sub='royalicing'), - cls('RuScrewed', sub='ru-screwed'), cls('RubyNation', sub='therubynation'), 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('RUScrewed', sub='ru-screwed'), + cls('RyuManwebcomicVersion', sub='ryuman-web', endOfLife=True), cls('SabishiiGhost', sub='sabishiighost'), cls('SaintforRent', sub='saint-for-rent'), - cls('SakuraDAY', sub='sakuraday'), + cls('SakuraDAY', sub='sakuraday4s'), 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('SayWhatYouMean', sub='saywhatyoumean'), + cls('SChIzO', sub='schizophrenic'), + 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('SenoireDelirium', sub='senoiredelirium', endOfLife=True), cls('SeriousTimes', sub='serioustimes'), - cls('Shameless', sub='shamelesscomic'), + cls('SFCBlackjackBay', sub='blackjackbay'), + cls('SFCForestofDreams', sub='sfcforestofdreams'), cls('ShamelessAdvertisements', sub='advertiseat'), + cls('Shameless', sub='shamelesscomic'), cls('ShotoutofCanon', sub='akumathfs'), cls('ShroudofLight', sub='shroudoflight'), cls('Signifikat', sub='signifikat', adult=True), - cls('SimonSues', sub='simonsues'), + cls('SimonSues', sub='simonsues', adult=True), cls('SimpleBear', sub='simplebear'), cls('SimplySarah', sub='simplysarah'), cls('Sire', host='sire.thewebcomic.com'), - cls('Skeptical', sub='skeptical'), + cls('Skeptical', host='www.skepticalthewebcomic.com'), cls('Slackmatic', sub='slackmatic'), + cls('SLightlyAbOVeAvErage', sub='slightlyaboveaverage', adult=True), cls('SlipstreamSingularity', sub='slipstreamsingularity'), cls('SmallPressAdventures', sub='smallpressadventures'), cls('SocksMittensandScarfs', sub='socksmitsscarfs'), @@ -588,18 +578,20 @@ class SmackJeeves(_ParserScraper): cls('SonicFuture', sub='sonicfuture'), cls('SonicSchoolRedo', sub='sonicschoolredo'), cls('SonicUniverseAsk', sub='sonicuniverseask'), + cls('SOSRadio', sub='sosradio'), cls('SouthernCross', host='southerncross.thewebcomic.com'), cls('SovereignTheMostAmazingComicEver', sub='mostamazingcomicever'), cls('SpaghettiAndMeatballs', sub='spaghettiandmeatballs', adult=True), - cls('SparElricsextras', sub='sparextras'), + 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('SpiderWings', sub='spiderwings'), + cls('SplitScreen', sub='splitscreencomic', adult=True, endOfLife=True), + cls('SPRITEDHeroesofDobalia', sub='spritedhod'), cls('Spriterschaos', sub='spriterschaos'), cls('Sprytts', sub='sprytts'), + cls('SpursAndStripes', sub='spursandstripes', adult=True), cls('StarTrip', sub='startrip'), cls('Stay', sub='stay-comic', adult=True), cls('StellaInChrome', sub='stellainchrome'), @@ -611,46 +603,45 @@ class SmackJeeves(_ParserScraper): cls('SubjecttoChangeCollegeWoes', sub='subject-to-change'), cls('Sunfall', host='sunfall.thewebcomic.com'), cls('SunmeetsMoon', sub='sunmeetsmoon'), + cls('SUNRISESTORY', sub='sunrisestory'), cls('SuperDimensionAfterTheHero', sub='afterthehero'), - cls('SuperMarioBros3', sub='smb3'), + cls('SuperMarioBros3', sub='smb3', endOfLife=True), cls('SuperMarjoBros', sub='marjobros'), cls('SupermassiveBlackHoleA', sub='smbhax'), cls('SurvivorFanCharacters', sub='sfc'), cls('SweetestPoison', sub='sweetestpoison'), - cls('SwitchMechanism', sub='switchmechanism'), + cls('SwitchMechanism', sub='switchmechanism', endOfLife=True), 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('TalesFromAaronsWings', sub='tfaw', endOfLife=True), + cls('TEN', sub='ten'), cls('ThatWasntThereYesterday', sub='twty'), cls('The13thWorld', sub='the13thworld'), - cls('TheAdventuresofBanjoZ', sub='abz-fancomic', adult=True), + cls('TheAdventuresOfBanjoZ', sub='abz-fancomic', adult=True, endOfLife=True), cls('TheAntihero', sub='antihero'), cls('TheArchipelago', sub='thearchipelago'), + cls('Theatrics', sub='theatrics'), cls('TheAvianStories', sub='theavianstories'), cls('TheBattleInTheSky', sub='thebattleinthesky'), - cls('TheBookofNosferatu', host='www.thebookofnosferatu.com'), + 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('TheCavernOfSecrets', sub='cavern'), cls('TheColony', sub='thecolony', adult=True), cls('TheContract', sub='the-contract'), cls('TheCrawl', sub='thecrawl'), - cls('TheCurtandTonyShow', sub='thecurtandtonyshow'), + cls('TheCurtAndTonyShow', sub='thecurtandtonyshow', endOfLife=True), cls('TheDarkAgeofMobius', sub='thedarkageofmobius'), cls('TheDarkLegacy', sub='tdlcomic'), - cls('TheDemonicAdventuresofAngelWitchPita', sub='angelwitchpita', adult=True), + cls('TheDemonicAdventuresOfAngelWitchPita', sub='angelwitchpita', adult=True), cls('TheDestroyer', sub='heartless-destroyer', adult=True), - cls('TheDragonandtheLemur', sub='dal', adult=True), - cls('TheDreaming', sub='thedreaming'), + cls('TheDragonAndTheLemur', sub='dal', adult=True), + cls('TheDreaming', sub='thedreaming', endOfLife=True), cls('TheDrifter', sub='thedrifter', adult=True), - cls('TheElectricRose', sub='electricrosecomic'), + cls('TheElectricRose', host='www.electricrosecomic.com'), cls('TheForestofWhispers', sub='theforestofwhispers'), cls('TheGhostWithTheMost', sub='theghostwiththemost'), cls('TheGoldRiderofPern', sub='goldrider'), @@ -658,82 +649,83 @@ class SmackJeeves(_ParserScraper): cls('TheHeadhunters', sub='headhunters'), cls('TheHeartofEarth', sub='heart-of-earth'), cls('TheHobbitbic', sub='hobbit'), - cls('TheJosephComics', sub='josephcomics'), - cls('TheKeyHotelEnding', sub='tekeyhotel'), + cls('TheiaMania', sub='theia-mania'), + cls('TheJosephComics', sub='josephcomics', endOfLife=True), + cls('TheKeyHotelEnding', sub='tekeyhotel', endOfLife=True), cls('TheKeyToReality', sub='keytoreality'), cls('TheKwiddexProtocol', sub='kwiddexprotocol'), cls('TheLastBloodCafe', sub='lastbloodcafe'), + cls('ThelaughingDeath', sub='thelaughingdeath'), cls('TheLegendaryQueen', sub='legendaryqueen', adult=True), cls('TheLifeofMagFlamequill', sub='lifeofmag'), cls('TheLoneSwordsman', sub='theloneswordsman'), cls('TheLostland', sub='thelostlandcomic'), + cls('TheMadMan', sub='themadman'), cls('TheMegaManandSonicSpriteShowcase', sub='megamanshowcase'), cls('TheMoistTouch', sub='themoisttouch'), - cls('TheNOMEDSEGA', sub='nomed'), cls('TheNightSurfers', sub='thenightsurfers'), cls('TheNocheComicSeries', sub='nochecomicseries', adult=True), + cls('TheNOMEDSEGA', sub='nomed'), cls('ThePirateBalthasar', sub='thepiratebalthasar'), cls('ThePremise', sub='thepremise'), - cls('ThePrincessandtheGiant', sub='princess'), + cls('ThePrincessAndTheGiant', sub='princess', endOfLife=True), cls('ThePropertyofHate', sub='tpoh'), cls('TheReborn', sub='reborn'), - cls('TheSearchforHenryJekyll', sub='thesearchforhenryjekyll'), + cls('TheSearchForHenryJekyll', sub='thesearchforhenryjekyll'), cls('TheSilverLeague', sub='thesilverleague'), cls('TheSummerofBlakeSinclair', sub='blake-sinclair'), + cls('Theswordsmanandtheamnesiac', sub='tsata', adult=True), cls('TheTimeDog', sub='timedog'), cls('TheTytonNuzlockeChallengeEmeraldEdition', sub='tytonnuzlockeemerald'), cls('TheWastelands', sub='wastelands'), - cls('TheWhiteTower', sub='thewhitetower'), + cls('TheWhiteTower', sub='thewhitetower', endOfLife=True), 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('ThornTopia', sub='tnt100'), + cls('TLAAOK', sub='tlaaok', adult=True), 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('TPTruePower', sub='truepower'), + cls('TrainerWantsToFight', sub='twtf'), + cls('Transfusions', sub='transfusions', adult=True), + cls('TransUMan', sub='transuman', adult=True, endOfLife=True), + cls('TRIPP', sub='tripp'), + cls('TroubleNextDoor', sub='troublenextdoor', endOfLife=True), cls('UglyBoysLove', sub='shounenai'), cls('Uglygame', sub='uglygame'), cls('UnderTheDeadSkies', host='www.underthedeadskies.com'), 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('VACANT', sub='vacant'), cls('VerloreGeleentheid', host='verlore.thewebcomic.com'), cls('VoidMisadventures', sub='voidmisadventures'), cls('VoidTheGuideToAHealthyRelationship', sub='vtgtahr', adult=True), 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('WelcomeToFreakshow', sub='welcometofreakshow'), + cls('WelcomeToThePCA', sub='welcometothepca', endOfLife=True), cls('WhatAboutLove', sub='whataboutlove', adult=True), - cls('Whatisdeepinonesheart', sub='ones-mindt'), + cls('WHATAboutSHADOWS', sub='was', endOfLife=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('WhOLE', sub='whole', adult=True), + cls('Wildflowers', host='www.wildflowerslgbt.ca'), cls('WildWingBoysKoathArc', sub='wwbka'), - cls('Wildflowers', sub='wildflowers'), + cls('WildWingBoys', sub='wwb'), cls('WingsOverEthereal', sub='wings-over-ethereal'), cls('WingsTurnedtoDust', sub='wingsturnedtodust'), cls('Wootlabs', host='wootlabs.thewebcomic.com'), @@ -744,6 +736,5 @@ class SmackJeeves(_ParserScraper): cls('YoungCannibals', host='www.youngcannibals.net'), cls('ZaenWell', sub='zaenwell'), cls('ZeldaTheNewAdventureofLinkIIMajorasMask', sub='newlink'), - cls('_A_', sub='a-the-stalker'), # END AUTOUPDATE ) diff --git a/scripts/smackjeeves.py b/scripts/smackjeeves.py index 690604729..0fcd8f3f5 100755 --- a/scripts/smackjeeves.py +++ b/scripts/smackjeeves.py @@ -19,13 +19,10 @@ class SmackJeevesUpdater(ComicListUpdater): # Absolute minumum number of pages a comic may have (restrict search space) MIN_COMICS = 90 - ADULT_IMG = 'http://www.smackjeeves.com/images/mature_content.png' - # names of comics to exclude excluded_comics = ( # comic moved/we have a better module "Amya", - "Carciphona", "Footloose", "TitleUnrelated", @@ -85,11 +82,14 @@ class SmackJeevesUpdater(ComicListUpdater): "Okamirai", # missing images + "AGirlAndHerShadow", + "Carciphona", "CatboyattheCon", "ContraandtheSpamDump", "Darkkyosshorts", "DollarStoreCaviar", "EdgeofDecember", + "EvD", "HAndJ", "HEARD", "IwillbenapoSpamDump", @@ -104,6 +104,7 @@ class SmackJeevesUpdater(ComicListUpdater): "SJArtCollab", "SlightlyDifferent", "TheAttackoftheRecoloursSeason1", + "ThroughTheWonkyEye", "TotallyKotor", "WinterMelody", "ZonowTheHedgehog", @@ -117,53 +118,41 @@ class SmackJeevesUpdater(ComicListUpdater): def __init__(self, name): super(SmackJeevesUpdater, self).__init__(name) - self.sleep = 2 + self.sleep = 1.5 def handle_url(self, url): """Parse one search result page.""" data = self.get_url(url) num = 999 - for comicdiv in data.cssselect( - 'div#webcomic_search_results div.full_banner_div'): - page_url = comicdiv.cssselect('a:first-child')[0].attrib['href'] - name = comicdiv.cssselect('img.banny') - if name: - name = name[0].attrib['title'] - else: - name = comicdiv.cssselect('h2')[0].text - # find out how many images this comic has - mo = comicdiv.cssselect('span.small-meter') - if not mo: - print("ERROR matching number of comics", file=sys.stderr) - continue - num = int(mo[0].text.strip()) + for comictag in data.cssselect('a.card'): + page_url = comictag.attrib['href'] + name = comictag.cssselect('div.title')[0].text # search for url in extra page data2 = self.get_url(page_url) - mo = data2.cssselect('div#quick_reading_links a:last-child') - if not mo: - print("ERROR matching comic URL", file=sys.stderr) - continue + + # find out how many images this comic has + mo = data2.cssselect('div.num-pages div.value') + num = int(mo[0].text.strip().replace(',', '')) + + mo = data2.cssselect('div.buttons a:last-child') comic_url = mo[0].attrib['href'] # search for adult flag - adult = data2.xpath('//img[@src="' + self.ADULT_IMG + '"]') - self.add_comic(name, (comic_url, bool(adult)), num) + adult = data2.cssselect('div.mature') + updates = data2.cssselect('div.updates div.value')[0].text_content() + self.add_comic(name, (comic_url, len(adult) > 0, updates), num) - next_url = data.cssselect( - "div.search_nav td:last-child a")[0].attrib['href'] + next_url = data.cssselect("a.next")[0].attrib['href'] return (next_url, num) def collect_results(self): """Parse all search result pages.""" # Sort by number of comics, so we can abort when we get under some # threshold. - next_url = ( - "http://www.smackjeeves.com/search.php?submit=1" + - "&search_mode=webcomics&comic_title=&sort_by=4&special=all" + - "&last_update=6&style_all=on&genre_all=on&format_all=on") + next_url = "http://www.smackjeeves.com/search.php?last_update=6&sort_by=5" last_count = 999 while last_count >= self.MIN_COMICS: - print(last_count, file=sys.stderr, end=" ") + print(last_count, file=sys.stderr) next_url, last_count = self.handle_url(next_url) def get_entry(self, name, data): @@ -174,6 +163,8 @@ class SmackJeevesUpdater(ComicListUpdater): opt = "host='%s.%s'" % (sub, top) if data[1]: opt += ", adult=True" + if data[2] == 'Completed': + opt += ", endOfLife=True" return u"cls('%s', %s)," % (name, opt) if __name__ == '__main__':